From b6366e3e62c9fc506f36ca993407e7246a1f6d6e Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Mon, 10 Oct 2016 15:09:50 -0500 Subject: [PATCH 001/107] Making building and linking tests fully parallel. This uses similar code that is used withing the toolchains to parallelize the linking process of all the tests accross all the available CPUs. It also respects the `-j` parameter if you wish to limit the number of cores used. --- tools/test_api.py | 130 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 90 insertions(+), 40 deletions(-) diff --git a/tools/test_api.py b/tools/test_api.py index 126328f3ad2..9b0e01aafc8 100644 --- a/tools/test_api.py +++ b/tools/test_api.py @@ -37,6 +37,7 @@ from Queue import Queue, Empty from os.path import join, exists, basename, relpath from threading import Thread, Lock +from multiprocessing import Pool, cpu_count from subprocess import Popen, PIPE # Imports related to mbed build api @@ -2068,6 +2069,27 @@ def norm_relative_path(path, start): path = path.replace("\\", "/") return path + +def build_test_worker(*args, **kwargs): + bin_file = None + ret = { + 'result': False, + 'args': args, + 'kwargs': kwargs + } + + try: + bin_file = build_project(*args, **kwargs) + ret['result'] = True + ret['bin_file'] = bin_file + ret['kwargs'] = kwargs + + except: + ret['reason'] = sys.exc_info()[1] + + return ret + + def build_tests(tests, base_source_paths, build_path, target, toolchain_name, clean=False, notify=None, verbose=False, jobs=1, macros=None, silent=False, report=None, properties=None, @@ -2095,58 +2117,86 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, result = True - map_outputs_total = list() + jobs_count = int(jobs if jobs else cpu_count()) + p = Pool(processes=jobs_count) + + results = [] for test_name, test_path in tests.iteritems(): test_build_path = os.path.join(build_path, test_path) src_path = base_source_paths + [test_path] bin_file = None test_case_folder_name = os.path.basename(test_path) + args = (src_path, test_build_path, target, toolchain_name) + kwargs = { + 'jobs': jobs, + 'clean': clean, + 'macros': macros, + 'name': test_case_folder_name, + 'project_id': test_name, + 'report': report, + 'properties': properties, + 'verbose': verbose, + 'app_config': app_config, + 'build_profile': build_profile + } - try: - bin_file = build_project(src_path, test_build_path, target, toolchain_name, - jobs=jobs, - clean=clean, - macros=macros, - name=test_case_folder_name, - project_id=test_name, - report=report, - properties=properties, - verbose=verbose, - app_config=app_config, - build_profile=build_profile) - - except NotSupportedException: - pass - except ToolException: - result = False - if continue_on_build_fail: - continue - else: - break + results.append(p.apply_async(build_test_worker, args, kwargs)) - # If a clean build was carried out last time, disable it for the next build. - # Otherwise the previously built test will be deleted. - if clean: - clean = False - - # Normalize the path - if bin_file: - bin_file = norm_relative_path(bin_file, execution_directory) - - test_build['tests'][test_name] = { - "binaries": [ - { - "path": bin_file - } - ] - } + p.close() + result = True + itr = 0 + while len(results): + itr += 1 + if itr > 360000: + p.terminate() + p.join() + raise ToolException("Compile did not finish in 10 minutes") + + sleep(0.01) + pending = 0 + for r in results: + if r.ready() is True: + try: + worker_result = r.get() + results.remove(r) + + + for test_key in worker_result['kwargs']['report'][target_name][toolchain_name].keys(): + report[target_name][toolchain_name][test_key] = worker_result['kwargs']['report'][target_name][toolchain_name][test_key] + + if not worker_result['result'] and not isinstance(worker_result['reason'], NotSupportedException): + result = False + + if worker_result['result'] and 'bin_file' in worker_result: + bin_file = norm_relative_path(worker_result['bin_file'], execution_directory) + + test_build['tests'][worker_result['kwargs']['project_id']] = { + "binaries": [ + { + "path": bin_file + } + ] + } + + # TODO: add 'Image: bin_file' print statement here + + except ToolException, err: + if p._taskqueue.queue: + p._taskqueue.queue.clear() + sleep(0.5) + p.terminate() + p.join() + raise ToolException(err) + else: + pending += 1 + if pending >= jobs_count: + break - print 'Image: %s'% bin_file + p.join() test_builds = {} test_builds["%s-%s" % (target_name, toolchain_name)] = test_build - return result, test_builds From d1eaefe6884e4e8e17fd0ae8184c4b682418f9bf Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Tue, 11 Oct 2016 14:31:02 -0500 Subject: [PATCH 002/107] Modifying behavior of 'silent' option in toolchains The 'silent' option has always been present in the toolchains API, however it did not actually stop anything from being printed. Instead, it just changed what was added to the build log. This make the 'silent' stop all prints, but ensures that the output for the toolchain is still preserved and accessible via the 'get_output' function. --- tools/toolchains/__init__.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index 98def031915..c57dda55e68 100644 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -370,24 +370,24 @@ def print_notify(self, event, silent=False): msg = '[%(severity)s] %(file)s@%(line)s,%(col)s: %(message)s' % event elif event['type'] == 'progress': - if not silent: - if 'percent' in event: - msg = '{} [{:>5.1f}%]: {}'.format(event['action'].title(), - event['percent'], - basename(event['file'])) - else: - msg = '{}: {}'.format(event['action'].title(), - basename(event['file'])) + if 'percent' in event: + msg = '{} [{:>5.1f}%]: {}'.format(event['action'].title(), + event['percent'], + basename(event['file'])) + else: + msg = '{}: {}'.format(event['action'].title(), + basename(event['file'])) if msg: - print msg + if not silent: + print msg self.output += msg + "\n" def print_notify_verbose(self, event, silent=False): """ Default command line notification with more verbose mode """ if event['type'] in ['info', 'debug']: - self.print_notify(event) # standard handle + self.print_notify(event, silent=silent) # standard handle elif event['type'] == 'cc': event['severity'] = event['severity'].title() @@ -396,7 +396,8 @@ def print_notify_verbose(self, event, silent=False): event['target_name'] = event['target_name'].upper() if event['target_name'] else "Unknown" event['toolchain_name'] = event['toolchain_name'].upper() if event['toolchain_name'] else "Unknown" msg = '[%(severity)s] %(target_name)s::%(toolchain_name)s::%(file)s@%(line)s: %(message)s' % event - print msg + if not silent: + print msg self.output += msg + "\n" elif event['type'] == 'progress': From 09a09f70b7dcae95f2e911a9b34bda2a67415ff4 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Tue, 11 Oct 2016 14:33:24 -0500 Subject: [PATCH 003/107] Handling output of parallelized test building. This makes use of the reports generated by the building of tests to prevent output from interleaving when the build is parallelized. This required some changes to memap to return a generated string from the 'generate_output' function. I also had an option to stop the prints from memap to prevent text from interleaving --- tools/memap.py | 70 +++++++++++++++++++++++------------- tools/test_api.py | 29 ++++++++++++--- tools/toolchains/__init__.py | 2 +- 3 files changed, 70 insertions(+), 31 deletions(-) diff --git a/tools/memap.py b/tools/memap.py index f26e97a819f..0b9e91f6a13 100644 --- a/tools/memap.py +++ b/tools/memap.py @@ -9,6 +9,7 @@ import json import argparse from prettytable import PrettyTable +from StringIO import StringIO from utils import argparse_filestring_type, \ argparse_lowercase_hyphen_type, argparse_uppercase_type @@ -396,7 +397,7 @@ def search_objects(self, path): export_formats = ["json", "csv-ci", "table"] - def generate_output(self, export_format, file_output=None): + def generate_output(self, export_format, file_output=None, silent=False): """ Generates summary of memory map data Positional arguments: @@ -407,10 +408,13 @@ def generate_output(self, export_format, file_output=None): """ try: - if file_output: - file_desc = open(file_output, 'wb') + if silent: + file_desc = None else: - file_desc = sys.stdout + if file_output: + file_desc = open(file_output, 'wb') + else: + file_desc = sys.stdout except IOError as error: print "I/O error({0}): {1}".format(error.errno, error.strerror) return False @@ -418,19 +422,25 @@ def generate_output(self, export_format, file_output=None): to_call = {'json': self.generate_json, 'csv-ci': self.generate_csv, 'table': self.generate_table}[export_format] - to_call(file_desc) + output_string = to_call(file_desc) - if file_desc is not sys.stdout: + if file_desc is not sys.stdout and file_desc is not None: file_desc.close() + return output_string + def generate_json(self, file_desc): """Generate a json file from a memory map Positional arguments: file_desc - the file to write out the final report to """ - file_desc.write(json.dumps(self.mem_report, indent=4)) - file_desc.write('\n') + output = json.dumps(self.mem_report, indent=4) + if file_desc: + file_desc.write(output) + file_desc.write('\n') + + return output def generate_csv(self, file_desc): """Generate a CSV file from a memoy map @@ -438,7 +448,8 @@ def generate_csv(self, file_desc): Positional arguments: file_desc - the file to write out the final report to """ - csv_writer = csv.writer(file_desc, delimiter=',', + string_io = StringIO() + csv_writer = csv.writer(string_io, delimiter=',', quoting=csv.QUOTE_MINIMAL) csv_module_section = [] @@ -472,6 +483,11 @@ def generate_csv(self, file_desc): csv_writer.writerow(csv_module_section) csv_writer.writerow(csv_sizes) + if file_desc: + file_desc.write(string_io.getvalue()) + + return string_io.getvalue() + def generate_table(self, file_desc): """Generate a table from a memoy map @@ -504,28 +520,32 @@ def generate_table(self, file_desc): table.add_row(subtotal_row) - file_desc.write(table.get_string()) - file_desc.write('\n') + output = table.get_string() + output += '\n' if self.mem_summary['heap'] == 0: - file_desc.write("Allocated Heap: unknown\n") + output += "Allocated Heap: unknown\n" else: - file_desc.write("Allocated Heap: %s bytes\n" % - str(self.mem_summary['heap'])) + output += "Allocated Heap: %s bytes\n" % \ + str(self.mem_summary['heap']) if self.mem_summary['stack'] == 0: - file_desc.write("Allocated Stack: unknown\n") + output += "Allocated Stack: unknown\n" else: - file_desc.write("Allocated Stack: %s bytes\n" % - str(self.mem_summary['stack'])) - - file_desc.write("Total Static RAM memory (data + bss): %s bytes\n" % - (str(self.mem_summary['static_ram']))) - file_desc.write( - "Total RAM memory (data + bss + heap + stack): %s bytes\n" - % (str(self.mem_summary['total_ram']))) - file_desc.write("Total Flash memory (text + data + misc): %s bytes\n" % - (str(self.mem_summary['total_flash']))) + output += "Allocated Stack: %s bytes\n" % \ + str(self.mem_summary['stack']) + + output += "Total Static RAM memory (data + bss): %s bytes\n" % \ + str(self.mem_summary['static_ram']) + output += "Total RAM memory (data + bss + heap + stack): %s bytes\n" % \ + str(self.mem_summary['total_ram']) + output += "Total Flash memory (text + data + misc): %s bytes\n" % \ + str(self.mem_summary['total_flash']) + + if file_desc: + file_desc.write(output) + + return output toolchains = ["ARM", "ARM_STD", "ARM_MICRO", "GCC_ARM", "IAR"] diff --git a/tools/test_api.py b/tools/test_api.py index 9b0e01aafc8..af503316ebc 100644 --- a/tools/test_api.py +++ b/tools/test_api.py @@ -2071,6 +2071,19 @@ def norm_relative_path(path, start): def build_test_worker(*args, **kwargs): + """This is a worker function for the parallel building of tests. The `args` + and `kwargs` are passed directly to `build_project`. It returns a dictionary + with the following structure: + + { + 'result': `True` if no exceptions were thrown, `False` otherwise + 'reason': Instance of exception that was thrown on failure + 'bin_file': Path to the created binary if `build_project` was + successful. Not present otherwise + 'kwargs': The keyword arguments that were passed to `build_project`. + This includes arguments that were modified (ex. report) + } + """ bin_file = None ret = { 'result': False, @@ -2138,7 +2151,8 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, 'properties': properties, 'verbose': verbose, 'app_config': app_config, - 'build_profile': build_profile + 'build_profile': build_profile, + 'silent': True } results.append(p.apply_async(build_test_worker, args, kwargs)) @@ -2161,13 +2175,16 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, worker_result = r.get() results.remove(r) + # Take report from the kwargs and merge it into existing report + report_entry = worker_result['kwargs']['report'][target_name][toolchain_name] + for test_key in report_entry.keys(): + report[target_name][toolchain_name][test_key] = report_entry[test_key] - for test_key in worker_result['kwargs']['report'][target_name][toolchain_name].keys(): - report[target_name][toolchain_name][test_key] = worker_result['kwargs']['report'][target_name][toolchain_name][test_key] - + # Set the overall result to a failure if a build failure occurred if not worker_result['result'] and not isinstance(worker_result['reason'], NotSupportedException): result = False + # Adding binary path to test build result if worker_result['result'] and 'bin_file' in worker_result: bin_file = norm_relative_path(worker_result['bin_file'], execution_directory) @@ -2179,7 +2196,9 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, ] } - # TODO: add 'Image: bin_file' print statement here + test_key = worker_result['kwargs']['project_id'].upper() + print report[target_name][toolchain_name][test_key][0][0]['output'].rstrip() + print 'Image: %s\n' % bin_file except ToolException, err: if p._taskqueue.queue: diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index c57dda55e68..595f2207695 100644 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -1076,7 +1076,7 @@ def mem_stats(self, map): return None # Write output to stdout in text (pretty table) format - memap.generate_output('table') + self.info(memap.generate_output('table', silent=True)) # Write output to file in JSON format map_out = splitext(map)[0] + "_map.json" From 32b4e609822f057de199fb9c4380e6fd35c4b2f2 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Tue, 11 Oct 2016 18:24:01 -0500 Subject: [PATCH 004/107] Removing need for memap to printed through toolchains --- tools/build_api.py | 16 +++++- tools/test_api.py | 107 ++++++++++++++++++++--------------- tools/toolchains/__init__.py | 12 +--- 3 files changed, 79 insertions(+), 56 deletions(-) diff --git a/tools/build_api.py b/tools/build_api.py index 67f8d911b24..0890574d671 100644 --- a/tools/build_api.py +++ b/tools/build_api.py @@ -455,12 +455,26 @@ def build_project(src_paths, build_path, target, toolchain_name, # Link Program res, _ = toolchain.link_program(resources, build_path, name) + memap_instance = getattr(toolchain, 'memap_instance', None) + memap_table = '' + if memap_instance: + # Write output to stdout in text (pretty table) format + memap_table = memap_instance.generate_output('table', silent=silent) + + # Write output to file in JSON format + map_out = join(build_path, name + "_map.json") + memap_instance.generate_output('json', map_out) + + # Write output to file in CSV format for the CI + map_csv = join(build_path, name + "_map.csv") + memap_instance.generate_output('csv-ci', map_csv) + resources.detect_duplicates(toolchain) if report != None: end = time() cur_result["elapsed_time"] = end - start - cur_result["output"] = toolchain.get_output() + cur_result["output"] = toolchain.get_output() + memap_table cur_result["result"] = "OK" cur_result["memory_usage"] = toolchain.map_outputs diff --git a/tools/test_api.py b/tools/test_api.py index af503316ebc..67dde758945 100644 --- a/tools/test_api.py +++ b/tools/test_api.py @@ -2097,8 +2097,16 @@ def build_test_worker(*args, **kwargs): ret['bin_file'] = bin_file ret['kwargs'] = kwargs + except NotSupportedException, e: + ret['reason'] = e + except ToolException, e: + ret['reason'] = e + except KeyboardInterrupt, e: + ret['reason'] = e except: - ret['reason'] = sys.exc_info()[1] + # Print unhandled exceptions here + import traceback + traceback.print_exc(file=sys.stdout) return ret @@ -2132,7 +2140,6 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, jobs_count = int(jobs if jobs else cpu_count()) p = Pool(processes=jobs_count) - results = [] for test_name, test_path in tests.iteritems(): test_build_path = os.path.join(build_path, test_path) @@ -2166,51 +2173,61 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, p.terminate() p.join() raise ToolException("Compile did not finish in 10 minutes") + else: + sleep(0.01) + pending = 0 + for r in results: + if r.ready() is True: + try: + worker_result = r.get() + results.remove(r) - sleep(0.01) - pending = 0 - for r in results: - if r.ready() is True: - try: - worker_result = r.get() - results.remove(r) - - # Take report from the kwargs and merge it into existing report - report_entry = worker_result['kwargs']['report'][target_name][toolchain_name] - for test_key in report_entry.keys(): - report[target_name][toolchain_name][test_key] = report_entry[test_key] - - # Set the overall result to a failure if a build failure occurred - if not worker_result['result'] and not isinstance(worker_result['reason'], NotSupportedException): - result = False - - # Adding binary path to test build result - if worker_result['result'] and 'bin_file' in worker_result: - bin_file = norm_relative_path(worker_result['bin_file'], execution_directory) - - test_build['tests'][worker_result['kwargs']['project_id']] = { - "binaries": [ - { - "path": bin_file - } - ] - } + # Take report from the kwargs and merge it into existing report + report_entry = worker_result['kwargs']['report'][target_name][toolchain_name] + for test_key in report_entry.keys(): + report[target_name][toolchain_name][test_key] = report_entry[test_key] - test_key = worker_result['kwargs']['project_id'].upper() - print report[target_name][toolchain_name][test_key][0][0]['output'].rstrip() - print 'Image: %s\n' % bin_file - - except ToolException, err: - if p._taskqueue.queue: - p._taskqueue.queue.clear() - sleep(0.5) - p.terminate() - p.join() - raise ToolException(err) - else: - pending += 1 - if pending >= jobs_count: - break + # Set the overall result to a failure if a build failure occurred + if not worker_result['result'] and not isinstance(worker_result['reason'], NotSupportedException): + result = False + break + + # Adding binary path to test build result + if worker_result['result'] and 'bin_file' in worker_result: + bin_file = norm_relative_path(worker_result['bin_file'], execution_directory) + + test_build['tests'][worker_result['kwargs']['project_id']] = { + "binaries": [ + { + "path": bin_file + } + ] + } + + test_key = worker_result['kwargs']['project_id'].upper() + print report[target_name][toolchain_name][test_key][0][0]['output'].rstrip() + print 'Image: %s\n' % bin_file + + except: + if p._taskqueue.queue: + p._taskqueue.queue.clear() + sleep(0.5) + p.terminate() + p.join() + raise + else: + pending += 1 + if pending >= jobs_count: + break + + # Break as soon as possible if there is a failure and we are not + # continuing on build failures + if not result and not continue_on_build_fail: + if p._taskqueue.queue: + p._taskqueue.queue.clear() + sleep(0.5) + p.terminate() + break p.join() diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index 595f2207695..ecda6b88b69 100644 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -1075,16 +1075,8 @@ def mem_stats(self, map): self.info("Unknown toolchain for memory statistics %s" % toolchain) return None - # Write output to stdout in text (pretty table) format - self.info(memap.generate_output('table', silent=True)) - - # Write output to file in JSON format - map_out = splitext(map)[0] + "_map.json" - memap.generate_output('json', map_out) - - # Write output to file in CSV format for the CI - map_csv = splitext(map)[0] + "_map.csv" - memap.generate_output('csv-ci', map_csv) + # Store the memap instance for later use + self.memap_instance = memap # Here we return memory statistics structure (constructed after # call to generate_output) which contains raw data in bytes From beb7ec247a6784fcdbe039aa0e898e74e81b3948 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Tue, 11 Oct 2016 18:37:54 -0500 Subject: [PATCH 005/107] Removing dependency on StringIO, only change return type of table export --- tools/build_api.py | 5 ++++- tools/memap.py | 49 +++++++++++++++++++++------------------------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/tools/build_api.py b/tools/build_api.py index 0890574d671..a5816aefe8e 100644 --- a/tools/build_api.py +++ b/tools/build_api.py @@ -459,7 +459,10 @@ def build_project(src_paths, build_path, target, toolchain_name, memap_table = '' if memap_instance: # Write output to stdout in text (pretty table) format - memap_table = memap_instance.generate_output('table', silent=silent) + memap_table = memap_instance.generate_output('table') + + if not silent: + print memap_table # Write output to file in JSON format map_out = join(build_path, name + "_map.json") diff --git a/tools/memap.py b/tools/memap.py index 0b9e91f6a13..ba598c2c868 100644 --- a/tools/memap.py +++ b/tools/memap.py @@ -9,7 +9,6 @@ import json import argparse from prettytable import PrettyTable -from StringIO import StringIO from utils import argparse_filestring_type, \ argparse_lowercase_hyphen_type, argparse_uppercase_type @@ -397,7 +396,7 @@ def search_objects(self, path): export_formats = ["json", "csv-ci", "table"] - def generate_output(self, export_format, file_output=None, silent=False): + def generate_output(self, export_format, file_output=None): """ Generates summary of memory map data Positional arguments: @@ -405,16 +404,15 @@ def generate_output(self, export_format, file_output=None, silent=False): Keyword arguments: file_desc - descriptor (either stdout or file) + + Returns: generated string for the 'table' format, otherwise None """ try: - if silent: - file_desc = None + if file_output: + file_desc = open(file_output, 'wb') else: - if file_output: - file_desc = open(file_output, 'wb') - else: - file_desc = sys.stdout + file_desc = sys.stdout except IOError as error: print "I/O error({0}): {1}".format(error.errno, error.strerror) return False @@ -422,12 +420,12 @@ def generate_output(self, export_format, file_output=None, silent=False): to_call = {'json': self.generate_json, 'csv-ci': self.generate_csv, 'table': self.generate_table}[export_format] - output_string = to_call(file_desc) + output = to_call(file_desc) - if file_desc is not sys.stdout and file_desc is not None: + if file_desc is not sys.stdout: file_desc.close() - return output_string + return output def generate_json(self, file_desc): """Generate a json file from a memory map @@ -435,12 +433,10 @@ def generate_json(self, file_desc): Positional arguments: file_desc - the file to write out the final report to """ - output = json.dumps(self.mem_report, indent=4) - if file_desc: - file_desc.write(output) - file_desc.write('\n') + file_desc.write(json.dumps(self.mem_report, indent=4)) + file_desc.write('\n') - return output + return None def generate_csv(self, file_desc): """Generate a CSV file from a memoy map @@ -448,8 +444,7 @@ def generate_csv(self, file_desc): Positional arguments: file_desc - the file to write out the final report to """ - string_io = StringIO() - csv_writer = csv.writer(string_io, delimiter=',', + csv_writer = csv.writer(file_desc, delimiter=',', quoting=csv.QUOTE_MINIMAL) csv_module_section = [] @@ -483,16 +478,15 @@ def generate_csv(self, file_desc): csv_writer.writerow(csv_module_section) csv_writer.writerow(csv_sizes) - if file_desc: - file_desc.write(string_io.getvalue()) - - return string_io.getvalue() + return None def generate_table(self, file_desc): """Generate a table from a memoy map Positional arguments: file_desc - the file to write out the final report to + + Returns: string of the generated table """ # Create table columns = ['Module'] @@ -542,9 +536,6 @@ def generate_table(self, file_desc): output += "Total Flash memory (text + data + misc): %s bytes\n" % \ str(self.mem_summary['total_flash']) - if file_desc: - file_desc.write(output) - return output toolchains = ["ARM", "ARM_STD", "ARM_MICRO", "GCC_ARM", "IAR"] @@ -667,11 +658,15 @@ def main(): if memap.parse(args.file, args.toolchain) is False: sys.exit(0) + returned_string = None # Write output in file if args.output != None: - memap.generate_output(args.export, args.output) + returned_string = memap.generate_output(args.export, args.output) else: # Write output in screen - memap.generate_output(args.export) + returned_string = memap.generate_output(args.export) + + if args.export == 'table' and returned_string: + print returned_string sys.exit(0) From 62c529819043e43035fe4eaf48b8835204832f43 Mon Sep 17 00:00:00 2001 From: bcostm Date: Thu, 13 Oct 2016 10:25:20 +0200 Subject: [PATCH 006/107] Fix wrong timer channel number of pwm PB_5 pin --- .../TARGET_STM32F0/TARGET_NUCLEO_F072RB/PeripheralPins.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/PeripheralPins.c index dda64c3ee90..e0a2e4a5aac 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/PeripheralPins.c +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/PeripheralPins.c @@ -116,7 +116,7 @@ const PinMap PinMap_PWM[] = { // {PB_1, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM1, 3, 1)}, // TIM1_CH3N // {PB_3, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2, 2, 0)}, // TIM2_CH2 {PB_4, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM3, 1, 0)}, // TIM3_CH1 - {PB_5, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM3, 1, 0)}, // TIM3_CH2 + {PB_5, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM3, 2, 0)}, // TIM3_CH2 {PB_6, PWM_16, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM16, 1, 1)}, // TIM16_CH1N {PB_7, PWM_17, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM17, 1, 1)}, // TIM17_CH1N {PB_8, PWM_16, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM16, 1, 0)}, // TIM16_CH1 From f118e893fddd84cc69ea5d3fb99d4c6e195edb3f Mon Sep 17 00:00:00 2001 From: bcostm Date: Thu, 13 Oct 2016 16:28:57 +0200 Subject: [PATCH 007/107] STM32xx - Change how the ADC internal pins are checked before pinmap_pinout --- targets/TARGET_STM/TARGET_STM32F0/analogin_api.c | 5 +++-- targets/TARGET_STM/TARGET_STM32F1/analogin_api.c | 5 +++-- targets/TARGET_STM/TARGET_STM32F2/analogin_api.c | 5 +++-- targets/TARGET_STM/TARGET_STM32F3/analogin_api.c | 5 +++-- targets/TARGET_STM/TARGET_STM32F4/analogin_api.c | 5 +++-- targets/TARGET_STM/TARGET_STM32F7/analogin_api.c | 5 +++-- targets/TARGET_STM/TARGET_STM32L0/analogin_api.c | 5 +++-- targets/TARGET_STM/TARGET_STM32L1/analogin_api.c | 5 +++-- targets/TARGET_STM/TARGET_STM32L4/analogin_api.c | 5 +++-- 9 files changed, 27 insertions(+), 18 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F0/analogin_api.c b/targets/TARGET_STM/TARGET_STM32F0/analogin_api.c index 9752cdd05d8..a55b0fa52b0 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/analogin_api.c +++ b/targets/TARGET_STM/TARGET_STM32F0/analogin_api.c @@ -50,8 +50,9 @@ void analogin_init(analogin_t *obj, PinName pin) { MBED_ASSERT(function != (uint32_t)NC); obj->channel = STM_PIN_CHANNEL(function); - // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat) - if ((obj->channel != 16) && (obj->channel != 17) && (obj->channel != 18)) { + // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat, ...) + // ADC Internal Channels "pins" are described in PinNames.h and must have a value >= 0xF0 + if (pin < 0xF0) { pinmap_pinout(pin, PinMap_ADC); } diff --git a/targets/TARGET_STM/TARGET_STM32F1/analogin_api.c b/targets/TARGET_STM/TARGET_STM32F1/analogin_api.c index d419d87a6b5..bd2da780f97 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/analogin_api.c +++ b/targets/TARGET_STM/TARGET_STM32F1/analogin_api.c @@ -52,8 +52,9 @@ void analogin_init(analogin_t *obj, PinName pin) MBED_ASSERT(function != (uint32_t)NC); obj->channel = STM_PIN_CHANNEL(function); - // Configure GPIO excepted for internal channels (Temperature, Vref) - if ((obj->channel != 16) && (obj->channel != 17)) { + // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat, ...) + // ADC Internal Channels "pins" are described in PinNames.h and must have a value >= 0xF0 + if (pin < 0xF0) { pinmap_pinout(pin, PinMap_ADC); } diff --git a/targets/TARGET_STM/TARGET_STM32F2/analogin_api.c b/targets/TARGET_STM/TARGET_STM32F2/analogin_api.c index 9428377a3ed..d6efdfb4cc6 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/analogin_api.c +++ b/targets/TARGET_STM/TARGET_STM32F2/analogin_api.c @@ -58,8 +58,9 @@ void analogin_init(analogin_t *obj, PinName pin) MBED_ASSERT(function != (uint32_t)NC); obj->channel = STM_PIN_CHANNEL(function); - // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat) - if ((obj->channel != 16) && (obj->channel != 17) && (obj->channel != 18)) { + // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat, ...) + // ADC Internal Channels "pins" are described in PinNames.h and must have a value >= 0xF0 + if (pin < 0xF0) { pinmap_pinout(pin, PinMap_ADC); } diff --git a/targets/TARGET_STM/TARGET_STM32F3/analogin_api.c b/targets/TARGET_STM/TARGET_STM32F3/analogin_api.c index 85ce3201ad1..3a0c690640f 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/analogin_api.c +++ b/targets/TARGET_STM/TARGET_STM32F3/analogin_api.c @@ -62,8 +62,9 @@ void analogin_init(analogin_t *obj, PinName pin) MBED_ASSERT(function != (uint32_t)NC); obj->channel = STM_PIN_CHANNEL(function); - // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat) - if ((obj->channel != 16) && (obj->channel != 17) && (obj->channel != 18)) { + // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat, ...) + // ADC Internal Channels "pins" are described in PinNames.h and must have a value >= 0xF0 + if (pin < 0xF0) { pinmap_pinout(pin, PinMap_ADC); } diff --git a/targets/TARGET_STM/TARGET_STM32F4/analogin_api.c b/targets/TARGET_STM/TARGET_STM32F4/analogin_api.c index 7cc8edcf7c1..f2204a1551c 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/analogin_api.c +++ b/targets/TARGET_STM/TARGET_STM32F4/analogin_api.c @@ -58,8 +58,9 @@ void analogin_init(analogin_t *obj, PinName pin) MBED_ASSERT(function != (uint32_t)NC); obj->channel = STM_PIN_CHANNEL(function); - // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat) - if ((obj->channel != 16) && (obj->channel != 17) && (obj->channel != 18)) { + // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat, ...) + // ADC Internal Channels "pins" are described in PinNames.h and must have a value >= 0xF0 + if (pin < 0xF0) { pinmap_pinout(pin, PinMap_ADC); } diff --git a/targets/TARGET_STM/TARGET_STM32F7/analogin_api.c b/targets/TARGET_STM/TARGET_STM32F7/analogin_api.c index 2eff4f10321..f98be3b6429 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/analogin_api.c +++ b/targets/TARGET_STM/TARGET_STM32F7/analogin_api.c @@ -59,8 +59,9 @@ void analogin_init(analogin_t *obj, PinName pin) MBED_ASSERT(function != (uint32_t)NC); obj->channel = STM_PIN_CHANNEL(function); - // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat) - if ((obj->channel != 16) && (obj->channel != 17) && (obj->channel != 18)) { + // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat, ...) + // ADC Internal Channels "pins" are described in PinNames.h and must have a value >= 0xF0 + if (pin < 0xF0) { pinmap_pinout(pin, PinMap_ADC); } diff --git a/targets/TARGET_STM/TARGET_STM32L0/analogin_api.c b/targets/TARGET_STM/TARGET_STM32L0/analogin_api.c index 8dbbf43b3a1..fa8d4765c0b 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/analogin_api.c +++ b/targets/TARGET_STM/TARGET_STM32L0/analogin_api.c @@ -51,8 +51,9 @@ void analogin_init(analogin_t *obj, PinName pin) MBED_ASSERT(function != (uint32_t)NC); obj->channel = STM_PIN_CHANNEL(function); - // Configure GPIO excepted for internal channels (Temperature, Vref, Vlcd) - if ((obj->channel != 16) && (obj->channel != 17) && (obj->channel != 18)) { + // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat, ...) + // ADC Internal Channels "pins" are described in PinNames.h and must have a value >= 0xF0 + if (pin < 0xF0) { pinmap_pinout(pin, PinMap_ADC); } diff --git a/targets/TARGET_STM/TARGET_STM32L1/analogin_api.c b/targets/TARGET_STM/TARGET_STM32L1/analogin_api.c index 81be02ffc9e..53a3ac06c05 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/analogin_api.c +++ b/targets/TARGET_STM/TARGET_STM32L1/analogin_api.c @@ -53,8 +53,9 @@ void analogin_init(analogin_t *obj, PinName pin) MBED_ASSERT(function != (uint32_t)NC); obj->channel = STM_PIN_CHANNEL(function); - // Configure GPIO excepted for internal channels (Temperature, Vref) - if ((obj->channel != 16) && (obj->channel != 17)) { + // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat, ...) + // ADC Internal Channels "pins" are described in PinNames.h and must have a value >= 0xF0 + if (pin < 0xF0) { pinmap_pinout(pin, PinMap_ADC); } diff --git a/targets/TARGET_STM/TARGET_STM32L4/analogin_api.c b/targets/TARGET_STM/TARGET_STM32L4/analogin_api.c index 9b4b623a716..1ec39e83dd3 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/analogin_api.c +++ b/targets/TARGET_STM/TARGET_STM32L4/analogin_api.c @@ -51,8 +51,9 @@ void analogin_init(analogin_t *obj, PinName pin) MBED_ASSERT(function != (uint32_t)NC); obj->channel = STM_PIN_CHANNEL(function); - // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat) - if ((obj->channel != 0) && (obj->channel != 17) && (obj->channel != 18)) { + // Configure GPIO excepted for internal channels (Temperature, Vref, Vbat, ...) + // ADC Internal Channels "pins" are described in PinNames.h and must have a value >= 0xF0 + if (pin < 0xF0) { pinmap_pinout(pin, PinMap_ADC); } From ad115672a2b6e1247c6d5b5f7d094d731fced513 Mon Sep 17 00:00:00 2001 From: jeromecoutant Date: Wed, 12 Oct 2016 10:07:27 +0200 Subject: [PATCH 008/107] digital_loop tests update for STM32 --- .../tests/mbed/digitalin_digitalout/main.cpp | 44 ++++++------------- .../tests/mbed/digitalinout/main.cpp | 40 +++++++---------- .../tests/mbed/interruptin/main.cpp | 41 +++++++---------- tools/tests.py | 2 +- 4 files changed, 45 insertions(+), 82 deletions(-) diff --git a/features/unsupported/tests/mbed/digitalin_digitalout/main.cpp b/features/unsupported/tests/mbed/digitalin_digitalout/main.cpp index 82f0d88110a..1e1de891bb7 100644 --- a/features/unsupported/tests/mbed/digitalin_digitalout/main.cpp +++ b/features/unsupported/tests/mbed/digitalin_digitalout/main.cpp @@ -9,37 +9,21 @@ DigitalIn in(dp2); // port pin), D1 is used as USBTX DigitalOut out(D7); DigitalIn in(D2); +#elif defined(TARGET_STM) && defined(TARGET_FF_ARDUINO) +// TARGET_FF_ARDUINO cannot be used +// D0 is used as USBRX for some NUCLEO64 +// D7 is not used for some NUCLEO32 +DigitalOut out(D9); +DigitalIn in(D2); + +#elif defined(TARGET_DISCO_L053C8) || \ + defined(TARGET_DISCO_F334C8) +DigitalOut out(PA_15); +DigitalIn in(PA_8); -#elif defined(TARGET_DISCO_F469NI) -DigitalOut out(PB_1); -DigitalIn in(PG_9); - -#elif defined(TARGET_NUCLEO_F030R8) || \ - defined(TARGET_NUCLEO_F070RB) || \ - defined(TARGET_NUCLEO_F072RB) || \ - defined(TARGET_NUCLEO_F091RC) || \ - defined(TARGET_NUCLEO_F103RB) || \ - defined(TARGET_NUCLEO_F302R8) || \ - defined(TARGET_NUCLEO_F303RE) || \ - defined(TARGET_NUCLEO_F334R8) || \ - defined(TARGET_NUCLEO_F401RE) || \ - defined(TARGET_NUCLEO_F410RB) || \ - defined(TARGET_NUCLEO_F411RE) || \ - defined(TARGET_NUCLEO_F429ZI) || \ - defined(TARGET_NUCLEO_F446RE) || \ - defined(TARGET_NUCLEO_F446ZE) || \ - defined(TARGET_NUCLEO_L053R8) || \ - defined(TARGET_NUCLEO_L073RZ) || \ - defined(TARGET_NUCLEO_L152RE) -DigitalOut out(PC_7); -DigitalIn in(PB_8); - -#elif defined(TARGET_NUCLEO_F031K6) || \ - defined(TARGET_NUCLEO_F042K6) || \ - defined(TARGET_NUCLEO_L011K4) || \ - defined(TARGET_NUCLEO_L031K6) -DigitalOut out(A4); -DigitalIn in(A5); +#elif defined(TARGET_DISCO_L476VG) +DigitalOut out(PA_1); +DigitalIn in(PA_2); #elif defined(TARGET_ARCH_MAX) || \ defined(TARGET_DISCO_F407VG) || \ diff --git a/features/unsupported/tests/mbed/digitalinout/main.cpp b/features/unsupported/tests/mbed/digitalinout/main.cpp index 21eb38f1ac0..22a1fad2af7 100644 --- a/features/unsupported/tests/mbed/digitalinout/main.cpp +++ b/features/unsupported/tests/mbed/digitalinout/main.cpp @@ -10,31 +10,21 @@ DigitalInOut d2(dp2); DigitalInOut d1(D2); DigitalInOut d2(D7); -#elif defined(TARGET_NUCLEO_F030R8) || \ - defined(TARGET_NUCLEO_F070RB) || \ - defined(TARGET_NUCLEO_F072RB) || \ - defined(TARGET_NUCLEO_F091RC) || \ - defined(TARGET_NUCLEO_F103RB) || \ - defined(TARGET_NUCLEO_F302R8) || \ - defined(TARGET_NUCLEO_F303RE) || \ - defined(TARGET_NUCLEO_F334R8) || \ - defined(TARGET_NUCLEO_F401RE) || \ - defined(TARGET_NUCLEO_F410RB) || \ - defined(TARGET_NUCLEO_F411RE) || \ - defined(TARGET_NUCLEO_F446RE) || \ - defined(TARGET_NUCLEO_F446ZE) || \ - defined(TARGET_NUCLEO_L053R8) || \ - defined(TARGET_NUCLEO_L073RZ) || \ - defined(TARGET_NUCLEO_L152RE) -DigitalInOut d1(PC_7); -DigitalInOut d2(PB_8); - -#elif defined(TARGET_NUCLEO_F031K6) || \ - defined(TARGET_NUCLEO_F042K6) || \ - defined(TARGET_NUCLEO_L011K4) || \ - defined(TARGET_NUCLEO_L031K6) -DigitalInOut d1(A4); -DigitalInOut d2(A5); +#elif defined(TARGET_STM) && defined(TARGET_FF_ARDUINO) +// TARGET_FF_ARDUINO cannot be used +// D0 is used as USBRX for some NUCLEO64 +// D7 is not used for some NUCLEO32 +DigitalInOut d1(D9); +DigitalInOut d2(D2); + +#elif defined(TARGET_DISCO_L053C8) || \ + defined(TARGET_DISCO_F334C8) +DigitalInOut d1(PA_15); +DigitalInOut d2(PA_8); + +#elif defined(TARGET_DISCO_L476VG) +DigitalInOut d1(PA_1); +DigitalInOut d2(PA_2); #elif defined(TARGET_ARCH_MAX) || \ defined(TARGET_DISCO_F407VG) || \ diff --git a/features/unsupported/tests/mbed/interruptin/main.cpp b/features/unsupported/tests/mbed/interruptin/main.cpp index d680849f7e3..cf49d86653a 100644 --- a/features/unsupported/tests/mbed/interruptin/main.cpp +++ b/features/unsupported/tests/mbed/interruptin/main.cpp @@ -39,32 +39,21 @@ void in_handler() { #define PIN_IN (p11) #define PIN_OUT (p12) -#elif defined(TARGET_NUCLEO_F030R8) || \ - defined(TARGET_NUCLEO_F070RB) || \ - defined(TARGET_NUCLEO_F072RB) || \ - defined(TARGET_NUCLEO_F091RC) || \ - defined(TARGET_NUCLEO_F103RB) || \ - defined(TARGET_NUCLEO_F302R8) || \ - defined(TARGET_NUCLEO_F303RE) || \ - defined(TARGET_NUCLEO_F334R8) || \ - defined(TARGET_NUCLEO_F401RE) || \ - defined(TARGET_NUCLEO_F410RB) || \ - defined(TARGET_NUCLEO_F411RE) || \ - defined(TARGET_NUCLEO_F429ZI) || \ - defined(TARGET_NUCLEO_F446RE) || \ - defined(TARGET_NUCLEO_F446ZE) || \ - defined(TARGET_NUCLEO_L053R8) || \ - defined(TARGET_NUCLEO_L073RZ) || \ - defined(TARGET_NUCLEO_L152RE) -#define PIN_IN PB_8 -#define PIN_OUT PC_7 - -#elif defined(TARGET_NUCLEO_F031K6) || \ - defined(TARGET_NUCLEO_F042K6) || \ - defined(TARGET_NUCLEO_L011K4) || \ - defined(TARGET_NUCLEO_L031K6) -#define PIN_IN A4 -#define PIN_OUT A5 +#elif defined(TARGET_STM) && defined(TARGET_FF_ARDUINO) +// TARGET_FF_ARDUINO cannot be used +// D0 is used as USBRX for some NUCLEO64 +// D7 is not used for some NUCLEO32 +#define PIN_OUT D2 +#define PIN_IN D9 + +#elif defined(TARGET_DISCO_L053C8) || \ + defined(TARGET_DISCO_F334C8) +#define PIN_OUT PA_15 +#define PIN_IN PA_8 + +#elif defined(TARGET_DISCO_L476VG) +#define PIN_OUT PA_1 +#define PIN_IN PA_2 #elif defined(TARGET_ARCH_MAX) || \ defined(TARGET_DISCO_F407VG) || \ diff --git a/tools/tests.py b/tools/tests.py index fae1ac85e6e..b4103f02c98 100644 --- a/tools/tests.py +++ b/tools/tests.py @@ -51,10 +51,10 @@ * digital_loop (Digital(In|Out|InOut), InterruptIn): * Arduino headers: (D0 <-> D7) + * NUCLEO_*: (D2 <-> D9) * LPC1549: (D2 <-> D7) * LPC1*: (p5 <-> p25 ) * KL25Z: (PTA5<-> PTC6) - * NUCLEO_F103RB: (PC_6 <-> PB_8) * MAXWSNENV: (TP3 <-> TP4) * MAX32600MBED: (P1_0 <-> P4_7) * VK_RZ_A1H: (P3_2 <-> P5_6) From 957c073edfa291c1f004dd1fae9d5b8a881cb717 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 17 Oct 2016 13:44:15 +0200 Subject: [PATCH 009/107] nRF5 - added serial flow control configure API implementation --- .../TARGET_NORDIC/TARGET_NRF5/serial_api.c | 30 ++++++++++++++----- targets/targets.json | 4 +-- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/serial_api.c b/targets/TARGET_NORDIC/TARGET_NRF5/serial_api.c index d94e9aecfbe..5af3bccd3c6 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/serial_api.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/serial_api.c @@ -116,6 +116,9 @@ typedef struct { static uart_ctlblock_t uart_cb[UART_INSTANCE_COUNT]; +static void internal_set_hwfc(FlowControl type, + PinName rxflow, PinName txflow); + #if DEVICE_SERIAL_ASYNCH static void end_asynch_rx(void) @@ -317,9 +320,10 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) { nrf_uart_baudrate_set(UART_INSTANCE, UART_CB.baudrate); nrf_uart_configure(UART_INSTANCE, UART_CB.parity, UART_CB.hwfc); if (UART_CB.hwfc == NRF_UART_HWFC_ENABLED) { - serial_set_flow_control(obj, FlowControlRTSCTS, + internal_set_hwfc(FlowControlRTSCTS, (PinName) UART_CB.pselrts, (PinName) UART_CB.pselcts); } + nrf_uart_enable(UART_INSTANCE); UART_CB.initialized = true; @@ -528,15 +532,14 @@ void serial_break_clear(serial_t *obj) nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTTX); } -void serial_set_flow_control(serial_t *obj, FlowControl type, + +static void internal_set_hwfc(FlowControl type, PinName rxflow, PinName txflow) { - (void)obj; - UART_CB.pselrts = - (rxflow == NC) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t)rxflow; + ((rxflow == NC) || (type == FlowControlCTS)) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t)rxflow; UART_CB.pselcts = - (txflow == NC) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t)txflow; + ((txflow == NC) || (type == FlowControlRTS)) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t)txflow; if (UART_CB.pselrts != NRF_UART_PSEL_DISCONNECTED) { nrf_gpio_pin_set(UART_CB.pselrts); @@ -545,11 +548,24 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, if (UART_CB.pselcts != NRF_UART_PSEL_DISCONNECTED) { nrf_gpio_cfg_input(UART_CB.pselcts, NRF_GPIO_PIN_NOPULL); } - nrf_uart_disable(UART_INSTANCE); + + UART_CB.hwfc = (type == FlowControlNone)? NRF_UART_HWFC_DISABLED : UART0_CONFIG_HWFC; + + nrf_uart_configure(UART_INSTANCE, UART_CB.parity, UART_CB.hwfc); nrf_uart_hwfc_pins_set(UART_INSTANCE, UART_CB.pselrts, UART_CB.pselcts); +} + +void serial_set_flow_control(serial_t *obj, FlowControl type, + PinName rxflow, PinName txflow) +{ + (void)obj; + + nrf_uart_disable(UART_INSTANCE); + internal_set_hwfc(type, rxflow, txflow); nrf_uart_enable(UART_INSTANCE); } + void serial_clear(serial_t *obj) { (void)obj; } diff --git a/targets/targets.json b/targets/targets.json index bf35a4d7ad7..8843e87c5b2 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -2240,7 +2240,7 @@ "NRF51_DK": { "supported_form_factors": ["ARDUINO"], "inherits": ["MCU_NRF51_32K_UNIFIED"], - "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"], + "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"], "release_versions": ["2", "5"], "device_name": "nRF51822_xxAA" }, @@ -2291,7 +2291,7 @@ "supported_form_factors": ["ARDUINO"], "inherits": ["MCU_NRF52"], "macros_add": ["BOARD_PCA10040", "NRF52_PAN_12", "NRF52_PAN_15", "NRF52_PAN_58", "NRF52_PAN_55", "NRF52_PAN_54", "NRF52_PAN_31", "NRF52_PAN_30", "NRF52_PAN_51", "NRF52_PAN_36", "NRF52_PAN_53", "S132", "CONFIG_GPIO_AS_PINRESET", "BLE_STACK_SUPPORT_REQD", "SWI_DISABLE0", "NRF52_PAN_20", "NRF52_PAN_64", "NRF52_PAN_62", "NRF52_PAN_63"], - "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"], + "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"], "release_versions": ["2", "5"], "device_name": "nRF52832_xxAA" }, From f5493913fce16d0f6def5792be7a7b9a9422bff1 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Thu, 20 Oct 2016 11:06:24 -0500 Subject: [PATCH 010/107] Making IAR exporter build test parallelized --- tools/export/iar/__init__.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tools/export/iar/__init__.py b/tools/export/iar/__init__.py index 0fdd74564be..f595a3606f4 100644 --- a/tools/export/iar/__init__.py +++ b/tools/export/iar/__init__.py @@ -10,6 +10,7 @@ from tools.export.exporters import Exporter, FailedBuildException import json from tools.export.cmsis import DeviceCMSIS +from multiprocessing import cpu_count class IAR(Exporter): NAME = 'iar' @@ -101,7 +102,7 @@ def generate(self): flags['c_flags'].remove('--vla') if '--no_static_destruction' in flags['c_flags']: flags['c_flags'].remove('--no_static_destruction') - #Optimizations + #Optimizations if '-Oh' in flags['c_flags']: flags['c_flags'].remove('-Oh') ctx = { @@ -135,6 +136,17 @@ def build(self): raise Exception("IarBuild.exe not found. Add to path.") cmd = [iar_exe, proj_file, '-build', self.project_name] + + # IAR does not support a '0' option to automatically use all + # available CPUs, so we use Python's multiprocessing library + # to detect the number of CPUs available + cpus_available = cpu_count() + jobs = cpus_available if cpus_available else None + + # Only add the parallel flag if we're using more than one CPU + if jobs: + cmd += ['-parallel', str(jobs)] + p = Popen(cmd, stdout=PIPE, stderr=PIPE) num_errors = 0 #Parse the output for printing and errors From 1b82e8c540c3b9466a3ff374fbea07dc8a63a76f Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 20 Oct 2016 13:52:17 +0200 Subject: [PATCH 011/107] nrf5 fix - gpioe pin was uninitialzied for new mode, should been uninitailzed for mode. --- targets/TARGET_NORDIC/TARGET_NRF5/gpio_api.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/gpio_api.c b/targets/TARGET_NORDIC/TARGET_NRF5/gpio_api.c index ab1714f7f5c..a5c6c850c21 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/gpio_api.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/gpio_api.c @@ -90,8 +90,7 @@ int gpio_read(gpio_t *obj) } } - -static void gpio_apply_config(uint8_t pin) +static void gpiote_pin_uninit(uint8_t pin) { if (m_gpio_initialized & (1UL << pin)) { if ((m_gpio_cfg[pin].direction == PIN_OUTPUT) && (!m_gpio_cfg[pin].used_as_irq)) { @@ -101,7 +100,10 @@ static void gpio_apply_config(uint8_t pin) nrf_drv_gpiote_in_uninit(pin); } } +} +static void gpio_apply_config(uint8_t pin) +{ if (m_gpio_cfg[pin].used_as_gpio || m_gpio_cfg[pin].used_as_irq) { if ((m_gpio_cfg[pin].direction == PIN_INPUT) || (m_gpio_cfg[pin].used_as_irq)) { @@ -151,6 +153,9 @@ static void gpio_apply_config(uint8_t pin) void gpio_mode(gpio_t *obj, PinMode mode) { MBED_ASSERT(obj->pin <= GPIO_PIN_COUNT); + + gpiote_pin_uninit(obj->pin); // try to uninitialize gpio before a change. + m_gpio_cfg[obj->pin].pull = mode; gpio_apply_config(obj->pin); } @@ -159,6 +164,9 @@ void gpio_mode(gpio_t *obj, PinMode mode) void gpio_dir(gpio_t *obj, PinDirection direction) { MBED_ASSERT(obj->pin <= GPIO_PIN_COUNT); + + gpiote_pin_uninit(obj->pin); // try to uninitialize gpio before a change. + m_gpio_cfg[obj->pin].direction = direction; gpio_apply_config(obj->pin); } @@ -176,6 +184,8 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 MBED_ASSERT((uint32_t)pin < GPIO_PIN_COUNT); (void) nrf_drv_gpiote_init(); + gpiote_pin_uninit(pin); // try to uninitialize gpio before a change. + m_gpio_cfg[pin].used_as_irq = true; m_channel_ids[pin] = id; obj->ch = pin; From 2a9bc597d204ad0d97e5dcd3abff7c9545a79eba Mon Sep 17 00:00:00 2001 From: Rob Meades Date: Thu, 13 Oct 2016 14:01:30 +0100 Subject: [PATCH 012/107] Add u-blox Sara-N target. --- TESTS/mbedmicro-rtos-mbed/threads/main.cpp | 2 + .../TARGET_HI2110/PeripheralNames.h | 87 ++ .../TARGET_ublox/TARGET_HI2110/PortNames.h | 31 + .../TARGET_SARA_NBIOT/PinNames.h | 111 +++ .../TARGET_HI2110/TARGET_SARA_NBIOT/device.h | 23 + .../device/TOOLCHAIN_ARM_STD/hi2110.sct | 15 + .../device/TOOLCHAIN_ARM_STD/startup_hi2110.s | 163 ++++ .../device/TOOLCHAIN_ARM_STD/sys.cpp | 31 + .../device/TOOLCHAIN_GCC_ARM/hi2110.ld | 170 ++++ .../device/TOOLCHAIN_GCC_ARM/startup_hi2110.s | 254 ++++++ .../device/TOOLCHAIN_IAR/hi2110.icf | 60 ++ .../device/TOOLCHAIN_IAR/startup_hi2110.s | 202 +++++ .../TARGET_ublox/TARGET_HI2110/device/cmsis.h | 27 + .../TARGET_HI2110/device/cmsis_nvic.c | 50 ++ .../TARGET_HI2110/device/cmsis_nvic.h | 38 + .../TARGET_HI2110/device/hi2110.h | 492 +++++++++++ .../TARGET_HI2110/device/system_hi2110.c | 86 ++ .../TARGET_HI2110/device/system_hi2110.h | 69 ++ targets/TARGET_ublox/TARGET_HI2110/gpio_api.c | 80 ++ .../TARGET_ublox/TARGET_HI2110/gpio_irq_api.c | 148 ++++ .../TARGET_ublox/TARGET_HI2110/gpio_object.h | 57 ++ .../TARGET_ublox/TARGET_HI2110/hi2110_init.c | 69 ++ .../TARGET_ublox/TARGET_HI2110/hi2110_init.h | 38 + .../TARGET_ublox/TARGET_HI2110/lp_ticker.c | 340 ++++++++ .../TARGET_HI2110/mbed_overrides.c | 38 + targets/TARGET_ublox/TARGET_HI2110/objects.h | 73 ++ targets/TARGET_ublox/TARGET_HI2110/pinmap.c | 145 ++++ targets/TARGET_ublox/TARGET_HI2110/port_api.c | 103 +++ .../TARGET_ublox/TARGET_HI2110/serial_api.c | 819 ++++++++++++++++++ targets/TARGET_ublox/TARGET_HI2110/sleep.c | 53 ++ .../TARGET_ublox/TARGET_HI2110/us_ticker.c | 247 ++++++ targets/TARGET_ublox/mbed_rtx.h | 37 + targets/targets.json | 26 + 33 files changed, 4184 insertions(+) create mode 100644 targets/TARGET_ublox/TARGET_HI2110/PeripheralNames.h create mode 100644 targets/TARGET_ublox/TARGET_HI2110/PortNames.h create mode 100644 targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/PinNames.h create mode 100644 targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/device.h create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/hi2110.sct create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/startup_hi2110.s create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/sys.cpp create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/hi2110.ld create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/startup_hi2110.s create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/hi2110.icf create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/startup_hi2110.s create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/cmsis.h create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.c create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.h create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/hi2110.h create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.c create mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.h create mode 100644 targets/TARGET_ublox/TARGET_HI2110/gpio_api.c create mode 100644 targets/TARGET_ublox/TARGET_HI2110/gpio_irq_api.c create mode 100644 targets/TARGET_ublox/TARGET_HI2110/gpio_object.h create mode 100644 targets/TARGET_ublox/TARGET_HI2110/hi2110_init.c create mode 100644 targets/TARGET_ublox/TARGET_HI2110/hi2110_init.h create mode 100644 targets/TARGET_ublox/TARGET_HI2110/lp_ticker.c create mode 100644 targets/TARGET_ublox/TARGET_HI2110/mbed_overrides.c create mode 100644 targets/TARGET_ublox/TARGET_HI2110/objects.h create mode 100644 targets/TARGET_ublox/TARGET_HI2110/pinmap.c create mode 100644 targets/TARGET_ublox/TARGET_HI2110/port_api.c create mode 100644 targets/TARGET_ublox/TARGET_HI2110/serial_api.c create mode 100644 targets/TARGET_ublox/TARGET_HI2110/sleep.c create mode 100644 targets/TARGET_ublox/TARGET_HI2110/us_ticker.c create mode 100644 targets/TARGET_ublox/mbed_rtx.h diff --git a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp index 27cd6428c33..f021ee8bd58 100644 --- a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp @@ -25,6 +25,8 @@ #define STACK_SIZE 512 #elif defined(TARGET_XDOT_L151CC) #define STACK_SIZE 1024 +#elif defined(TARGET_HI2110) + #define STACK_SIZE 512 #else #define STACK_SIZE DEFAULT_STACK_SIZE #endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/PeripheralNames.h b/targets/TARGET_ublox/TARGET_HI2110/PeripheralNames.h new file mode 100644 index 00000000000..1dea1967185 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/PeripheralNames.h @@ -0,0 +1,87 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define STDIO_UART_TX UART0_TX +#define STDIO_UART_RX UART0_RX + +typedef enum { + SERIAL_CONFIG_UARTLP_RX_UART0_TX, + SERIAL_CONFIG_UART0_RX_UART0_TX, + SERIAL_CONFIG_UART1_RX_UART1_TX, + MAX_NUM_SERIAL_CONFIGS +} SerialConfig; + +typedef enum { + PIN_FUNCTION_UNCLAIMED = 0, + PIN_FUNCTION_GPIO = 1, + PIN_FUNCTION_PWM0 = 2, + PIN_FUNCTION_PWM0B = 3, + PIN_FUNCTION_PWM1 = 4, + PIN_FUNCTION_PWM1B = 5, + PIN_FUNCTION_SSP0TXD = 6, + PIN_FUNCTION_SSP0RXD = 7, + PIN_FUNCTION_SSP0TRX = 8, + PIN_FUNCTION_SSP0CLK = 9, + PIN_FUNCTION_SSP0FSS = 10, + PIN_FUNCTION_SSP1CLK = 11, + PIN_FUNCTION_SSP1FSS = 12, + PIN_FUNCTION_SSP1TXD = 13, + PIN_FUNCTION_SSP1RXD = 14, + PIN_FUNCTION_SSP1TRX = 15, + PIN_FUNCTION_I2C0 = 16, + PIN_FUNCTION_I2C1 = 17, + PIN_FUNCTION_UART0_TXD = 18, + PIN_FUNCTION_UART0_TXIR = 19, + PIN_FUNCTION_UART0_O2 = 20, + PIN_FUNCTION_UART0_O1 = 21, + PIN_FUNCTION_UART0_RTS = 22, + PIN_FUNCTION_UART0_DTR = 23, + PIN_FUNCTION_UART0_RXD = 24, + PIN_FUNCTION_UART0_RXIR = 25, + PIN_FUNCTION_UART0_CTS = 26, + PIN_FUNCTION_UART0_DCD = 27, + PIN_FUNCTION_UART0_DSR = 28, + PIN_FUNCTION_UART0_RI = 29, + PIN_FUNCTION_UART1_TXD = 30, + PIN_FUNCTION_UART1_TXIR = 31, + PIN_FUNCTION_UART1_O2 = 32, + PIN_FUNCTION_UART1_O1 = 33, + PIN_FUNCTION_UART1_RTS = 34, + PIN_FUNCTION_UART1_DTR = 35, + PIN_FUNCTION_UART1_RXD = 36, + PIN_FUNCTION_UART1_RXIR = 37, + PIN_FUNCTION_UART1_CTS = 38, + PIN_FUNCTION_UART1_DCD = 39, + PIN_FUNCTION_UART1_DSR = 40, + PIN_FUNCTION_UART1_RI = 41, + PIN_FUNCTION_LP_UART = 42, + PIN_FUNCTION_MAX_NUMBER +} PinFunction; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/PortNames.h b/targets/TARGET_ublox/TARGET_HI2110/PortNames.h new file mode 100644 index 00000000000..68bbc8c3c1f --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/PortNames.h @@ -0,0 +1,31 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, //GPIO pins 0-19 + PortMaxNumber +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/PinNames.h b/targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/PinNames.h new file mode 100644 index 00000000000..175bec97d59 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/PinNames.h @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +typedef enum { + p0 = 0, + p1 = 1, + p2 = 2, + p3 = 3, + p4 = 4, + p5 = 5, + p6 = 6, + p7 = 7, + p8 = 8, + p9 = 9, + p10 = 10, + p11 = 11, + p12 = 12, + p13 = 13, + p14 = 14, + p15 = 15, + p16 = 16, + p17 = 17, + p18 = 18, + p19 = 19, + + UART0_RX = p13, + UART0_TX = p18, + UART0_CTS = p12, + UART0_RTS = p11, + I2C_SCL = p0, + I2C_SDA = p1, + SPI_CS = p2, + SPI_CLK = p3, + SPI_MOSI = p4, + SPI_MISO = p5, + UART1_RX = p7, + UART1_TX = p6, + LED1 = p2, + LED2 = p3, + LED3 = p4, + LED4 = p5, + + // mBed interface Pins + USBTX = UART0_TX, + USBRX = UART0_RX, + + P0_0 = p0, + P0_1 = p1, + P0_2 = p2, + P0_3 = p3, + P0_4 = p4, + P0_5 = p5, + P0_6 = p6, + P0_7 = p7, + P0_8 = p8, + P0_9 = p9, + P0_10 = p10, + P0_11 = p11, + P0_12 = p12, + P0_13 = p13, + P0_14 = p14, + P0_15 = p15, + P0_16 = p16, + P0_17 = p17, + P0_18 = p18, + P0_19 = p19, + NUM_PINS, + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + +typedef enum { + PullNone = 0, + PullDown = 1, + PullUp = 0xff, /* TODO: current HI2110 chip does not have pull-up */ + PullDefault = PullDown /* TODO: mbed requires PullUp as default but HI2110 doesn't have it */ +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif // MBED_PINNAMES_H diff --git a/targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/device.h b/targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/device.h new file mode 100644 index 00000000000..493844b8012 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/device.h @@ -0,0 +1,23 @@ +// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches. +// Check the 'features' section of the target description in 'targets.json' for more details. +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#include "objects.h" + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/hi2110.sct b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/hi2110.sct new file mode 100644 index 00000000000..d7d9d472133 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/hi2110.sct @@ -0,0 +1,15 @@ +LR_IROM1 0x00000000 0x20000 { + ER_IROM1 0x00000000 0x20000 { + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_IRAM_VTABLE 0x01000000 EMPTY 128 { + } + RW_IRAM1 +0 (0x5000 - 256) { + .ANY (+RW +ZI) + } + RW_IPCRAM +0 256 { + ipc.o (+RW) + } +} \ No newline at end of file diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/startup_hi2110.s b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/startup_hi2110.s new file mode 100644 index 00000000000..2bc9ff77039 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/startup_hi2110.s @@ -0,0 +1,163 @@ +; mbed Microcontroller Library +; Copyright (c) 2016 u-blox. +;Licensed under the Apache License, Version 2.0 (the "License"); +;you may not use this file except in compliance with the License. +;You may obtain a copy of the License at +;http://www.apache.org/licenses/LICENSE-2.0 +;Unless required by applicable law or agreed to in writing, software +;distributed under the License is distributed on an "AS IS" BASIS, +;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;See the License for the specific language governing permissions and +;limitations under the License. + +; Description message + +__initial_sp EQU (0x01000000 + 0x5000 - 256) + + PRESERVE8 + THUMB + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + +; External Interrupts + DCD IRQ0_RTC_Handler + DCD IRQ1_TMR0_Handler + DCD IRQ2_SECURITY_Handler + DCD IRQ3_PROTOCOL_Handler + DCD IRQ4_APPS_Handler + DCD IRQ5_GPIO_Handler + DCD IRQ6_DMA_Handler + DCD IRQ7_UART0_Handler + DCD IRQ8_UART1_Handler + DCD IRQ9_SSP0_Handler + DCD IRQ10_SSP1_Handler + DCD IRQ11_PWM0IN_Handler + DCD IRQ12_PWM0OUT_Handler + DCD IRQ13_PWM1IN_Handler + DCD IRQ14_PWM1OUT_Handler + DCD IRQ15_I2C_Handler + DCD IRQ16_LPUART_Handler + DCD IRQ17_CAP_Handler + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT IRQ0_RTC_Handler [WEAK] + EXPORT IRQ1_TMR0_Handler [WEAK] + EXPORT IRQ2_SECURITY_Handler [WEAK] + EXPORT IRQ3_PROTOCOL_Handler [WEAK] + EXPORT IRQ4_APPS_Handler [WEAK] + EXPORT IRQ5_GPIO_Handler [WEAK] + EXPORT IRQ6_DMA_Handler [WEAK] + EXPORT IRQ7_UART0_Handler [WEAK] + EXPORT IRQ8_UART1_Handler [WEAK] + EXPORT IRQ9_SSP0_Handler [WEAK] + EXPORT IRQ10_SSP1_Handler [WEAK] + EXPORT IRQ11_PWM0IN_Handler [WEAK] + EXPORT IRQ12_PWM0OUT_Handler [WEAK] + EXPORT IRQ13_PWM1IN_Handler [WEAK] + EXPORT IRQ14_PWM1OUT_Handler [WEAK] + EXPORT IRQ15_I2C_Handler [WEAK] + EXPORT IRQ16_LPUART_Handler [WEAK] + EXPORT IRQ17_CAP_Handler [WEAK] +IRQ0_RTC_Handler +IRQ1_TMR0_Handler +IRQ2_SECURITY_Handler +IRQ3_PROTOCOL_Handler +IRQ4_APPS_Handler +IRQ5_GPIO_Handler +IRQ6_DMA_Handler +IRQ7_UART0_Handler +IRQ8_UART1_Handler +IRQ9_SSP0_Handler +IRQ10_SSP1_Handler +IRQ11_PWM0IN_Handler +IRQ12_PWM0OUT_Handler +IRQ13_PWM1IN_Handler +IRQ14_PWM1OUT_Handler +IRQ15_I2C_Handler +IRQ16_LPUART_Handler +IRQ17_CAP_Handler + + B . + ENDP + ALIGN + END diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/sys.cpp b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/sys.cpp new file mode 100644 index 00000000000..6e74061d9ab --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/sys.cpp @@ -0,0 +1,31 @@ +/* mbed Microcontroller Library - stackheap + * Copyright (C) 2009-2016 ARM Limited. All rights reserved. + * + * Setup a fixed single stack/heap memory model, + * between the top of the RW/ZI region and the stackpointer + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +extern char Image$$RW_IRAM1$$ZI$$Limit[]; + +extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { + uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit; + uint32_t sp_limit = __current_sp(); + + zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned + + struct __initial_stackheap r; + r.heap_base = zi_limit; + r.heap_limit = sp_limit; + return r; +} + +#ifdef __cplusplus +} +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/hi2110.ld b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/hi2110.ld new file mode 100644 index 00000000000..c39ec675a35 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/hi2110.ld @@ -0,0 +1,170 @@ +/* mbed Microcontroller Library */ +/* Copyright (c) 2016 u-blox. */ + +OUTPUT_FORMAT("elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) +MEMORY +{ + FLASH_VECTORS : ORIGIN = 0, LENGTH = 192 + FLASH : ORIGIN = (0 + 192), LENGTH = (0x20000 - 192) + RAM_VECTORS : ORIGIN = 0, LENGTH = 128 /* Reserve space for dynamic vectors mapped to RAM (see cmsis_nvic.c) */ + RAM : ORIGIN = 0x01000000 + 128, LENGTH = 0x5000 - 256 + IPC_MAILBOX : ORIGIN = (0x01000000 + 128 + 0x5000 - 256), LENGTH = 256 +} +SECTIONS +{ + /* Vector table in FLASH */ + . = 0; + startup : + { + KEEP (*(.isr_vector)) + } > FLASH_VECTORS + + /* Code and const data */ + .text : + { + . = ALIGN(4); + *(.text) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata) + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + __etext = .; + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __RAM_START__ = ORIGIN(RAM); + __RAM_SIZE__ = LENGTH(RAM); + + /* Initialised data */ + .data : + { + FILL(0xFF) + __data_load__ = LOADADDR(.data); + __data_start__ = .; + *(.data) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + __data_end__ = .; + } > RAM AT > FLASH + + __data_size__ = __data_end__ - __data_start__; + + /* Uninitialised data */ + .bss (NOLOAD): + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + __bss_size__ = __bss_end__ - __bss_start__; + + .resume (NOLOAD): + { + . = ALIGN(4); + *(preserve) + } > RAM + + /* Heap fills the rest of the space up to the start of the stack */ + .heap (NOLOAD): + { + __end__ = .; + end = __end__; + __HeapBase = .; + *(.heap*) + . = ORIGIN(RAM) + LENGTH(RAM) - Stack_Size; /* Remember that LENGTH(RAM) is already reduced by the IPC block */ + __HeapLimit = .; + } > RAM + + PROVIDE(__heap_start = ADDR(.heap)); + PROVIDE(__heap_size = SIZEOF(.heap)); + PROVIDE(__mbed_sbrk_start = ADDR(.heap)); + PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap)); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (NOLOAD): + { + __SYSTEM_STACK_START__ = .; + *(.stack*) + __SYSTEM_STACK_END__ = .; + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); /* Remember that LENGTH(RAM) is already reduced by the IPC block */ + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + /* IPC mailboxes at the top of RAM */ + /* The size of this section (256 bytes) is already taken off the size of RAM so there is no danger of the heap overflowing into it */ + .ipc_mailbox (NOLOAD): + { + . = ALIGN(4); + __ipc_mailbox_start__ = .; + *(.ipc_mailbox) + *(.ipc_mailbox*) + __ipc_mailbox_end__ = .; + } > IPC_MAILBOX +} \ No newline at end of file diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/startup_hi2110.s b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/startup_hi2110.s new file mode 100644 index 00000000000..b1de07a1d19 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/startup_hi2110.s @@ -0,0 +1,254 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + .syntax unified + .cpu cortex-m0 + .fpu softvfp + .thumb + +/* Setup the stack + * Since it grows downward the stack_system is the first location is the highest address + * The first other usage should therefore be at stack_system + 4 + * Should the stack overflow, there would be a hard fault in the core + */ + + .section .stacks,"aw",%progbits + +#ifdef __STACK_SIZE + .equ Stack_Size, __STACK_SIZE +#else + .equ Stack_Size, 1024 +#endif + .globl Stack_Size + .globl __StackTop + .globl __StackLimit + .align 2 + .type stack_system, %object + .size stack_system, Stack_Size +stack_system_end: + .space Stack_Size - 4 +stack_system: + .space 4 + + +/* This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + */ + .section .text.Reset_Handler,"ax",%progbits + .weak Reset_Handler + .type Reset_Handler, %function + .thumb + .func Reset_Handler +Reset_Handler: + + /* Make sure SP is really at the start of the stack */ + ldr r0, =stack_system + msr msp, r0 + + /* Prefill the system stack with 0xefbeadde (or deafbeef in little endian) */ + ldr r1, =__SYSTEM_STACK_START__ + ldr r3, =__SYSTEM_STACK_END__ + subs r3, r3, r1 + beq .stack_fill_loop_end + ldr r2, =0xefbeadde +.stack_fill_loop: + str r2, [r1, #0] /* Store the quad octet initialisation value in r2 into address in r1 */ + adds r1, r1, #4 /* Increased address in r1 by a quad octet */ + subs r3, r3, #4 /* Decrease the number of bytes to do by a quad octet */ + bgt .stack_fill_loop /* Keep going until it is all done */ +.stack_fill_loop_end: + + /* setup .data section */ + ldr r1, =__data_start__ + ldr r2, =__data_load__ + ldr r3, =__data_size__ + cmp r3, #0 + beq .end_set_data_loop + +.set_data_loop: + ldrb r4, [r2, #0] /* Load the octet value into r4 from address in r2 */ + strb r4, [r1, #0] /* Store the octet value in r4 to address in r1 */ + adds r2, r2, #1 /* Move onto next octet */ + adds r1, r1, #1 + subs r3, r3, #1 /* Decrease the number of bytes to do by an octet */ + bgt .set_data_loop /* Keep going until it is all done */ +.end_set_data_loop: + + /* Call init function */ + ldr r0, =SystemInit + blx r0 + + /* Call C++ startup */ + ldr r0, =_start + bx r0 + bl . + + .size Reset_Handler, .-Reset_Handler + .endfunc + +/* This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + */ + .section .text.Default_Handler,"ax",%progbits + .global Default_Handler + .func Default_Handler +Default_Handler: +Infinite_Loop: + b Infinite_Loop + + .endfunc + .size Default_Handler, .-Default_Handler + +/****************************************************************************** + * The minimal vector table for a Cortex M0+. Note that the proper constructs + * must be placed on this to ensure that it ends up at physical address 0x0000.0000. + *******************************************************************************/ + + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + .global g_pfnVectors + +g_pfnVectors: + .word stack_system + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word 0 + .word 0 + .word PendSV_Handler + .word SysTick_Handler + +/* External Interrupts */ + .word IRQ0_RTC_Handler + .word IRQ1_TMR0_Handler + .word IRQ2_SECURITY_Handler + .word IRQ3_PROTOCOL_Handler + .word IRQ4_APPS_Handler + .word IRQ5_GPIO_Handler + .word IRQ6_DMA_Handler + .word IRQ7_UART0_Handler + .word IRQ8_UART1_Handler + .word IRQ9_SSP0_Handler + .word IRQ10_SSP1_Handler + .word IRQ11_PWM0IN_Handler + .word IRQ12_PWM0OUT_Handler + .word IRQ13_PWM1IN_Handler + .word IRQ14_PWM1OUT_Handler + .word IRQ15_I2C_Handler + .word IRQ16_LPUART_Handler + .word IRQ17_CAP_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + +/******************************************************************************* + * Provide weak aliases for each Exception handler to the Default_Handler. + * As they are weak aliases, any function with the same name will override this definition. + * Note: For system exception handlers we don't want those references to be weak + * - we want to force someone to write those handlers. + *******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak IRQ0_RTC_Handler + .thumb_set IRQ0_RTC_Handler,Default_Handler + + .weak IRQ1_TMR0_Handler + .thumb_set IRQ1_TMR0_Handler,Default_Handler + + .weak IRQ2_SECURITY_Handler + .thumb_set IRQ2_SECURITY_Handler,Default_Handler + + .weak IRQ3_PROTOCOL_Handler + .thumb_set IRQ3_PROTOCOL_Handler,Default_Handler + + .weak IRQ4_APPS_Handler + .thumb_set IRQ4_APPS_Handler,Default_Handler + + .weak IRQ5_GPIO_Handler + .thumb_set IRQ5_GPIO_Handler,Default_Handler + + .weak IRQ6_DMA_Handler + .thumb_set IRQ6_DMA_Handler,Default_Handler + + .weak IRQ7_UART0_Handler + .thumb_set IRQ7_UART0_Handler,Default_Handler + + .weak IRQ8_UART1_Handler + .thumb_set IRQ8_UART1_Handler,Default_Handler + + .weak IRQ9_SSP0_Handler + .thumb_set IRQ9_SSP0_Handler,Default_Handler + + .weak IRQ10_SSP1_Handler + .thumb_set IRQ10_SSP1_Handler,Default_Handler + + .weak IRQ11_PWM0IN_Handler + .thumb_set IRQ11_PWM0IN_Handler,Default_Handler + + .weak IRQ12_PWM0OUT_Handler + .thumb_set IRQ12_PWM0OUT_Handler,Default_Handler + + .weak IRQ13_PWM1IN_Handler + .thumb_set IRQ13_PWM1IN_Handler,Default_Handler + + .weak IRQ14_PWM1OUT_Handler + .thumb_set IRQ14_PWM1OUT_Handler,Default_Handler + + .weak IRQ15_I2C_Handler + .thumb_set IRQ15_I2C_Handler,Default_Handler + + .weak IRQ16_LPUART_Handler + .thumb_set IRQ16_LPUART_Handler,Default_Handler + + .weak IRQ17_CAP_Handler + .thumb_set IRQ17_CAP_Handler,Default_Handler + diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/hi2110.icf b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/hi2110.icf new file mode 100644 index 00000000000..356658423a0 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/hi2110.icf @@ -0,0 +1,60 @@ +/* Sizes and locations */ + +define symbol __start_flash__ = 0x00000000; +define symbol __size_flash__ = 0x20000; +define symbol __start_ram__ = 0x01000000; +define symbol __size_ram__ = 0x5000; +define symbol __size_flash_vtable__ = 192; +define symbol __size_ram_vtable__ = 128; /* Reserve space for dynamic vectors mapped to RAM (see cmsis_nvic.c) */ +define symbol __size_ipc__ = 256; + +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 1024; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = (1024 * 8); +} + +/* Memory regions */ + +define symbol __region_INTVEC_FLASH_start__ = __start_flash__; +define symbol __region_INTVEC_FLASH_end__ = __start_flash__ + __size_flash_vtable__ - 1; +define symbol __region_TEXT_start__ = __start_flash__ + __size_flash_vtable__; /* Leave room for flash vector table at start */ +define symbol __region_TEXT_end__ = __start_flash__ + __size_flash__ - 1; +define symbol __region_INTVEC_RAM_start__ = __start_ram__; +define symbol __region_DATA_start__ = __start_ram__ + __size_ram_vtable__; /* Leave room for RAM vector table at start */ +define symbol __region_DATA_end__ = __start_ram__ + __size_ram__ - __size_cstack__ - __size_ipc__ - 1; /* Leave room for IPC and stack at end */ +define symbol __region_CSTACK_start__ = __start_ram__ + __size_ram__ - __size_cstack__ - __size_ipc__; +define symbol __region_CSTACK_end__ = __start_ram__ + __size_ram__ - __size_ipc__ - 1; +define symbol __region_IPC_start__ = __start_ram__ + __size_ram__ - __size_ipc__; +define symbol __region_IPC_end__ = __start_ram__ + __size_ram__ - 1; + +define memory mem with size = 4G; +define region FLASH_region = mem:[from __region_INTVEC_FLASH_start__ to __region_INTVEC_FLASH_end__] | mem:[from __region_TEXT_start__ to __region_TEXT_end__]; +define region DATA_region = mem:[from __region_DATA_start__ to __region_DATA_end__]; +define region CSTACK_region = mem:[from __region_CSTACK_start__ to __region_CSTACK_end__]; +define region IPC_region = mem:[from __region_IPC_start__ to __region_IPC_end__]; + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +/* Place sections */ + +initialize by copy { readwrite }; +do not initialize { section .noinit }; +do not initialize { section .ipc }; + +place at address mem:__region_INTVEC_FLASH_start__ { readonly section .intvec }; +place in FLASH_region { readonly }; +place in DATA_region { block RW }; +place in DATA_region { block ZI }; +place in DATA_region { last block HEAP }; +place in CSTACK_region { block CSTACK }; +place in IPC_region { section .ipc }; diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/startup_hi2110.s b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/startup_hi2110.s new file mode 100644 index 00000000000..0c69cc0541e --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/startup_hi2110.s @@ -0,0 +1,202 @@ +; mbed Microcontroller Library +; Copyright (c) 2016 u-blox. +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; http://www.apache.org/licenses/LICENSE-2.0 +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +; Description message + + MODULE ?cstartup + + ; Stack size default : 1024 + ; Heap size default : 2048 + + ; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + DCD NMI_Handler + DCD HardFault_Handler + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD SVC_Handler + DCD 0 + DCD 0 + DCD PendSV_Handler + DCD SysTick_Handler + +; External Interrupts + DCD IRQ0_RTC_Handler + DCD IRQ1_TMR0_Handler + DCD IRQ2_SECURITY_Handler + DCD IRQ3_PROTOCOL_Handler + DCD IRQ4_APPS_Handler + DCD IRQ5_GPIO_Handler + DCD IRQ6_DMA_Handler + DCD IRQ7_UART0_Handler + DCD IRQ8_UART1_Handler + DCD IRQ9_SSP0_Handler + DCD IRQ10_SSP1_Handler + DCD IRQ11_PWM0IN_Handler + DCD IRQ12_PWM0OUT_Handler + DCD IRQ13_PWM1IN_Handler + DCD IRQ14_PWM1OUT_Handler + DCD IRQ15_I2C_Handler + DCD IRQ16_LPUART_Handler + DCD IRQ17_CAP_Handler + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + +__Vectors_End +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + +; Default handlers. + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + ; Dummy exception handlers + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + ; Dummy interrupt handlers + + PUBWEAK IRQ0_RTC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ0_RTC_Handler + B . + PUBWEAK IRQ1_TMR0_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ1_TMR0_Handler + B . + PUBWEAK IRQ2_SECURITY_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ2_SECURITY_Handler + B . + PUBWEAK IRQ3_PROTOCOL_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ3_PROTOCOL_Handler + B . + PUBWEAK IRQ4_APPS_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ4_APPS_Handler + B . + PUBWEAK IRQ5_GPIO_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ5_GPIO_Handler + B . + PUBWEAK IRQ6_DMA_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ6_DMA_Handler + B . + PUBWEAK IRQ7_UART0_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ7_UART0_Handler + B . + PUBWEAK IRQ8_UART1_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ8_UART1_Handler + B . + PUBWEAK IRQ9_SSP0_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ9_SSP0_Handler + B . + PUBWEAK IRQ10_SSP1_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ10_SSP1_Handler + B . + PUBWEAK IRQ11_PWM0IN_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ11_PWM0IN_Handler + B . + PUBWEAK IRQ12_PWM0OUT_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ12_PWM0OUT_Handler + B . + PUBWEAK IRQ13_PWM1IN_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ13_PWM1IN_Handler + B . + PUBWEAK IRQ14_PWM1OUT_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ14_PWM1OUT_Handler + B . + PUBWEAK IRQ15_I2C_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ15_I2C_Handler + B . + PUBWEAK IRQ16_LPUART_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ16_LPUART_Handler + B . + PUBWEAK IRQ17_CAP_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ17_CAP_Handler + + END diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/cmsis.h b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis.h new file mode 100644 index 00000000000..b14157ad415 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis.h @@ -0,0 +1,27 @@ +/* + * PackageLicenseDeclared: Apache-2.0 + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_CMSIS_H +#define MBED_CMSIS_H + +#include "hi2110.h" +#include "cmsis_nvic.h" + +/** Reference clock in Hz */ +#define CLOCKS_REFERENCE_CLOCK_FREQ 32768 + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.c b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.c new file mode 100644 index 00000000000..86531fc09d1 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.c @@ -0,0 +1,50 @@ +/* mbed Microcontroller Library + * CMSIS-style functionality to support dynamic vectors + ******************************************************************************* + * Copyright (c) 2011 ARM Limited. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of ARM Limited nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis_nvic.h" + +#define NVIC_RAM_VECTOR_ADDRESS (0x01000000) // Location of vectors in RAM +#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { + // Space for dynamic vectors, initialised to allocate in R/W + static volatile uint32_t* vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; + + // Set the vector + vectors[IRQn + 16] = vector; +} + +uint32_t NVIC_GetVector(IRQn_Type IRQn) { + // We can always read vectors at 0x0, as the addresses are remapped + uint32_t *vectors = (uint32_t*)0; + + // Return the vector + return vectors[IRQn + 16]; +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.h b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.h new file mode 100644 index 00000000000..46ee73e063d --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.h @@ -0,0 +1,38 @@ +/* + * PackageLicenseDeclared: Apache-2.0 + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_USER_IRQ_OFFSET 16 + +#include "cmsis.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/hi2110.h b/targets/TARGET_ublox/TARGET_HI2110/device/hi2110.h new file mode 100644 index 00000000000..bbc1a08c357 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/hi2110.h @@ -0,0 +1,492 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HI2110_H +#define HI2110_H + +#ifdef __cplusplus + extern "C" { +#endif + +/******************************************************************************/ +/* Processor and Core Peripherals */ +/******************************************************************************/ + +/* + * ========================================================================== + * ---------- Interrupt Number Definition ----------------------------------- + * ========================================================================== + */ + +typedef enum IRQn +{ +/****** Cortex-M0 Processor Exceptions Numbers ***************************************************/ + Thread_mode = -16, /*!< 0 Thread mode */ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 Hard Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 SV Call Interrupt */ + PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 System Tick Interrupt */ + +/****** Device Specific Interrupt Numbers ********************************************************/ + RTC_IRQn = 0, /*!< RTC Interrupt */ + Timer_IRQn = 1, /*!< Timer Interrupt */ + Security_IRQn = 2, /*!< From Security Interrupt */ + Protocol_IRQn = 3, /*!< From Protocol Interrupt */ + Apps_IRQn = 4, /*!< Core Self Interrupt */ + GPIO_IRQn = 5, /*!< GPIO Interrupt */ + DMA_IRQn = 6, /*!< DMA Interrupt */ + UART0_IRQn = 7, /*!< UART0 Interrupt */ + UART1_IRQn = 8, /*!< UART1 Interrupt */ + SSP0_IRQn = 9, /*!< SPI0 Interrupt */ + SSP1_IRQn = 10, /*!< SPI1 Interrupt */ + PWM0_Inner_IRQn = 11, /*!< PW0 Inner Interrupt */ + PWM0_Outer_IRQn = 12, /*!< PW0 Outer Interrupt */ + PWM1_Inner_IRQn = 13, /*!< PW1 Inner Interrupt */ + PWM1_Outer_IRQn = 14, /*!< PW1 Outer Interrupt */ + I2C_IRQn = 15, /*!< I2C Interrupt */ + LPUART_IRQn = 16, /*!< Low Power UART Interrupt */ + CAP_IRQn = 17, /*!< CAP Interrupt */ + COMP_IRQn = 18, /*!< COMP Interrupt */ + EDGE_IRQn = 19, /*!< EDGE Interrupt */ + Pulse_SWD_IRQn = 23, /*!< SWD Pulse Interrupt */ + +} IRQn_Type; + +/* + * ========================================================================== + * ----------- Processor and Core Peripheral Section ------------------------ + * ========================================================================== + */ + +/* Configuration of the Cortex-M# Processor and Core Peripherals */ +#define __CM0_REV 0x0000 /*!< Core Revision r2p1 */ +#define __NVIC_PRIO_BITS 2 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __FPU_PRESENT 0 /*!< FPU present or not */ + +#include /* Cortex-M# processor and core peripherals */ + +/******************************************************************************/ +/* Device Specific Peripheral registers structures */ +/******************************************************************************/ + +/* UART */ +typedef struct { + uint32_t UARTDR; + uint32_t UARTRSR; + uint32_t res0; + uint32_t res1; + uint32_t res2; + uint32_t res3; + uint32_t UARTFR; + uint32_t res4; + uint32_t UARTILPR; + uint32_t UARTIBRD; // Integer baud divider + uint32_t UARTFBRD; // Fractional Baud divider + uint32_t UARTLCR_H; + uint32_t UARTCR; + uint32_t UARTIFLS; + uint32_t UARTIMSC; + uint32_t UARTRIS; + uint32_t UARTMIS; + uint32_t UARTICR; + uint32_t UARTDMACR; +} uart_ctrl_t; + +/******************************************************************************/ +/* Peripheral memory map */ +/******************************************************************************/ + +#define RTC_IRQ_TIME_LSBS (*(volatile uint32_t *)(0x40002000)) +#define RTC_IRQ_TIME_LSBS_BITSET (*(volatile uint32_t *)(0x40002400)) +#define RTC_IRQ_TIME_LSBS_BITCLR (*(volatile uint32_t *)(0x40002800)) +#define RTC_IRQ_TIME_LSBS_BITTOG (*(volatile uint32_t *)(0x40002C00)) +#define RTC_IRQ_TIME_MSBS (*(volatile uint32_t *)(0x40002004)) +#define RTC_IRQ_TIME_MSBS_BITSET (*(volatile uint32_t *)(0x40002404)) +#define RTC_IRQ_TIME_MSBS_BITCLR (*(volatile uint32_t *)(0x40002804)) +#define RTC_IRQ_TIME_MSBS_BITTOG (*(volatile uint32_t *)(0x40002C04)) +#define RTC_IRQ_CLR (*(volatile uint32_t *)(0x40002008)) +#define RTC_IRQ_CLR_BITSET (*(volatile uint32_t *)(0x40002408)) +#define RTC_IRQ_CLR_BITCLR (*(volatile uint32_t *)(0x40002808)) +#define RTC_IRQ_CLR_BITTOG (*(volatile uint32_t *)(0x40002C08)) +#define TIMER0_LOAD (*(volatile uint32_t *)(0x4000200C)) +#define TIMER0_LOAD_BITSET (*(volatile uint32_t *)(0x4000240C)) +#define TIMER0_LOAD_BITCLR (*(volatile uint32_t *)(0x4000280C)) +#define TIMER0_LOAD_BITTOG (*(volatile uint32_t *)(0x40002C0C)) +#define TIMER0_CTRL (*(volatile uint32_t *)(0x40002010)) +#define TIMER0_CTRL_BITSET (*(volatile uint32_t *)(0x40002410)) +#define TIMER0_CTRL_BITCLR (*(volatile uint32_t *)(0x40002810)) +#define TIMER0_CTRL_BITTOG (*(volatile uint32_t *)(0x40002C10)) +#define TIMER0_TIME (*(volatile uint32_t *)(0x40002014)) +#define ARM_IRQ_REG (*(volatile uint32_t *)(0x40002018)) +#define ARM_IRQ_REG_BITSET (*(volatile uint32_t *)(0x40002418)) +#define ARM_IRQ_REG_BITCLR (*(volatile uint32_t *)(0x40002818)) +#define ARM_IRQ_REG_BITTOG (*(volatile uint32_t *)(0x40002C18)) +#define PIO_FUNC0 (*(volatile uint32_t *)(0x4000201C)) +#define PIO_FUNC0_BITSET (*(volatile uint32_t *)(0x4000241C)) +#define PIO_FUNC0_BITCLR (*(volatile uint32_t *)(0x4000281C)) +#define PIO_FUNC0_BITTOG (*(volatile uint32_t *)(0x40002C1C)) +#define PIO_FUNC1 (*(volatile uint32_t *)(0x40002020)) +#define PIO_FUNC1_BITSET (*(volatile uint32_t *)(0x40002420)) +#define PIO_FUNC1_BITCLR (*(volatile uint32_t *)(0x40002820)) +#define PIO_FUNC1_BITTOG (*(volatile uint32_t *)(0x40002C20)) +#define PIO_FUNC2 (*(volatile uint32_t *)(0x40002024)) +#define PIO_FUNC2_BITSET (*(volatile uint32_t *)(0x40002424)) +#define PIO_FUNC2_BITCLR (*(volatile uint32_t *)(0x40002824)) +#define PIO_FUNC2_BITTOG (*(volatile uint32_t *)(0x40002C24)) +#define PIO_FUNC3 (*(volatile uint32_t *)(0x40002028)) +#define PIO_FUNC3_BITSET (*(volatile uint32_t *)(0x40002428)) +#define PIO_FUNC3_BITCLR (*(volatile uint32_t *)(0x40002828)) +#define PIO_FUNC3_BITTOG (*(volatile uint32_t *)(0x40002C28)) +#define PIO_FUNC4 (*(volatile uint32_t *)(0x4000202C)) +#define PIO_FUNC4_BITSET (*(volatile uint32_t *)(0x4000242C)) +#define PIO_FUNC4_BITCLR (*(volatile uint32_t *)(0x4000282C)) +#define PIO_FUNC4_BITTOG (*(volatile uint32_t *)(0x40002C2C)) +#define GPIO_DIR (*(volatile uint32_t *)(0x40002030)) +#define GPIO_DIR_BITSET (*(volatile uint32_t *)(0x40002430)) +#define GPIO_DIR_BITCLR (*(volatile uint32_t *)(0x40002830)) +#define GPIO_DIR_BITTOG (*(volatile uint32_t *)(0x40002C30)) +#define GPIO_OUT (*(volatile uint32_t *)(0x40002034)) +#define GPIO_OUT_BITSET (*(volatile uint32_t *)(0x40002434)) +#define GPIO_OUT_BITCLR (*(volatile uint32_t *)(0x40002834)) +#define GPIO_OUT_BITTOG (*(volatile uint32_t *)(0x40002C34)) +#define GPIO_DRIVE (*(volatile uint32_t *)(0x40002038)) +#define GPIO_DRIVE_BITSET (*(volatile uint32_t *)(0x40002438)) +#define GPIO_DRIVE_BITCLR (*(volatile uint32_t *)(0x40002838)) +#define GPIO_DRIVE_BITTOG (*(volatile uint32_t *)(0x40002C38)) +#define GPIO_PULLEN (*(volatile uint32_t *)(0x4000203C)) +#define GPIO_PULLEN_BITSET (*(volatile uint32_t *)(0x4000243C)) +#define GPIO_PULLEN_BITCLR (*(volatile uint32_t *)(0x4000283C)) +#define GPIO_PULLEN_BITTOG (*(volatile uint32_t *)(0x40002C3C)) +#define GPIO_INT_RISE (*(volatile uint32_t *)(0x40002040)) +#define GPIO_INT_RISE_BITSET (*(volatile uint32_t *)(0x40002440)) +#define GPIO_INT_RISE_BITCLR (*(volatile uint32_t *)(0x40002840)) +#define GPIO_INT_RISE_BITTOG (*(volatile uint32_t *)(0x40002C40)) +#define GPIO_INT_FALL (*(volatile uint32_t *)(0x40002044)) +#define GPIO_INT_FALL_BITSET (*(volatile uint32_t *)(0x40002444)) +#define GPIO_INT_FALL_BITCLR (*(volatile uint32_t *)(0x40002844)) +#define GPIO_INT_FALL_BITTOG (*(volatile uint32_t *)(0x40002C44)) +#define GPIO_INT_HIGH (*(volatile uint32_t *)(0x40002048)) +#define GPIO_INT_HIGH_BITSET (*(volatile uint32_t *)(0x40002448)) +#define GPIO_INT_HIGH_BITCLR (*(volatile uint32_t *)(0x40002848)) +#define GPIO_INT_HIGH_BITTOG (*(volatile uint32_t *)(0x40002C48)) +#define GPIO_INT_LOW (*(volatile uint32_t *)(0x4000204C)) +#define GPIO_INT_LOW_BITSET (*(volatile uint32_t *)(0x4000244C)) +#define GPIO_INT_LOW_BITCLR (*(volatile uint32_t *)(0x4000284C)) +#define GPIO_INT_LOW_BITTOG (*(volatile uint32_t *)(0x40002C4C)) +#define GPIO_INT_CLR (*(volatile uint32_t *)(0x40002050)) +#define GPIO_INT_CLR_BITSET (*(volatile uint32_t *)(0x40002450)) +#define GPIO_INT_CLR_BITCLR (*(volatile uint32_t *)(0x40002850)) +#define GPIO_INT_CLR_BITTOG (*(volatile uint32_t *)(0x40002C50)) +#define GPIO_VALUE (*(volatile uint32_t *)(0x40002054)) +#define GPIO_IRQ (*(volatile uint32_t *)(0x40002058)) +#define WDT_INTERVAL (*(volatile uint32_t *)(0x4000205C)) +#define WDT_INTERVAL_BITSET (*(volatile uint32_t *)(0x4000245C)) +#define WDT_INTERVAL_BITCLR (*(volatile uint32_t *)(0x4000285C)) +#define WDT_INTERVAL_BITTOG (*(volatile uint32_t *)(0x40002C5C)) +#define WDT_CTRL (*(volatile uint32_t *)(0x40002060)) +#define WDT_CTRL_BITSET (*(volatile uint32_t *)(0x40002460)) +#define WDT_CTRL_BITCLR (*(volatile uint32_t *)(0x40002860)) +#define WDT_CTRL_BITTOG (*(volatile uint32_t *)(0x40002C60)) +#define WDT_TIME (*(volatile uint32_t *)(0x40002064)) +#define RESET_CAUSE (*(volatile uint32_t *)(0x40002134)) +#define PWM0_CTRL (*(volatile uint32_t *)(0x40002068)) +#define PWM0_CTRL_BITSET (*(volatile uint32_t *)(0x40002468)) +#define PWM0_CTRL_BITCLR (*(volatile uint32_t *)(0x40002868)) +#define PWM0_CTRL_BITTOG (*(volatile uint32_t *)(0x40002C68)) +#define PWM0_COUNT (*(volatile uint32_t *)(0x4000206C)) +#define PWM0_COUNT_BITSET (*(volatile uint32_t *)(0x4000246C)) +#define PWM0_COUNT_BITCLR (*(volatile uint32_t *)(0x4000286C)) +#define PWM0_COUNT_BITTOG (*(volatile uint32_t *)(0x40002C6C)) +#define PWM1_CTRL (*(volatile uint32_t *)(0x40002070)) +#define PWM1_CTRL_BITSET (*(volatile uint32_t *)(0x40002470)) +#define PWM1_CTRL_BITCLR (*(volatile uint32_t *)(0x40002870)) +#define PWM1_CTRL_BITTOG (*(volatile uint32_t *)(0x40002C70)) +#define PWM1_COUNT (*(volatile uint32_t *)(0x40002074)) +#define PWM1_COUNT_BITSET (*(volatile uint32_t *)(0x40002474)) +#define PWM1_COUNT_BITCLR (*(volatile uint32_t *)(0x40002874)) +#define PWM1_COUNT_BITTOG (*(volatile uint32_t *)(0x40002C74)) +#define PWM_STATUS (*(volatile uint32_t *)(0x40002078)) +#define CLKEN_REG (*(volatile uint32_t *)(0x4000207C)) +#define CLKEN_REG_BITSET (*(volatile uint32_t *)(0x4000247C)) +#define CLKEN_REG_BITCLR (*(volatile uint32_t *)(0x4000287C)) +#define CLKEN_REG_BITTOG (*(volatile uint32_t *)(0x40002C7C)) +#define I2C_INTERRUPT_STATUS (*(volatile uint32_t *)(0x40002080)) +#define I2C_INTERRUPT_CLEAR (*(volatile uint32_t *)(0x40002084)) +#define I2C_INTERRUPT_CLEAR_BITSET (*(volatile uint32_t *)(0x40002484)) +#define I2C_INTERRUPT_CLEAR_BITCLR (*(volatile uint32_t *)(0x40002884)) +#define I2C_INTERRUPT_CLEAR_BITTOG (*(volatile uint32_t *)(0x40002C84)) +#define I2C_INTERRUPT_ENABLE (*(volatile uint32_t *)(0x40002088)) +#define I2C_INTERRUPT_ENABLE_BITSET (*(volatile uint32_t *)(0x40002488)) +#define I2C_INTERRUPT_ENABLE_BITCLR (*(volatile uint32_t *)(0x40002888)) +#define I2C_INTERRUPT_ENABLE_BITTOG (*(volatile uint32_t *)(0x40002C88)) +#define I2C_MODE (*(volatile uint32_t *)(0x4000208C)) +#define I2C_MODE_BITSET (*(volatile uint32_t *)(0x4000248C)) +#define I2C_MODE_BITCLR (*(volatile uint32_t *)(0x4000288C)) +#define I2C_MODE_BITTOG (*(volatile uint32_t *)(0x40002C8C)) +#define I2C_TX_DATA (*(volatile uint32_t *)(0x40002090)) +#define I2C_TX_DATA_BITSET (*(volatile uint32_t *)(0x40002490)) +#define I2C_TX_DATA_BITCLR (*(volatile uint32_t *)(0x40002890)) +#define I2C_TX_DATA_BITTOG (*(volatile uint32_t *)(0x40002C90)) +#define I2C_RX_DATA (*(volatile uint32_t *)(0x40002144)) +#define I2C_TX_RD_WRB (*(volatile uint32_t *)(0x40002094)) +#define I2C_TX_RD_WRB_BITSET (*(volatile uint32_t *)(0x40002494)) +#define I2C_TX_RD_WRB_BITCLR (*(volatile uint32_t *)(0x40002894)) +#define I2C_TX_RD_WRB_BITTOG (*(volatile uint32_t *)(0x40002C94)) +#define I2C_TX_NO_BYTES (*(volatile uint32_t *)(0x40002098)) +#define I2C_TX_NO_BYTES_BITSET (*(volatile uint32_t *)(0x40002498)) +#define I2C_TX_NO_BYTES_BITCLR (*(volatile uint32_t *)(0x40002898)) +#define I2C_TX_NO_BYTES_BITTOG (*(volatile uint32_t *)(0x40002C98)) +#define I2C_RX_NO_BYTES (*(volatile uint32_t *)(0x4000209C)) +#define I2C_RX_NO_BYTES_MASTER (*(volatile uint32_t *)(0x400020A0)) +#define I2C_RX_NO_BYTES_MASTER_BITSET (*(volatile uint32_t *)(0x400024A0)) +#define I2C_RX_NO_BYTES_MASTER_BITCLR (*(volatile uint32_t *)(0x400028A0)) +#define I2C_RX_NO_BYTES_MASTER_BITTOG (*(volatile uint32_t *)(0x40002CA0)) +#define I2C_GO (*(volatile uint32_t *)(0x400020A4)) +#define I2C_GO_BITSET (*(volatile uint32_t *)(0x400024A4)) +#define I2C_GO_BITCLR (*(volatile uint32_t *)(0x400028A4)) +#define I2C_GO_BITTOG (*(volatile uint32_t *)(0x40002CA4)) +#define I2C_RX_EARLY_THRESHOLD (*(volatile uint32_t *)(0x400020A8)) +#define I2C_RX_EARLY_THRESHOLD_BITSET (*(volatile uint32_t *)(0x400024A8)) +#define I2C_RX_EARLY_THRESHOLD_BITCLR (*(volatile uint32_t *)(0x400028A8)) +#define I2C_RX_EARLY_THRESHOLD_BITTOG (*(volatile uint32_t *)(0x40002CA8)) +#define I2C_RX_AUTO_NAG_BYTE_CNT (*(volatile uint32_t *)(0x400020AC)) +#define I2C_RX_AUTO_NAG_BYTE_CNT_BITSET (*(volatile uint32_t *)(0x400024AC)) +#define I2C_RX_AUTO_NAG_BYTE_CNT_BITCLR (*(volatile uint32_t *)(0x400028AC)) +#define I2C_RX_AUTO_NAG_BYTE_CNT_BITTOG (*(volatile uint32_t *)(0x40002CAC)) +#define I2C_HALF_TIME (*(volatile uint32_t *)(0x400020B0)) +#define I2C_HALF_TIME_BITSET (*(volatile uint32_t *)(0x400024B0)) +#define I2C_HALF_TIME_BITCLR (*(volatile uint32_t *)(0x400028B0)) +#define I2C_HALF_TIME_BITTOG (*(volatile uint32_t *)(0x40002CB0)) +#define I2C_ADDRESS (*(volatile uint32_t *)(0x400020B4)) +#define I2C_ADDRESS_BITSET (*(volatile uint32_t *)(0x400024B4)) +#define I2C_ADDRESS_BITCLR (*(volatile uint32_t *)(0x400028B4)) +#define I2C_ADDRESS_BITTOG (*(volatile uint32_t *)(0x40002CB4)) +#define I2C_ADDR_TYPE (*(volatile uint32_t *)(0x400020B8)) +#define I2C_ADDR_TYPE_BITSET (*(volatile uint32_t *)(0x400024B8)) +#define I2C_ADDR_TYPE_BITCLR (*(volatile uint32_t *)(0x400028B8)) +#define I2C_ADDR_TYPE_BITTOG (*(volatile uint32_t *)(0x40002CB8)) +#define I2C_SOFT_RESET (*(volatile uint32_t *)(0x400020BC)) +#define I2C_SOFT_RESET_BITSET (*(volatile uint32_t *)(0x400024BC)) +#define I2C_SOFT_RESET_BITCLR (*(volatile uint32_t *)(0x400028BC)) +#define I2C_SOFT_RESET_BITTOG (*(volatile uint32_t *)(0x40002CBC)) +#define I2C_SLAVE_RWB (*(volatile uint32_t *)(0x400020C0)) +#define I2C_MASTER_SM (*(volatile uint32_t *)(0x400020C4)) +#define I2C_SLAVE_SM (*(volatile uint32_t *)(0x400020C8)) +#define I2C_SLAVE_ENABLE (*(volatile uint32_t *)(0x400020CC)) +#define I2C_SLAVE_ENABLE_BITSET (*(volatile uint32_t *)(0x400024CC)) +#define I2C_SLAVE_ENABLE_BITCLR (*(volatile uint32_t *)(0x400028CC)) +#define I2C_SLAVE_ENABLE_BITTOG (*(volatile uint32_t *)(0x40002CCC)) +#define I2C_MASTER_SEND_RESTART (*(volatile uint32_t *)(0x400020D0)) +#define I2C_MASTER_SEND_RESTART_BITSET (*(volatile uint32_t *)(0x400024D0)) +#define I2C_MASTER_SEND_RESTART_BITCLR (*(volatile uint32_t *)(0x400028D0)) +#define I2C_MASTER_SEND_RESTART_BITTOG (*(volatile uint32_t *)(0x40002CD0)) +#define DMA_MUX (*(volatile uint32_t *)(0x400020D4)) +#define DMA_MUX_BITSET (*(volatile uint32_t *)(0x400024D4)) +#define DMA_MUX_BITCLR (*(volatile uint32_t *)(0x400028D4)) +#define DMA_MUX_BITTOG (*(volatile uint32_t *)(0x40002CD4)) +#define DMA_CTRL_STAT (*(volatile uint32_t *)(0x400020D8)) +#define COMP_CTRL (*(volatile uint32_t *)(0x400020DC)) +#define COMP_CTRL_BITSET (*(volatile uint32_t *)(0x400024DC)) +#define COMP_CTRL_BITCLR (*(volatile uint32_t *)(0x400028DC)) +#define COMP_CTRL_BITTOG (*(volatile uint32_t *)(0x40002CDC)) +#define COMP_STAT (*(volatile uint32_t *)(0x400020E0)) +#define LP_UART_CTRL (*(volatile uint32_t *)(0x400020E4)) +#define LP_UART_CTRL_BITSET (*(volatile uint32_t *)(0x400024E4)) +#define LP_UART_CTRL_BITCLR (*(volatile uint32_t *)(0x400028E4)) +#define LP_UART_CTRL_BITTOG (*(volatile uint32_t *)(0x40002CE4)) +#define LP_UART_STATUS (*(volatile uint32_t *)(0x400020E8)) +#define LP_UART_DATA (*(volatile uint32_t *)(0x40002154)) +#define CAP_FILT_CONF (*(volatile uint32_t *)(0x400020EC)) +#define CAP_FILT_CONF_BITSET (*(volatile uint32_t *)(0x400024EC)) +#define CAP_FILT_CONF_BITCLR (*(volatile uint32_t *)(0x400028EC)) +#define CAP_FILT_CONF_BITTOG (*(volatile uint32_t *)(0x40002CEC)) +#define CAP_IRQ_CONF (*(volatile uint32_t *)(0x400020F0)) +#define CAP_IRQ_CONF_BITSET (*(volatile uint32_t *)(0x400024F0)) +#define CAP_IRQ_CONF_BITCLR (*(volatile uint32_t *)(0x400028F0)) +#define CAP_IRQ_CONF_BITTOG (*(volatile uint32_t *)(0x40002CF0)) +#define CAP_STATUS (*(volatile uint32_t *)(0x400020F4)) +#define CORE_ENABLE_SWD_ACCESS_APPS (*(volatile uint32_t *)(0x400020F8)) +#define CORE_ENABLE_SWD_ACCESS_APPS_BITSET (*(volatile uint32_t *)(0x400024F8)) +#define CORE_ENABLE_SWD_ACCESS_APPS_BITCLR (*(volatile uint32_t *)(0x400028F8)) +#define CORE_ENABLE_SWD_ACCESS_APPS_BITTOG (*(volatile uint32_t *)(0x40002CF8)) +#define APPS_DEBUGGER_TO_CORE_DATA (*(volatile uint32_t *)(0x400020FC)) +#define APPS_CORE_TO_DEBUGGER_DATA (*(volatile uint32_t *)(0x40002100)) +#define APPS_CORE_TO_DEBUGGER_DATA_BITSET (*(volatile uint32_t *)(0x40002500)) +#define APPS_CORE_TO_DEBUGGER_DATA_BITCLR (*(volatile uint32_t *)(0x40002900)) +#define APPS_CORE_TO_DEBUGGER_DATA_BITTOG (*(volatile uint32_t *)(0x40002D00)) +#define APPS_DEBUG_DATA_TO_CORE_AVAILABLE (*(volatile uint32_t *)(0x40002104)) +#define APPS_DEBUG_DATA_TO_CORE_ACCEPTED (*(volatile uint32_t *)(0x40002108)) +#define APPS_DEBUG_DATA_TO_CORE_ACCEPTED_BITSET (*(volatile uint32_t *)(0x40002508)) +#define APPS_DEBUG_DATA_TO_CORE_ACCEPTED_BITCLR (*(volatile uint32_t *)(0x40002908)) +#define APPS_DEBUG_DATA_TO_CORE_ACCEPTED_BITTOG (*(volatile uint32_t *)(0x40002D08)) +#define APPS_CORE_DATA_TO_DEBUGGER_AVAILABLE (*(volatile uint32_t *)(0x4000210C)) +#define APPS_CORE_DATA_TO_DEBUGGER_AVAILABLE_BITSET (*(volatile uint32_t *)(0x4000250C)) +#define APPS_CORE_DATA_TO_DEBUGGER_AVAILABLE_BITCLR (*(volatile uint32_t *)(0x4000290C)) +#define APPS_CORE_DATA_TO_DEBUGGER_AVAILABLE_BITTOG (*(volatile uint32_t *)(0x40002D0C)) +#define APPS_CORE_DATA_TO_DEBUGGER_ACCEPTED (*(volatile uint32_t *)(0x40002110)) +#define SWD_REQUEST (*(volatile uint32_t *)(0x40002114)) +#define EDGE_CTRL0 (*(volatile uint32_t *)(0x40002118)) +#define EDGE_CTRL0_BITSET (*(volatile uint32_t *)(0x40002518)) +#define EDGE_CTRL0_BITCLR (*(volatile uint32_t *)(0x40002918)) +#define EDGE_CTRL0_BITTOG (*(volatile uint32_t *)(0x40002D18)) +#define EDGE_CTRL1 (*(volatile uint32_t *)(0x4000211C)) +#define EDGE_CTRL1_BITSET (*(volatile uint32_t *)(0x4000251C)) +#define EDGE_CTRL1_BITCLR (*(volatile uint32_t *)(0x4000291C)) +#define EDGE_CTRL1_BITTOG (*(volatile uint32_t *)(0x40002D1C)) +#define EDGE_COUNT (*(volatile uint32_t *)(0x40002120)) +#define RESET_REG (*(volatile uint32_t *)(0x40002124)) +#define RESET_REG_BITSET (*(volatile uint32_t *)(0x40002524)) +#define RESET_REG_BITCLR (*(volatile uint32_t *)(0x40002924)) +#define RESET_REG_BITTOG (*(volatile uint32_t *)(0x40002D24)) +#define DIGITAL_VERSION (*(volatile uint32_t *)(0x40000000)) +#define CLK_FREQ_DAC (*(volatile uint32_t *)(0x40000004)) +#define CLK_FREQ_SET (*(volatile uint32_t *)(0x40000008)) +#define CLK_FREQ_SET_BITSET (*(volatile uint32_t *)(0x40000408)) +#define CLK_FREQ_SET_BITCLR (*(volatile uint32_t *)(0x40000808)) +#define CLK_FREQ_SET_BITTOG (*(volatile uint32_t *)(0x40000C08)) +#define CLK_FREQ_NREFCLKS (*(volatile uint32_t *)(0x4000000C)) +#define CLK_FREQ_NREFCLKS_BITSET (*(volatile uint32_t *)(0x4000040C)) +#define CLK_FREQ_NREFCLKS_BITCLR (*(volatile uint32_t *)(0x4000080C)) +#define CLK_FREQ_NREFCLKS_BITTOG (*(volatile uint32_t *)(0x40000C0C)) +#define CLK_FREQ_REF_SEL (*(volatile uint32_t *)(0x40000010)) +#define CLK_FREQ_REF_SEL_BITSET (*(volatile uint32_t *)(0x40000410)) +#define CLK_FREQ_REF_SEL_BITCLR (*(volatile uint32_t *)(0x40000810)) +#define CLK_FREQ_REF_SEL_BITTOG (*(volatile uint32_t *)(0x40000C10)) +#define CLK_FREQ_DIG_CLKS (*(volatile uint32_t *)(0x40000014)) +#define CLK_FREQ_HIGHTARGET (*(volatile uint32_t *)(0x40000018)) +#define CLK_FREQ_HIGHTARGET_BITSET (*(volatile uint32_t *)(0x40000418)) +#define CLK_FREQ_HIGHTARGET_BITCLR (*(volatile uint32_t *)(0x40000818)) +#define CLK_FREQ_HIGHTARGET_BITTOG (*(volatile uint32_t *)(0x40000C18)) +#define CLK_FREQ_LOWTARGET (*(volatile uint32_t *)(0x4000001C)) +#define CLK_FREQ_LOWTARGET_BITSET (*(volatile uint32_t *)(0x4000041C)) +#define CLK_FREQ_LOWTARGET_BITCLR (*(volatile uint32_t *)(0x4000081C)) +#define CLK_FREQ_LOWTARGET_BITTOG (*(volatile uint32_t *)(0x40000C1C)) +#define CLK_FREQ_LP_BACKOFF (*(volatile uint32_t *)(0x40000020)) +#define CLK_FREQ_LP_BACKOFF_BITSET (*(volatile uint32_t *)(0x40000420)) +#define CLK_FREQ_LP_BACKOFF_BITCLR (*(volatile uint32_t *)(0x40000820)) +#define CLK_FREQ_LP_BACKOFF_BITTOG (*(volatile uint32_t *)(0x40000C20)) +#define CLK_FREQ_ENABLE (*(volatile uint32_t *)(0x40000024)) +#define CLK_FREQ_ENABLE_BITSET (*(volatile uint32_t *)(0x40000424)) +#define CLK_FREQ_ENABLE_BITCLR (*(volatile uint32_t *)(0x40000824)) +#define CLK_FREQ_ENABLE_BITTOG (*(volatile uint32_t *)(0x40000C24)) +#define CLK_GATE_SYS (*(volatile uint32_t *)(0x40000028)) +#define CLK_GATE_SYS_BITSET (*(volatile uint32_t *)(0x40000428)) +#define CLK_GATE_SYS_BITCLR (*(volatile uint32_t *)(0x40000828)) +#define CLK_GATE_SYS_BITTOG (*(volatile uint32_t *)(0x40000C28)) +#define CLK_GATE_MODEM (*(volatile uint32_t *)(0x4000002C)) +#define CLK_GATE_MODEM_BITSET (*(volatile uint32_t *)(0x4000042C)) +#define CLK_GATE_MODEM_BITCLR (*(volatile uint32_t *)(0x4000082C)) +#define CLK_GATE_MODEM_BITTOG (*(volatile uint32_t *)(0x40000C2C)) +#define CLK_GATE_RADIO (*(volatile uint32_t *)(0x40000030)) +#define CLK_GATE_RADIO_BITSET (*(volatile uint32_t *)(0x40000430)) +#define CLK_GATE_RADIO_BITCLR (*(volatile uint32_t *)(0x40000830)) +#define CLK_GATE_RADIO_BITTOG (*(volatile uint32_t *)(0x40000C30)) +#define CLK_GATE_DEBUG (*(volatile uint32_t *)(0x40000034)) +#define CLK_GATE_DEBUG_BITSET (*(volatile uint32_t *)(0x40000434)) +#define CLK_GATE_DEBUG_BITCLR (*(volatile uint32_t *)(0x40000834)) +#define CLK_GATE_DEBUG_BITTOG (*(volatile uint32_t *)(0x40000C34)) +#define CLK_GATE_RBIST (*(volatile uint32_t *)(0x40000038)) +#define CLK_GATE_RBIST_BITSET (*(volatile uint32_t *)(0x40000438)) +#define CLK_GATE_RBIST_BITCLR (*(volatile uint32_t *)(0x40000838)) +#define CLK_GATE_RBIST_BITTOG (*(volatile uint32_t *)(0x40000C38)) +#define LPC_CTRL (*(volatile uint32_t *)(0x4000003C)) +#define LPC_CTRL_BITSET (*(volatile uint32_t *)(0x4000043C)) +#define LPC_CTRL_BITCLR (*(volatile uint32_t *)(0x4000083C)) +#define LPC_CTRL_BITTOG (*(volatile uint32_t *)(0x40000C3C)) +#define LPC_TEST (*(volatile uint32_t *)(0x40000040)) +#define LPC_TEST_BITSET (*(volatile uint32_t *)(0x40000440)) +#define LPC_TEST_BITCLR (*(volatile uint32_t *)(0x40000840)) +#define LPC_TEST_BITTOG (*(volatile uint32_t *)(0x40000C40)) +#define FPGA_FLASH_WR (*(volatile uint32_t *)(0x40000044)) +#define FPGA_FLASH_WR_BITSET (*(volatile uint32_t *)(0x40000444)) +#define FPGA_FLASH_WR_BITCLR (*(volatile uint32_t *)(0x40000844)) +#define FPGA_FLASH_WR_BITTOG (*(volatile uint32_t *)(0x40000C44)) +#define FPGA_FLASH_RD (*(volatile uint32_t *)(0x40000048)) +#define PMU_CTRL (*(volatile uint32_t *)(0x4000004C)) +#define PMU_CTRL_BITSET (*(volatile uint32_t *)(0x4000044C)) +#define PMU_CTRL_BITCLR (*(volatile uint32_t *)(0x4000084C)) +#define PMU_CTRL_BITTOG (*(volatile uint32_t *)(0x40000C4C)) +#define APP_CTRL0 (*(volatile uint32_t *)(0x40000050)) +#define APP_CTRL0_BITSET (*(volatile uint32_t *)(0x40000450)) +#define APP_CTRL0_BITCLR (*(volatile uint32_t *)(0x40000850)) +#define APP_CTRL0_BITTOG (*(volatile uint32_t *)(0x40000C50)) +#define APP_CTRL1 (*(volatile uint32_t *)(0x40000054)) +#define APP_CTRL1_BITSET (*(volatile uint32_t *)(0x40000454)) +#define APP_CTRL1_BITCLR (*(volatile uint32_t *)(0x40000854)) +#define APP_CTRL1_BITTOG (*(volatile uint32_t *)(0x40000C54)) +#define APP_CTRL2 (*(volatile uint32_t *)(0x40000058)) +#define APP_CTRL2_BITSET (*(volatile uint32_t *)(0x40000458)) +#define APP_CTRL2_BITCLR (*(volatile uint32_t *)(0x40000858)) +#define APP_CTRL2_BITTOG (*(volatile uint32_t *)(0x40000C58)) +#define APP_CTRL3 (*(volatile uint32_t *)(0x4000005C)) +#define APP_CTRL3_BITSET (*(volatile uint32_t *)(0x4000045C)) +#define APP_CTRL3_BITCLR (*(volatile uint32_t *)(0x4000085C)) +#define APP_CTRL3_BITTOG (*(volatile uint32_t *)(0x40000C5C)) +#define PMU_STAT (*(volatile uint32_t *)(0x40000060)) +#define PMUBIST_ADC_CONF (*(volatile uint32_t *)(0x40000064)) +#define PMUBIST_ADC_CONF_BITSET (*(volatile uint32_t *)(0x40000464)) +#define PMUBIST_ADC_CONF_BITCLR (*(volatile uint32_t *)(0x40000864)) +#define PMUBIST_ADC_CONF_BITTOG (*(volatile uint32_t *)(0x40000C64)) +#define PMUBIST_ADC_DATA (*(volatile uint32_t *)(0x40000068)) +#define STATUS (*(volatile uint32_t *)(0x4000006C)) +#define LPC_STATUS (*(volatile uint32_t *)(0x40000070)) +#define LPC_PDTIMER (*(volatile uint32_t *)(0x40000074)) +#define LPC_PDTIMER_BITSET (*(volatile uint32_t *)(0x40000474)) +#define LPC_PDTIMER_BITCLR (*(volatile uint32_t *)(0x40000874)) +#define LPC_PDTIMER_BITTOG (*(volatile uint32_t *)(0x40000C74)) +#define PIO_OWNER0 (*(volatile uint32_t *)(0x40000078)) +#define PIO_OWNER1 (*(volatile uint32_t *)(0x4000007C)) +#define RTC_TIME_LSBS (*(volatile uint32_t *)(0x40000080)) +#define RTC_TIME_MSBS (*(volatile uint32_t *)(0x40000084)) +#define DEBUG_SEL (*(volatile uint32_t *)(0x40000088)) +#define DEBUG_SEL_BITSET (*(volatile uint32_t *)(0x40000488)) +#define DEBUG_SEL_BITCLR (*(volatile uint32_t *)(0x40000888)) +#define DEBUG_SEL_BITTOG (*(volatile uint32_t *)(0x40000C88)) +#define FLASH_STATUS (*(volatile uint32_t *)(0x4000008C)) +#define CHIP_WDT_INTERVAL (*(volatile uint32_t *)(0x40000090)) +#define CHIP_WDT_INTERVAL_BITSET (*(volatile uint32_t *)(0x40000490)) +#define CHIP_WDT_INTERVAL_BITCLR (*(volatile uint32_t *)(0x40000890)) +#define CHIP_WDT_INTERVAL_BITTOG (*(volatile uint32_t *)(0x40000C90)) +#define CHIP_WDT_CTRL (*(volatile uint32_t *)(0x40000094)) +#define CHIP_WDT_CTRL_BITSET (*(volatile uint32_t *)(0x40000494)) +#define CHIP_WDT_CTRL_BITCLR (*(volatile uint32_t *)(0x40000894)) +#define CHIP_WDT_CTRL_BITTOG (*(volatile uint32_t *)(0x40000C94)) +#define CHIP_WDT_TIME (*(volatile uint32_t *)(0x40000098)) +#define CHIP_RESET (*(volatile uint32_t *)(0x4000009C)) +#define CHIP_RESET_BITSET (*(volatile uint32_t *)(0x4000049C)) +#define CHIP_RESET_BITCLR (*(volatile uint32_t *)(0x4000089C)) +#define CHIP_RESET_BITTOG (*(volatile uint32_t *)(0x40000C9C)) +#define SWD_PIN_CFG (*(volatile uint32_t *)(0x400000A0)) +#define SWD_PIN_CFG_BITSET (*(volatile uint32_t *)(0x400004A0)) +#define SWD_PIN_CFG_BITCLR (*(volatile uint32_t *)(0x400008A0)) +#define SWD_PIN_CFG_BITTOG (*(volatile uint32_t *)(0x40000CA0)) + +/******************************************************************************/ +/* Peripheral declaration */ +/******************************************************************************/ + +/* UART Defines */ +#define UART0_BASE 0x50003000 +#define UART1_BASE 0x50004000 + +#ifdef __cplusplus +} +#endif + +#endif /* HI2110_H */ diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.c b/targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.c new file mode 100644 index 00000000000..b082e7abefa --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.c @@ -0,0 +1,86 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "system_hi2110.h" +#include "cmsis.h" + +/*lint ++flb "Enter library region" */ + +#define __SYSTEM_CLOCK (48000000UL) + +#if defined ( __CC_ARM ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; +#elif defined ( __ICCARM__ ) + __root uint32_t SystemCoreClock = __SYSTEM_CLOCK; +#elif defined ( __GNUC__ ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; +#endif + +void SystemCoreClockUpdate(void) +{ + SystemCoreClock = __SYSTEM_CLOCK; +} + +/* Restart the core if we're in an interrupt context to ensure a known state. + * Also reset any PIOs and ensure interrupts are disabled. */ +void SystemInit(void) +{ + uint32_t x = __get_xPSR(); + + /* Check for interrupt context and reboot needed. */ + if (x & 0x3f) { + /* Processor is in an interrupt context, reset the core by triggering + * the reset vector using the SYSRESETREQ bit in the AIRCR register */ + x = SCB->AIRCR; + x &= 0xffff; /* Mask out the top 16 bits */ + x |= 0x05fa0000; /* Must write with this value for the write to take effect */ + x |= 0x04; /* Set the SYSRESETREQ bit */ + SCB->AIRCR = x; /* Reset the core */ + } + + /* Release claim on any pins */ + PIO_FUNC0_BITCLR = 0xFFFFFFFF; + PIO_FUNC1_BITCLR = 0xFFFFFFFF; + PIO_FUNC2_BITCLR = 0xFFFFFFFF; + PIO_FUNC3_BITCLR = 0xFFFFFFFF; + PIO_FUNC4_BITCLR = 0xFFFFFFFF; + + /* Disable all IRQ interrupts */ + NVIC->ICER[0] = 0xffffffff; + + /* Ensure interrupts are enabled */ + __set_PRIMASK(0); + + /* Allow sleep */ + SystemAllowSleep(true); +} + +void SystemAllowSleep(bool sleepAllowed) +{ + if (sleepAllowed) { + /* Set deep sleep, though not on exit */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk; + } else { + /* Unset deep sleep */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + } +} + +/*lint --flb "Leave library region" */ diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.h b/targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.h new file mode 100644 index 00000000000..0f8b78aee55 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.h @@ -0,0 +1,69 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_HI2110_H +#define SYSTEM_HI2110_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + + +/** + * Allow the system to go to sleep, shutting down clocks, etc. + * or not. If the system is allowed to sleep it will awake + * and restore clocks automatically on an interrupt however + * there will be a 200 to 300 usecond delay. + * + * @param sleepAllowed if true then sleep is allowed. + * @return none + * + * @brief Allow full sleep, or not. + */ +extern void SystemAllowSleep(bool sleepAllowed); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_HI2110_H */ diff --git a/targets/TARGET_ublox/TARGET_HI2110/gpio_api.c b/targets/TARGET_ublox/TARGET_HI2110/gpio_api.c new file mode 100644 index 00000000000..7024631750a --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/gpio_api.c @@ -0,0 +1,80 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * TYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * MBED API CALLS + * ----------------------------------------------------------------*/ + +void gpio_init(gpio_t *obj, PinName pin) +{ + if (pin == (PinName)NC) { + return; + } + + MBED_ASSERT (pin < NUM_PINS); + + obj->pin = pin; + obj->mask = (1ul << pin); + + obj->reg_set = &GPIO_OUT_BITSET; + obj->reg_clr = &GPIO_OUT_BITCLR; + obj->reg_val = &GPIO_VALUE; + obj->reg_dir = &GPIO_DIR; + + /* Claim the pin */ + pin_function(pin, PIN_FUNCTION_GPIO); +} + +void gpio_mode(gpio_t *obj, PinMode mode) +{ + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) +{ + MBED_ASSERT(obj->pin != (PinName)NC); + + switch (direction) { + case PIN_INPUT: + { + *(obj->reg_dir) &= ~(obj->mask); + } + break; + case PIN_OUTPUT: + { + *(obj->reg_dir) |= obj->mask; + } + break; + /* TODO: looks as though the default is + * not normally trapped here */ + } +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/gpio_irq_api.c b/targets/TARGET_ublox/TARGET_HI2110/gpio_irq_api.c new file mode 100644 index 00000000000..ab8d0812ccd --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/gpio_irq_api.c @@ -0,0 +1,148 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* TODO: this needs testing */ + +#include +#include "cmsis.h" + +#include "gpio_irq_api.h" +#include "mbed_error.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * TYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* Each GPIO pin is given an ID, if the ID is 0 the pin can be ignored. */ +static uint8_t channel_ids[20] = {0}; +static gpio_irq_handler irq_handler; + +static bool initialised = false; + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +void IRQ5_GPIO_Handler() +{ + if (initialised) { + for (uint8_t i = 0; i < sizeof (channel_ids) / sizeof (channel_ids[0]); i++) { + uint8_t id = channel_ids[i]; + uint32_t mask = 1 << id; + + if (id != 0) { + if (GPIO_IRQ | mask) { + if (GPIO_INT_RISE | mask) { + irq_handler(id, IRQ_RISE); + } else if (GPIO_INT_FALL | mask) { + irq_handler(id, IRQ_FALL); + } + } + } + } + } + + /* Clear all the interrupt bits (rather than wasting time on + * each individual one), or we might get stuck if a spurious + * one should arrive. */ + GPIO_INT_CLR = 0xFFFFFFFF; +} + +/* ---------------------------------------------------------------- + * MBED API CALLS + * ----------------------------------------------------------------*/ + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) +{ + bool return_value = -1; + + if (initialised) { + return_value = 0; + } else { + if (pin != NC) { + MBED_ASSERT (pin < NUM_PINS); + + irq_handler = handler; + obj->ch = pin; + channel_ids[pin] = id; + + uint32_t mask = 1 << obj->ch; + + /* Remove any existing setting */ + GPIO_INT_RISE_BITCLR &= ~mask; + GPIO_INT_FALL_BITCLR &= ~mask; + GPIO_INT_LOW_BITCLR &= ~mask; + GPIO_INT_HIGH_BITCLR &= ~mask; + + initialised = true; + NVIC_EnableIRQ (GPIO_IRQn); + + return_value = 0; + } + } + + return return_value; +} + +void gpio_irq_free(gpio_irq_t *obj) +{ + channel_ids[obj->ch] = 0; +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) +{ + uint32_t mask = 1 << obj->ch; + + if (enable) { + if (event == IRQ_RISE) { + GPIO_INT_RISE_BITSET |= mask; + } else if (event == IRQ_FALL) { + GPIO_INT_FALL_BITSET |= mask; + } + } + else + { + if (event == IRQ_RISE) { + GPIO_INT_RISE_BITSET &= ~mask; + } else if (event == IRQ_FALL) { + GPIO_INT_FALL_BITSET &= ~mask; + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) +{ + (void) obj; + NVIC_EnableIRQ (GPIO_IRQn); +} + +void gpio_irq_disable(gpio_irq_t *obj) +{ + (void) obj; + NVIC_DisableIRQ (GPIO_IRQn); +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/gpio_object.h b/targets/TARGET_ublox/TARGET_HI2110/gpio_object.h new file mode 100644 index 00000000000..2be82b78b9c --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/gpio_object.h @@ -0,0 +1,57 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + __IO uint32_t *reg_dir; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + __I uint32_t *reg_val; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + MBED_ASSERT(obj->pin != (PinName)NC); + if (value) { + *obj->reg_set = obj->mask; + } else { + *obj->reg_clr = obj->mask; + } +} + +static inline int gpio_read(gpio_t *obj) { + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_val & obj->mask) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/hi2110_init.c b/targets/TARGET_ublox/TARGET_HI2110/hi2110_init.c new file mode 100644 index 00000000000..281034c7ccd --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/hi2110_init.c @@ -0,0 +1,69 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "mbed_assert.h" +#include "cmsis.h" +#include "hi2110_init.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +static uint8_t get_owner(uint8_t pin); + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +/* Determine which core owns a given pin + * 0: None + * 1: security core + * 2: protocol core + * 3: apps core */ +static uint8_t get_owner(uint8_t pin) +{ + uint8_t value; + uint8_t pio_owner_shift = (pin & 0x0F) << 1; + volatile uint32_t * pio_owner_reg = (&PIO_OWNER0 + (pin >> 4)); + + value = 0x03 & (*pio_owner_reg >> pio_owner_shift); + + return value; +} + +/* ---------------------------------------------------------------- + * MBED API FUNCTIONS + * ----------------------------------------------------------------*/ + +void HI2110_init(void) +{ + __attribute__ ((unused)) uint8_t owner[20]; + + /* This purely for diagnostics to see who owns which PIO pin. + * Put a break-point at the end of this function and take a look + * at the array. + * Any items marked as 1 or 2 belong to the security or protocol + * cores. Otherwise they are up for grabs. */ + for (uint8_t x = 0; x < 20; x++) { + owner[x] = get_owner(x); + } +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/hi2110_init.h b/targets/TARGET_ublox/TARGET_HI2110/hi2110_init.h new file mode 100644 index 00000000000..a2da23e2b4a --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/hi2110_init.h @@ -0,0 +1,38 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HI2110_INIT_H +#define HI2110_INIT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +void HI2110_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/lp_ticker.c b/targets/TARGET_ublox/TARGET_HI2110/lp_ticker.c new file mode 100644 index 00000000000..205e68b898a --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/lp_ticker.c @@ -0,0 +1,340 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* The LP Ticker performs two functions for mbed: + * + * 1. Allows tracking of the passage of time. + * 2. Allows the system to enter the lowest power + * state for a given time. + * + * For this to work the single RTC interrupt needs + * to perform two functions. It needs to increment + * an overflow counter at every 32-bit overflow without + * otherwise affecting the system state (i.e. not waking it + * up and not putting it to sleep) and, when requested, + * it *also* needs to wake the system up from sleep + * at a specific time. Note also that the units of time + * from an mbed perspective are useconds, whereas the RTC + * is clocked at 32 kHz, hence there is conversion to be done. + * + * Since it is not possible to reset the RTC, we maintain + * a 32-bit window on it, starting at g_last_32bit_overflow_value + * and ending at g_next_32bit_overflow_value. All values + * fed back up to mbed are relative to g_last_32bit_overflow_value. + */ + +#include "lp_ticker_api.h" +#include "sleep_api.h" +#include "critical.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* The maximum value of the RTC (48 bits) */ +#define RTC_MAX 0x0000FFFFFFFFFFFFULL + +/* RTC modulo */ +#define RTC_MODULO (RTC_MAX + 1) + +/* The 32-bit overflow value */ +#define MODULO_32BIT 0x100000000ULL + +/* Macro to increment a 64-bit RTC value x by y, with wrap */ +#define INCREMENT_MOD(x, y) (x = ((uint64_t) x + (uint64_t) y) % RTC_MODULO) + +/* Macro to get MSBs from a 64-bit integer */ +#define MSBS(x) ((uint32_t) ((uint64_t) (x) >> 32)) + +/* Macro to get LSBs from a 64-bit integer */ +#define LSBS(x) ((uint32_t) (x)) + +/* ---------------------------------------------------------------- + * TYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* Incremented each time the RTC goes over 32 bits */ +static uint32_t g_overflow_count = 0; + +/* Set when a user interrupt has been requested but an overflow + * interrupt needs to happen first */ +static bool g_user_interrupt_pending = false; + +/* Set when a user interrupt is the next interrupt to happen */ +static bool g_user_interrupt_set = false; + +/* Initialised flag, used to protect against interrupts going + * off before we're initialised */ +static bool g_initialised = false; + +/* The next overflow value to be used */ +static uint64_t g_next_32bit_overflow_value; + +/* The next match-compare value to be used */ +static uint64_t g_next_compare_value; + +/* Keep track of the previous 32-bit overflow + * value so that we can report 32-bit time + * correctly */ +static uint64_t g_last_32bit_overflow_value; + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +static void set_interrupt_to_32bit_overflow(void); +static void set_interrupt_to_user_value(void); + +/* ---------------------------------------------------------------- + * STATIC FUNCTIONS + * ----------------------------------------------------------------*/ + +/* Convert a tick value (32,768 Hz) into a microsecond value */ +static inline uint32_t ticksToUSeconds(uint32_t x) +{ + /* TODO: find a way to avoid the multiply by 1000000 + * Shift by 20 would introduce a 5% error, which is + * probably too much */ + uint64_t result = ((((uint64_t) x) * 1000000) >> 15); + + if (result > 0xFFFFFFFF) { + result = 0xFFFFFFFF; + } + + return (uint32_t) result; +} + +/* Convert a microsecond value into a tick value (32,768 Hz) */ +static inline uint32_t uSecondsToTicks(uint32_t x) +{ + /* TODO: find a way to avoid the divide by 1000000 + * Shift by 20 would introduce a 5% error, which is + * probably too much */ + return (uint32_t) ((((uint64_t) x) << 15) / 1000000); +} + +/* Take g_next_32bit_overflow_value and apply it to g_next_compare_value and + * then the chip registers + * NOTE: the RTC interrupt should be disabled when calling this function */ +static inline void set_interrupt_to_32bit_overflow() +{ + /* Load up the values */ + g_next_compare_value = g_next_32bit_overflow_value; + + /* Set up the match register values */ + RTC_IRQ_TIME_MSBS = MSBS(g_next_compare_value); + RTC_IRQ_TIME_LSBS = LSBS(g_next_compare_value); +} + +/* Take g_next_compare_value and apply it to the chip registers + * NOTE: the RTC interrupt should be disabled when calling this function */ +static inline void set_interrupt_to_user_value() +{ + g_user_interrupt_set = true; + + /* Write MSBS first, then the value is latched on LSBS write */ + RTC_IRQ_TIME_MSBS = MSBS(g_next_compare_value); + RTC_IRQ_TIME_LSBS = LSBS(g_next_compare_value); +} + +/* Get the RTC value + * NOTE: the RTC interrupt should be disabled when calling this function */ +static inline uint64_t get_rtc_value() +{ + uint64_t rtc_value; + + rtc_value = ((uint64_t) RTC_TIME_MSBS) << 32; + rtc_value |= RTC_TIME_LSBS; + + return rtc_value; +} + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +/* RTC handler */ +void IRQ0_RTC_Handler(void) +{ + /* Have seen this interrupt occurring before initialisation, so guard + * against that */ + if (g_initialised) { + if (g_user_interrupt_pending) { + /* If there was a user interrupt pending, set it now */ + set_interrupt_to_user_value(); + + /* Reset the pending flag */ + g_user_interrupt_pending = false; + + /* This must have been a 32-bit overflow interrupt so + * increment the count */ + g_overflow_count++; + g_last_32bit_overflow_value = g_next_32bit_overflow_value; + INCREMENT_MOD(g_next_32bit_overflow_value, MODULO_32BIT); + } else { + if (g_user_interrupt_set) { + /* It's a user interrupt, so wake from sleep but don't + * increment the overflow count as this is not an + * overflow interrupt */ + + /* Reset the user interrupt flag and call mbed */ + g_user_interrupt_set = false; + lp_ticker_irq_handler(); + } else { + /* Increment the count as this was a 32-bit overflow + * interrupt rather than a user interrupt */ + g_overflow_count++; + g_last_32bit_overflow_value = g_next_32bit_overflow_value; + INCREMENT_MOD(g_next_32bit_overflow_value, MODULO_32BIT); + } + + /* Set the next interrupt to be at the 32-bit overflow */ + set_interrupt_to_32bit_overflow(); + } + } + + /* Clear the interrupt */ + RTC_IRQ_CLR = 0xFFFFFFFF; +} + +/* ---------------------------------------------------------------- + * MBED API CALLS + * ----------------------------------------------------------------*/ + +/* This will be called once at start of day to get the RTC running */ +void lp_ticker_init(void) +{ + if (!g_initialised) { + /* Reset the overflow count and the flags */ + g_overflow_count = 0; + g_user_interrupt_pending = false; + g_user_interrupt_set = false; + + /* Setup the next natural 32-bit overflow value */ + g_next_32bit_overflow_value = get_rtc_value(); + g_last_32bit_overflow_value = g_next_32bit_overflow_value; + INCREMENT_MOD(g_next_32bit_overflow_value, MODULO_32BIT); + + /* Clear the interrupt */ + RTC_IRQ_CLR = 0xFFFFFFFF; + + /* Interrupt at 32-bit overflow */ + set_interrupt_to_32bit_overflow(); + + /* Enable the interrupt */ + g_initialised = true; + NVIC_EnableIRQ(RTC_IRQn); + } +} + +uint32_t lp_ticker_read(void) +{ + uint64_t rtcNow; + + /* Disable interrupts to avoid collisions */ + core_util_critical_section_enter(); + + /* Just in case this is called before initialisation has been performed */ + if (!g_initialised) { + lp_ticker_init(); + } + + /* What mbed expects here is a 32 bit timer value. There is no + * way to reset the RTC so, to pretend it is 32 bits, we have to + * maintain a 32-bit window on it using the remembered overflow + * value */ + rtcNow = get_rtc_value(); + + /* Put interrupts back */ + core_util_critical_section_exit(); + + return ticksToUSeconds(rtcNow - g_last_32bit_overflow_value); +} + +void lp_ticker_set_interrupt(timestamp_t time) +{ + uint32_t timeNow = get_rtc_value() - g_last_32bit_overflow_value; + uint32_t timeOffset = uSecondsToTicks(time) - timeNow; + + /* Disable interrupts to avoid collisions */ + core_util_critical_section_enter(); + + g_user_interrupt_pending = false; + g_user_interrupt_set = false; + + /* Handle time slipping into the past */ + if (timeOffset > 0xEFFFFFFF) { + timeOffset = 100; + } + + /* Read the current time */ + g_next_compare_value = get_rtc_value(); + + /* Add the offset */ + INCREMENT_MOD(g_next_compare_value, timeOffset); + + /* We must let the normal overflow interrupt occur as + * well as setting this interrupt so, if the value + * of 'time' would occur after the overflow point, + * put the change of compare-value off until afterwards. */ + /* TODO: this needs proper testing. */ + if (g_next_32bit_overflow_value > g_next_compare_value) { + /* The easy case, no overlap */ + } else { + /* Could be because g_next_compare_value has wrapped (around the + * 48-bit limit of the RTC) */ + if (g_next_32bit_overflow_value - g_next_compare_value >= MODULO_32BIT) { + /* The wrap case, we're OK */ + } else { + /* There is an overlap, apply the value later */ + g_user_interrupt_pending = true; + + if (g_next_32bit_overflow_value == g_next_compare_value) { + /* If they are on top of each other, bump this + * one forward to avoid losing the interrupt */ + INCREMENT_MOD(g_next_compare_value, 2); + } + } + } + + if (!g_user_interrupt_pending) { + /* Make the change immediately */ + set_interrupt_to_user_value(); + } + + /* Put interrupts back */ + core_util_critical_section_exit(); +} + +void lp_ticker_disable_interrupt(void) +{ + /* Can't disable interrupts as we need them to manage + * overflow. Instead, switch off the user part. */ + g_user_interrupt_pending = false; + g_user_interrupt_set = false; +} + +void lp_ticker_clear_interrupt(void) +{ + /* Can't disable interrupts as we need them to manage + * overflow. Instead, switch off the user part. */ + g_user_interrupt_pending = false; + g_user_interrupt_set = false; +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/mbed_overrides.c b/targets/TARGET_ublox/TARGET_HI2110/mbed_overrides.c new file mode 100644 index 00000000000..bbc29831c08 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/mbed_overrides.c @@ -0,0 +1,38 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "hi2110_init.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * MBED API FUNCTIONS + * ----------------------------------------------------------------*/ + +void mbed_sdk_init(void) +{ + HI2110_init(); +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/objects.h b/targets/TARGET_ublox/TARGET_HI2110/objects.h new file mode 100644 index 00000000000..b189e083a4a --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/objects.h @@ -0,0 +1,73 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" +#include "stdbool.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + IRQ_NOT_SET, + IRQ_ON, + IRQ_OFF +} irq_setting_t; + +struct port_s { + __IO uint32_t *reg_dir; + __IO uint32_t *reg_out; + __IO uint32_t *reg_val; + __IO uint32_t *reg_drv; + PortName port; + uint32_t mask; +}; + +struct gpio_irq_s { + /* Don't bother with having a port number here as there's only one */ + uint32_t ch; /* Corresponds to the interrupt pin */ +}; + +struct serial_s { + SerialConfig config; + PinName rx_pin; + PinName tx_pin; + volatile uart_ctrl_t *reg_base; + uint8_t index; + uint32_t baud_rate; + bool format_set; /* If true then the struct that follows is populated */ + struct { + uint8_t stop_bits; + uint8_t data_bits; + uint8_t parity; + } format; + irq_setting_t irq_rx_setting; + irq_setting_t irq_tx_setting; +}; + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/pinmap.c b/targets/TARGET_ublox/TARGET_HI2110/pinmap.c new file mode 100644 index 00000000000..81535f511e8 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/pinmap.c @@ -0,0 +1,145 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* As well as claiming and setting pins, the functions here also need + * to take into account the way the pins are powered. On the Boudica + * chip they are arranged in three banks, PIO 0:5, PIO 6:10 and + * PIO 11:19. + * + * The arrangement for which PIO bank is powered is determined by the module + * in which the HI2110 chip is mounted, hence the use of conditional + * compilation below. + */ + +#include "stdbool.h" +#include "mbed_assert.h" +#include "mbed_error.h" +#include "pinmap.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +#define HAL_PIO_MASK_FUNC (0xFF) +#define HAL_PIO_MODULO_4_MASK (0x3) + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +static inline uint32_t clr_mask (PinName pin); +static inline uint32_t set_mask (PinName pin, int function); +static inline volatile uint32_t * func_reg (PinName pin); + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +// Return the clear mask for a pin +static inline uint32_t clr_mask (PinName pin) +{ + return HAL_PIO_MASK_FUNC << ((pin & HAL_PIO_MODULO_4_MASK) << 3); +} + +// Return the set mask for a pin and a given function +static inline uint32_t set_mask (PinName pin, int function) +{ + return function << ((pin & HAL_PIO_MODULO_4_MASK) << 3); +} + +// Return the function register for a pin +static inline volatile uint32_t * func_reg (PinName pin) +{ + return &PIO_FUNC0 + (pin >> 2); +} + +// Return the owner of a pin +// 0: None +// 1: security core +// 2: protocol core +// 3: apps core +static inline uint8_t get_owner(PinName pin) +{ + uint8_t pio_owner_shift = (pin & 0x0F) << 1; + volatile uint32_t * pio_owner_reg = (&PIO_OWNER0 + (pin >> 4)); + + return 0x03 & (*pio_owner_reg >> pio_owner_shift); +} + +/* ---------------------------------------------------------------- + * MBED "INTERNAL" API CALLS + * ----------------------------------------------------------------*/ + +void pin_function(PinName pin, int function) +{ + volatile uint32_t *pio_func_reg; + + /* Set the function for the given pin */ + pio_func_reg = func_reg (pin); + *pio_func_reg = (*pio_func_reg & ~(clr_mask(pin))) | set_mask(pin, function); + + /* Power the pin */ +#ifdef TARGET_SARA_NBIOT + /* On Sara NBIoT, GPIO pin 19 has to be high to power GPIO pins 0 to 10 */ + if ((pin >= p0) && (pin <= p10)) { + /* Grab pin 19 as a GPIO if we don't have it already */ + if (get_owner(p19) != 0x03) { + pio_func_reg = func_reg (p19); + *pio_func_reg = (*pio_func_reg & ~(clr_mask(p19))) | set_mask(p19, 1); /* 1 == PIN_FUNCTION_GPIO */ + + MBED_ASSERT (get_owner(p19) == 0x03); + } + + /* Set pin 19 to be an output and to be high */ + GPIO_DIR |= (1ul << p19); + GPIO_OUT_BITSET = (1ul << p19); + + /* Note: the level on pins 6 to 10 is controlled by the protocol + * processor to be the VCC level required by the SIM. The + * application has no control over this. */ + } + /* The power to GPIOs 11 to 19 is fed directly from pin 51 of the module */ +#endif +} + +void pin_mode(PinName pin, PinMode mode) +{ + MBED_ASSERT(pin != (PinName)NC); + + switch (mode) { + case PullUp: + { + MBED_ASSERT(false); /* Not currently supported on HI2100 */ + } + break; + case PullDown: + { + GPIO_PULLEN_BITSET = 1U << pin; + } + break; + case PullNone: + { + GPIO_PULLEN_BITCLR = 1U << pin; + } + break; + default: + break; + } +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/port_api.c b/targets/TARGET_ublox/TARGET_HI2110/port_api.c new file mode 100644 index 00000000000..05e8b2f8785 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/port_api.c @@ -0,0 +1,103 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* TODO: this needs testing */ + +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" + +PinName port_pin(PortName port, int pin_n) +{ + MBED_ASSERT (port < PortMaxNumber); + + (void) port; + return (PinName)(pin_n); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) +{ + MBED_ASSERT (port < PortMaxNumber); + + obj->port = port; + obj->mask = mask; + + obj->reg_dir = &GPIO_DIR; + obj->reg_out = &GPIO_OUT; + obj->reg_val = &GPIO_VALUE; + obj->reg_drv = &GPIO_DRIVE; + + /* Claim the pins */ + for (uint8_t x = 0; x < NUM_PINS; x++) { + if (mask & (1ul << x)) { + pin_function((PinName) x, PIN_FUNCTION_GPIO); + } + } + + /* Set up the pins */ + port_dir(obj, dir); +} + +void port_mode(port_t *obj, PinMode mode) +{ + switch (mode) { + case PullUp: + { + MBED_ASSERT(false); /* Not currently supported on HI2110 */ + } + break; + case PullDown: + { + GPIO_PULLEN_BITSET |= obj->mask; + } + break; + case PullNone: + { + GPIO_PULLEN_BITCLR &= ~(obj->mask); + } + break; + default: + break; + } +} + +void port_dir(port_t *obj, PinDirection dir) +{ + switch (dir) { + case PIN_INPUT: + { + *(obj->reg_dir) &= ~(obj->mask); + } + break; + case PIN_OUTPUT: + { + *(obj->reg_dir) |= obj->mask; + /* TODO: do we need to set the drive strength? If so, how do we decide which way? */ + /* obj->reg_drv |= obj->mask; */ + } + break; + } +} + +void port_write(port_t *obj, int value) +{ + *(obj->reg_out) = value; +} + +int port_read(port_t *obj) +{ + return *(obj->reg_val); +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/serial_api.c b/targets/TARGET_ublox/TARGET_HI2110/serial_api.c new file mode 100644 index 00000000000..2670f5b3fb4 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/serial_api.c @@ -0,0 +1,819 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* The serial driver connects UART HW to mbed and also associates the UART + * HW with physical pins. Any physical pin can be linked to any UART, + * however the mbed serial port initialisation API makes no mention of + * which UART HW is to be used (only the pins) and hence the driver needs + * to make some decisions for itself. + * + * There are two and a half UARTs on the chip: UART0, UART1 and a + * lower-power, receive-only UART that is clocked from 32 kHz and can + * therefore be awake while the rest of the chip is sleeping peacefully. + * This provides maximal power saving, however the LP UART can only run + * at 9600 bits/s (which is quite sufficient for all NB-IoT needs). + * + * So, if the baud rate is 9600 the driver code configures the LP UART + * for Rx and UART0 for Tx. If the baud rate is not 9600 then it configures + * UART0 for both Rx and Tx. Unless... the Tx pin is the pin UART1_TX (it + * is an mbed convention to use the Tx pin), which is p6, in which case UART1 + * is configured instead. This latter is not the normal case as this pin + * is intended to be used as a GPIO. + * + * If the baud rate is changed the driver reconfigures to match. + * + * TODO: implement asynchronous and flow control APIs. + */ + +#include "mbed_assert.h" +#include "serial_api.h" +#include "pinmap.h" + +#include "cmsis.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* Registers banks for the standard UARTs */ +#define UART0_REG (*(volatile uart_ctrl_t *) UART0_BASE) +#define UART1_REG (*(volatile uart_ctrl_t *) UART1_BASE) + +/* Masks for the UART control bits in the reset and clock enable registers */ +#define UART0_CTRL (1 << 3) +#define UART1_CTRL (1 << 4) +#define UARTLP_CTRL (1 << 6) + +/* Convert number of data bits to register values */ +#define MIN_NUM_UART_DATA_BITS 5 +#define MAX_NUM_UART_DATA_BITS 8 +#define REGISTER_DATA_BITS(x) ((x) - MIN_NUM_UART_DATA_BITS) + +/* Number of stop bits */ +#define NUM_UART_STOP_BITS_1 1 +#define NUM_UART_STOP_BITS_2 2 + +/* ---------------------------------------------------------------- + * TYPES + * ----------------------------------------------------------------*/ + +/* Enum to identify the interrupt to the UART handler */ +typedef enum { + IRQ_UART_ID_0_AND_LP, + IRQ_UART_ID_1, + NUM_IRQ_IDS +} irq_uart_id_t; + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* The IRQ configuration variables, set up and named by mbed */ +static uint32_t serial_irq_ids[NUM_IRQ_IDS] = {0}; +static uart_irq_handler irq_handler = NULL; + +/* RTX needs these */ +int stdio_uart_inited = 0; +serial_t stdio_uart; + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +static void init_config(serial_t *obj); +static void deinit_config(serial_t *obj); +static void set_baud(serial_t *obj, uint32_t baud_rate); +static void irq_enable(serial_t *obj); +static void irq_disable(serial_t *obj); + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +/* Initialise the given serial config by setting the pin functions + * and then resetting the relevant HW */ +static void init_config(serial_t *obj) +{ + uint32_t x; + + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + pin_function(obj->rx_pin, PIN_FUNCTION_LP_UART); + pin_function(obj->tx_pin, PIN_FUNCTION_UART0_TXD); + CLKEN_REG_BITSET = UARTLP_CTRL | UART0_CTRL; + obj->reg_base = &UART0_REG; + obj->index = IRQ_UART_ID_0_AND_LP; + /* Reset the LPUART and UART0 HW */ + /* NOTE: RESET_REG_BITTOG doesn't have the desired + * effect, need to use BITSET and then BITCLR */ + RESET_REG_BITSET |= 1ul << 6; + RESET_REG_BITCLR |= 1ul << 6; + RESET_REG_BITSET |= 1ul << 3; + RESET_REG_BITCLR |= 1ul << 3; + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + { + pin_function(obj->rx_pin, PIN_FUNCTION_UART0_RXD); + pin_function(obj->tx_pin, PIN_FUNCTION_UART0_TXD); + CLKEN_REG_BITSET = UART0_CTRL; + obj->reg_base = &UART0_REG; + obj->index = IRQ_UART_ID_0_AND_LP; + /* Reset the UART0 HW */ + RESET_REG_BITSET |= 1ul << 3; + RESET_REG_BITCLR |= 1ul << 3; + } + break; + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + pin_function(obj->rx_pin, PIN_FUNCTION_UART1_RXD); + pin_function(obj->tx_pin, PIN_FUNCTION_UART1_TXD); + CLKEN_REG_BITSET = UART1_CTRL; + obj->reg_base = &UART1_REG; + obj->index = IRQ_UART_ID_1; + /* Reset the UART1 HW */ + RESET_REG_BITSET |= 1ul << 4; + RESET_REG_BITCLR |= 1ul << 4; + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + /* Tickle the UART control register to make sure it is updated */ + x = obj->reg_base->UARTLCR_H; + obj->reg_base->UARTLCR_H = x; + + /* Set the FIFO. The meaning of the three FIFO interrupt-level + * bits are as follows: + * + * 0 = 1/8 full + * 1 = 1/4 full + * 2 = 1/2 full + * 3 = 3/4 full + * 4 = 7/8 full + * + * Set up the Rx FIFO to be used fully (but we will also set + * a timeout to get immediate notice) and also the Tx FIFO + * to be fully used. */ + obj->reg_base->UARTIFLS = (obj->reg_base->UARTIFLS & ~(0x07 << 0)) | (4 << 0); + obj->reg_base->UARTIFLS = (obj->reg_base->UARTIFLS & ~(0x07 << 3)) | (4 << 3); + obj->reg_base->UARTLCR_H |= 1 << 4; + + /* Enable for Tx and Rx (TODO: add CTS when we add flow control) */ + obj->reg_base->UARTCR |= (1 << 8) | (1 << 9); + + /* Now enable it */ + obj->reg_base->UARTCR |= 1 << 0; + + obj->format_set = false; + obj->baud_rate = 0; + obj->irq_rx_setting = IRQ_NOT_SET; + obj->irq_tx_setting = IRQ_NOT_SET; +} + +/* Release a serial port */ +static void deinit_config(serial_t *obj) +{ + pin_function(obj->rx_pin, PIN_FUNCTION_UNCLAIMED); + pin_function(obj->tx_pin, PIN_FUNCTION_UNCLAIMED); + + /* Disable UART */ + obj->reg_base->UARTCR &= ~(1 << 0); + + /* Flush transmit FIFO */ + obj->reg_base->UARTLCR_H = 0; + + /* Disable everything */ + obj->reg_base->UARTCR = 0; + + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + CLKEN_REG_BITCLR = UARTLP_CTRL | UART0_CTRL; + LP_UART_CTRL &= ~(0xF << 20); /* Disable all LP interrupts */ + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + { + CLKEN_REG_BITCLR = UART0_CTRL; + } + break; + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + CLKEN_REG_BITCLR = UART1_CTRL; + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + obj->config = MAX_NUM_SERIAL_CONFIGS; + obj->reg_base = NULL; +} + +/* Set the baud rate for either of the two (non-LP) UARTS */ +static void set_baud(serial_t *obj, uint32_t baud_rate) +{ + uint32_t baud_rate_divider_i; + uint32_t baud_rate_divider_f; + uint32_t remainder; + uint32_t core_clock; + uint32_t x; + + /* Baud rate divider calculation: + * + * The integer part is: clock / (16 * baud) + * + * The fractional part is: round (decimal_part * 64), + * ...where decimal part is, for example, 0.085 + * + * decimal_part is: remainder / (16 * baud), + * ...where: remainder = core_clock % (baud * 16), + * + * So the fractional part becomes: + * round (decimal_part * 64) = round (remainder * 64 / (16 * baud)) = round (remainder * 4 / baud) + */ + + /* Get the mean clock frequency */ + core_clock = (CLK_FREQ_HIGHTARGET >> 1) + (CLK_FREQ_LOWTARGET >> 1); + /* Work out the actual clock frequency */ + core_clock = (core_clock * CLOCKS_REFERENCE_CLOCK_FREQ) / (((CLK_FREQ_NREFCLKS + 1) & 0xFFFF) * (CLK_GATE_SYS & 0xFF)); + baud_rate_divider_i = core_clock / (baud_rate << 4); + remainder = core_clock % (baud_rate << 4); + baud_rate_divider_f = ((remainder << 3) / baud_rate) >> 1; + /* Round it */ + baud_rate_divider_f += ((remainder << 3) / baud_rate) & 1; + + /* Disable UART while writing to control registers */ + obj->reg_base->UARTCR &= ~(1 << 0); + + obj->reg_base->UARTIBRD = baud_rate_divider_i; + obj->reg_base->UARTFBRD = baud_rate_divider_f; + + /* Make IBRD and FBRD update */ + x = obj->reg_base->UARTLCR_H; + obj->reg_base->UARTLCR_H = x; + + /* Now enable the UART again */ + obj->reg_base->UARTCR |= 1 << 0; +} + +/* Set the NVIC bits */ +static void irq_enable(serial_t *obj) +{ + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + NVIC_EnableIRQ(UART0_IRQn); + NVIC_EnableIRQ(LPUART_IRQn); + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + { + NVIC_EnableIRQ(UART0_IRQn); + } + break; + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + NVIC_EnableIRQ(UART1_IRQn); + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } +} + +/* Unset the NVIC bits */ +static void irq_disable(serial_t *obj) +{ + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + NVIC_DisableIRQ(UART0_IRQn); + NVIC_DisableIRQ(LPUART_IRQn); + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + { + NVIC_DisableIRQ(UART0_IRQn); + } + break; + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + NVIC_DisableIRQ(UART1_IRQn); + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } +} + +/* UART0 IRQ */ +void IRQ7_UART0_Handler() +{ + uint32_t id = serial_irq_ids[IRQ_UART_ID_0_AND_LP]; + + /* Check Rx and Rx Timeout bit */ + if (UART0_REG.UARTMIS & ((1 << 4) | (1 << 6))) { + if (id != 0) { + irq_handler(id, RxIrq); + /* Reading the character clears the interrupt, + * no way to protect against another arriving + * while processing one */ + } + } + /* Check Tx bit */ + if (UART0_REG.UARTMIS & (1 << 5)) { + if (id != 0) { + irq_handler(id, TxIrq); + } + /* Not sure what clears the interrupt so clear it explicitly */ + NVIC_ClearPendingIRQ(UART1_IRQn); + } +} + +/* UART1 IRQ */ +void IRQ8_UART1_Handler() +{ + uint32_t id = serial_irq_ids[IRQ_UART_ID_1]; + + /* Check Rx and Rx Timeout bit */ + if (UART1_REG.UARTMIS & ((1 << 4) | (1 << 6))) { + if (id != 0) { + irq_handler(id, RxIrq); + } + /* Reading the character clears the interrupt, + * no way to protect against another arriving + * while processing one */ + } + /* Check Tx bit */ + if (UART1_REG.UARTMIS & (1 << 5)) { + if (id != 0) { + irq_handler(id, TxIrq); + } + /* Not sure what clears the interrupt so clear it explicitly */ + NVIC_ClearPendingIRQ(UART1_IRQn); + } +} + +/* LP UART IRQ, receive only */ +void IRQ16_LPUART_Handler() +{ + uint32_t id = serial_irq_ids[IRQ_UART_ID_0_AND_LP]; + + if (id != 0) { + irq_handler(id, RxIrq); + + /* Another character might have arrived while + * we are processing the last, so + * check status bits 8 to 10 again and pend + * interrupt if there's something there */ + if (((LP_UART_STATUS >> 8) & 0x07) != 0) { + NVIC_SetPendingIRQ(LPUART_IRQn); + } else { + LP_UART_CTRL |= 1 << 27; /* Clear the interrupt */ + } + } +} + +/* ---------------------------------------------------------------- + * MBED API CALLS: SETUP FUNCTIONS + * ----------------------------------------------------------------*/ + +void serial_init(serial_t *obj, PinName tx, PinName rx) +{ + uint32_t clock = CLK_FREQ_DIG_CLKS; + + /* There are two and a half UARTs on the chip. The normal + * configuration is to use the LP_UART for Rx and UART0 for + * Tx. This gives maximal power saving in that the chip can + * wake up on receipt of data. However, this only works if the + * data rate is 9600 because that's the only data rate that + * the 32 kHz (i.e. RTC) clock driving the LP UART can support. + * + * So, if the data rate is 9600, use the LP_UART/UART0 + * combination, otherwise use UART0 for both Rx and Tx. However, + * we don't know the data rate at this point so assume LP_UART + * (as this works at the default baud rate) and we can change + * our minds later. + * + * There is another serial port, UART1, which is normally used + * by the modem processor to send out debug. We only initialise + * that here if the Tx pin is UART1_TX. */ + + /* Wait for the clock to be stable */ + while ((clock < CLK_FREQ_LOWTARGET) || (clock > CLK_FREQ_HIGHTARGET)) { + clock = CLK_FREQ_DIG_CLKS; + } + + if (tx == UART1_TX) { + /* Use UART1 for Rx and Tx */ + obj->config = SERIAL_CONFIG_UART1_RX_UART1_TX; + } else { + /* Use LP_UART for Rx, UART0 for Tx */ + obj->config = SERIAL_CONFIG_UARTLP_RX_UART0_TX; + } + + obj->rx_pin = rx; + obj->tx_pin = tx; + init_config(obj); + + /* TODO: set rx pin Pull mode ? */ + + /* set default baud rate and format */ + serial_baud(obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + if (tx == UART0_TX) { + /* The UART0 pins are the stdio pins */ + stdio_uart_inited = 1; + stdio_uart = *obj; + } +} + +void serial_free(serial_t *obj) +{ + if (obj->tx_pin == UART0_TX) { + stdio_uart_inited = 0; + } + + serial_irq_ids[obj->index] = 0; + + /* Release the port HW */ + deinit_config(obj); +} + +void serial_baud(serial_t *obj, int baudrate) +{ + bool switch_port_config = false; + bool format_set = obj->format_set; + uint8_t stop_bits = obj->format.stop_bits; + uint8_t data_bits = obj->format.data_bits; + SerialParity parity = (SerialParity) obj->format.parity; + irq_setting_t irq_rx_setting = obj->irq_rx_setting; + irq_setting_t irq_tx_setting = obj->irq_tx_setting; + + if ((obj->config == SERIAL_CONFIG_UARTLP_RX_UART0_TX) && (baudrate != 9600)) { + /* If we were on LP UART but the baud rate is not 9600 then + * switch to the standard UART (as the LP UART can't go any higher + * because it's clocked from 32 kHz) */ + deinit_config(obj); + obj->config = SERIAL_CONFIG_UART0_RX_UART0_TX; + init_config(obj); + switch_port_config = true; + } else if ((obj->config == SERIAL_CONFIG_UART0_RX_UART0_TX) && (baudrate == 9600)) { + /* If we were on UART0 but the baud rate is 9600 then switch to the + * LP UART for receive */ + deinit_config(obj); + obj->config = SERIAL_CONFIG_UARTLP_RX_UART0_TX; + init_config(obj); + switch_port_config = true; + } + + /* Disable UART while writing to control registers */ + obj->reg_base->UARTCR &= ~(1 << 0); + + if (switch_port_config) { + /* If the port was switched, switch the port configuration also */ + if (format_set) { + /* This serial port has been previously set up so switch the + * settings across to this new configuration */ + serial_format(obj, data_bits, parity, stop_bits); + } + if (irq_rx_setting != IRQ_NOT_SET) { + /* Do the same for Rx interrupts, if they were set */ + serial_irq_set(obj, RxIrq, (irq_rx_setting == IRQ_ON)); + } + if (irq_tx_setting != IRQ_NOT_SET) { + /* Do the same for Tx interrupts, if they were set */ + serial_irq_set(obj, TxIrq, (irq_tx_setting == IRQ_ON)); + } + } + + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + /* Set LP UART to 9600 (numerator 75 (0x4B), denominator 256 (00 == 256)) */ + LP_UART_CTRL = (LP_UART_CTRL & ~0xFFFF) | 0x004B; + set_baud(obj, baudrate); + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + set_baud(obj, baudrate); + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + /* Enable the UART again */ + obj->reg_base->UARTCR |= 1 << 0; + + obj->baud_rate = baudrate; +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) +{ + bool lp_also = false; + + MBED_ASSERT(data_bits >= MIN_NUM_UART_DATA_BITS); + MBED_ASSERT(data_bits <= MAX_NUM_UART_DATA_BITS); + MBED_ASSERT(stop_bits >= NUM_UART_STOP_BITS_1); + MBED_ASSERT(stop_bits <= NUM_UART_STOP_BITS_2); + + /* The LP UART is different to UARTs 0 and 1 so deal with it + * explicitly when required */ + if (obj->config == SERIAL_CONFIG_UARTLP_RX_UART0_TX) { + lp_also = true; + } + + /* Disable UART while writing to control registers */ + obj->reg_base->UARTCR &= ~(1 << 0); + + /* Set data bits (bits 5 and 6 of the UART0/1 register, bits 18 and 19 of the LP UART register) */ + obj->reg_base->UARTLCR_H = (obj->reg_base->UARTLCR_H & ~(0x03 << 5)) | (REGISTER_DATA_BITS(data_bits) << 5); + if (lp_also) { + LP_UART_CTRL = (LP_UART_CTRL & ~(0x03 << 18)) | (REGISTER_DATA_BITS(data_bits) << 18); + } + obj->format.data_bits = (uint8_t) data_bits; + + /* Set stop bits (bit 7 of the UART0/1 register) (there is no such setting for the LP UART) */ + if (stop_bits == NUM_UART_STOP_BITS_1) { + /* Clear 2-stop-bits bit */ + obj->reg_base->UARTLCR_H &= ~(1 << 7); + } else { + /* Set 2-stop-bits bit */ + obj->reg_base->UARTLCR_H |= 1 << 7; + } + obj->format.stop_bits = (uint8_t) stop_bits; + + /* Set parity */ + switch (parity) { + case ParityNone: + { + /* Disable parity */ + obj->reg_base->UARTLCR_H &= ~0x02; + if (lp_also) + { + LP_UART_CTRL &= ~(1 << 24); + } + } + break; + case ParityOdd: + { + /* Set even bit and enable parity */ + obj->reg_base->UARTLCR_H = (obj->reg_base->UARTLCR_H | (1 << 3)) | (1 << 2); + if (lp_also) + { + LP_UART_CTRL |= (1 << 24) | (1 << 25); + } + } + break; + case ParityEven: + { + /* Clear even bit and enable parity */ + obj->reg_base->UARTLCR_H = (obj->reg_base->UARTLCR_H & ~(1 << 3)) | (1 << 2); + if (lp_also) + { + LP_UART_CTRL &= ~(1 << 25); + LP_UART_CTRL |= 1 << 24; + } + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + /* Enable the UART again */ + obj->reg_base->UARTCR |= 1 << 0; + + obj->format.parity = (uint8_t) parity; + obj->format_set = true; +} + +/* ---------------------------------------------------------------- + * MBED API CALLS: INTERRUPT FUNCTIONS + * ----------------------------------------------------------------*/ + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) +{ + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) +{ + bool lp_also = false; + + if (obj->config == SERIAL_CONFIG_UARTLP_RX_UART0_TX) { + lp_also = true; + } + + /* Disable UART while writing to control registers */ + obj->reg_base->UARTCR &= ~(1 << 0); + + if (enable) { + switch (irq) { + case RxIrq: + { + /* Bit 4 for Rx and bit 6 for Rx Timeout */ + obj->reg_base->UARTIMSC |= (1 << 4) | (1 << 6); + if (lp_also) + { + /* "Word Received" IRQ */ + LP_UART_CTRL |= 1 << 23; + } + obj->irq_rx_setting = IRQ_ON; + irq_enable(obj); + } + break; + case TxIrq: + { + /* Bit 5 */ + obj->reg_base->UARTIMSC |= 1 << 5; + obj->irq_tx_setting = IRQ_ON; + irq_enable(obj); + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + } else { + switch (irq) { + case RxIrq: + { + /* Bit 4 for Rx and bit 6 for Rx Timeout */ + obj->reg_base->UARTIMSC &= ~((1 << 4) | (1 << 6)); + if (lp_also) + { + /* "Word Received" IRQ */ + LP_UART_CTRL &= ~(1 << 23); + } + obj->irq_rx_setting = IRQ_OFF; + } + break; + case TxIrq: + { + /* Bit 5 */ + obj->reg_base->UARTIMSC &= ~(1 << 5); + obj->irq_tx_setting = IRQ_OFF; + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + if ((obj->irq_rx_setting == IRQ_OFF) && (obj->irq_tx_setting == IRQ_OFF)) { + irq_disable(obj); + } + } + + /* Enable the UART again */ + obj->reg_base->UARTCR |= 1 << 0; +} + +/* ---------------------------------------------------------------- + * MBED API CALLS: TRANSMIT AND RECEIVE FUNCTIONS + * ----------------------------------------------------------------*/ + +int serial_getc(serial_t *obj) +{ + uint8_t data = 0; + + /* Block until there is data to read */ + while (!serial_readable(obj)) {} + + /* Read the data */ + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + data = (uint8_t) LP_UART_DATA; + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + data = (uint8_t) obj->reg_base->UARTDR; + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + return (int) data; +} + +void serial_putc(serial_t *obj, int c) +{ + /* Block until there is room to write */ + while (!serial_writable(obj)) {} + + /* Write the data */ + obj->reg_base->UARTDR = (uint8_t) c; +} + +int serial_readable(serial_t *obj) +{ + bool readable = false; + + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + /* Check the status register, bits 8 to 10 indicate + * the number of Rx bytes (make sure it's the status + * register not the data register as a read from that + * register would clear the Rx interrupt) */ + readable = (((LP_UART_STATUS >> 8) & 0x07) != 0); + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + /* Check the Rx FIFO Empty bit */ + readable = ((obj->reg_base->UARTFR & (1 << 4)) != (1 << 4)); + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + return (int) readable; +} + +int serial_writable(serial_t *obj) +{ + /* Check the "UART TX FIFO full" bit: + * only if this is 0 can we transmit */ + return (obj->reg_base->UARTFR & (1 << 5)) != (1 << 5); +} + +void serial_break_set(serial_t *obj) +{ + /* Disable UART while writing to control registers */ + obj->reg_base->UARTCR &= ~(1 << 0); + + /* Set bit 1 of the line control register */ + obj->reg_base->UARTLCR_H |= 1 << 0; + + /* Enable the UART again */ + obj->reg_base->UARTCR |= 1 << 0; +} + +void serial_break_clear(serial_t *obj) +{ + /* Disable UART while writing to control registers */ + obj->reg_base->UARTCR &= ~(1 << 0); + + /* Clear bit 1 of the line control register */ + obj->reg_base->UARTLCR_H &= ~(1 << 0); + + /* Enable the UART again */ + obj->reg_base->UARTCR |= 1 << 0; +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/sleep.c b/targets/TARGET_ublox/TARGET_HI2110/sleep.c new file mode 100644 index 00000000000..9a5eb809506 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/sleep.c @@ -0,0 +1,53 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sleep_api.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * TYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * STATIC FUNCTIONS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * MBED API CALLS + * ----------------------------------------------------------------*/ + +void sleep(void) +{ + __DSB(); + __WFI(); + __ISB(); +} + +void deepsleep() +{ + sleep(); +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/us_ticker.c b/targets/TARGET_ublox/TARGET_HI2110/us_ticker.c new file mode 100644 index 00000000000..72f5468385a --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/us_ticker.c @@ -0,0 +1,247 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* The usecond ticker is mapped to TIMER0. A few issues must be dealt + * with in this driver: + * + * 1. The us_ticker API must count upwards, not down. + * 2. The expected range/resolution is 32 bits each of 1 usecond, + * whereas TIMER0 runs at 48 MHz (not 1 MHz) and so actually + * has a range/resolution of 26 bits at 0.02 useconds. Software + * has to compensate for this. + */ + +#include "us_ticker_api.h" +#include "critical.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* TIMER0 clock is 48 MHz */ +#define CLOCK_TICKS_PER_US 48 + +/* The number of clock ticks in a full-run of + * TIMER0, scaled to represent useconds */ +#define USECONDS_PER_FULL_TIMER0_RUN 89478485 + +/* ---------------------------------------------------------------- + * TYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* Are we ready? */ +static bool g_initialised = false; + +/* Keep track of the number of useconds elapsed. */ +static uint32_t g_us_overflow = 0; + +/* The number of useconds to increment the by at each interrupt */ +static uint32_t g_us_overflow_increment = USECONDS_PER_FULL_TIMER0_RUN; + +/* Keep track of extra loops required to represent a particular time + * as the HW timer runs faster than 1 MHz */ +static uint32_t g_timer_extra_loops_required = 0; +static uint32_t g_timer_extra_loops_done = 0; + +/* Keep track of any adjustment due to user interrupts . */ +static uint32_t g_user_interrupt_offset = 0; + +/* Flag that a user timer is running */ +static bool g_user_interrupt = false; + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +static inline uint32_t divide_by_48(uint32_t x); + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +/* Perform a divide-by-48 operation. + * This is done as a multiply-shift operation to take advantage of + * the ARM 32 bit single-cycle multiply and avoid using division; + * 1/48 is equivalent to 1365/2^16. It is also done in two halves + * to make sure that the multiplies fit into 32 bits. + * + * The principle is: + * - divide the top 16 bits by 48 using multiply-shift (=> x1), + * - work out the remainder of that operation and divide that by 48 (=> x1r), + * - divide the bottom 16 bits by 48 using multiply-shift (=> x2), + * - add the lot together to get the result. + * + * The cost is 29 instructions. + */ +static inline uint32_t divide_by_48(uint32_t x) +{ + uint32_t x1 = ((x >> 16) * 1365) >> 16; + uint32_t x1r = ((x & 0xFFFF0000) - ((x1 * 48) << 16)); + x1r = (x1r * 1365) >> 16; + uint32_t x2 = ((x & 0xFFFF) * 1365) >> 16; + + return (x1 << 16) + x1r + x2; +} + +/* Timer0 handler */ +void IRQ1_TMR0_Handler(void) +{ + if (g_initialised) { + /* Increment the overflow count and set the increment + * value for next time */ + g_us_overflow += g_us_overflow_increment; + g_us_overflow_increment = USECONDS_PER_FULL_TIMER0_RUN; + + /* Now handle the user interrupt case */ + if (g_user_interrupt) { + if (g_timer_extra_loops_done < g_timer_extra_loops_required) { + /* Let the timer go round again */ + g_timer_extra_loops_done++; + } else { + /* We've done with looping around for a user interrupt */ + g_user_interrupt = false; + + /* Call the mbed API */ + us_ticker_irq_handler(); + } + } + } + + NVIC_ClearPendingIRQ(Timer_IRQn); +} + +/* ---------------------------------------------------------------- + * MBED API CALLS + * ----------------------------------------------------------------*/ + +void us_ticker_init(void) +{ + if (!g_initialised) { + /* Reset the globals */ + g_timer_extra_loops_done = 0; + g_timer_extra_loops_required = 0; + g_us_overflow = 0; + g_us_overflow_increment = USECONDS_PER_FULL_TIMER0_RUN; + g_user_interrupt_offset = 0; + g_user_interrupt = false; + + /* Get the timer running (starting at what is zero, + * once inverted), with repeat */ + NVIC_ClearPendingIRQ(Timer_IRQn); + TIMER0_LOAD = 0xFFFFFFFF; + TIMER0_CTRL = 0x03; + NVIC_EnableIRQ(Timer_IRQn); + + g_initialised = true; + } +} + +uint32_t us_ticker_read() +{ + uint32_t timeValue; + + /* This can be called before initialisation has been performed */ + if (!g_initialised) { + us_ticker_init(); + } + + /* Disable interrupts to avoid collisions */ + core_util_critical_section_enter(); + + /* Get the timer value, adding the offset in case we've been moved + * around by user activity, inverting it (as a count-up timer is + * expected), then scaling it to useconds and finally adding the + * usecond overflow value to make up the 32-bit usecond total */ + timeValue = divide_by_48(~(TIMER0_TIME + g_user_interrupt_offset)) + g_us_overflow; + + /* Put interrupts back */ + core_util_critical_section_exit(); + + return timeValue; +} + +/* NOTE: it seems to be an accepted fact that users + * will never ask for a timeout of more than 2^31 useconds + * and hence it's possible to do signed arithmetic + */ +void us_ticker_set_interrupt(timestamp_t timestamp) +{ + g_timer_extra_loops_required = 0; + g_timer_extra_loops_done = 0; + int32_t timeDelta; + + /* Disable interrupts to avoid collisions */ + core_util_critical_section_enter(); + + /* Establish how far we're being asked to move */ + timeDelta = (int32_t) ((uint32_t) timestamp - us_ticker_read()); + + if (timeDelta <= 0) { + /* Make delta positive if it's not, it will expire pretty quickly */ + /* Note: can't just call us_ticker_irq_handler() directly as we + * may already be in it and will overflow the stack */ + timeDelta = 1; + } + + /* The TIMER0 clock source is greater than 1 MHz, so + * work out how many times we have to go around + * and what the remainder is */ + g_timer_extra_loops_required = (uint32_t) timeDelta / USECONDS_PER_FULL_TIMER0_RUN; + timeDelta -= g_timer_extra_loops_required * USECONDS_PER_FULL_TIMER0_RUN; + + /* Next time we hit the interrupt the increment will be smaller */ + g_us_overflow_increment = (uint32_t) timeDelta; + + /* We're about to modify the timer value; work out the + * difference so that we can compensate for it when + * the time is read */ + timeDelta = timeDelta * CLOCK_TICKS_PER_US; + g_user_interrupt_offset += TIMER0_TIME - timeDelta; + + /* Run for the remainder first, then we can loop for the full + * USECONDS_PER_FULL_TIMER0_RUN afterwards */ + TIMER0_LOAD = timeDelta; + + /* A user interrupt is now running */ + g_user_interrupt = true; + + /* Put interrupts back */ + core_util_critical_section_exit(); +} + +void us_ticker_disable_interrupt(void) +{ + /* Can't actually disable the interrupt here + * as we need it to manage the timer overflow, + * instead switch off the user interrupt part */ + g_user_interrupt = false; + g_timer_extra_loops_required = 0; + g_us_overflow_increment = 0; +} + +void us_ticker_clear_interrupt(void) +{ + /* As above, can't clear the interrupt as it + * may just be an overflow interrupt, instead + * clear the variables */ + g_user_interrupt = false; + g_timer_extra_loops_required = 0; + g_us_overflow_increment = 0; +} diff --git a/targets/TARGET_ublox/mbed_rtx.h b/targets/TARGET_ublox/mbed_rtx.h new file mode 100644 index 00000000000..98cf1d6d75f --- /dev/null +++ b/targets/TARGET_ublox/mbed_rtx.h @@ -0,0 +1,37 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_MBED_RTX_H +#define MBED_MBED_RTX_H + +#if defined(TARGET_HI2110) + +#ifndef INITIAL_SP +#define INITIAL_SP (0x01000000 + 0x05000 - 256) +#endif + +#ifndef OS_TASKCNT +#define OS_TASKCNT 6 +#endif +#ifndef OS_MAINSTKSIZE +#define OS_MAINSTKSIZE 128 +#endif +#ifndef OS_CLOCK +#define OS_CLOCK 48000000 +#endif +#endif + +#endif // MBED_MBED_RTX_H diff --git a/targets/targets.json b/targets/targets.json index 8843e87c5b2..6a2e01a9ed8 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -2345,5 +2345,31 @@ "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH"], "release_versions": ["2", "5"], "device_name": "M453VG6AE" + }, + "HI2110": { + "inherits": ["Target"], + "core": "Cortex-M0", + "default_toolchain": "GCC_ARM", + "supported_toolchains": ["GCC_ARM", "ARM", "IAR"], + "extra_labels": ["ublox"], + "macros": ["TARGET_PROCESSOR_FAMILY_BOUDICA", "BOUDICA_SARA", "NDEBUG=1"], + "public": false, + "target_overrides": { + "*": { + "core.stdio-flush-at-exit": false + } + }, + "device_has": ["INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "SERIAL", "SLEEP", "STDIO_MESSAGES"], + "default_lib": "std", + "release_versions": ["5"] + }, + "SARA_NBIOT": { + "inherits": ["HI2110"], + "extra_labels": ["ublox", "HI2110"], + "public": false + }, + "SARA_NBIOT_EVK": { + "inherits": ["SARA_NBIOT"], + "extra_labels": ["ublox", "HI2110", "SARA_NBIOT"] } } From 5b7d40bea8824c4c04da058d557680280e3bdd14 Mon Sep 17 00:00:00 2001 From: pradeep-gr Date: Thu, 20 Oct 2016 16:20:14 +0530 Subject: [PATCH 013/107] LOAD_ADDRESS added --- targets/targets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/targets.json b/targets/targets.json index 6a2e01a9ed8..630536a78e0 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -2330,7 +2330,7 @@ "post_binary_hook": {"function": "NCS36510TargetCode.ncs36510_addfib"}, "macros": ["REVD", "CM3", "CPU_NCS36510", "TARGET_NCS36510", "LOAD_ADDRESS=0x3000"], "supported_toolchains": ["GCC_ARM", "ARM", "IAR"], - "device_has": ["ANALOGIN", "SERIAL", "I2C", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "LOWPOWERTIMER"], + "device_has": ["ANALOGIN", "SERIAL", "I2C", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "LOWPOWERTIMER", "TRNG"], "device_name": "NCS36510", "release_versions": ["2", "5"] }, From 5b9638c3947eaf7d519038e3f8b634e01b6cbd8c Mon Sep 17 00:00:00 2001 From: pradeep-gr Date: Wed, 26 Oct 2016 14:47:51 +0530 Subject: [PATCH 014/107] To resolve conflict --- targets/TARGET_ONSEMI/TARGET_NCS36510/Pad.c | 20 ++- .../device/TOOLCHAIN_IAR/startup_NCS36510.s | 60 ++++----- .../TARGET_NCS36510/device/system_NCS36510.c | 2 +- .../TARGET_ONSEMI/TARGET_NCS36510/dma_map.h | 14 -- .../TARGET_ONSEMI/TARGET_NCS36510/macHw_map.h | 16 --- .../TARGET_NCS36510/ncs36510_trng.h | 42 ++++++ .../TARGET_NCS36510/ncs36510_trng_api.c | 113 ++++++++++++++++ .../TARGET_ONSEMI/TARGET_NCS36510/objects.h | 6 +- targets/TARGET_ONSEMI/TARGET_NCS36510/pad.h | 4 +- .../TARGET_ONSEMI/TARGET_NCS36510/pad_map.h | 4 +- .../TARGET_ONSEMI/TARGET_NCS36510/port_api.c | 2 + .../TARGET_ONSEMI/TARGET_NCS36510/pwm_map.h | 32 ----- .../TARGET_NCS36510/random_map.h | 3 - targets/TARGET_ONSEMI/TARGET_NCS36510/rfAna.c | 123 ------------------ .../TARGET_ONSEMI/TARGET_NCS36510/rfAna_map.h | 10 -- targets/TARGET_ONSEMI/TARGET_NCS36510/rtc.c | 50 ++++--- targets/TARGET_ONSEMI/TARGET_NCS36510/rtc.h | 6 + .../TARGET_ONSEMI/TARGET_NCS36510/rtc_api.c | 2 - .../TARGET_ONSEMI/TARGET_NCS36510/rtc_map.h | 67 ---------- targets/TARGET_ONSEMI/TARGET_NCS36510/sleep.c | 6 +- targets/TARGET_ONSEMI/TARGET_NCS36510/sleep.h | 10 +- .../TARGET_ONSEMI/TARGET_NCS36510/sleep_api.c | 48 +------ .../TARGET_ONSEMI/TARGET_NCS36510/spi_api.c | 18 +-- .../TARGET_ONSEMI/TARGET_NCS36510/trim_map.h | 5 +- .../TARGET_ONSEMI/TARGET_NCS36510/wdt_map.h | 95 -------------- targets/targets.json | 2 +- 26 files changed, 266 insertions(+), 494 deletions(-) create mode 100644 targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng.h create mode 100644 targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng_api.c diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/Pad.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/Pad.c index 9a48bf31698..142101fbd3a 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/Pad.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/Pad.c @@ -1,4 +1,3 @@ -#ifdef REVD /** ****************************************************************************** * @file pad.c @@ -83,20 +82,20 @@ void fPadInit() PADREG->PADIO1.WORD = PAD_INPUT_PD_L1_PP; /* UART1 RXD */ PADREG->PADIO2.WORD = PAD_INPUT_PD_L1_PP; /* UART1 CTS */ PADREG->PADIO3.WORD = PAD_OUTPUT_PN_L1_OD; /* UART1 RTS */ - PADREG->PADIO4.WORD = PAD_UNUSED_PD_L0_PP; - PADREG->PADIO5.WORD = PAD_UNUSED_PD_L0_PP; - PADREG->PADIO6.WORD = PAD_UNUSED_PD_L0_PP; - PADREG->PADIO7.WORD = PAD_UNUSED_PD_L0_PP; + PADREG->PADIO4.WORD = PAD_UNUSED_PD_L1_PP; + PADREG->PADIO5.WORD = PAD_UNUSED_PD_L1_PP; + PADREG->PADIO6.WORD = PAD_UNUSED_PD_L1_PP; + PADREG->PADIO7.WORD = PAD_UNUSED_PD_L1_PP; PADREG->PADIO8.WORD = PAD_OUTPUT_PN_L1_OD; /* UART2 TXD */ PADREG->PADIO9.WORD = PAD_INPUT_PD_L1_PP; /* UART2 RXD */ - PADREG->PADIO10.WORD = PAD_UNUSED_PD_L0_PP; + PADREG->PADIO10.WORD = PAD_UNUSED_PD_L1_PP; PADREG->PADIO11.WORD = PAD_INPUT_PD_L1_PP; /* SWO */ PADREG->PADIO12.WORD = PAD_INPUT_PD_L1_PP; /* SWCLK */ PADREG->PADIO13.WORD = PAD_INPUT_PD_L1_PP; /* SWDIO */ PADREG->PADIO14.WORD = PAD_INPUT_PD_L1_PP; - PADREG->PADIO15.WORD = PAD_UNUSED_PD_L0_PP; - PADREG->PADIO16.WORD = PAD_UNUSED_PD_L0_PP; - PADREG->PADIO17.WORD = PAD_UNUSED_PD_L0_PP; + PADREG->PADIO15.WORD = PAD_UNUSED_PD_L1_PP; + PADREG->PADIO16.WORD = PAD_UNUSED_PD_L1_PP; + PADREG->PADIO17.WORD = PAD_UNUSED_PD_L1_PP; /** - Disable the clock for PAD peripheral device */ CLOCK_DISABLE(CLOCK_PAD); @@ -142,5 +141,4 @@ boolean fPadIOCtrl(uint8_t PadNum, uint8_t OutputDriveStrength, uint8_t OutputDr } /* Invalid parameter/s */ return False; -} -#endif /* REVD */ +} \ No newline at end of file diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/device/TOOLCHAIN_IAR/startup_NCS36510.s b/targets/TARGET_ONSEMI/TARGET_NCS36510/device/TOOLCHAIN_IAR/startup_NCS36510.s index e6ca52d23ef..e3a7ab075c2 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/device/TOOLCHAIN_IAR/startup_NCS36510.s +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/device/TOOLCHAIN_IAR/startup_NCS36510.s @@ -157,153 +157,153 @@ Reset_Handler BX R0 PUBWEAK NMI_Handler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) NMI_Handler B NMI_Handler ; PUBWEAK HardFault_Handler -; SECTION .text:CODE:REORDER(1) +; SECTION .text:CODE:REORDER:NOROOT(1) ;HardFault_Handler ; B HardFault_Handler PUBWEAK MemManage_Handler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) MemManage_Handler B MemManage_Handler PUBWEAK BusFault_Handler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) BusFault_Handler B BusFault_Handler PUBWEAK UsageFault_Handler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) UsageFault_Handler B UsageFault_Handler ; PUBWEAK vPortSVCHandler -; SECTION .text:CODE:REORDER(1) +; SECTION .text:CODE:REORDER:NOROOT(1) ;vPortSVCHandler ; B vPortSVCHandler PUBWEAK DebugMon_Handler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) DebugMon_Handler B DebugMon_Handler ; PUBWEAK xPortPendSVHandler -; SECTION .text:CODE:REORDER(1) +; SECTION .text:CODE:REORDER:NOROOT(1) ;xPortPendSVHandler ; B xPortPendSVHandler ; PUBWEAK SysTick_Handler -; SECTION .text:CODE:REORDER(1) +; SECTION .text:CODE:REORDER:NOROOT(1) ;SysTick_Handler ; B SysTick_Handler ; PUBWEAK fIrqTim0Handler -; SECTION .text:CODE:REORDER(1) +; SECTION .text:CODE:REORDER:NOROOT(1) ;fIrqTim0Handler ; B fIrqTim0Handler ; PUBWEAK fIrqTim1Handler -; SECTION .text:CODE:REORDER(1) +; SECTION .text:CODE:REORDER:NOROOT(1) ;fIrqTim1Handler ; B fIrqTim1Handler ; PUBWEAK fIrqTim2Handler -; SECTION .text:CODE:REORDER(1) +; SECTION .text:CODE:REORDER:NOROOT(1) ;fIrqTim2Handler ; B fIrqTim2Handler ; PUBWEAK fIrqUart1Handler -; SECTION .text:CODE:REORDER(1) +; SECTION .text:CODE:REORDER:NOROOT(1) ;fIrqUart1Handler ; B fIrqUart1Handler ; PUBWEAK fIrqSpiHandler -; SECTION .text:CODE:REORDER(1) +; SECTION .text:CODE:REORDER:NOROOT(1) ;fIrqSpiHandler ; B fIrqSpiHandler PUBWEAK fIrqI2CHandler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) fIrqI2CHandler B fIrqI2CHandler ; PUBWEAK fIrqGpioHandler -; SECTION .text:CODE:REORDER(1) +; SECTION .text:CODE:REORDER:NOROOT(1) ;fIrqGpioHandler ; B fIrqGpioHandler PUBWEAK fIrqRtcHandler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) fIrqRtcHandler B fIrqRtcHandler PUBWEAK fIrqFlashHandler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) fIrqFlashHandler B fIrqFlashHandler PUBWEAK fIrqMacHwHandler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) fIrqMacHwHandler B fIrqMacHwHandler PUBWEAK fIrqAesHandler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) fIrqAesHandler B fIrqAesHandler PUBWEAK fIrqAdcHandler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) fIrqAdcHandler B fIrqAdcHandler PUBWEAK fIrqClockCalHandler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) fIrqClockCalHandler B fIrqClockCalHandler ; PUBWEAK fIrqUart2Handler -; SECTION .text:CODE:REORDER(1) +; SECTION .text:CODE:REORDER:NOROOT(1) ;fIrqUart2Handler ; B fIrqUart2Handler PUBWEAK fIrqDbgPwrUpHandler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) fIrqDbgPwrUpHandler B fIrqDbgPwrUpHandler PUBWEAK fIrqDmaHandler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) fIrqDmaHandler B fIrqDmaHandler PUBWEAK fIrqUviHandler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) fIrqUviHandler B fIrqUviHandler PUBWEAK fIrqSpi2Handler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) fIrqSpi2Handler B fIrqSpi2Handler PUBWEAK fIrqI2c2Handler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) fIrqI2c2Handler B fIrqI2c2Handler PUBWEAK FIrqFVDDHCompHandler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) FIrqFVDDHCompHandler B FIrqFVDDHCompHandler PUBWEAK DEF_IRQHandler - SECTION .text:CODE:REORDER(1) + SECTION .text:CODE:REORDER:NOROOT(1) DEF_IRQHandler B DEF_IRQHandler diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/device/system_NCS36510.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/device/system_NCS36510.c index d3fa866265d..f12bfb62108 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/device/system_NCS36510.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/device/system_NCS36510.c @@ -23,7 +23,7 @@ ******************************************************************************/ #include -//#include "ncs36510Init.h" /* TODO */ +#include "ncs36510Init.h" /*---------------------------------------------------------------------------- Define clocks *----------------------------------------------------------------------------*/ diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/dma_map.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/dma_map.h index 6728c46f107..db396a7df39 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/dma_map.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/dma_map.h @@ -47,19 +47,6 @@ **************************************************************************************************/ /** DMA control HW registers structure overlay */ -#ifdef REVB -typedef struct { - __IO uint32_t CONTROL; /**< Write 1 to enable DMA, write 0 to disable */ - __IO uint32_t SOURCE; /**< Address of source, read to get the number of bytes written */ - __IO uint32_t DESTINATION; /**< Address of destination, read to get the number of bytes written */ - __IO uint32_t SIZE; /**< Lenght of the entire transfer */ - __IO uint32_t STATUS; /**< To be debined */ - __IO uint32_t INT_ENABLE; /**< Enable interrupt source by writing 1. Bit 0: DMA done, Bit 1: Source Error, Bit 2: Destination Error */ - __IO uint32_t INT_CLEAR_ENABLE; /**< Clear Interrupt source by writing 1. Bit 0: DMA done, Bit 1: Source Error, Bit 2: Destination Error */ - __I uint32_t INT_STATUS; /**< Current interrupt status. Bit 0: DMA done, Bit 1: Source Error, Bit 2: Destination Error */ -} DmaReg_t, *DmaReg_pt; -#endif /* REVB */ -#ifdef REVD typedef struct { union { struct { @@ -104,5 +91,4 @@ typedef struct { __I uint32_t WORD; } INT_STATUS; /**< Interrupt status */ } DmaReg_t, *DmaReg_pt; -#endif /* REVD */ #endif /* DMA_MAP_H_ */ diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/macHw_map.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/macHw_map.h index c0c6c9f8ba3..f92241a4670 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/macHw_map.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/macHw_map.h @@ -131,9 +131,7 @@ typedef struct { __O uint32_t FS:1; __O uint32_t FP:1; __O uint32_t FMD:1; -#ifdef REVD __I uint32_t PC:1; -#endif /* REVD */ } BITS; __O uint32_t WORD; } CLEAR_IRQ; /**< 0x40014030 */ @@ -145,9 +143,7 @@ typedef struct { __IO uint32_t FS:1; __IO uint32_t FP:1; __IO uint32_t FM:1; -#ifdef REVD __I uint32_t PC:1; -#endif /* REVD */ } BITS; __IO uint32_t WORD; } MASK_IRQ; /**< 0x40014034 */ @@ -159,9 +155,7 @@ typedef struct { __I uint32_t FS:1; __I uint32_t FP:1; __I uint32_t FM:1; -#ifdef REVD __I uint32_t PC:1; -#endif /* REVD */ } BITS; __I uint32_t WORD; } IRQ_STATUS; /**< 0x40014038 */ @@ -202,9 +196,6 @@ typedef struct { __IO uint32_t WORD; } SLOT_OFFSET; /**< 0x40014064 */ __I uint32_t TIME_STAMP; /**< 0x40014068 */ -#ifdef REVB - __O uint32_t PAD5; /**< 0x4001406C */ -#endif /* REVB */ union { struct { __IO uint32_t CRD_SHORT_ADDRESS:16; @@ -214,17 +205,10 @@ typedef struct { __IO uint32_t PAN_COORD_ADDR_S:1; } BITS; __IO uint32_t WORD; -#ifdef REVB - } CRD_SHORT_ADDR; /**< 0x40014070 */ - __IO uint32_t CRD_LONG_ADDR_HI; /**< 0x40014074 */ - __IO uint32_t CRD_LONG_ADDR_LO; /**< 0x40014078 */ -#endif /* REVB */ -#ifdef REVD } CRD_SHORT_ADDR; /**< 0x4001406C */ __IO uint32_t CRD_LONG_ADDR_HI; /**< 0x40014070 */ __IO uint32_t CRD_LONG_ADDR_LO; /**< 0x40014074 */ __O uint32_t PAD5; /**< 0x40014078 */ -#endif /* REVD */ __O uint32_t PAD9; /**< 0x4001407C */ __O uint32_t PAD10; /**< 0x40014080 */ __O uint32_t PAD11; /**< 0x40014084 */ diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng.h new file mode 100644 index 00000000000..75439d8a524 --- /dev/null +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng.h @@ -0,0 +1,42 @@ +/** + ****************************************************************************** + * @file ncs36510_trng.h + * @brief Header file for ncs36510_trng_api.c. + * @internal + * @author ON Semiconductor. + * $Rev: $ + * $Date: $ + ****************************************************************************** + * Copyright 2016 Semiconductor Components Industries LLC (d/b/a “ON Semiconductor”). + * All rights reserved. This software and/or documentation is licensed by ON Semiconductor + * under limited terms and conditions. The terms and conditions pertaining to the software + * and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf + * (“ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software”) and + * if applicable the software license agreement. Do not use this software and/or + * documentation unless you have carefully read and you agree to the limited terms and + * conditions. By using this software and/or documentation, you agree to the limited + * terms and conditions. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, + * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * @endinternal + * + * @ingroup TRNG header + * + */ + +#ifndef RANDOM_H_ +#define RANDOM_H_ + +#define TRNG_SLOW_MODE 0 +#define TRNG_FAST_MODE 1 + +#define TRNG_DISABLE 0 +#define TRNG_ENABLE 1 + +#define TRNG_ON_READ_EVENT 1 + +#endif /* RANDOM_H_ */ diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng_api.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng_api.c new file mode 100644 index 00000000000..b3defd45dd5 --- /dev/null +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng_api.c @@ -0,0 +1,113 @@ +/** + ****************************************************************************** + * @file trng_api.c + * @brief Implementation of TRNG functionality. + * @internal + * @author ON Semiconductor. + * $Rev: $ + * $Date: $ + ****************************************************************************** + * Copyright 2016 Semiconductor Components Industries LLC (d/b/a “ON Semiconductor”). + * All rights reserved. This software and/or documentation is licensed by ON Semiconductor + * under limited terms and conditions. The terms and conditions pertaining to the software + * and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf + * (“ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software”) and + * if applicable the software license agreement. Do not use this software and/or + * documentation unless you have carefully read and you agree to the limited terms and + * conditions. By using this software and/or documentation, you agree to the limited + * terms and conditions. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, + * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * @endinternal + * + * @ingroup TRNG + * + */ +#if DEVICE_TRNG + +/************************************************************************************************* +* * +* Header files * +* * +*************************************************************************************************/ +#include "trng_api.h" +#include "memory_map.h" +#include "ncs36510_trng.h" +#include "clock.h" + +/************************************************************************************************* +* * +* Functions * +* * +*************************************************************************************************/ + + +void trng_init(trng_t *obj) +{ + /* Enable TRNG */ + CLOCK_ENABLE(CLOCK_RAND); + + /* Initialize TRNG */ + RANDREG->CONTROL.WORD = False; + + return; +} +void trng_free(trng_t *obj) +{ + /* Stop TRNG */ + RANDREG->CONTROL.WORD = False; + + /* Disable TRNG */ + CLOCK_DISABLE(CLOCK_RAND); + + return; +} + +int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length) +{ + uint32_t MSLRandom = 0, Index, TempLen, *TempPtr = (uint32_t*)output; + volatile uint32_t delay; + + RANDREG->CONTROL.BITS.METASTABLE_LATCH_EN = TRNG_ENABLE; /* ENable MSL TRNG */ + RANDREG->CONTROL.BITS.MEATSTABLE_SPEED = TRNG_FAST_MODE; /* Meta-stable Latch TRNG Speed Control */ + RANDREG->CONTROL.BITS.MODE = TRNG_ON_READ_EVENT; /* TRNG is only updated on a read event of the TRNG register */ + + for(uint32_t delay = 0;delay < 0x1F; delay++); /* Wait till generate MSL TRNG after enable for the first time */ + + TempLen = length / 4; + + for(Index = 0; Index < TempLen; Index++) + { + MSLRandom = RANDREG->METASTABLE_LATCH_VAL; + *TempPtr++ = MSLRandom ; + } + + TempLen = length % 4; + Index *= 4; + + if(TempLen-- > 0) + { + MSLRandom = RANDREG->METASTABLE_LATCH_VAL; + *(output + Index++) = (MSLRandom >> 0) & 0xFF; + if(TempLen-- > 0) + { + *(output + Index++) = (MSLRandom >> 8) & 0xFF; + if(TempLen-- > 0) + { + *(output + Index++) = (MSLRandom >> 16) & 0xFF; + } + } + } + + RANDREG->CONTROL.BITS.METASTABLE_LATCH_EN = TRNG_DISABLE; /* Disable MSL */ + + *output_length = Index; + + return 0; /* Success */ +} + +#endif /* DEVICE_TRNG */ \ No newline at end of file diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/objects.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/objects.h index b58c02c3d36..83a603caaca 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/objects.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/objects.h @@ -169,7 +169,7 @@ struct spi_s { uint8_t rxWatermark; /* Receive FIFO Watermark: Defines level of TX Half Full Flag: * - Value between 1 and 15 * * (unused option in current implementation / rxWatermark fixed to 1) */ - spi_ipc7207_endian_t endian; /* Bits endianness: + spi_ipc7207_endian_t endian; /* Bits endianness: * - LITTLE_ENDIAN = LSB first * - BIG_ENDIAN = MSB first */ uint8_t samplingEdge; /* SDI sampling edge (relative to SDO sampling edge): @@ -193,6 +193,10 @@ struct i2c_s { //queue_pt rxQueue; /**< The receive queue for the device instance. */ }; +struct trng_s { + RandReg_pt membase; /**< The memory base for the device's registers. */ +}; + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/pad.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/pad.h index 26d3e5c7ec2..9aa7c39045e 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/pad.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/pad.h @@ -1,4 +1,3 @@ -#ifdef REVD /** ****************************************************************************** * @file pad.h @@ -84,5 +83,4 @@ extern void fPadInit(); */ extern boolean fPadIOCtrl(uint8_t, uint8_t, uint8_t, uint8_t); -#endif //_PAD_H_ -#endif /* REVD */ \ No newline at end of file +#endif //_PAD_H_ \ No newline at end of file diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/pad_map.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/pad_map.h index be718d48c01..63a99a45d55 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/pad_map.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/pad_map.h @@ -71,14 +71,12 @@ #define PAD_LOW_POWER (PAD_PULL_NONE | (PAD_DRIVE_L0<<2) | (PAD_OOUTCFG_OPENDRAIN<<5)) /** custom Power PAD configuration */ -#ifdef REVD #define PAD_OUTPUT_PN_L1_OD (PAD_PULL_NONE | (PAD_DRIVE_L1<<2) | (PAD_OOUTCFG_OPENDRAIN<<5)) #define PAD_INPUT_PD_L1_PP (PAD_PULL_DOWN | (PAD_DRIVE_L1<<2) | (PAD_OUTCFG_PUSHPULL<<5)) -#define PAD_UNUSED_PD_L0_PP (PAD_PULL_DOWN | (PAD_DRIVE_L0<<2) | (PAD_OUTCFG_PUSHPULL<<5)) +#define PAD_UNUSED_PD_L1_PP (PAD_PULL_DOWN | (PAD_DRIVE_L1<<2) | (PAD_OUTCFG_PUSHPULL<<5)) #define PAD_UART_TX (PAD_PULL_UP | (PAD_DRIVE_L1<<2) | (PAD_OUTCFG_PUSHPULL<<5)) #define PAD_UART_RX (PAD_PULL_UP | (PAD_DRIVE_L1<<2) | (PAD_OOUTCFG_OPENDRAIN<<5)) -#endif /* REVD */ /************************************************************************************************** * * diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/port_api.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/port_api.c index e0fb1c08584..4975a3697cd 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/port_api.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/port_api.c @@ -24,7 +24,9 @@ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. */ #include "gpio.h" +#include "gpio_api.h" #include "port_api.h" +#include "pinmap.h" #if DEVICE_PORTIN || DEVICE_PORTOUT diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/pwm_map.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/pwm_map.h index e567848c02b..a720d0c5639 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/pwm_map.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/pwm_map.h @@ -44,37 +44,6 @@ #include "architecture.h" /** Power management Control HW Structure Overlay */ -#ifdef REVB -typedef struct { - __IO uint32_t DUTYCYCLE; - union { - struct { - __IO uint32_t ENABLED :1;/**< 1 = PWM enable , 0 = PWM disable */ - __I uint32_t CURRENT :1;/**< current state of PWM enable signal */ - __O uint32_t PAD1 :6; /**< Reserved. Writes have no effect; Read as 0x00. */ - __O uint32_t RDPWMEN :1;/**< current state of pwmEnable configuration */ - __O uint32_t RDPWMOP :1;/**< current state of PWM out signal */ - __O uint32_t PAD2 :6; /**< Reserved. Writes have no effect; Read as 0x00. */ - } BITS; - __I uint32_t WORD; - } PWMOUT; - __O uint32_t DISABLE; - union { - struct { - __IO uint32_t ENABLED :1; - __O uint32_t PAD1 :7; /**< Reserved. Writes have no effect */ - __O uint32_t STATE :1; /**< current state of prescaler enable configuration. */ - __O uint32_t PAD2 :7; /**< Reserved. Writes have no effect; Read as 0x00. */ - } BITS; - __I uint32_t WORD; - } PRESCALE_EN; - - __O uint32_t PRESCALE_DIS; - -} PwmReg_t, *PwmReg_pt; -#endif /* REVB */ - -#ifdef REVD typedef struct { __IO uint32_t DUTYCYCLE; union { @@ -96,5 +65,4 @@ typedef struct { } PRESCALE_ENABLE; __O uint32_t PRESCALE_DISABLE; } PwmReg_t, *PwmReg_pt; -#endif /* REVD */ #endif /* PWM_MAP_H_ */ diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/random_map.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/random_map.h index bc33441fb5a..7e25f21f895 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/random_map.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/random_map.h @@ -49,9 +49,6 @@ /** Random Number Generator Control HW Structure Overlay */ typedef struct { __IO uint32_t WR_SEED_RD_RAND; /* Seed set & random read reg - 0x40011000 */ -#ifdef REVB - __IO uint32_t MODE; -#endif /* REVB */ union { struct { __IO uint32_t MODE :1; /**PLL_TIMING.BITS.PLL_RESET_TIME = 0x1E; // 30us RFANAREG->PLL_TIMING.BITS.PLL_LOCK_TIME = 0x2F; // 47us @@ -239,29 +140,6 @@ boolean fRfAnaIoctl (uint32_t request, void *argument) RFANAREG->RX_LO_CONTROL.BITS.INT_WORD = rfLut[channel - 11][0]; // Set tx/rx vco trims -#ifdef REVB - /** REVB is requiering to adjust tx/rx vco trims each time a new 15.4 channel is used, in revB it is done - * from trims stored in flash A, it has the drawback that it is not workable when flash A is not accessible.*/ - if (channel < 19) { - RFANATRIMREG->PLL_TRIM.BITS.TX_VCO_TRIM = (TRIMREG->TX_VCO_LUT1.WORD) >> ((channel - 11) * 4); - RFANATRIMREG->PLL_TRIM.BITS.RX_VCO_TRIM = (TRIMREG->RX_VCO_LUT1.WORD) >> ((channel - 11) * 4); - } else { - RFANATRIMREG->PLL_TRIM.BITS.TX_VCO_TRIM = (TRIMREG->TX_VCO_LUT2.WORD) >> ((channel - 19) * 4); - RFANATRIMREG->PLL_TRIM.BITS.RX_VCO_TRIM = (TRIMREG->RX_VCO_LUT2.WORD) >> ((channel - 19) * 4); - } -#endif /* REVB */ -#ifdef REVC - /** REVC is requiering to adjust tx/rx vco trims each time a new 15.4 channel is used, in revB it is done - * from trims stored in dedicated registers available in digital.*/ - if (channel < 19) { - RFANATRIMREG->PLL_TRIM.BITS.TX_VCO_TRIM = (RFANATRIMREG->TX_VCO_TRIM_LUT1) >> ((channel - 11) * 4); - RFANATRIMREG->PLL_TRIM.BITS.RX_VCO_TRIM = (RFANATRIMREG->RX_VCO_TRIM_LUT1) >> ((channel - 11) * 4); - } else { - RFANATRIMREG->PLL_TRIM.BITS.TX_VCO_TRIM = (RFANATRIMREG->TX_VCO_TRIM_LUT2) >> ((channel - 19) * 4); - RFANATRIMREG->PLL_TRIM.BITS.RX_VCO_TRIM = (RFANATRIMREG->RX_VCO_TRIM_LUT2) >> ((channel - 19) * 4); - } -#endif /* REVC */ -#ifdef REVD /** REVD is requiering to adjust tx/rx vco trims each time a new 15.4 channel is used, in revB it is done * from trims stored in dedicated registers available in digital.*/ if (channel < 19) { @@ -271,7 +149,6 @@ boolean fRfAnaIoctl (uint32_t request, void *argument) RFANATRIMREG->PLL_TRIM.BITS.TX_VCO_TRIM = (RFANATRIMREG->TX_VCO_TRIM_LUT2) >> ((channel - 19) * 4); RFANATRIMREG->PLL_TRIM.BITS.RX_VCO_TRIM = (RFANATRIMREG->RX_VCO_TRIM_LUT2) >> ((channel - 19) * 4); } -#endif /* REVD */ break; case SET_TX_POWER: txPower = *(uint8_t*)argument; diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/rfAna_map.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/rfAna_map.h index 22ee1e48a67..328f6dbab85 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/rfAna_map.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/rfAna_map.h @@ -105,21 +105,11 @@ typedef struct { } PLL_TRIM; __IO uint32_t PLL_VCO_TAP_LOCATION; __IO uint32_t TX_CHAIN_TRIM; -#ifdef REVC __IO uint32_t RX_VCO_TRIM_LUT2; /** 0x40019098 */ __IO uint32_t RX_VCO_TRIM_LUT1; /** 0x4001909C */ __IO uint32_t TX_VCO_TRIM_LUT2; /** 0x400190A0 */ __IO uint32_t TX_VCO_TRIM_LUT1; /** 0x400190A4 */ __IO uint32_t ADC_OFFSET_BUF; /** 0x400190A8 */ -#endif - -#ifdef REVD - __IO uint32_t RX_VCO_TRIM_LUT2; /** 0x40019098 */ - __IO uint32_t RX_VCO_TRIM_LUT1; /** 0x4001909C */ - __IO uint32_t TX_VCO_TRIM_LUT2; /** 0x400190A0 */ - __IO uint32_t TX_VCO_TRIM_LUT1; /** 0x400190A4 */ - __IO uint32_t ADC_OFFSET_BUF; /** 0x400190A8 */ -#endif /* REVD */ } RfAnaTrimReg_t, *RfAnaTrimReg_pt; #endif /* RFANA_MAP_H_ */ diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc.c index a3e35b0b681..1bedbcc534c 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc.c @@ -43,6 +43,7 @@ */ #include "rtc.h" #include "mbed_assert.h" +#include "lp_ticker_api.h" static uint16_t SubSecond; static uint64_t LastRtcTimeus; @@ -100,7 +101,7 @@ void fRtcFree(void) void fRtcSetInterrupt(uint32_t timestamp) { SubSecond = False; - uint32_t Second = False; + uint32_t Second = False, EnableInterrupt = False; uint8_t DividerAdjust = 1; if(timestamp) { @@ -110,7 +111,7 @@ void fRtcSetInterrupt(uint32_t timestamp) RTCREG->SECOND_ALARM = Second; /* Write to alarm register */ /* Enable second interrupt */ - RTCREG->CONTROL.WORD |= (True << RTC_CONTROL_SEC_CNT_INT_BIT_POS); + EnableInterrupt = True << RTC_CONTROL_SEC_CNT_INT_BIT_POS; } timestamp = timestamp - Second * RTC_SEC_TO_US; /* Take out micro second for sub second alarm */ if(timestamp > False) { @@ -129,7 +130,6 @@ void fRtcSetInterrupt(uint32_t timestamp) SubSecond = 0; } - if(SubSecond > False) { /* Second interrupt not enabled */ @@ -137,12 +137,18 @@ void fRtcSetInterrupt(uint32_t timestamp) RTCREG->SUB_SECOND_ALARM = SubSecond; /* Write to sub second alarm */ /* Enable sub second interrupt */ - while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); - RTCREG->CONTROL.WORD |= (True << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS); + EnableInterrupt |= (True << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS); } } - - while(RTCREG->STATUS.BITS.BSY_ANY_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ + + RTCREG->CONTROL.WORD |= EnableInterrupt; + /* Enable RTC interrupt */ + NVIC_EnableIRQ(Rtc_IRQn); + + /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ + while((RTCREG->STATUS.WORD & ((True << RTC_STATUS_SUB_SEC_ALARM_WRT_BIT_POS) | + (True << RTC_STATUS_SEC_ALARM_WRT_BIT_POS) | + (True << RTC_STATUS_CONTROL_WRT_BIT_POS))) == True); } return; } @@ -150,17 +156,15 @@ void fRtcSetInterrupt(uint32_t timestamp) /* See rtc.h for details */ void fRtcDisableInterrupt(void) { - /* Disable subsec/sec interrupt */ - RTCREG->CONTROL.WORD &= ~((RTC_ALL_INTERRUPT_BIT_VAL) << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS); - while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ + /* Disable RTC interrupt */ + NVIC_DisableIRQ(Rtc_IRQn); } /* See rtc.h for details */ void fRtcEnableInterrupt(void) { - /* Disable subsec/sec interrupt */ - RTCREG->CONTROL.WORD |= ((RTC_ALL_INTERRUPT_BIT_VAL) << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS); - while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ + /* Enable RTC interrupt */ + NVIC_EnableIRQ(Rtc_IRQn); } /* See rtc.h for details */ @@ -170,7 +174,9 @@ void fRtcClearInterrupt(void) /* Clear sec & sub_sec interrupts */ RTCREG->INT_CLEAR.WORD = ((True << RTC_INT_CLR_SUB_SEC_BIT_POS) | (True << RTC_INT_CLR_SEC_BIT_POS)); - while(RTCREG->STATUS.BITS.BSY_ANY_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ + + while((RTCREG->STATUS.WORD & ((True << RTC_STATUS_SUB_SEC_INT_CLR_WRT_BIT_POS) | + (True << RTC_STATUS_SEC_INT_CLR_WRT_BIT_POS))) == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ } /* See rtc.h for details */ @@ -191,9 +197,9 @@ uint64_t fRtcRead(void) */ do { - Second = RTCREG->SECOND_COUNTER; /* Get SEC_COUNTER reg value */ - SubSecond = (RTCREG->SUB_SECOND_COUNTER - 1) & 0x7FFF; /* Get SUB_SEC_COUNTER reg value */ - } while (Second != RTCREG->SECOND_COUNTER); /* Repeat if the second has changed */ + Second = RTCREG->SECOND_COUNTER; /* Get SEC_COUNTER reg value */ + SubSecond = (RTCREG->SUB_SECOND_COUNTER - 1) & SUB_SEC_MASK; /* Get SUB_SEC_COUNTER reg value */ + } while (Second != RTCREG->SECOND_COUNTER); /* Repeat if the second has changed */ //note: casting to float removed to avoid reduction in resolution uint64_t RtcTimeus = ((uint64_t)SubSecond * RTC_SEC_TO_US / RTC_CLOCK_HZ) + ((uint64_t)Second * RTC_SEC_TO_US); @@ -208,8 +214,8 @@ uint64_t fRtcRead(void) /* See rtc.h for details */ void fRtcWrite(uint64_t RtcTimeus) { - uint32_t Second = 0; - uint16_t SubSecond = 0; + uint32_t Second = False; + uint16_t SubSecond = False; /* Stop RTC */ RTCREG->CONTROL.WORD &= ~((True << RTC_CONTROL_SUBSEC_CNT_START_BIT_POS) | (True << RTC_CONTROL_SEC_CNT_START_BIT_POS)); @@ -270,7 +276,11 @@ void fRtcHandler(void) NVIC_EnableIRQ(Rtc_IRQn); - while(RTCREG->STATUS.BITS.BSY_ANY_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ + /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ + while((RTCREG->STATUS.WORD & ((True << RTC_STATUS_SUB_SEC_ALARM_WRT_BIT_POS) | + (True << RTC_STATUS_CONTROL_WRT_BIT_POS) | + (True << RTC_STATUS_SUB_SEC_INT_CLR_WRT_BIT_POS) | + (True << RTC_STATUS_SEC_INT_CLR_WRT_BIT_POS))) == True); lp_ticker_irq_handler(); } diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc.h index 4843975d186..d9a4dc4b2ef 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc.h @@ -52,9 +52,15 @@ #define RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS 2 #define RTC_CONTROL_SEC_CNT_INT_BIT_POS 3 +#define RTC_STATUS_SUB_SEC_ALARM_WRT_BIT_POS 6 +#define RTC_STATUS_SEC_ALARM_WRT_BIT_POS 7 +#define RTC_STATUS_CONTROL_WRT_BIT_POS 8 #define RTC_STATUS_SUB_SEC_INT_CLR_WRT_BIT_POS 9 #define RTC_STATUS_SEC_INT_CLR_WRT_BIT_POS 10 +#define SUB_SEC_MASK 0x7FFF + + /* FUnction pointer for call back */ typedef void (* fRtcCallBack)(void); diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc_api.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc_api.c index 15cb73c8562..4b63069a2bb 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc_api.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc_api.c @@ -39,8 +39,6 @@ #include "rtc.h" #include "cmsis_nvic.h" -static IRQn_Type Irq; - /* See rtc_apc.h for description */ void rtc_init(void) diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc_map.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc_map.h index 86f6325821b..18ab0a4d772 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc_map.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/rtc_map.h @@ -45,72 +45,6 @@ /** Real Time Clock Control HW Structure Overlay */ typedef struct { -#ifdef REVB - /*REVD REPLACE COMPLETE MAP WITH DATA FROM DIG DESIGN SPEC */ - __IO uint32_t SECOND;/**SCR &= ~SCB_SCR_SLEEPDEEP_Msk; @@ -55,7 +55,7 @@ void sleep(void) __WFI(); } -void deepsleep(void) +void fncs36510_deepsleep(void) { /** Set SLEEPDEEP (SCR) and unset COMA to select deep sleep mode */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; @@ -72,7 +72,7 @@ void deepsleep(void) PMUREG->CONTROL.BITS.INT32M = 1; } -void coma(void) +void fncs36510_coma(void) { /** Set SLEEPDEEP (SCR) and set COMA to select coma mode */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/sleep.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/sleep.h index f3f9ff1fc50..44c20199275 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/sleep.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/sleep.h @@ -42,10 +42,10 @@ #include "crossbar.h" #include "clock.h" -#define SLEEP_TYPE_NONE 0 +#define SLEEP_TYPE_NONE 0 #define SLEEP_TYPE_SLEEP 1 #define SLEEP_TYPE_DEEPSLEEP 2 -#define SLEEP_TYPE_COMA 3 +#define SLEEP_TYPE_COMA 3 #define SLEEP_TYPE_DEFAULT SLEEP_TYPE_DEEPSLEEP @@ -54,6 +54,10 @@ #define SLEEP_DURATION_DEEPSLEEP_MAX 500 /* msec */ #define SLEEP_DURATION_COMA_MAX 1000000000 /* TODO 1000 sec */ -void coma(void); +void fncs36510_sleep(void); + +void fncs36510_deepsleep(void); + +void fncs36510_coma(void); #endif // SLEEP_H_ diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/sleep_api.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/sleep_api.c index a59dde1026d..dd6680cc56d 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/sleep_api.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/sleep_api.c @@ -37,54 +37,14 @@ #include "sleep_api.h" #include "cmsis_nvic.h" -void mbed_enter_sleep(sleep_t *obj) +void sleep() { - -#ifdef SLEEP_TYPE_DEFAULT - - if(SLEEP_TYPE_DEFAULT == SLEEP_TYPE_SLEEP) { - /* Sleep mode */ - sleep(); - } else if(SLEEP_TYPE_DEFAULT == SLEEP_TYPE_DEEPSLEEP) { - /* Deep Sleep mode */ - deepsleep(); - } else { - /* Coma mode */ - coma(); - } - -#else - - if(obj->SleepType == SLEEP_TYPE_NONE) { - /* Select low power mode based on sleep duration */ - - if(obj->timeToSleep <= SLEEP_DURATION_SLEEP_MAX) { - /* Sleep mode */ - sleep(); - } else if(obj->timeToSleep <= SLEEP_DURATION_DEEPSLEEP_MAX) { - /* Deep sleep */ - deepsleep(); - } else { - /* Coma */ - coma(); - } - } else if(obj->SleepType == SLEEP_TYPE_SLEEP) { - /* Sleep mode */ - sleep(); - } else if(obj->SleepType == SLEEP_TYPE_DEEPSLEEP) { - /* Deep Sleep mode */ - deepsleep(); - } else { - /* Coma mode */ - coma(); - } - -#endif + fncs36510_sleep(); } -void mbed_exit_sleep(sleep_t *obj) +void deepsleep() { - (void)obj; + fncs36510_deepsleep(); } #endif /* DEVICE_SLEEP */ \ No newline at end of file diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/spi_api.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/spi_api.c index af039865947..2d96ec0be90 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/spi_api.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/spi_api.c @@ -99,28 +99,28 @@ uint8_t spi_get_module(spi_t *obj) int spi_slave_receive(spi_t *obj) { - if(obj->membase->STATUS.BITS.RX_EMPTY != True){ /* if receive status is not empty */ - return True; /* Byte available to read */ - } - return False; /* Byte not available to read */ + if(obj->membase->STATUS.BITS.RX_EMPTY != True){ /* if receive status is not empty */ + return True; /* Byte available to read */ + } + return False; /* Byte not available to read */ } int spi_slave_read(spi_t *obj) { - int byte; - - while (obj->membase->STATUS.BITS.RX_EMPTY == True); /* Wait till Receive status is empty */ + int byte; + + while (obj->membase->STATUS.BITS.RX_EMPTY == True); /* Wait till Receive status is empty */ byte = obj->membase->RX_DATA; return byte; } void spi_slave_write(spi_t *obj, int value) { - while((obj->membase->STATUS.BITS.TX_FULL == True) && (obj->membase->STATUS.BITS.RX_FULL == True)); /* Wait till Tx/Rx status is full */ + while((obj->membase->STATUS.BITS.TX_FULL == True) && (obj->membase->STATUS.BITS.RX_FULL == True)); /* Wait till Tx/Rx status is full */ obj->membase->TX_DATA = value; } -#if DEVICE_SPI_ASYNCH /* TODO Not implemented yet */ +#if DEVICE_SPI_ASYNCH /* TODO Not yet implemented */ void spi_master_transfer(spi_t *obj, void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t handler, uint32_t event, DMAUsage hint) { diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/trim_map.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/trim_map.h index 79ec6945348..cd215b97f32 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/trim_map.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/trim_map.h @@ -50,6 +50,7 @@ **************************************************************************************************/ /** trim register map */ +<<<<<<< HEAD typedef struct { /**< REV B REV D */ __I uint32_t PAD0; /**< 0x1FA0 0x1FA0 */ __I uint32_t MAC_ADDR_LOW; /**< 0x1FA4 */ @@ -59,9 +60,7 @@ typedef struct { /**< REV B REV D */ #endif __I uint32_t TRIM_32K_EXT; /**< 0x1FB0 0x1FAC */ __I uint32_t TRIM_32M_EXT; /**< 0x1FB4 0x1FB0 */ -#ifdef REVD __I uint32_t FVVDH_COMP_TH; /**< 0x1FB4 */ -#endif union { struct { /* Common to REV B & REV D */ __I uint32_t CHANNEL11:4; @@ -130,4 +129,4 @@ typedef struct { /**< REV B REV D */ __I uint32_t REVISION_CODE; /**< 0x1FFC */ } TrimReg_t, *TrimReg_pt; -#endif /* TRIM_MAP_H_ */ +#endif /* TRIM_MAP_H_ */ \ No newline at end of file diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/wdt_map.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/wdt_map.h index fd63cc82204..a4ac0bcd555 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/wdt_map.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/wdt_map.h @@ -42,100 +42,6 @@ #include "architecture.h" -#ifdef REVB -/** Watch Dog Timer Control HW Structure Overlay */ -typedef struct { - __IO uint32_t LOAD; /**< Watchdog load value */ - __I uint32_t VALUE; /**< Watchdog current value */ - union { - struct { - __IO uint32_t INT_EN :1; /**< interrupt event : 0 = disable counter and interrupt , 1 = enable counter and interrupt */ - __IO uint32_t RESET_EN :1; /**< Watchdog reset output : 0 = disable 1 = enable */ - __IO uint32_t PAD :30; /**< Reserved, read undefined, must read as zeros. */ - } BITS; - __IO uint32_t WORD; - } CONTROL; - __IO uint32_t INT_CLEAR; /**< Watchdog interrupt clear */ - __I uint32_t RAW_INT_STAT; /**< Raw interrupt status from the counter */ - __I uint32_t MASKED_INT_STAT; /**< Enabled interrupt status from the counter */ - union { - struct { - __IO uint32_t WRITE_EN :1; /**< write access to all other registers : 0 = enabled(default) , 1 = disabled */ - __IO uint32_t REG_WRITE_EN :31; /**< Enable write access to all other registers by writing 0x1ACCE551. Disable it by writing any other value.*/ - } BITS; - __IO uint32_t WORD; - } LOCK; - __I uint32_t TEST_CTRL; /**< Integration Test Mode : 0 = disable , 1 = Enable */ - union { - struct { - __IO uint32_t VAL_INT :1; /**< Value output on WDOGINT when in Integration Test Mode */ - __IO uint32_t VAL_RES :1; /**< Value output on WDOGRES when in Integration Test Mode */ - __IO uint32_t PAD:30; /**< Reserved, read undefined, must read as zeros.*/ - } BITS; - __IO uint32_t WORD; - } TEST_OUT; - union { - struct { - __IO uint32_t PART_0 :8; /**< These bits read back as 0x05 */ - __IO uint32_t PAD :24; /**< Reserved, read undefined, must read as zeros.*/ - } BITS; - __IO uint32_t WORD; - } PID_REG0; - union { - struct { - __IO uint32_t PART_1 :4; /**< These bits read back as 0x08 */ - __IO uint32_t DESIGNER_0 :4; /**< These bits read back as 0x01 */ - __IO uint32_t PAD :24; /**< Reserved, read undefined, must read as zeros.*/ - } BITS; - __IO uint32_t WORD; - } PID_REG1; - union { - struct { - __IO uint32_t DESIGNER_1 :4; /**< These bits read back as 0x4 */ - __IO uint32_t REVISION :4; /**< These bits read back as 0x0*/ - __IO uint32_t PAD :24; /**< Reserved, read undefined, must read as zeros.*/ - } BITS; - __IO uint32_t WORD; - } PID_REG2; - union { - struct { - __IO uint32_t CONFIG :8; /**< These bits read back as 0x00 */ - __IO uint32_t PAD :24; /**< Reserved, read undefined, must read as zeros.*/ - } BITS; - __IO uint32_t WORD; - } PID_REG3; - union { - struct { - __IO uint32_t ID0 :8; /**< These bits read back as 0x0D */ - __IO uint32_t PAD :24; /**< Reserved, read undefined, must read as zeros.*/ - } BITS; - __IO uint32_t WORD; - } PCELL_ID0; - union { - struct { - __IO uint32_t ID :8; /**< These bits read back as 0xF0*/ - __IO uint32_t PAD :24; /**< Reserved, read undefined, must read as zeros.*/ - } BITS; - __IO uint32_t WORD; - } PCELL_ID1; - union { - struct { - __IO uint32_t ID :8; /**< These bits read back as 0x05*/ - __IO uint32_t PAD :24; /**< Reserved, read undefined, must read as zeros.*/ - } BITS; - __IO uint32_t WORD; - } PCELL_ID2; - union { - struct { - __IO uint32_t ID :8; /**< These bits read back as 0xB1*/ - __IO uint32_t PAD :24; /**< Reserved, read undefined, must read as zeros.*/ - } BITS; - __IO uint32_t WORD; - } PCELL_ID3; -} WdtReg_t, *WdtReg_pt; -#endif /* REVB */ - -#ifdef REVD typedef struct { __IO uint32_t LOAD; /**< 0x4000A000 Contains the value from which the counter is decremented. When this register is written to the count is immediately restarted from the new value. The minimum valid value is 1. */ __I uint32_t CURRENT_VALUE; /**< 0x4000A004 Gives the current value of the decrementing counter */ @@ -157,5 +63,4 @@ typedef struct { __IO uint32_t WORD; } STATUS; /* 0x4000A014 */ } WdtReg_t, *WdtReg_pt; -#endif /* REVD */ #endif /* WDT_MAP_H_ */ diff --git a/targets/targets.json b/targets/targets.json index 630536a78e0..b9d3395ece7 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -2328,7 +2328,7 @@ "core": "Cortex-M3", "extra_labels": ["ONSEMI"], "post_binary_hook": {"function": "NCS36510TargetCode.ncs36510_addfib"}, - "macros": ["REVD", "CM3", "CPU_NCS36510", "TARGET_NCS36510", "LOAD_ADDRESS=0x3000"], + "macros": ["CM3", "CPU_NCS36510", "TARGET_NCS36510", "LOAD_ADDRESS=0x3000"], "supported_toolchains": ["GCC_ARM", "ARM", "IAR"], "device_has": ["ANALOGIN", "SERIAL", "I2C", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "LOWPOWERTIMER", "TRNG"], "device_name": "NCS36510", From c968f58462f9b7f9a4e5f478f8e54f121d4227df Mon Sep 17 00:00:00 2001 From: pradeep-gr Date: Wed, 26 Oct 2016 15:07:52 +0530 Subject: [PATCH 015/107] Conflict resolved --- .../TARGET_ONSEMI/TARGET_NCS36510/trim_map.h | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/trim_map.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/trim_map.h index cd215b97f32..13d5905a4f5 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/trim_map.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/trim_map.h @@ -50,19 +50,15 @@ **************************************************************************************************/ /** trim register map */ -<<<<<<< HEAD -typedef struct { /**< REV B REV D */ - __I uint32_t PAD0; /**< 0x1FA0 0x1FA0 */ +typedef struct { + __I uint32_t PAD0; /**< 0x1FA0 */ __I uint32_t MAC_ADDR_LOW; /**< 0x1FA4 */ __I uint32_t MAC_ADDR_HIGH; /**< 0x1FA8 */ -#ifdef REVB - __I uint32_t TX_POWER; /**< 0x1FAC */ -#endif - __I uint32_t TRIM_32K_EXT; /**< 0x1FB0 0x1FAC */ - __I uint32_t TRIM_32M_EXT; /**< 0x1FB4 0x1FB0 */ - __I uint32_t FVVDH_COMP_TH; /**< 0x1FB4 */ + __I uint32_t TRIM_32K_EXT; /**< 0x1FAC */ + __I uint32_t TRIM_32M_EXT; /**< 0x1FB0 */ + __I uint32_t FVVDH_COMP_TH; /**< 0x1FB4 */ union { - struct { /* Common to REV B & REV D */ + struct { __I uint32_t CHANNEL11:4; __I uint32_t CHANNEL12:4; __I uint32_t CHANNEL13:4; @@ -129,4 +125,4 @@ typedef struct { /**< REV B REV D */ __I uint32_t REVISION_CODE; /**< 0x1FFC */ } TrimReg_t, *TrimReg_pt; -#endif /* TRIM_MAP_H_ */ \ No newline at end of file +#endif /* TRIM_MAP_H_ */ From c07b9a011fb45b474df2028978ed723f6afdbfe5 Mon Sep 17 00:00:00 2001 From: pradeep-gr Date: Wed, 26 Oct 2016 16:49:29 +0530 Subject: [PATCH 016/107] mbed-os-tests-mbedtls-selftest issue fixed --- targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng_api.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng_api.c index b3defd45dd5..d255a6eaf05 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng_api.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_trng_api.c @@ -38,6 +38,7 @@ #include "memory_map.h" #include "ncs36510_trng.h" #include "clock.h" +#include "wait_api.h" /************************************************************************************************* * * @@ -70,13 +71,12 @@ void trng_free(trng_t *obj) int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length) { uint32_t MSLRandom = 0, Index, TempLen, *TempPtr = (uint32_t*)output; - volatile uint32_t delay; RANDREG->CONTROL.BITS.METASTABLE_LATCH_EN = TRNG_ENABLE; /* ENable MSL TRNG */ RANDREG->CONTROL.BITS.MEATSTABLE_SPEED = TRNG_FAST_MODE; /* Meta-stable Latch TRNG Speed Control */ RANDREG->CONTROL.BITS.MODE = TRNG_ON_READ_EVENT; /* TRNG is only updated on a read event of the TRNG register */ - for(uint32_t delay = 0;delay < 0x1F; delay++); /* Wait till generate MSL TRNG after enable for the first time */ + wait_us(1); /* Wait till MSL generates random number after enable for the first time */ TempLen = length / 4; From bd3f7282c17e62b170c19dfd27123a527c1aab04 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Wed, 26 Oct 2016 17:33:36 +0100 Subject: [PATCH 017/107] Handle [NOT_SUPPORTED] exception in make.py That let us to ignore build failures for examples on not supported platforms. --- tools/make.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/make.py b/tools/make.py index 28767cd70cc..0f84ebc32fe 100644 --- a/tools/make.py +++ b/tools/make.py @@ -29,6 +29,7 @@ sys.path.insert(0, ROOT) from tools.utils import args_error +from tools.utils import NotSupportedException from tools.paths import BUILD_DIR from tools.paths import MBED_LIBRARIES from tools.paths import RTOS_LIBRARIES @@ -326,6 +327,8 @@ except KeyboardInterrupt, e: print "\n[CTRL+c] exit" + except NotSupportedException, e: + print "\nNot supported for selected target" except Exception,e: if options.verbose: import traceback From c254e07ae76b95ecf6c34270d513b1f6c0e78749 Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Mon, 17 Oct 2016 17:16:04 +0200 Subject: [PATCH 018/107] STM32F207: GCC_ARM remove zero bss, in startup. zero bss is done in libc init after call to _start. --- .../TOOLCHAIN_GCC_ARM/startup_stm32f207xx.s | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/TOOLCHAIN_GCC_ARM/startup_stm32f207xx.s b/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/TOOLCHAIN_GCC_ARM/startup_stm32f207xx.s index e2eef1628c9..d9d12251277 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/TOOLCHAIN_GCC_ARM/startup_stm32f207xx.s +++ b/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/TOOLCHAIN_GCC_ARM/startup_stm32f207xx.s @@ -57,10 +57,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -94,17 +90,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system initialization function.*/ bl SystemInit @@ -520,4 +505,4 @@ g_pfnVectors: .weak HASH_RNG_IRQHandler .thumb_set HASH_RNG_IRQHandler,Default_Handler -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ \ No newline at end of file +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ From 829c053c783b595d780ed1ff3ff9dc325fb56f90 Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Mon, 17 Oct 2016 17:18:25 +0200 Subject: [PATCH 019/107] STM32F3xxx : GCC_ARM remove zero bss, in startup. zero bss is done in libc init after call _start. --- .../TOOLCHAIN_GCC_ARM/startup_stm32f303xc.S | 16 ---------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f334x8.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f302x8.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f303x8.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f303xe.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f303xe.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f334x8.S | 15 --------------- 7 files changed, 106 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F303VC/device/TOOLCHAIN_GCC_ARM/startup_stm32f303xc.S b/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F303VC/device/TOOLCHAIN_GCC_ARM/startup_stm32f303xc.S index 170cfc16a70..cfb18f24f8e 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F303VC/device/TOOLCHAIN_GCC_ARM/startup_stm32f303xc.S +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F303VC/device/TOOLCHAIN_GCC_ARM/startup_stm32f303xc.S @@ -50,10 +50,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF1E0F85F /** @@ -87,18 +83,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss - /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F334C8/device/TOOLCHAIN_GCC_ARM/startup_stm32f334x8.S b/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F334C8/device/TOOLCHAIN_GCC_ARM/startup_stm32f334x8.S index d5eb80b6b0f..942f27707fb 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F334C8/device/TOOLCHAIN_GCC_ARM/startup_stm32f334x8.S +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F334C8/device/TOOLCHAIN_GCC_ARM/startup_stm32f334x8.S @@ -50,10 +50,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF1E0F85F /** @@ -87,17 +83,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f302x8.S b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f302x8.S index 8fd8505c261..a8818176d47 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f302x8.S +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f302x8.S @@ -50,10 +50,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF1E0F85F /** @@ -87,17 +83,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/device/TOOLCHAIN_GCC_ARM/startup_stm32f303x8.S b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/device/TOOLCHAIN_GCC_ARM/startup_stm32f303x8.S index d31da878a31..e6a250a2add 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/device/TOOLCHAIN_GCC_ARM/startup_stm32f303x8.S +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/device/TOOLCHAIN_GCC_ARM/startup_stm32f303x8.S @@ -50,10 +50,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF1E0F85F /** @@ -87,17 +83,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f303xe.S b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f303xe.S index efa5681b0e5..20412ac4382 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f303xe.S +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f303xe.S @@ -50,10 +50,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF1E0F85F /** @@ -87,17 +83,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303ZE/device/TOOLCHAIN_GCC_ARM/startup_stm32f303xe.S b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303ZE/device/TOOLCHAIN_GCC_ARM/startup_stm32f303xe.S index efa5681b0e5..20412ac4382 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303ZE/device/TOOLCHAIN_GCC_ARM/startup_stm32f303xe.S +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303ZE/device/TOOLCHAIN_GCC_ARM/startup_stm32f303xe.S @@ -50,10 +50,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF1E0F85F /** @@ -87,17 +83,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f334x8.S b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f334x8.S index d5eb80b6b0f..942f27707fb 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f334x8.S +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f334x8.S @@ -50,10 +50,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF1E0F85F /** @@ -87,17 +83,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit From 0bd2ba6519589069b9e5029d7d2d8ba4c3d500a3 Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Mon, 17 Oct 2016 17:21:46 +0200 Subject: [PATCH 020/107] STM32F4xx: GCC_ARM remove zero bss, in startup. zero bss is done in libc init after call to _start. --- .../TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f401xc.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f429xx.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f469xx.s | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f429xx.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S | 16 ---------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f401xe.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f410rx.s | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f407xx.S | 17 +---------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f439xx.S | 15 --------------- 14 files changed, 1 insertion(+), 212 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_B96B_F446VE/device/TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S b/targets/TARGET_STM/TARGET_STM32F4/TARGET_B96B_F446VE/device/TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S index c350865a09d..a0152a148a2 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_B96B_F446VE/device/TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_B96B_F446VE/device/TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F401VC/device/TOOLCHAIN_GCC_ARM/startup_stm32f401xc.S b/targets/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F401VC/device/TOOLCHAIN_GCC_ARM/startup_stm32f401xc.S index a83a8c8c60d..7b9f27eac18 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F401VC/device/TOOLCHAIN_GCC_ARM/startup_stm32f401xc.S +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F401VC/device/TOOLCHAIN_GCC_ARM/startup_stm32f401xc.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F429ZI/device/TOOLCHAIN_GCC_ARM/startup_stm32f429xx.S b/targets/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F429ZI/device/TOOLCHAIN_GCC_ARM/startup_stm32f429xx.S index c431df8da02..e5d498532da 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F429ZI/device/TOOLCHAIN_GCC_ARM/startup_stm32f429xx.S +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F429ZI/device/TOOLCHAIN_GCC_ARM/startup_stm32f429xx.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F469NI/device/TOOLCHAIN_GCC_ARM/startup_stm32f469xx.s b/targets/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F469NI/device/TOOLCHAIN_GCC_ARM/startup_stm32f469xx.s index 1925d08b373..44e20f3fb86 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F469NI/device/TOOLCHAIN_GCC_ARM/startup_stm32f469xx.s +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_DISCO_F469NI/device/TOOLCHAIN_GCC_ARM/startup_stm32f469xx.s @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_ELMO_F411RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S b/targets/TARGET_STM/TARGET_STM32F4/TARGET_ELMO_F411RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S index 8950a21b6b1..0b4a80ed6dd 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_ELMO_F411RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_ELMO_F411RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_F429_F439/device/TOOLCHAIN_GCC_ARM/startup_stm32f429xx.S b/targets/TARGET_STM/TARGET_STM32F4/TARGET_F429_F439/device/TOOLCHAIN_GCC_ARM/startup_stm32f429xx.S index 2c2f6692f34..1285f12fb62 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_F429_F439/device/TOOLCHAIN_GCC_ARM/startup_stm32f429xx.S +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_F429_F439/device/TOOLCHAIN_GCC_ARM/startup_stm32f429xx.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S index 8950a21b6b1..49181a09f31 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,18 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss - /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F401RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f401xe.S b/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F401RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f401xe.S index 75415e42b6e..a49a2d47d4b 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F401RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f401xe.S +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F401RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f401xe.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F410RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f410rx.s b/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F410RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f410rx.s index a27adb3fcea..5a1c1b10d6d 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F410RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f410rx.s +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F410RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f410rx.s @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F411RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S b/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F411RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S index 8950a21b6b1..0b4a80ed6dd 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F411RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F411RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f411xe.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F446RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S b/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F446RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S index c350865a09d..a0152a148a2 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F446RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F446RE/device/TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F446ZE/device/TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S b/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F446ZE/device/TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S index c350865a09d..a0152a148a2 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F446ZE/device/TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F446ZE/device/TOOLCHAIN_GCC_ARM/startup_stm32f446xx.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407VG/device/TOOLCHAIN_GCC_ARM/startup_stm32f407xx.S b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407VG/device/TOOLCHAIN_GCC_ARM/startup_stm32f407xx.S index d1dda571705..93f41bf20a3 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407VG/device/TOOLCHAIN_GCC_ARM/startup_stm32f407xx.S +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407VG/device/TOOLCHAIN_GCC_ARM/startup_stm32f407xx.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,18 +91,7 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss - + /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_GCC_ARM/startup_stm32f439xx.S b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_GCC_ARM/startup_stm32f439xx.S index efc3d5450e1..87d60833b4e 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_GCC_ARM/startup_stm32f439xx.S +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_GCC_ARM/startup_stm32f439xx.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit From 58fbe60ebb3fb256b1468940e6f725b4c7eeefef Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Mon, 17 Oct 2016 17:22:26 +0200 Subject: [PATCH 021/107] STM32L4xx : GCC_ARM remove zero bss, in startup. zero bss is done in libc init after call to _start. --- .../TOOLCHAIN_GCC_ARM/startup_stm32l476xx.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32l476xx.S | 16 ---------------- .../TOOLCHAIN_GCC_ARM/startup_stm32l432xx.S | 16 ---------------- 3 files changed, 47 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_DISCO_L476VG/device/TOOLCHAIN_GCC_ARM/startup_stm32l476xx.S b/targets/TARGET_STM/TARGET_STM32L4/TARGET_DISCO_L476VG/device/TOOLCHAIN_GCC_ARM/startup_stm32l476xx.S index fe37df3700b..8e825b181c3 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_DISCO_L476VG/device/TOOLCHAIN_GCC_ARM/startup_stm32l476xx.S +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_DISCO_L476VG/device/TOOLCHAIN_GCC_ARM/startup_stm32l476xx.S @@ -59,10 +59,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF1E0F85F /** @@ -96,17 +92,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_L476_L486/device/TOOLCHAIN_GCC_ARM/startup_stm32l476xx.S b/targets/TARGET_STM/TARGET_STM32L4/TARGET_L476_L486/device/TOOLCHAIN_GCC_ARM/startup_stm32l476xx.S index fe37df3700b..8510b46ecdd 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_L476_L486/device/TOOLCHAIN_GCC_ARM/startup_stm32l476xx.S +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_L476_L486/device/TOOLCHAIN_GCC_ARM/startup_stm32l476xx.S @@ -59,11 +59,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss - .equ BootRAM, 0xF1E0F85F /** * @brief This is the code that gets called when the processor first @@ -96,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_NUCLEO_L432KC/device/TOOLCHAIN_GCC_ARM/startup_stm32l432xx.S b/targets/TARGET_STM/TARGET_STM32L4/TARGET_NUCLEO_L432KC/device/TOOLCHAIN_GCC_ARM/startup_stm32l432xx.S index cfc614e8755..c272e19398d 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_NUCLEO_L432KC/device/TOOLCHAIN_GCC_ARM/startup_stm32l432xx.S +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_NUCLEO_L432KC/device/TOOLCHAIN_GCC_ARM/startup_stm32l432xx.S @@ -59,11 +59,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss - .equ BootRAM, 0xF1E0F85F /** * @brief This is the code that gets called when the processor first @@ -96,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit From 981ebbc95ba51293239114753aa9cb14e0e87d84 Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Mon, 17 Oct 2016 17:23:50 +0200 Subject: [PATCH 022/107] STM32F7xx : GCC_ARM remove zero bss, in startup. zero bss is done in libc init after call to _start. --- .../TOOLCHAIN_GCC_ARM/startup_stm32f746xx.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f769xx.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f746xx.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f769xx.s | 15 --------------- 4 files changed, 60 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/device/TOOLCHAIN_GCC_ARM/startup_stm32f746xx.S b/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/device/TOOLCHAIN_GCC_ARM/startup_stm32f746xx.S index b14a8455b89..8a950e13b30 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/device/TOOLCHAIN_GCC_ARM/startup_stm32f746xx.S +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/device/TOOLCHAIN_GCC_ARM/startup_stm32f746xx.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system initialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F769NI/device/TOOLCHAIN_GCC_ARM/startup_stm32f769xx.S b/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F769NI/device/TOOLCHAIN_GCC_ARM/startup_stm32f769xx.S index 3cb97ec6334..72833bf1767 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F769NI/device/TOOLCHAIN_GCC_ARM/startup_stm32f769xx.S +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F769NI/device/TOOLCHAIN_GCC_ARM/startup_stm32f769xx.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system initialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_F746_F756/device/TOOLCHAIN_GCC_ARM/startup_stm32f746xx.S b/targets/TARGET_STM/TARGET_STM32F7/TARGET_F746_F756/device/TOOLCHAIN_GCC_ARM/startup_stm32f746xx.S index b14a8455b89..8a950e13b30 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_F746_F756/device/TOOLCHAIN_GCC_ARM/startup_stm32f746xx.S +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_F746_F756/device/TOOLCHAIN_GCC_ARM/startup_stm32f746xx.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system initialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_NUCLEO_F767ZI/device/TOOLCHAIN_GCC_ARM/startup_stm32f769xx.s b/targets/TARGET_STM/TARGET_STM32F7/TARGET_NUCLEO_F767ZI/device/TOOLCHAIN_GCC_ARM/startup_stm32f769xx.s index 3cb97ec6334..72833bf1767 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_NUCLEO_F767ZI/device/TOOLCHAIN_GCC_ARM/startup_stm32f769xx.s +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_NUCLEO_F767ZI/device/TOOLCHAIN_GCC_ARM/startup_stm32f769xx.s @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system initialization function.*/ bl SystemInit From b6f411e25a736bebc8cc5cf8502042cab8af1981 Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Mon, 17 Oct 2016 17:34:28 +0200 Subject: [PATCH 023/107] STM32L1xx : GCC_ARM a call to _start which performs zero bss, C++ init and the call to main. Remove direct call to __libc_init_array and main not needed as _start is beeing called. --- .../device/TOOLCHAIN_GCC_ARM/startup_stm32l152xc.S | 13 +++++++++---- .../device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S | 14 +++++++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/TOOLCHAIN_GCC_ARM/startup_stm32l152xc.S b/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/TOOLCHAIN_GCC_ARM/startup_stm32l152xc.S index 66ab8dcb7b6..4231d379e1d 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/TOOLCHAIN_GCC_ARM/startup_stm32l152xc.S +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/TOOLCHAIN_GCC_ARM/startup_stm32l152xc.S @@ -109,11 +109,16 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit -/* Call static constructors */ - bl __libc_init_array -/* Call the application's entry point.*/ - bl main + +/** + * Calling the crt0 'cold-start' entry point. There __libc_init_array is called + * and when existing hardware_init_hook() and software_init_hook() before + * starting main(). software_init_hook() is available and has to be called due + * to initializsation when using rtos. +*/ + bl _start bx lr + .size Reset_Handler, .-Reset_Handler /** diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S index 41f7c989812..3823f29335c 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S @@ -109,11 +109,15 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit -/* Call static constructors */ - bl __libc_init_array -/* Call the application's entry point.*/ - bl main - bx lr + +/** + * Calling the crt0 'cold-start' entry point. There __libc_init_array is called + * and when existing hardware_init_hook() and software_init_hook() before + * starting main(). software_init_hook() is available and has to be called due + * to initializsation when using rtos. +*/ + bl _start + bx lr .size Reset_Handler, .-Reset_Handler /** From 550afdffd78df8c952939107e4746a3552bd4770 Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Mon, 17 Oct 2016 17:34:28 +0200 Subject: [PATCH 024/107] STM32L1xx : GCC_ARM remove zero bss, in startup. zero bss is done in libc init after call to _start. --- .../TOOLCHAIN_GCC_ARM/startup_stm32l152xc.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32l152xe.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S | 15 --------------- 4 files changed, 60 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/TOOLCHAIN_GCC_ARM/startup_stm32l152xc.S b/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/TOOLCHAIN_GCC_ARM/startup_stm32l152xc.S index 4231d379e1d..6ea483ac406 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/TOOLCHAIN_GCC_ARM/startup_stm32l152xc.S +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/TOOLCHAIN_GCC_ARM/startup_stm32l152xc.S @@ -59,10 +59,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF108F85F /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/TOOLCHAIN_GCC_ARM/startup_stm32l152xe.S b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/TOOLCHAIN_GCC_ARM/startup_stm32l152xe.S index d80d4ac7cec..9b3b181a9a8 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/TOOLCHAIN_GCC_ARM/startup_stm32l152xe.S +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/TOOLCHAIN_GCC_ARM/startup_stm32l152xe.S @@ -59,10 +59,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF108F85F /** @@ -97,17 +93,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S index 3823f29335c..f0524e11e30 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S @@ -59,10 +59,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF108F85F /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S index 27be06bc5c6..cf4fee1bad6 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_GCC_ARM/startup_stm32l151xc.S @@ -59,10 +59,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF108F85F /** @@ -95,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit From 00c983959f067050edf4b5a916018f3cb35143d7 Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Mon, 17 Oct 2016 17:38:50 +0200 Subject: [PATCH 025/107] STM32L0xx : GCC_ARM remove zero bss, in startup. zero bss is done in libc init after call to _start. --- .../TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S | 17 ----------------- .../TOOLCHAIN_GCC_ARM/startup_stm32l011xx.s | 17 ----------------- .../TOOLCHAIN_GCC_ARM/startup_stm32l031xx.S | 19 +------------------ .../TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S | 19 +------------------ .../TOOLCHAIN_GCC_ARM/startup_stm32l073xx.S | 17 ----------------- 5 files changed, 2 insertions(+), 87 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S index 91f3adff145..19ab5c6e41c 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S @@ -55,10 +55,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .section .text.Reset_Handler .weak Reset_Handler @@ -83,19 +79,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2] - adds r2, r2, #4 - - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/TOOLCHAIN_GCC_ARM/startup_stm32l011xx.s b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/TOOLCHAIN_GCC_ARM/startup_stm32l011xx.s index 22b00218d51..9bc87d8dae2 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/TOOLCHAIN_GCC_ARM/startup_stm32l011xx.s +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/TOOLCHAIN_GCC_ARM/startup_stm32l011xx.s @@ -55,10 +55,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .section .text.Reset_Handler .weak Reset_Handler @@ -83,19 +79,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2] - adds r2, r2, #4 - - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32l031xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32l031xx.S index c8063a7c88f..325c46fbcb1 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32l031xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32l031xx.S @@ -55,10 +55,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .section .text.Reset_Handler .weak Reset_Handler @@ -83,20 +79,7 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2] - adds r2, r2, #4 - - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss - + /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S index 5a3fc511e3a..ad199c5225d 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S @@ -55,10 +55,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .section .text.Reset_Handler .weak Reset_Handler @@ -83,20 +79,7 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2] - adds r2, r2, #4 - - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss - + /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_GCC_ARM/startup_stm32l073xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_GCC_ARM/startup_stm32l073xx.S index a294978d3be..f2fecb6915d 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_GCC_ARM/startup_stm32l073xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_GCC_ARM/startup_stm32l073xx.S @@ -55,10 +55,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .section .text.Reset_Handler .weak Reset_Handler @@ -83,19 +79,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2] - adds r2, r2, #4 - - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit From 0af5d103d6e461864a4420258c4396d06c6b7a71 Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Mon, 17 Oct 2016 17:53:33 +0200 Subject: [PATCH 026/107] STM32F0xx : GCC_ARM use a call to _start which performs zero bss, C++ init and the call to main. Remove direct call to __libc_init_array and main not needed as _start is beeing called. --- .../device/TOOLCHAIN_GCC_ARM/startup_stm32f051x8.S | 13 ++++++++----- .../device/TOOLCHAIN_GCC_ARM/startup_stm32f030x8.S | 3 +-- .../device/TOOLCHAIN_GCC_ARM/startup_stm32f031x6.s | 3 +-- .../device/TOOLCHAIN_GCC_ARM/startup_stm32f042x6.s | 3 +-- .../device/TOOLCHAIN_GCC_ARM/startup_stm32f070xb.S | 3 +-- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f051x8.S b/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f051x8.S index d39ff65ab9b..bfc86250de4 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f051x8.S +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f051x8.S @@ -99,11 +99,14 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit -/* Call static constructors */ - bl __libc_init_array -/* Call the application's entry point.*/ - bl main - bl exit + +/** + * Calling the crt0 'cold-start' entry point. There __libc_init_array is called + * and when existing hardware_init_hook() and software_init_hook() before + * starting main(). software_init_hook() is available and has to be called due + * to initializsation when using rtos. +*/ + bl _start LoopForever: b LoopForever diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f030x8.S b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f030x8.S index 554d1f07e69..06050630c9c 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f030x8.S +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f030x8.S @@ -99,8 +99,7 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit -/* Call static constructors */ - bl __libc_init_array + /* Call the application's entry point.*/ // bl main bl _start diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f031x6.s b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f031x6.s index 5984c47c93c..a59f74c6038 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f031x6.s +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f031x6.s @@ -99,8 +99,7 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit -/* Call static constructors */ - bl __libc_init_array + /* Call the application's entry point.*/ // bl main bl _start diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f042x6.s b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f042x6.s index caf8f926d84..e874b81e5ae 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f042x6.s +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f042x6.s @@ -131,8 +131,7 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit -/* Call static constructors */ - bl __libc_init_array + /* Call the application's entry point.*/ // bl main bl _start diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f070xb.S b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f070xb.S index d65df5a677f..0d2ce0c64e9 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f070xb.S +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f070xb.S @@ -99,8 +99,7 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit -/* Call static constructors */ - bl __libc_init_array + /* Call the application's entry point.*/ // bl main bl _start From 3245ad6815b1f48df2e42c5db61ec783a69201d4 Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Mon, 17 Oct 2016 17:53:33 +0200 Subject: [PATCH 027/107] STM32F0xx: GCC_ARM remove zero bss, in startup. zero bss is done in libc init after call to _start. --- .../TOOLCHAIN_GCC_ARM/startup_stm32f051x8.S | 17 ----------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f030x8.S | 17 ----------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f031x6.s | 17 ----------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f042x6.s | 17 ----------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f070xb.S | 18 +----------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f072xb.S | 17 ----------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f091xc.S | 17 ----------------- 7 files changed, 1 insertion(+), 119 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f051x8.S b/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f051x8.S index bfc86250de4..5ae8717ba31 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f051x8.S +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f051x8.S @@ -55,10 +55,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .section .text.Reset_Handler .weak Reset_Handler @@ -83,19 +79,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2] - adds r2, r2, #4 - - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f030x8.S b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f030x8.S index 06050630c9c..45267362742 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f030x8.S +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/TOOLCHAIN_GCC_ARM/startup_stm32f030x8.S @@ -55,10 +55,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .section .text.Reset_Handler .weak Reset_Handler @@ -83,19 +79,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2] - adds r2, r2, #4 - - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f031x6.s b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f031x6.s index a59f74c6038..2d505708c31 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f031x6.s +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f031x6.s @@ -55,10 +55,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .section .text.Reset_Handler .weak Reset_Handler @@ -83,19 +79,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2] - adds r2, r2, #4 - - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f042x6.s b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f042x6.s index e874b81e5ae..a751fe57843 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f042x6.s +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/TOOLCHAIN_GCC_ARM/startup_stm32f042x6.s @@ -55,10 +55,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss /** * @brief This is the code that gets called when the processor first @@ -115,19 +111,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2] - adds r2, r2, #4 - - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f070xb.S b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f070xb.S index 0d2ce0c64e9..26e72d5a92e 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f070xb.S +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f070xb.S @@ -55,10 +55,7 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss + .section .text.Reset_Handler .weak Reset_Handler @@ -83,19 +80,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2] - adds r2, r2, #4 - - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f072xb.S b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f072xb.S index 15f7d9e03e3..525d175a139 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f072xb.S +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f072xb.S @@ -55,10 +55,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .section .text.Reset_Handler .weak Reset_Handler @@ -83,19 +79,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2] - adds r2, r2, #4 - - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/TOOLCHAIN_GCC_ARM/startup_stm32f091xc.S b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/TOOLCHAIN_GCC_ARM/startup_stm32f091xc.S index a4f13199b10..cc06a7ff626 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/TOOLCHAIN_GCC_ARM/startup_stm32f091xc.S +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/TOOLCHAIN_GCC_ARM/startup_stm32f091xc.S @@ -55,10 +55,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .section .text.Reset_Handler .weak Reset_Handler @@ -83,19 +79,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2] - adds r2, r2, #4 - - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit From 142cdb1be8aeb263026ca829af09589d91fa135a Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Mon, 17 Oct 2016 17:59:42 +0200 Subject: [PATCH 028/107] STM32F1xx : GCC_ARM remove zero bss done at startup. Zero bss is done after the call to _start. --- .../TOOLCHAIN_GCC_ARM/startup_stm32f103xb.S | 15 --------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f100xb.S | 16 +--------------- .../TOOLCHAIN_GCC_ARM/startup_stm32f103xb.S | 15 --------------- 3 files changed, 1 insertion(+), 45 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/device/TOOLCHAIN_GCC_ARM/startup_stm32f103xb.S b/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/device/TOOLCHAIN_GCC_ARM/startup_stm32f103xb.S index 902be7ebb71..9f79c00cd41 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/device/TOOLCHAIN_GCC_ARM/startup_stm32f103xb.S +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/device/TOOLCHAIN_GCC_ARM/startup_stm32f103xb.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF108F85F /** @@ -96,17 +92,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f100xb.S b/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f100xb.S index 35b512f7648..16f9bff1a59 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f100xb.S +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f100xb.S @@ -58,10 +58,7 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss + .equ BootRAM, 0xF108F85F /** @@ -94,17 +91,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f103xb.S b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f103xb.S index 902be7ebb71..9f79c00cd41 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f103xb.S +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/TOOLCHAIN_GCC_ARM/startup_stm32f103xb.S @@ -58,10 +58,6 @@ defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss .equ BootRAM, 0xF108F85F /** @@ -96,17 +92,6 @@ LoopCopyDataInit: adds r2, r0, r1 cmp r2, r3 bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss /* Call the clock system intitialization function.*/ bl SystemInit From 169e577145f195156b9dd689ca95ba20d09a47f8 Mon Sep 17 00:00:00 2001 From: Michel Jaouen Date: Fri, 7 Oct 2016 09:24:23 +0200 Subject: [PATCH 029/107] INIT:GCC add call to HAL_Init system_init, stops all on going timer. gcc _start , perform zero initialized. => HAL_Init must be done again also in GCC toolchain --- targets/TARGET_STM/TARGET_STM32F0/mbed_overrides.c | 2 -- targets/TARGET_STM/TARGET_STM32F1/mbed_overrides.c | 2 -- targets/TARGET_STM/TARGET_STM32F3/mbed_overrides.c | 2 -- targets/TARGET_STM/TARGET_STM32F4/mbed_overrides.c | 2 -- targets/TARGET_STM/TARGET_STM32F7/mbed_overrides.c | 2 -- targets/TARGET_STM/TARGET_STM32L0/mbed_overrides.c | 2 -- targets/TARGET_STM/TARGET_STM32L1/mbed_overrides.c | 2 -- targets/TARGET_STM/TARGET_STM32L4/mbed_overrides.c | 2 -- 8 files changed, 16 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F0/mbed_overrides.c b/targets/TARGET_STM/TARGET_STM32F0/mbed_overrides.c index a14c2980e12..4d387789145 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/mbed_overrides.c +++ b/targets/TARGET_STM/TARGET_STM32F0/mbed_overrides.c @@ -31,8 +31,6 @@ void mbed_sdk_init() { // Update the SystemCoreClock variable. SystemCoreClockUpdate(); -#if !defined(TOOLCHAIN_GCC_ARM) // Need to restart HAL driver after the RAM is initialized HAL_Init(); -#endif } diff --git a/targets/TARGET_STM/TARGET_STM32F1/mbed_overrides.c b/targets/TARGET_STM/TARGET_STM32F1/mbed_overrides.c index 2252f1c8249..9783dd90a53 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/mbed_overrides.c +++ b/targets/TARGET_STM/TARGET_STM32F1/mbed_overrides.c @@ -32,8 +32,6 @@ void mbed_sdk_init() { // Update the SystemCoreClock variable. SystemCoreClockUpdate(); -#if !defined(TOOLCHAIN_GCC_ARM) // Need to restart HAL driver after the RAM is initialized HAL_Init(); -#endif } diff --git a/targets/TARGET_STM/TARGET_STM32F3/mbed_overrides.c b/targets/TARGET_STM/TARGET_STM32F3/mbed_overrides.c index 2252f1c8249..9783dd90a53 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/mbed_overrides.c +++ b/targets/TARGET_STM/TARGET_STM32F3/mbed_overrides.c @@ -32,8 +32,6 @@ void mbed_sdk_init() { // Update the SystemCoreClock variable. SystemCoreClockUpdate(); -#if !defined(TOOLCHAIN_GCC_ARM) // Need to restart HAL driver after the RAM is initialized HAL_Init(); -#endif } diff --git a/targets/TARGET_STM/TARGET_STM32F4/mbed_overrides.c b/targets/TARGET_STM/TARGET_STM32F4/mbed_overrides.c index 93e4da780b3..a21a749f800 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/mbed_overrides.c +++ b/targets/TARGET_STM/TARGET_STM32F4/mbed_overrides.c @@ -33,10 +33,8 @@ void mbed_sdk_init() { // Update the SystemCoreClock variable. SystemCoreClockUpdate(); -#if !defined(TOOLCHAIN_GCC_ARM) // Need to restart HAL driver after the RAM is initialized HAL_Init(); -#endif } /** diff --git a/targets/TARGET_STM/TARGET_STM32F7/mbed_overrides.c b/targets/TARGET_STM/TARGET_STM32F7/mbed_overrides.c index 6b174b89801..496c4adc66d 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/mbed_overrides.c +++ b/targets/TARGET_STM/TARGET_STM32F7/mbed_overrides.c @@ -35,10 +35,8 @@ void mbed_sdk_init() { // Update the SystemCoreClock variable. SystemCoreClockUpdate(); -#if !defined(TOOLCHAIN_GCC_ARM) // Need to restart HAL driver after the RAM is initialized HAL_Init(); -#endif } diff --git a/targets/TARGET_STM/TARGET_STM32L0/mbed_overrides.c b/targets/TARGET_STM/TARGET_STM32L0/mbed_overrides.c index 4025d0aaa0c..4c3ff4c6c94 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/mbed_overrides.c +++ b/targets/TARGET_STM/TARGET_STM32L0/mbed_overrides.c @@ -32,8 +32,6 @@ void mbed_sdk_init() { // Update the SystemCoreClock variable. SystemCoreClockUpdate(); -#if !defined(TOOLCHAIN_GCC_ARM) // Need to restart HAL driver after the RAM is initialized HAL_Init(); -#endif } diff --git a/targets/TARGET_STM/TARGET_STM32L1/mbed_overrides.c b/targets/TARGET_STM/TARGET_STM32L1/mbed_overrides.c index 9b9c85031fd..16d77cc84c5 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/mbed_overrides.c +++ b/targets/TARGET_STM/TARGET_STM32L1/mbed_overrides.c @@ -35,10 +35,8 @@ void mbed_sdk_init() { // Update the SystemCoreClock variable. SystemCoreClockUpdate(); -#if !defined(TOOLCHAIN_GCC_ARM) // Need to restart HAL driver after the RAM is initialized HAL_Init(); -#endif #if defined(TARGET_XDOT_L151CC) if (PWR->CSR & PWR_CSR_SBF) { diff --git a/targets/TARGET_STM/TARGET_STM32L4/mbed_overrides.c b/targets/TARGET_STM/TARGET_STM32L4/mbed_overrides.c index 4025d0aaa0c..4c3ff4c6c94 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/mbed_overrides.c +++ b/targets/TARGET_STM/TARGET_STM32L4/mbed_overrides.c @@ -32,8 +32,6 @@ void mbed_sdk_init() { // Update the SystemCoreClock variable. SystemCoreClockUpdate(); -#if !defined(TOOLCHAIN_GCC_ARM) // Need to restart HAL driver after the RAM is initialized HAL_Init(); -#endif } From 9e8f5bc5645fe57615e52519ba47ac96859733a2 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Wed, 26 Oct 2016 16:55:49 -0500 Subject: [PATCH 030/107] Replacing getchar with RawSerial getc in greentea-client. This change prevents the standard library from allocating a large buffer on the heap. On GCC_ARM, this is a saving of 1K. On ARM, this is a saving of 64 bytes. --- features/frameworks/greentea-client/source/test_env.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/frameworks/greentea-client/source/test_env.cpp b/features/frameworks/greentea-client/source/test_env.cpp index c0a69a8a79c..54f1586d144 100644 --- a/features/frameworks/greentea-client/source/test_env.cpp +++ b/features/frameworks/greentea-client/source/test_env.cpp @@ -533,7 +533,7 @@ enum Token { * */ static int _get_char() { - return getchar(); + return greentea_serial->getc(); } /** From 9e8195f436e3b6fdc490cf776fc82dc9a896b8cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=20Lepp=C3=A4nen?= Date: Fri, 28 Oct 2016 09:51:00 +0300 Subject: [PATCH 031/107] Added support for 6lowpan PAN ID filter to mbed mesh api configuration --- .../nanostack/FEATURE_NANOSTACK/mbed-mesh-api/README.md | 1 + .../nanostack/FEATURE_NANOSTACK/mbed-mesh-api/mbed_lib.json | 1 + .../mbed-mesh-api/source/include/static_config.h | 6 ++++++ .../FEATURE_NANOSTACK/mbed-mesh-api/source/nd_tasklet.c | 4 ++++ 4 files changed, 12 insertions(+) diff --git a/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/README.md b/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/README.md index 920231b694d..207a6beacf7 100644 --- a/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/README.md +++ b/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/README.md @@ -54,6 +54,7 @@ An example of the configuration file: | 6lowpan-nd-channel-mask | number [0-0x07fff800] | Channel mask, bit-mask of channels to use | | 6lowpan-nd-channel-page | number [0, 2] | 0 for 2,4 GHz and 2 for sub-GHz radios | | 6lowpan-nd-channel | number [0-27] | RF channel to use when `channel_mask` is not defined | +| 6lowpan-nd-panid-filter | number [0-0xffff] | Beacon PAN ID filter, 0xffff means no filtering | | 6lowpan-nd-security-mode | "NONE" or "PSK" | To use either no security, or Pre shared network key | | 6lowpan-nd-psk-key-id | number | PSK key id when PSK is enabled | | 6lowpan-nd-psk-key | byte array [16] | Pre shared network key | diff --git a/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/mbed_lib.json b/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/mbed_lib.json index 4d216435987..0b32c7c767c 100644 --- a/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/mbed_lib.json +++ b/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/mbed_lib.json @@ -5,6 +5,7 @@ "6lowpan-nd-channel-mask": "(1<<12)", "6lowpan-nd-channel-page": 0, "6lowpan-nd-channel": 12, + "6lowpan-nd-panid-filter": "0xffff", "6lowpan-nd-security-mode": "NONE", "6lowpan-nd-psk-key-id": 1, "6lowpan-nd-psk-key": "{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf}", diff --git a/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/include/static_config.h b/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/include/static_config.h index cd2ff27149e..d4fcf9557af 100644 --- a/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/include/static_config.h +++ b/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/include/static_config.h @@ -100,6 +100,12 @@ extern "C" { #define MBED_MESH_API_6LOWPAN_ND_SEC_LEVEL 5 #endif +#if defined MBED_CONF_MBED_MESH_API_6LOWPAN_ND_PANID_FILTER +#define MBED_MESH_API_6LOWPAN_ND_PANID_FILTER MBED_CONF_MBED_MESH_API_6LOWPAN_ND_PANID_FILTER +#else +#define MBED_MESH_API_6LOWPAN_ND_PANID_FILTER 0xffff +#endif + /* Thread configuration */ // PSKd, must be longer than 6 #ifdef YOTTA_CFG_MBED_MESH_API_THREAD_PSKD diff --git a/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/nd_tasklet.c b/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/nd_tasklet.c index 3b74fe02bb9..136c067cce5 100644 --- a/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/nd_tasklet.c +++ b/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/source/nd_tasklet.c @@ -263,6 +263,10 @@ void nd_tasklet_configure_and_connect_to_network(void) arm_nwk_6lowpan_link_nwk_id_filter_for_nwk_scan( tasklet_data_ptr->network_interface_id, NULL); + arm_nwk_6lowpan_link_panid_filter_for_nwk_scan( + tasklet_data_ptr->network_interface_id, + MBED_MESH_API_6LOWPAN_ND_PANID_FILTER); + status = arm_nwk_interface_up(tasklet_data_ptr->network_interface_id); if (status >= 0) { tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED; From 45bd8cec3a59c41a0041896a7ede445207934b58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Tue, 11 Oct 2016 21:05:21 +0200 Subject: [PATCH 032/107] Update of can_api.c fixing #2987 --- targets/TARGET_STM/TARGET_STM32F0/can_api.c | 48 ++++++++++++++------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F0/can_api.c b/targets/TARGET_STM/TARGET_STM32F0/can_api.c index d392491fe41..e02d085d51c 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/can_api.c +++ b/targets/TARGET_STM/TARGET_STM32F0/can_api.c @@ -349,23 +349,39 @@ int can_mode(can_t *obj, CanMode mode) int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) { - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - CAN_FilterConfTypeDef sFilterConfig; + int retval = 0; - sFilterConfig.FilterNumber = handle; - sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; - sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; - sFilterConfig.FilterIdHigh = (uint8_t) (id >> 8); - sFilterConfig.FilterIdLow = (uint8_t) id; - sFilterConfig.FilterMaskIdHigh = (uint8_t) (mask >> 8); - sFilterConfig.FilterMaskIdLow = (uint8_t) mask; - sFilterConfig.FilterFIFOAssignment = 0; - sFilterConfig.FilterActivation = ENABLE; - sFilterConfig.BankNumber = 14; - - HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig); - - return 0; + // filter for CANAny format cannot be configured for STM32 + if((format == CANStandard) || (format == CANExtended)) { + + CanHandle.Instance = (CAN_TypeDef *)(obj->can); + CAN_FilterConfTypeDef sFilterConfig; + + sFilterConfig.FilterNumber = handle; + sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; + sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; + + if(format == CANStandard) { + sFilterConfig.FilterIdHigh = id << 5; + sFilterConfig.FilterIdLow = 0x0; + sFilterConfig.FilterMaskIdHigh = mask << 5; + sFilterConfig.FilterMaskIdLow = 0x0; // allows both remote and data frames + } + else if(format == CANExtended){ + sFilterConfig.FilterIdHigh = id >> 13; // EXTID[28:13] + sFilterConfig.FilterIdLow = (0x00FF & (id << 3)) | (1 << 2); // EXTID[12:0] + sFilterConfig.FilterMaskIdHigh = mask >> 13; + sFilterConfig.FilterMaskIdLow = (0x00FF & (mask << 3)) | (1 << 2); + } + + sFilterConfig.FilterFIFOAssignment = 0; + sFilterConfig.FilterActivation = ENABLE; + sFilterConfig.BankNumber = 14 + handle; + + HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig); + retval = handle; + } + return retval; } static void can_irq(CANName name, int id) From 5a153dd3cd2db0d24a0402ea87f3e77939712a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Sun, 30 Oct 2016 16:49:49 +0100 Subject: [PATCH 033/107] Fixing some typos --- targets/TARGET_STM/TARGET_STM32F0/can_api.c | 44 +++++++++------------ 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F0/can_api.c b/targets/TARGET_STM/TARGET_STM32F0/can_api.c index e02d085d51c..d6483cede12 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/can_api.c +++ b/targets/TARGET_STM/TARGET_STM32F0/can_api.c @@ -36,7 +36,7 @@ void can_init(can_t *obj, PinName rd, PinName td) obj->can = (CANName)pinmap_merge(can_rd, can_td); MBED_ASSERT((int)obj->can != NC); - if(obj->can == CAN_1) { + if (obj->can == CAN_1) { __HAL_RCC_CAN1_CLK_ENABLE(); obj->index = 0; } @@ -173,11 +173,11 @@ int can_frequency(can_t *obj, int f) if (btr > 0) { can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { + while ((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { } can->BTR = btr; can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { + while ((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { } return 1; } else { @@ -203,12 +203,9 @@ int can_write(can_t *obj, CAN_Message msg, int cc) if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX) { can->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ; - if (!(msg.format)) - { + if (!(msg.format)) { can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 21) | msg.type); - } - else - { + } else { can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 3) | CAN_ID_EXT | msg.type); } @@ -262,7 +259,7 @@ int can_read(can_t *obj, CAN_Message *msg, int handle) msg->data[7] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 24); /* Release the FIFO */ - if(handle == CAN_FIFO0) { + if (handle == CAN_FIFO0) { /* Release FIFO0 */ can->RF0R = CAN_RF0R_RFOM0; } else { /* FIFONumber == CAN_FIFO1 */ @@ -315,7 +312,7 @@ int can_mode(can_t *obj, CanMode mode) int success = 0; CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { + while ((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { } switch (mode) { case MODE_NORMAL: @@ -342,7 +339,7 @@ int can_mode(can_t *obj, CanMode mode) break; } can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { + while ((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { } return success; } @@ -352,27 +349,24 @@ int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t int retval = 0; // filter for CANAny format cannot be configured for STM32 - if((format == CANStandard) || (format == CANExtended)) { - + if ((format == CANStandard) || (format == CANExtended)) { CanHandle.Instance = (CAN_TypeDef *)(obj->can); CAN_FilterConfTypeDef sFilterConfig; - sFilterConfig.FilterNumber = handle; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; - if(format == CANStandard) { + if (format == CANStandard) { sFilterConfig.FilterIdHigh = id << 5; sFilterConfig.FilterIdLow = 0x0; sFilterConfig.FilterMaskIdHigh = mask << 5; sFilterConfig.FilterMaskIdLow = 0x0; // allows both remote and data frames - } - else if(format == CANExtended){ + } else if (format == CANExtended) { sFilterConfig.FilterIdHigh = id >> 13; // EXTID[28:13] sFilterConfig.FilterIdLow = (0x00FF & (id << 3)) | (1 << 2); // EXTID[12:0] sFilterConfig.FilterMaskIdHigh = mask >> 13; sFilterConfig.FilterMaskIdLow = (0x00FF & (mask << 3)) | (1 << 2); - } + } sFilterConfig.FilterFIFOAssignment = 0; sFilterConfig.FilterActivation = ENABLE; @@ -389,7 +383,7 @@ static void can_irq(CANName name, int id) uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0; CanHandle.Instance = (CAN_TypeDef *)name; - if(__HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_TME)) { + if (__HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_TME)) { tmp1 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_0); tmp2 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_1); tmp3 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_2); @@ -402,7 +396,7 @@ static void can_irq(CANName name, int id) tmp1 = __HAL_CAN_MSG_PENDING(&CanHandle, CAN_FIFO0); tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_FMP0); - if((tmp1 != 0) && tmp2) { + if ((tmp1 != 0) && tmp2) { irq_handler(can_irq_ids[id], IRQ_RX); } @@ -410,19 +404,19 @@ static void can_irq(CANName name, int id) tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_EPV); tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { + if (tmp1 && tmp2 && tmp3) { irq_handler(can_irq_ids[id], IRQ_PASSIVE); } tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_BOF); tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_BOF); tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { + if (tmp1 && tmp2 && tmp3) { irq_handler(can_irq_ids[id], IRQ_BUS); } tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { + if (tmp1 && tmp2 && tmp3) { irq_handler(can_irq_ids[id], IRQ_ERROR); } } @@ -440,7 +434,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) uint32_t vector = 0; uint32_t ier; - if(obj->can == CAN_1) { + if (obj->can == CAN_1) { switch (type) { case IRQ_RX: ier = CAN_IT_FMP0; @@ -463,7 +457,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) vector = (uint32_t)&CAN_IRQHandler; } - if(enable) { + if (enable) { can->IER |= ier; } else { can->IER &= ~ier; From af2116981e511fcc24a95cf3b3a8bc56368c1686 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Mon, 31 Oct 2016 18:28:34 -0500 Subject: [PATCH 034/107] Updating IAR definition for the NCS36510 for IAR EW v7.8 --- tools/export/iar/iar_definitions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/export/iar/iar_definitions.json b/tools/export/iar/iar_definitions.json index 5d168b091fe..5eb71cba442 100644 --- a/tools/export/iar/iar_definitions.json +++ b/tools/export/iar/iar_definitions.json @@ -151,6 +151,6 @@ "OGChipSelectEditMenu": "nRF52832-xxAA\tNordicSemi nRF52832-xxAA" }, "NCS36510":{ - "OGChipSelectEditMenu": "Orion\tON Semiconductor NCS36510" + "OGChipSelectEditMenu": "NCS36510\tONSemiconductor NCS36510" } } From 1106c36a61c3cf092b1eca6c9d05155d2c7c47a7 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Mon, 31 Oct 2016 14:52:06 -0500 Subject: [PATCH 035/107] Preventing test from printing before Greentea __sync This test was causing issues on some platforms because the serial output would get garbled and cause exceptions to occur in the testing tools. This corrects the behavior to follow the other tests. It will now defer all pritning until after the __sync event occurs. --- TESTS/mbedmicro-mbed/cpp/main.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/TESTS/mbedmicro-mbed/cpp/main.cpp b/TESTS/mbedmicro-mbed/cpp/main.cpp index bfa02200aef..fc5bcc21ce2 100644 --- a/TESTS/mbedmicro-mbed/cpp/main.cpp +++ b/TESTS/mbedmicro-mbed/cpp/main.cpp @@ -9,8 +9,10 @@ class Test { const int pattern; public: - Test(const char* _name) : name(_name), pattern(PATTERN_CHECK_VALUE) { - print("init"); + Test(const char* _name, bool print_message=true) : name(_name), pattern(PATTERN_CHECK_VALUE) { + if (print_message) { + print("init"); + } } void print(const char *message) { @@ -39,7 +41,7 @@ class Test { }; /* Check C++ startup initialisation */ -Test s("Static"); +Test s("Static", false); /* EXPECTED OUTPUT: ******************* @@ -59,6 +61,7 @@ int main (void) { bool result = true; for (;;) { + s.print("init"); // Global stack object simple test s.stack_test(); if (s.check_init() == false) From 7cccf2edace18fd21c119be2797343906ae88a15 Mon Sep 17 00:00:00 2001 From: Mahadevan Mahesh Date: Thu, 13 Oct 2016 10:03:23 -0500 Subject: [PATCH 036/107] Update USB driver for devices with Kinetis SDK support 1. Fix build issues with IAR and GCC toolchain 2. Update clock initialization code Signed-off-by: Mahadevan Mahesh --- .../USBDevice/USBDevice/USBHAL_KL25Z.cpp | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/features/unsupported/USBDevice/USBDevice/USBHAL_KL25Z.cpp b/features/unsupported/USBDevice/USBDevice/USBHAL_KL25Z.cpp index 4948fe44a97..853f1cc4331 100644 --- a/features/unsupported/USBDevice/USBDevice/USBHAL_KL25Z.cpp +++ b/features/unsupported/USBDevice/USBDevice/USBHAL_KL25Z.cpp @@ -18,6 +18,9 @@ #if defined(TARGET_KL25Z) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D50M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1) +#if defined(TARGET_KSDK2_MCUS) +#include "fsl_common.h" +#endif #include "USBHAL.h" USBHAL * USBHAL::instance; @@ -65,7 +68,8 @@ typedef struct BDT { // there are: // * 16 bidirectionnal endpt -> 32 physical endpt // * as there are ODD and EVEN buffer -> 32*2 bdt -__attribute__((__aligned__(512))) BDT bdt[NUMBER_OF_PHYSICAL_ENDPOINTS * 2]; +MBED_ALIGN(512) BDT bdt[NUMBER_OF_PHYSICAL_ENDPOINTS * 2]; // 512 bytes aligned! + uint8_t * endpoint_buffer[(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2]; uint8_t * endpoint_buffer_iso[2*2]; @@ -86,7 +90,7 @@ USBHAL::USBHAL(void) { // Disable IRQ NVIC_DisableIRQ(USB0_IRQn); -#if defined(TARGET_K64F) +#if (defined(FSL_FEATURE_SOC_MPU_COUNT) && (FSL_FEATURE_SOC_MPU_COUNT > 0U)) MPU->CESR=0; #endif // fill in callback array @@ -121,18 +125,9 @@ USBHAL::USBHAL(void) { epCallback[28] = &USBHAL::EP15_OUT_callback; epCallback[29] = &USBHAL::EP15_IN_callback; -#if defined(TARGET_KL43Z) +#if defined(TARGET_KL43Z) || defined(TARGET_K22F) || defined(TARGET_K64F) // enable USBFS clock - SIM->SCGC4 |= SIM_SCGC4_USBFS_MASK; - - // enable the IRC48M clock - USB0->CLK_RECOVER_IRC_EN |= USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK; - - // enable the USB clock recovery tuning - USB0->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK; - - // choose usb src clock - SIM->SOPT2 |= SIM_SOPT2_USBSRC_MASK; + CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U); #else // choose usb src as PLL SIM->SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK; @@ -148,10 +143,6 @@ USBHAL::USBHAL(void) { NVIC_EnableIRQ(USB0_IRQn); // USB Module Configuration - // Reset USB Module - USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; - while(USB0->USBTRC0 & USB_USBTRC0_USBRESET_MASK); - // Set BDT Base Register USB0->BDTPAGE1 = (uint8_t)((uint32_t)bdt>>8); USB0->BDTPAGE2 = (uint8_t)((uint32_t)bdt>>16); From 81733d3388fa178d595d102e82c02f93b5fe7001 Mon Sep 17 00:00:00 2001 From: Mahadevan Mahesh Date: Fri, 28 Oct 2016 12:10:50 -0500 Subject: [PATCH 037/107] FAT tests: Add support for KL43Z Signed-off-by: Mahadevan Mahesh --- features/unsupported/tests/mbed/sd/main.cpp | 2 +- features/unsupported/tests/mbed/sd_perf_fatfs/main.cpp | 2 +- features/unsupported/tests/mbed/sd_perf_fhandle/main.cpp | 2 +- features/unsupported/tests/mbed/sd_perf_stdio/main.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/unsupported/tests/mbed/sd/main.cpp b/features/unsupported/tests/mbed/sd/main.cpp index 246be534249..7edf69853fd 100644 --- a/features/unsupported/tests/mbed/sd/main.cpp +++ b/features/unsupported/tests/mbed/sd/main.cpp @@ -5,7 +5,7 @@ #if defined(TARGET_KL25Z) SDFileSystem sd(PTD2, PTD3, PTD1, PTD0, "sd"); -#elif defined(TARGET_KL46Z) +#elif defined(TARGET_KL46Z) || defined(TARGET_KL43Z) SDFileSystem sd(PTD6, PTD7, PTD5, PTD4, "sd"); #elif defined(TARGET_K64F) || defined(TARGET_K66F) diff --git a/features/unsupported/tests/mbed/sd_perf_fatfs/main.cpp b/features/unsupported/tests/mbed/sd_perf_fatfs/main.cpp index d71c3e2b85e..d4eee731af0 100644 --- a/features/unsupported/tests/mbed/sd_perf_fatfs/main.cpp +++ b/features/unsupported/tests/mbed/sd_perf_fatfs/main.cpp @@ -7,7 +7,7 @@ #if defined(TARGET_KL25Z) SDFileSystem sd(PTD2, PTD3, PTD1, PTD0, "sd"); -#elif defined(TARGET_KL46Z) +#elif defined(TARGET_KL46Z) || defined(TARGET_KL43Z) SDFileSystem sd(PTD6, PTD7, PTD5, PTD4, "sd"); #elif defined(TARGET_K64F) || defined(TARGET_K66F) diff --git a/features/unsupported/tests/mbed/sd_perf_fhandle/main.cpp b/features/unsupported/tests/mbed/sd_perf_fhandle/main.cpp index 50dd6f356d6..c9c8bc82776 100644 --- a/features/unsupported/tests/mbed/sd_perf_fhandle/main.cpp +++ b/features/unsupported/tests/mbed/sd_perf_fhandle/main.cpp @@ -7,7 +7,7 @@ #if defined(TARGET_KL25Z) SDFileSystem sd(PTD2, PTD3, PTD1, PTD0, "sd"); -#elif defined(TARGET_KL46Z) +#elif defined(TARGET_KL46Z) || defined(TARGET_KL43Z) SDFileSystem sd(PTD6, PTD7, PTD5, PTD4, "sd"); #elif defined(TARGET_K64F) || defined(TARGET_K66F) diff --git a/features/unsupported/tests/mbed/sd_perf_stdio/main.cpp b/features/unsupported/tests/mbed/sd_perf_stdio/main.cpp index 74e35b063af..10855ee5954 100644 --- a/features/unsupported/tests/mbed/sd_perf_stdio/main.cpp +++ b/features/unsupported/tests/mbed/sd_perf_stdio/main.cpp @@ -7,7 +7,7 @@ #if defined(TARGET_KL25Z) SDFileSystem sd(PTD2, PTD3, PTD1, PTD0, "sd"); -#elif defined(TARGET_KL46Z) +#elif defined(TARGET_KL46Z) || defined(TARGET_KL43Z) SDFileSystem sd(PTD6, PTD7, PTD5, PTD4, "sd"); #elif defined(TARGET_K64F) || defined(TARGET_K66F) From e3561fa358c39a2e01003994685757961481e66c Mon Sep 17 00:00:00 2001 From: Mahadevan Mahesh Date: Thu, 27 Oct 2016 16:28:31 -0500 Subject: [PATCH 038/107] Add K64F, K22F and KL43Z to travis build Signed-off-by: Mahadevan Mahesh --- tools/build_travis.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tools/build_travis.py b/tools/build_travis.py index f4b3f01fc7e..55b26d1ba98 100644 --- a/tools/build_travis.py +++ b/tools/build_travis.py @@ -137,6 +137,30 @@ "rtos" : ["RTOS_1", "RTOS_2", "RTOS_3"], "usb" : ["USB_1", "USB_2" ,"USB_3"], } + }, + {"target": "K64F", + "toolchains": "GCC_ARM", + "tests": {"" : ["MBED_2", "MBED_10", "MBED_11", "MBED_15", "MBED_16", "MBED_17"], + "fat" : ["MBED_A12", "PERF_1", "PERF_2", "PERF_3"], + "rtos" : ["RTOS_1", "RTOS_2", "RTOS_3"], + "usb" : ["USB_1", "USB_2" ,"USB_3"], + } + }, + {"target": "K22F", + "toolchains": "GCC_ARM", + "tests": {"" : ["MBED_2", "MBED_10", "MBED_11", "MBED_15", "MBED_16", "MBED_17"], + "fat" : ["MBED_A12", "PERF_1", "PERF_2", "PERF_3"], + "rtos" : ["RTOS_1", "RTOS_2", "RTOS_3"], + "usb" : ["USB_1", "USB_2" ,"USB_3"], + } + }, + {"target": "KL43Z", + "toolchains": "GCC_ARM", + "tests": {"" : ["MBED_2", "MBED_10", "MBED_11", "MBED_15", "MBED_16", "MBED_17"], + "fat" : ["MBED_A12", "PERF_1", "PERF_2", "PERF_3"], + "rtos" : ["RTOS_1", "RTOS_2", "RTOS_3"], + "usb" : ["USB_1", "USB_2" ,"USB_3"], + } } ] From 25fa65c63380187499387537f01528de3c5d2c42 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Mon, 31 Oct 2016 12:42:15 -0500 Subject: [PATCH 039/107] Adding Kinetis devices to mbed 2 tests and updating build_travis script --- tools/build_travis.py | 7 ++++--- tools/tests.py | 16 ++++++++-------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/tools/build_travis.py b/tools/build_travis.py index 55b26d1ba98..13a3d6f0c81 100644 --- a/tools/build_travis.py +++ b/tools/build_travis.py @@ -98,6 +98,7 @@ { "target": "K20D50M", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] }, { "target": "TEENSY3_1", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] }, { "target": "K64F", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] }, + { "target": "K22F", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] }, { "target": "LPC4088", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] }, { "target": "ARCH_PRO", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] }, { "target": "LPC1549", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] }, @@ -140,7 +141,7 @@ }, {"target": "K64F", "toolchains": "GCC_ARM", - "tests": {"" : ["MBED_2", "MBED_10", "MBED_11", "MBED_15", "MBED_16", "MBED_17"], + "tests": {"" : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"], "fat" : ["MBED_A12", "PERF_1", "PERF_2", "PERF_3"], "rtos" : ["RTOS_1", "RTOS_2", "RTOS_3"], "usb" : ["USB_1", "USB_2" ,"USB_3"], @@ -148,7 +149,7 @@ }, {"target": "K22F", "toolchains": "GCC_ARM", - "tests": {"" : ["MBED_2", "MBED_10", "MBED_11", "MBED_15", "MBED_16", "MBED_17"], + "tests": {"" : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"], "fat" : ["MBED_A12", "PERF_1", "PERF_2", "PERF_3"], "rtos" : ["RTOS_1", "RTOS_2", "RTOS_3"], "usb" : ["USB_1", "USB_2" ,"USB_3"], @@ -156,7 +157,7 @@ }, {"target": "KL43Z", "toolchains": "GCC_ARM", - "tests": {"" : ["MBED_2", "MBED_10", "MBED_11", "MBED_15", "MBED_16", "MBED_17"], + "tests": {"" : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"], "fat" : ["MBED_A12", "PERF_1", "PERF_2", "PERF_3"], "rtos" : ["RTOS_1", "RTOS_2", "RTOS_3"], "usb" : ["USB_1", "USB_2" ,"USB_3"], diff --git a/tools/tests.py b/tools/tests.py index b4103f02c98..0c82bcf9369 100644 --- a/tools/tests.py +++ b/tools/tests.py @@ -730,7 +730,7 @@ "automated": True, #"host_test": "wait_us_auto", "mcu": ["LPC1768", "LPC1549", "LPC11U24", "LPC812", "LPC2460", "LPC824", "SSCI824", - "KL25Z", "KL05Z", "K64F", "K66F", "KL46Z", "HEXIWEAR", + "KL25Z", "KL05Z", "K22F", "K64F", "K66F", "KL43Z", "KL46Z", "HEXIWEAR", "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F429ZI", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F070RB", "NUCLEO_F207ZG", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "NUCLEO_L432KC", "DISCO_L476VG", "NUCLEO_L476RG", @@ -744,7 +744,7 @@ "dependencies": [MBED_LIBRARIES, RTOS_LIBRARIES, TEST_MBED_LIB], "automated": True, "mcu": ["LPC1768", "LPC1549", "LPC11U24", "LPC812", "LPC2460", "LPC824", "SSCI824", - "KL25Z", "KL05Z", "K64F", "K66F", "KL46Z", "HEXIWEAR", + "KL25Z", "KL05Z", "K22F", "K64F", "K66F", "KL43Z", "KL46Z", "HEXIWEAR", "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F429ZI", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F303ZE", "NUCLEO_F070RB", "NUCLEO_F207ZG", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "NUCLEO_L432KC", "DISCO_L476VG", "NUCLEO_L476RG", @@ -759,7 +759,7 @@ "dependencies": [MBED_LIBRARIES, RTOS_LIBRARIES, TEST_MBED_LIB], "automated": True, "mcu": ["LPC1768", "LPC1549", "LPC11U24", "LPC812", "LPC2460", "LPC824", "SSCI824", - "KL25Z", "KL05Z", "K64F", "K66F", "KL46Z", "HEXIWEAR", + "KL25Z", "KL05Z", "K22F", "K64F", "K66F", "KL43Z", "KL46Z", "HEXIWEAR", "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F429ZI", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F303ZE", "NUCLEO_F070RB", "NUCLEO_F207ZG", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "NUCLEO_L432KC", "DISCO_L476VG", "NUCLEO_L476RG", @@ -775,7 +775,7 @@ "dependencies": [MBED_LIBRARIES, RTOS_LIBRARIES, TEST_MBED_LIB], "automated": True, "mcu": ["LPC1768", "LPC1549", "LPC11U24", "LPC812", "LPC2460", "LPC824", "SSCI824", - "KL25Z", "KL05Z", "K64F", "K66F", "KL46Z", "HEXIWEAR", + "KL25Z", "KL05Z", "K22F", "K64F", "K66F", "KL43Z", "KL46Z", "HEXIWEAR", "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F429ZI", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F303ZE", "NUCLEO_F070RB", "NUCLEO_F207ZG", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "NUCLEO_L432KC", "DISCO_L476VG", "NUCLEO_L476RG", @@ -791,7 +791,7 @@ "dependencies": [MBED_LIBRARIES, RTOS_LIBRARIES, TEST_MBED_LIB], "automated": True, "mcu": ["LPC1768", "LPC1549", "LPC11U24", "LPC812", "LPC2460", "LPC824", "SSCI824", - "KL25Z", "KL05Z", "K64F", "K66F", "KL46Z", "HEXIWEAR", + "KL25Z", "KL05Z", "K22F", "K64F", "K66F", "KL43Z", "KL46Z", "HEXIWEAR", "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F429ZI", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F303ZE", "NUCLEO_F070RB", "NUCLEO_F207ZG", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "NUCLEO_L432KC", "DISCO_L476VG", "NUCLEO_L476RG", @@ -806,7 +806,7 @@ "dependencies": [MBED_LIBRARIES, RTOS_LIBRARIES, TEST_MBED_LIB], "automated": True, "mcu": ["LPC1768", "LPC1549", "LPC11U24", "LPC812", "LPC2460", "LPC824", "SSCI824", - "KL25Z", "KL05Z", "K64F", "K66F", "KL46Z", "HEXIWEAR", + "KL25Z", "KL05Z", "K22F", "K64F", "K66F", "KL43Z", "KL46Z", "HEXIWEAR", "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F429ZI", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F303ZE", "NUCLEO_F070RB", "NUCLEO_F207ZG", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "NUCLEO_L432KC", "DISCO_L476VG", "NUCLEO_L476RG", @@ -822,7 +822,7 @@ "automated": True, #"host_test": "wait_us_auto", "mcu": ["LPC1768", "LPC1549", "LPC11U24", "LPC812", "LPC2460", "LPC824", "SSCI824", - "KL25Z", "KL05Z", "K64F", "K66F", "KL46Z", "HEXIWEAR", + "KL25Z", "KL05Z", "K22F", "K64F", "K66F", "KL43Z", "KL46Z", "HEXIWEAR", "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F429ZI", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F303ZE", "NUCLEO_F070RB", "NUCLEO_F207ZG", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "NUCLEO_L432KC", "DISCO_L476VG", "NUCLEO_L476RG", @@ -837,7 +837,7 @@ "dependencies": [MBED_LIBRARIES, RTOS_LIBRARIES, TEST_MBED_LIB], "automated": True, "mcu": ["LPC1768", "LPC1549", "LPC11U24", "LPC812", "LPC2460", "LPC824", "SSCI824", - "KL25Z", "KL05Z", "K64F", "K66F", "KL46Z", "HEXIWEAR", + "KL25Z", "KL05Z", "K22F", "K64F", "K66F", "KL43Z", "KL46Z", "HEXIWEAR", "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F429ZI", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F303ZE", "NUCLEO_F070RB", "NUCLEO_F207ZG", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "NUCLEO_L432KC", "DISCO_L476VG", "NUCLEO_L476RG", From 4600de67cbfd068f11c3b319450c2a2e8a401c71 Mon Sep 17 00:00:00 2001 From: Marcus Chang Date: Thu, 27 Oct 2016 10:26:28 +0100 Subject: [PATCH 040/107] Removed static declaration for the StorageVolumeManager in the CFStore because this componenent is shared across all users of the flash. Added define guards to the CFStore location and size so that these can be changed from the settings file. --- .../storage/FEATURE_STORAGE/cfstore/source/cfstore_svm.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/features/storage/FEATURE_STORAGE/cfstore/source/cfstore_svm.cpp b/features/storage/FEATURE_STORAGE/cfstore/source/cfstore_svm.cpp index c1c6c72d86f..e8fcd853c80 100644 --- a/features/storage/FEATURE_STORAGE/cfstore/source/cfstore_svm.cpp +++ b/features/storage/FEATURE_STORAGE/cfstore/source/cfstore_svm.cpp @@ -29,8 +29,13 @@ * so it can be called by the C-HAL implementation configuration_store.c */ +#ifndef CFSTORE_SVM_VOL_01_START_OFFSET #define CFSTORE_SVM_VOL_01_START_OFFSET 0x80000UL +#endif + +#ifndef CFSTORE_SVM_VOL_01_SIZE #define CFSTORE_SVM_VOL_01_SIZE 0x80000UL +#endif #ifdef CFSTORE_CONFIG_BACKEND_FLASH_ENABLED extern ARM_DRIVER_STORAGE ARM_Driver_Storage_MTD_K64F; @@ -39,7 +44,7 @@ static ARM_DRIVER_STORAGE *cfstore_svm_storage_drv = &ARM_Driver_Storage_MTD_K64 #endif /* CFSTORE_CONFIG_BACKEND_FLASH_ENABLED */ /* the storage volume manager instance used to generate virtual mtd descriptors */ -static StorageVolumeManager volumeManager; +StorageVolumeManager volumeManager; /* used only for the initialization of the volume-manager. */ static void cfstore_svm_volume_manager_initialize_callback(int32_t status) From 14f9518709bd73546bc5acac0b89876ea9686c05 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 25 Oct 2016 13:22:17 -0500 Subject: [PATCH 041/107] lwip - Fixed memory leak in k64f cyclic-buffer overflow This was actually several bugs colluding together. 1. Confusion on the buffer-semaphore paradigm used led to misuse of the tx semaphore and potential for odd behaviour. 2. Equality tests on tx_consume_index and tx_produce_index did not handle overflow correctly. This would allow tx_consume_index to catch up to tx_produce_index and trick the k64f_rx_reclaim function into forgetting about a whole buffer of pbufs. 3. On top of all of that, the ENET_BUFFDESCRIPTOR_TX_READ_MASK was not correctly read immediately after being set due to either a compiler optimization or hardware delays. This caused k64f_low_level_output to eagerly overrun existing buff-descriptors before they had been completely sent. Adopting the counting-semaphore paradigm for 1 avoided this concern. As pointed out by @infinnovation, the overflow only occurs in the rare case that the 120MHz CPU can actually generate packets faster than the ENET hardware can transmit on a 100Mbps link. --- .../arch/TARGET_Freescale/k64f_emac.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c index 7fb4dcf7e6d..66a0b587b02 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c @@ -102,24 +102,22 @@ static void update_read_buffer(uint8_t *buf) */ static void k64f_tx_reclaim(struct k64f_enetdata *k64f_enet) { - uint8_t i = 0 ; - /* Get exclusive access */ sys_mutex_lock(&k64f_enet->TXLockMutex); - i = k64f_enet->tx_consume_index; // Traverse all descriptors, looking for the ones modified by the uDMA - while((i != k64f_enet->tx_produce_index) && (!(g_handle.txBdDirty->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))) { - pbuf_free(tx_buff[i]); + while((k64f_enet->tx_consume_index != k64f_enet->tx_produce_index) && + (!(g_handle.txBdDirty->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))) { + pbuf_free(tx_buff[k64f_enet->tx_consume_index % ENET_TX_RING_LEN]); if (g_handle.txBdDirty->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK) g_handle.txBdDirty = g_handle.txBdBase; else g_handle.txBdDirty++; - i = (i + 1) % ENET_TX_RING_LEN; + k64f_enet->tx_consume_index += 1; + osSemaphoreRelease(k64f_enet->xTXDCountSem.id); } - k64f_enet->tx_consume_index = i; /* Restore access */ sys_mutex_unlock(&k64f_enet->TXLockMutex); } @@ -526,15 +524,14 @@ static err_t k64f_low_level_output(struct netif *netif, struct pbuf *p) /* Wait until a descriptor is available for the transfer. */ /* THIS WILL BLOCK UNTIL THERE ARE A DESCRIPTOR AVAILABLE */ - while (g_handle.txBdCurrent->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK) - osSemaphoreWait(k64f_enet->xTXDCountSem.id, osWaitForever); + osSemaphoreWait(k64f_enet->xTXDCountSem.id, osWaitForever); /* Get exclusive access */ sys_mutex_lock(&k64f_enet->TXLockMutex); /* Save the buffer so that it can be freed when transmit is done */ - tx_buff[k64f_enet->tx_produce_index] = temp_pbuf; - k64f_enet->tx_produce_index = (k64f_enet->tx_produce_index + 1) % ENET_TX_RING_LEN; + tx_buff[k64f_enet->tx_produce_index % ENET_TX_RING_LEN] = temp_pbuf; + k64f_enet->tx_produce_index += 1; /* Setup transfers */ g_handle.txBdCurrent->buffer = psend; From 5c97ea92544fd062c8fa05c8e2034a7ca5858d97 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Fri, 28 Oct 2016 15:22:08 -0500 Subject: [PATCH 042/107] lwip - Change k64f emac layer to drop frames on buffer exhaustion Previously, exhausting hardware buffers would begin blocking the lwip thread. This patch changes the emac layer to simply drop ethernet frames, leaving recovery up to a higher level protocol. This is consistent with the behaviour of the emac layer when unable to allocate dynamic memory. --- .../lwip-eth/arch/TARGET_Freescale/k64f_emac.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c index 66a0b587b02..0710450ffce 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c @@ -522,9 +522,10 @@ static err_t k64f_low_level_output(struct netif *netif, struct pbuf *p) dst += q->len; } - /* Wait until a descriptor is available for the transfer. */ - /* THIS WILL BLOCK UNTIL THERE ARE A DESCRIPTOR AVAILABLE */ - osSemaphoreWait(k64f_enet->xTXDCountSem.id, osWaitForever); + /* Check if a descriptor is available for the transfer. */ + int32_t count = osSemaphoreWait(k64f_enet->xTXDCountSem.id, 0); + if (count < 1) + return ERR_BUF; /* Get exclusive access */ sys_mutex_lock(&k64f_enet->TXLockMutex); From 0665a17e91cff7f5fb6d515f3438dc00404267e0 Mon Sep 17 00:00:00 2001 From: Anna Bridge Date: Mon, 17 Oct 2016 16:56:28 +0100 Subject: [PATCH 043/107] Make update.py test compile examples prior to updating mbed-os version. Changes: Refactor examples.py to add a new command line option to provide an update tag. Refactor examples.py to add new functionality to update the version of mbed-os in the examples to a supplied tag. Refactor examples.py to make cloning the example repos, updating their mbed-os version and compiling, into library functions and move to a new library module. Refactor the format of the examples.json file to make it compatible with both examples.py and update.py. Refactor update.py so that examples are test compiled prior to updating. Refactor update.py so that only examples tagged as auto-updatable and that fully compile are automatically updated. --- tools/test/examples/examples.json | 108 +++++++++- tools/test/examples/examples.py | 91 +++------ tools/test/examples/examples_lib.py | 210 ++++++++++++++++++++ tools/test/examples/update.py | 293 ++++++++++++++++++++++++++++ 4 files changed, 629 insertions(+), 73 deletions(-) create mode 100644 tools/test/examples/examples_lib.py create mode 100644 tools/test/examples/update.py diff --git a/tools/test/examples/examples.json b/tools/test/examples/examples.json index 0e7a99924eb..6c693d3984d 100644 --- a/tools/test/examples/examples.json +++ b/tools/test/examples/examples.json @@ -1,8 +1,102 @@ { - "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-blinky" : {}, - "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-mesh-minimal" : - {"features": ["IPV6"]}, - "https://github.com/ARMmbed/mbed-os-example-client" : {"features": ["IPV6"]}, - "https://github.com/ARMmbed/mbed-os-example-sockets" : {"features": ["IPV6"]}, - "https://github.com/ARMmbed/mbed-os-example-uvisor" : {"targets": ["K64F"], "toolchains":["GCC_ARM"]} -} + "examples": [ + { + "name": "mbed-os-example-blinky", + "github": "https://github.com/ARMmbed/mbed-os-example-blinky", + "mbed": [ + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-blinky" + ], + "features" : [], + "targets" : [], + "toolchains" : [], + "auto-update" : true + }, + { + "name": "mbed-os-example-tls", + "github": "https://github.com/ARMmbed/mbed-os-example-tls", + "mbed": [ + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-tls-benchmark", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-tls-tls-client", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-tls-hashing", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-tls-authcrypt" + ], + "features" : [], + "targets" : [], + "toolchains" : [], + "auto-update" : true + }, + { + "name": "mbed-os-example-mesh-minimal", + "github":"https://github.com/ARMmbed/mbed-os-example-mesh-minimal", + "mbed": [ + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-mesh-minimal" + ], + "features" : ["IPV6"], + "targets" : [], + "toolchains" : [], + "auto-update" : true + }, + { + "name": "mbed-os-example-ble", + "github":"https://github.com/ARMmbed/mbed-os-example-ble", + "mbed": [ + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-Beacon", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-HeartRate", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-URIBeacon", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-Thermometer", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-LEDBlinker", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-LED", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-GAPButton", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-EddystoneService", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-EddystoneObserver", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-Button", + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-BatteryLevel" + ], + "features" : ["BLE"], + "targets" : [], + "toolchains" : [], + "auto-update" : true + }, + { + "name": "mbed-os-example-client", + "github":"https://github.com/ARMmbed/mbed-os-example-client", + "mbed": [ + "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-client" + ], + "features" : ["IPV6"], + "targets" : [], + "toolchains" : [], + "auto-update" : true + }, + { + "name": "mbed-os-example-sockets", + "github":"https://github.com/ARMmbed/mbed-os-example-sockets", + "mbed": [ + ], + "features" : ["IPV6"], + "targets" : [], + "toolchains" : [], + "auto-update" : true + }, + { + "name": "mbed-os-example-wifi", + "github":"https://github.com/ARMmbed/mbed-os-example-wifi", + "mbed": [ + ], + "features" : [], + "targets" : [], + "toolchains" : [], + "auto-update" : true + }, + { + "name": "mbed-os-example-uvisor", + "github":"https://github.com/ARMmbed/mbed-os-example-uvisor", + "mbed": [ + ], + "features" : [], + "targets" : ["K64F"], + "toolchains" : ["GCC_ARM"], + "auto-update" : false + } + ] +} \ No newline at end of file diff --git a/tools/test/examples/examples.py b/tools/test/examples/examples.py index c06933f5bf5..fecadef4567 100644 --- a/tools/test/examples/examples.py +++ b/tools/test/examples/examples.py @@ -11,56 +11,21 @@ ROOT = abspath(dirname(dirname(dirname(dirname(__file__))))) sys.path.insert(0, ROOT) -from tools.build_api import get_mbed_official_release -from tools.targets import TARGET_MAP from tools.utils import argparse_force_uppercase_type - - -EXAMPLES = json.load(open(os.path.join(os.path.dirname(__file__), - "examples.json"))) - -def print_stuff(name, lst): - if lst: - print("#"*80) - print("# {} example combinations".format(name)) - print("#") - for thing in lst: - print(thing) - - -SUPPORTED_TOOLCHAINS = ["ARM", "IAR", "GCC_ARM"] - - -def target_cross_toolchain(allowed_toolchains, - features=[], targets=TARGET_MAP.keys(), - toolchains=SUPPORTED_TOOLCHAINS): - """Generate pairs of target and toolchains - - Args: - allowed_toolchains - a list of all possible toolchains - - Kwargs: - features - the features that must be in the features array of a - target - targets - a list of available targets - toolchains - a list of available toolchains - """ - for release_target, release_toolchains in get_mbed_official_release("5"): - for toolchain in release_toolchains: - if (toolchain in allowed_toolchains and - toolchain in toolchains and - release_target in targets and - all(feature in TARGET_MAP[release_target].features - for feature in features)): - yield release_target, toolchain +import examples_lib as lib +from examples_lib import SUPPORTED_TOOLCHAINS def main(): """Entry point""" parser = ArgumentParser() + parser.add_argument("-c", dest="config", default="examples.json") subparsers = parser.add_subparsers() import_cmd = subparsers.add_parser("import") import_cmd.set_defaults(fn=do_import) + version_cmd = subparsers.add_parser("tag") + version_cmd.add_argument("tag") + version_cmd.set_defaults(fn=do_versionning) compile_cmd = subparsers.add_parser("compile") compile_cmd.set_defaults(fn=do_compile) compile_cmd.add_argument( @@ -68,38 +33,32 @@ def main(): type=argparse_force_uppercase_type(SUPPORTED_TOOLCHAINS, "toolchain")) args = parser.parse_args() - return args.fn(args) + config = json.load(open(os.path.join(os.path.dirname(__file__), + args.config))) + return args.fn(args, config) -def do_import(_): + +def do_import(_, config): """Do the import step of this process""" - for example, _ in EXAMPLES.iteritems(): - subprocess.call(["mbed-cli", "import", example]) + lib.source_repos(config) return 0 - -def do_compile(args): +def do_compile(args, config): """Do the compile step""" - failures = [] - sucesses = [] - for example, requirements in EXAMPLES.iteritems(): - os.chdir(basename(example)) - for target, toolchain in target_cross_toolchain(args.toolchains, - **requirements): - proc = subprocess.Popen(["mbed-cli", "compile", "-t", toolchain, - "-m", target, "--silent"]) - proc.wait() - example_name = "{} {} {}".format(basename(example), target, - toolchain) - if proc.returncode: - failures.append(example_name) - else: - sucesses.append(example_name) - os.chdir("..") + results = {} + results = lib.compile_repos(config, args.toolchains) + + lib.print_compilation_summary(results) + failures = lib.get_num_failures(results) + print("Number of failures = %d" % failures) + return failures + +def do_versionning(args, config): + """ Test update the mbed-os to the version specified by the tag """ + lib.update_mbedos_version(config, args.tag) + return 0 - print_stuff("Passed", sucesses) - print_stuff("Failed", failures) - return len(failures) if __name__ == "__main__": sys.exit(main()) diff --git a/tools/test/examples/examples_lib.py b/tools/test/examples/examples_lib.py new file mode 100644 index 00000000000..c02d295d7c9 --- /dev/null +++ b/tools/test/examples/examples_lib.py @@ -0,0 +1,210 @@ +""" Import and bulid a bunch of example programs + + This library includes functions that are shared between the examples.py and + the update.py modules. + + """ +import os +from os.path import dirname, abspath, basename +import os.path +import sys +import subprocess + +ROOT = abspath(dirname(dirname(dirname(dirname(__file__))))) +sys.path.insert(0, ROOT) + +from tools.build_api import get_mbed_official_release +from tools.targets import TARGET_MAP + +SUPPORTED_TOOLCHAINS = ["ARM", "IAR", "GCC_ARM"] + +def print_list(lst): + """Prints to screen the contents of a list + + Args: + lst - a list of any type, to be displayed + + """ + if lst: + for thing in lst: + print("# %s" % thing) + +def print_compilation_summary(results): + """Prints to screen the results of compiling combinations of example programs, + targets and compile chains. + + Args: + results - results of the compilation stage. See compile_repos() for + details of the format. + + """ + + print("#"*80) + print("# Examples compilation summary") + print("#"*80) + print("#") + print("# Passed example combinations") + print("#") + for key, val in results.iteritems(): + print_list(val[1]) + + print("#") + print("# Failed example combinations") + print("#") + for key, val in results.iteritems(): + print_list(val[2]) + print("#") + print("#"*80) + + +def target_cross_toolchain(allowed_toolchains, + features=[], targets=[]): + """Generate pairs of target and toolchains + + Args: + allowed_toolchains - a list of all possible toolchains + + Kwargs: + features - the features that must be in the features array of a + target + targets - a list of available targets + """ + if len(targets) == 0: + targets=TARGET_MAP.keys() + + for target, toolchains in get_mbed_official_release("5"): + for toolchain in toolchains: + if (toolchain in allowed_toolchains and + target in targets and + all(feature in TARGET_MAP[target].features + for feature in features)): + yield target, toolchain + + +def get_repo_list(example): + """ Returns a list of all the repos associated with the specific example in the json + config file. + If there are repos listed under the mbed section then these will be returned as a + list. If not then the github single repo with be returned. + NOTE: This does not currently deal with multiple examples underneath a github + sourced exampe repo. + + Args: + example - Example for which the repo list is requested + repos - The list of repos contained within that example in the json file + + """ + repos = [] + if len(example['mbed']) > 0: + for repo in example['mbed']: + repos.append(repo) + else: + repos.append(example['github']) + return repos + +def source_repos(config): + """ Clones each of the repos associated with the specific examples name from the + json config file. Note if there is already a clone of the repo then it will first + be removed to ensure a clean, up to date cloning. + Args: + config - the json object imported from the file. + + """ + print("\nImporting example repos....\n") + for example in config['examples']: + for repo in get_repo_list(example): + name = basename(repo) + if os.path.exists(name): + print("'%s' example directory already exists. Deleting..." % name) + subprocess.call(['rm', '-rf', name]) + + subprocess.call(["mbed-cli", "import", repo]) + +def get_num_failures(results): + """ Returns the number of failed compilations from the results summary + Args: + results - results summary of the compilation stage. See compile_repos() for + details of the format. + num_failures + + """ + num_failures = 0 + + for key, val in results.iteritems(): + num_failures = num_failures + len(val[2]) + + return num_failures + +def compile_repos(config, toolchains): + """Compiles combinations of example programs, targets and compile chains. + + The results are returned in a [key: value] dictionary format: + Where key = The example name from the json config file + value = a list containing: pass_status, successes, and failures failures + + where pass_status = The overall pass status for the compilation of the full + set of example programs comprising the example suite. + True if all examples pass, false otherwise + successes = list of passing examples. + failures = list of failing examples. + + Both successes and failures contain the example name, target and compile chain + + Args: + config - the json object imported from the file. + toolchains - List of toolchains to compile for. + results - results of the compilation stage. + + """ + results = {} + print("\nCompiling example repos....\n") + for example in config['examples']: + failures = [] + successes = [] + if len(example['toolchains']) > 0: + toolchains = example['toolchains'] + + for repo in get_repo_list(example): + os.chdir(basename(repo)) + + # Check that the target, toolchain and features combinations are valid and return a + # list of valid combinations to work through + for target, toolchain in target_cross_toolchain(toolchains, + example['features'], example['targets']): + proc = subprocess.Popen(["mbed-cli", "compile", "-t", toolchain, + "-m", target, "--silent"]) + proc.wait() + example_summary = "{} {} {}".format(basename(repo), target, toolchain) + if proc.returncode: + failures.append(example_summary) + else: + successes.append(example_summary) + os.chdir("..") + pass_status = True + + # If there are any compilation failures for the example 'set' then the overall status is fail. + if len(failures) > 0: + pass_status = False + results[example['name']] = [pass_status, successes, failures] + return results + + +def update_mbedos_version(config, tag): + """ For each example repo identified in the config json object, update the version of + mbed-os to that specified by the supplied GitHub tag. This function assumes that each + example repo has already been cloned. + + Args: + config - the json object imported from the file. + tag - GitHub tag corresponding to a version of mbed-os to upgrade to. + + """ + print("Updating mbed-os in examples to version %s\n" % tag) + for example in config['examples']: + for repo in get_repo_list(example): + update_dir = basename(repo) + "/mbed-os" + print("\nChanging dir to %s\n" % update_dir) + os.chdir(update_dir) + subprocess.call(["mbed-cli", "update", tag, "--clean"]) + os.chdir("../..") + diff --git a/tools/test/examples/update.py b/tools/test/examples/update.py new file mode 100644 index 00000000000..32edbc46a60 --- /dev/null +++ b/tools/test/examples/update.py @@ -0,0 +1,293 @@ +#!/usr/bin/env python + +import os +from os.path import dirname, abspath, basename +import sys +import argparse +import json +import subprocess +import shutil +import stat + +ROOT = abspath(dirname(dirname(dirname(dirname(__file__))))) +sys.path.insert(0, ROOT) + +import examples_lib as lib +from examples_lib import SUPPORTED_TOOLCHAINS + +def run_cmd(command, print_warning_on_fail=True): + """ Takes the command specified and runs it in a sub-process, obtaining the return code. + + Args: + command - command to run, provided as a list of individual fields which are combined into a + single command before passing to the sub-process call. + return_code - result of the command. + + """ + print('[Exec] %s' % ' '.join(command)) + return_code = subprocess.call(command) + + if return_code: + print("The command '%s' failed with return code: %s" % (' '.join(command), return_code)) + print("Ignoring and moving on to the next example") + + return return_code + + +def rmtree_readonly(directory): + """ Deletes a readonly directory tree. + + Args: + directory - tree to delete + """ + def remove_readonly(func, path, _): + os.chmod(path, stat.S_IWRITE) + func(path) + + shutil.rmtree(directory, onerror=remove_readonly) + +def find_all_examples(path): + """ Searches the path specified for sub-example folders, ie those containing an + mbed-os.lib file. If found adds the path to the sub-example to a list which is + then returned. + + Args: + path - path to search. + examples - (returned) list of paths to example directories. + + """ + examples = [] + for root, dirs, files in os.walk(path): + for file in files: + if file == 'mbed-os.lib': + examples += [root] + + return examples + +def upgrade_single_example(example, tag, directory): + """ Updates the mbed-os.lib file in the example specified to correspond to the + version specified by the GitHub tag supplied. Also deals with + multiple sub-examples in the GitHub repo, updating them in the same way. + + Args: + example - json example object containing the GitHub repo to update. + tag - GitHub tag corresponding to a version of mbed-os to upgrade to. + directory - directory path for the example. + returns - True if the upgrade was successful, False otherwise. + + """ + print("Upgrading single example at path '%s'" % directory) + cwd = os.getcwd() + os.chdir(directory) + + return_code = None + + # Change directories to the mbed-os library + if not os.path.exists('mbed-os'): + print("'mbed-os' directory not found in the root of '%s'" % directory) + print("Ignoring and moving on to the next example") + os.chdir(cwd) + return False + + os.chdir('mbed-os') + + # Setup and run the update command + update_cmd = ['mbed', 'update', tag] + return_code = run_cmd(update_cmd) + + if return_code: + os.chdir(cwd) + return False + + os.chdir('../') + + # Setup and run the add command + add_cmd = ['git', 'add', 'mbed-os.lib'] + return_code = run_cmd(add_cmd) + + if return_code: + os.chdir(cwd) + return False + + os.chdir(cwd) + return True + +def upgrade_example(example, tag): + """ Clones the example specified from GitHub and updates the associated mbed-os.lib file + to correspond to the version specified by the GitHub tag supplied. Also deals with + multiple sub-examples in the GitHub repo, updating them in the same way. + + Args: + example - json example object containing the GitHub repo to update. + tag - GitHub tag corresponding to a version of mbed-os to upgrade to. + + """ + print("Updating example '%s'" % example['name']) + cwd = os.getcwd() + + # Setup and run the import command + clone_cmd = ['git', 'clone', example['github']] + return_code = run_cmd(clone_cmd) + + if return_code: + return False + + # Find all examples + example_directories = find_all_examples(example['name']) + + os.chdir(example['name']) + + # Setup and run the update command + import_cmd = ['mbed', 'update'] + return_code = run_cmd(import_cmd) + if return_code: + os.chdir(cwd) + return False + + for example_directory in example_directories: + if not upgrade_single_example(example, tag, os.path.relpath(example_directory, example['name'])): + os.chdir(cwd) + return False + + # Setup the default commit message + commit_message = 'Updating mbed-os to {{' + tag +'}}' + + # Setup and run the commit command + commit_cmd = ['git', 'commit', '-m', commit_message] + return_code = run_cmd(commit_cmd) + if return_code: + if return_code == 1: + print("[WARNING] 'git commit' exited with a return code of 1. " + \ + "This usually inidicates that no update was made. Still " + \ + "attempting to create a tag.") + else: + os.chdir(cwd) + return False + + # Setup and run the tag command + tag_cmd = ['git', 'tag', '-a', tag, '-m', tag] + return_code = run_cmd(tag_cmd) + if return_code: + os.chdir(cwd) + return False + + # Setup and run the push command + push_cmd = ['git', 'push', 'origin', 'master'] + return_code = run_cmd(push_cmd) + + if return_code: + os.chdir(cwd) + return False + + push_cmd = ['git', 'push', 'origin', tag] + return_code = run_cmd(push_cmd) + + if return_code: + os.chdir(cwd) + return False + + os.chdir(cwd) + return True + +def create_work_directory(path): + """ Create a new directory specified in 'path', overwrite if the directory already + exists. + + Args: + path - directory path to be created. + + """ + if os.path.exists(path): + print("'%s' directory already exists. Deleting..." % path) + rmtree_readonly(path) + + os.makedirs(path) + +def test_compile(config, tag): + """ For each example repo identified in the config json object, clone, update mbed-os to + the specified tag and then compile for all supported toolchains. + + Args: + config - the json object imported from the file. + tag - GitHub tag corresponding to a version of mbed-os to upgrade to. + results - summary of compilation results. + + """ + # Create work directories + create_work_directory('test_compile') + + # Loop through the examples + results = {} + os.chdir('test_compile') + + lib.source_repos(config) + lib.update_mbedos_version(config, tag) + results = lib.compile_repos(config, SUPPORTED_TOOLCHAINS) + os.chdir("..") + + return results + + +def main(arguments): + + parser = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument('tag', help="mbed-os tag to which all examples will be updated") + parser.add_argument('-c', '--config_file', help="Path to the configuration file (default is 'examples.json')", default='examples.json') + + args = parser.parse_args(arguments) + + cfg = os.path.join(os.path.dirname(__file__), args.config_file) + print cfg + + # Load the config file + config = json.load(open(os.path.join(os.path.dirname(__file__), + args.config_file))) + + if not config: + print("Failed to load config file '%s'" % args.config_file) + sys.exit(1) + + # Create work directories + create_work_directory('examples') + + # Loop through the examples + failures = [] + successes = [] + results = {} + os.chdir('examples') + + results = test_compile(config, args.tag) + lib.print_compilation_summary(results) + + for example in config['examples']: + # Determine if this example should be updated + + # Attempt to update if: + # group of examples passed compilation and + # auto update is set to True + if results[example['name']][0] and example['auto-update']: + if upgrade_example(example, args.tag): + successes += [example['name']] + else: + failures += [example['name']] + else: + failures += [example['name']] + + os.chdir('../') + + # Finish the script and report the results + print(os.linesep + os.linesep +'Finished updating examples!' + os.linesep) + + if successes: + print('The following examples updated successfully:') + for success in successes: + print(' - %s' % success) + + if failures: + print('\nThe following were not updated:') + for fail in failures: + print(' - %s' % fail) + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) \ No newline at end of file From 56c0a4d14888863bba35eaae3f3719e8e7df372c Mon Sep 17 00:00:00 2001 From: Anna Bridge Date: Tue, 18 Oct 2016 12:30:19 +0100 Subject: [PATCH 044/107] Review: Update example_lib.py to use rmtree rather than rm system call. Update examples.json to limit TLS examples to a couple of boards and only GCC_ARM and ARM compilers. --- tools/test/examples/examples.json | 4 ++-- tools/test/examples/examples_lib.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/test/examples/examples.json b/tools/test/examples/examples.json index 6c693d3984d..a7e085d0a3f 100644 --- a/tools/test/examples/examples.json +++ b/tools/test/examples/examples.json @@ -21,8 +21,8 @@ "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-tls-authcrypt" ], "features" : [], - "targets" : [], - "toolchains" : [], + "targets" : ["K64F", "NUCLEO_F429ZI"], + "toolchains" : ["GCC_ARM", "ARM"], "auto-update" : true }, { diff --git a/tools/test/examples/examples_lib.py b/tools/test/examples/examples_lib.py index c02d295d7c9..3de8ab1604b 100644 --- a/tools/test/examples/examples_lib.py +++ b/tools/test/examples/examples_lib.py @@ -9,6 +9,7 @@ import os.path import sys import subprocess +from shutil import rmtree ROOT = abspath(dirname(dirname(dirname(dirname(__file__))))) sys.path.insert(0, ROOT) @@ -116,7 +117,7 @@ def source_repos(config): name = basename(repo) if os.path.exists(name): print("'%s' example directory already exists. Deleting..." % name) - subprocess.call(['rm', '-rf', name]) + rmtree(name) subprocess.call(["mbed-cli", "import", repo]) From 1a1c41e40d4fa356a75e9c01c86d581b29d1d630 Mon Sep 17 00:00:00 2001 From: Anna Bridge Date: Tue, 25 Oct 2016 12:37:29 +0100 Subject: [PATCH 045/107] Minor review comments plus add new 'compile' option to examples json file. Adding the new compile option allows the marking of a set of examples to indicate whether they should be compiled or not. For the update process examples that are not compiled will not be auto updated irrespective of that setting. Other changes to make return logic from some functions in update.py more efficient and some typos in the lib file. --- tools/test/examples/examples.json | 8 ++++ tools/test/examples/examples_lib.py | 62 ++++++++++++++++------------- tools/test/examples/update.py | 43 ++++++++++---------- 3 files changed, 65 insertions(+), 48 deletions(-) diff --git a/tools/test/examples/examples.json b/tools/test/examples/examples.json index a7e085d0a3f..5bd1e081733 100644 --- a/tools/test/examples/examples.json +++ b/tools/test/examples/examples.json @@ -9,6 +9,7 @@ "features" : [], "targets" : [], "toolchains" : [], + "compile" : true, "auto-update" : true }, { @@ -23,6 +24,7 @@ "features" : [], "targets" : ["K64F", "NUCLEO_F429ZI"], "toolchains" : ["GCC_ARM", "ARM"], + "compile" : true, "auto-update" : true }, { @@ -34,6 +36,7 @@ "features" : ["IPV6"], "targets" : [], "toolchains" : [], + "compile" : true, "auto-update" : true }, { @@ -55,6 +58,7 @@ "features" : ["BLE"], "targets" : [], "toolchains" : [], + "compile" : true, "auto-update" : true }, { @@ -66,6 +70,7 @@ "features" : ["IPV6"], "targets" : [], "toolchains" : [], + "compile" : true, "auto-update" : true }, { @@ -76,6 +81,7 @@ "features" : ["IPV6"], "targets" : [], "toolchains" : [], + "compile" : true, "auto-update" : true }, { @@ -86,6 +92,7 @@ "features" : [], "targets" : [], "toolchains" : [], + "compile" : true, "auto-update" : true }, { @@ -96,6 +103,7 @@ "features" : [], "targets" : ["K64F"], "toolchains" : ["GCC_ARM"], + "compile" : true, "auto-update" : false } ] diff --git a/tools/test/examples/examples_lib.py b/tools/test/examples/examples_lib.py index 3de8ab1604b..ec34c416df9 100644 --- a/tools/test/examples/examples_lib.py +++ b/tools/test/examples/examples_lib.py @@ -47,13 +47,13 @@ def print_compilation_summary(results): print("# Passed example combinations") print("#") for key, val in results.iteritems(): - print_list(val[1]) + print_list(val[2]) print("#") print("# Failed example combinations") print("#") for key, val in results.iteritems(): - print_list(val[2]) + print_list(val[3]) print("#") print("#"*80) @@ -132,7 +132,7 @@ def get_num_failures(results): num_failures = 0 for key, val in results.iteritems(): - num_failures = num_failures + len(val[2]) + num_failures = num_failures + len(val[3]) return num_failures @@ -141,7 +141,7 @@ def compile_repos(config, toolchains): The results are returned in a [key: value] dictionary format: Where key = The example name from the json config file - value = a list containing: pass_status, successes, and failures failures + value = a list containing: pass_status, successes, and failures where pass_status = The overall pass status for the compilation of the full set of example programs comprising the example suite. @@ -162,31 +162,37 @@ def compile_repos(config, toolchains): for example in config['examples']: failures = [] successes = [] - if len(example['toolchains']) > 0: - toolchains = example['toolchains'] - - for repo in get_repo_list(example): - os.chdir(basename(repo)) - - # Check that the target, toolchain and features combinations are valid and return a - # list of valid combinations to work through - for target, toolchain in target_cross_toolchain(toolchains, - example['features'], example['targets']): - proc = subprocess.Popen(["mbed-cli", "compile", "-t", toolchain, - "-m", target, "--silent"]) - proc.wait() - example_summary = "{} {} {}".format(basename(repo), target, toolchain) - if proc.returncode: - failures.append(example_summary) - else: - successes.append(example_summary) - os.chdir("..") + compiled = True pass_status = True - - # If there are any compilation failures for the example 'set' then the overall status is fail. - if len(failures) > 0: - pass_status = False - results[example['name']] = [pass_status, successes, failures] + if example['compile']: + if len(example['toolchains']) > 0: + toolchains = example['toolchains'] + + for repo in get_repo_list(example): + os.chdir(basename(repo)) + + # Check that the target, toolchain and features combinations are valid and return a + # list of valid combinations to work through + for target, toolchain in target_cross_toolchain(toolchains, + example['features'], example['targets']): + proc = subprocess.Popen(["mbed-cli", "compile", "-t", toolchain, + "-m", target, "--silent"]) + proc.wait() + example_summary = "{} {} {}".format(basename(repo), target, toolchain) + if proc.returncode: + failures.append(example_summary) + else: + successes.append(example_summary) + os.chdir("..") + + # If there are any compilation failures for the example 'set' then the overall status is fail. + if len(failures) > 0: + pass_status = False + else: + compiled = False + + results[example['name']] = [compiled, pass_status, successes, failures] + return results diff --git a/tools/test/examples/update.py b/tools/test/examples/update.py index 32edbc46a60..8180b3e2b3b 100644 --- a/tools/test/examples/update.py +++ b/tools/test/examples/update.py @@ -58,9 +58,8 @@ def find_all_examples(path): """ examples = [] for root, dirs, files in os.walk(path): - for file in files: - if file == 'mbed-os.lib': - examples += [root] + if 'mbed-os.lib' in files: + examples += [root] return examples @@ -105,12 +104,8 @@ def upgrade_single_example(example, tag, directory): add_cmd = ['git', 'add', 'mbed-os.lib'] return_code = run_cmd(add_cmd) - if return_code: - os.chdir(cwd) - return False - os.chdir(cwd) - return True + return not return_code def upgrade_example(example, tag): """ Clones the example specified from GitHub and updates the associated mbed-os.lib file @@ -182,12 +177,8 @@ def upgrade_example(example, tag): push_cmd = ['git', 'push', 'origin', tag] return_code = run_cmd(push_cmd) - if return_code: - os.chdir(cwd) - return False - os.chdir(cwd) - return True + return not return_code def create_work_directory(path): """ Create a new directory specified in 'path', overwrite if the directory already @@ -254,6 +245,7 @@ def main(arguments): # Loop through the examples failures = [] successes = [] + not_compiled = [] results = {} os.chdir('examples') @@ -266,13 +258,18 @@ def main(arguments): # Attempt to update if: # group of examples passed compilation and # auto update is set to True - if results[example['name']][0] and example['auto-update']: - if upgrade_example(example, args.tag): - successes += [example['name']] - else: + # Note: results fields are [compiled flag, pass flag, successes list, failures list] + if not results[example['name']][0]: + # Example was not compiled + not_compiled += [example['name']] + else: + if results[example['name']][1] and example['auto-update']: + if upgrade_example(example, args.tag): + successes += [example['name']] + else: + failures += [example['name']] + else: failures += [example['name']] - else: - failures += [example['name']] os.chdir('../') @@ -285,9 +282,15 @@ def main(arguments): print(' - %s' % success) if failures: - print('\nThe following were not updated:') + print('\nThe following examples were not updated:') for fail in failures: print(' - %s' % fail) + if not_compiled: + print('The following examples were skipped:') + for example in not_compiled: + print(' - %s' % example) + + if __name__ == '__main__': sys.exit(main(sys.argv[1:])) \ No newline at end of file From 7801c50e427d7ee185bfeb9182d410d1a0bc72b6 Mon Sep 17 00:00:00 2001 From: Anna Bridge Date: Wed, 26 Oct 2016 16:24:42 +0100 Subject: [PATCH 046/107] Update ble example meta data to fix unsupported compilation combinations. Remove URI beacon example as this is no longer required. Add specific set of supported targets. --- tools/test/examples/examples.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/test/examples/examples.json b/tools/test/examples/examples.json index 5bd1e081733..251577724ed 100644 --- a/tools/test/examples/examples.json +++ b/tools/test/examples/examples.json @@ -45,7 +45,6 @@ "mbed": [ "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-Beacon", "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-HeartRate", - "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-URIBeacon", "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-Thermometer", "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-LEDBlinker", "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-LED", @@ -56,7 +55,7 @@ "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-BatteryLevel" ], "features" : ["BLE"], - "targets" : [], + "targets" : ["NRF51_DK", "NRF52_DK", "K64F", "NUCLEO_F401RE"], "toolchains" : [], "compile" : true, "auto-update" : true From dbe95cf298ff8519c78fd063450a7c52caf3dc9e Mon Sep 17 00:00:00 2001 From: Anna Bridge Date: Fri, 28 Oct 2016 15:20:36 +0100 Subject: [PATCH 047/107] Remove superfluous debugging line. --- tools/test/examples/update.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/test/examples/update.py b/tools/test/examples/update.py index 8180b3e2b3b..404e56e6f37 100644 --- a/tools/test/examples/update.py +++ b/tools/test/examples/update.py @@ -229,7 +229,6 @@ def main(arguments): args = parser.parse_args(arguments) cfg = os.path.join(os.path.dirname(__file__), args.config_file) - print cfg # Load the config file config = json.load(open(os.path.join(os.path.dirname(__file__), From 9d7049ed947b4e6970dd9cc0985c5435c7e35615 Mon Sep 17 00:00:00 2001 From: Anna Bridge Date: Fri, 28 Oct 2016 16:10:41 +0100 Subject: [PATCH 048/107] Switch off compilation of wifi example while awaiting a fix for issue 3152 is submitted. --- tools/test/examples/examples.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/test/examples/examples.json b/tools/test/examples/examples.json index 251577724ed..538017318a3 100644 --- a/tools/test/examples/examples.json +++ b/tools/test/examples/examples.json @@ -91,7 +91,7 @@ "features" : [], "targets" : [], "toolchains" : [], - "compile" : true, + "compile" : false, "auto-update" : true }, { From 7efae2ebc9bcf5754bbb0afbdc45bf84924bf748 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Fri, 28 Oct 2016 14:23:34 -0500 Subject: [PATCH 049/107] lwip/nsapi - Cleaned up warnings in network code - cc.h@57,1: "BYTE_ORDER" redefined - lwip_inet_chksum.c@560,44: passing argument 1 of 'thumb2_checksum' discards 'const' qualifier from pointer target type - lwip_pbuf.c@1172,9: variable 'err' set but not used - SocketAddress.cpp@293,1: control reaches end of non-void function --- features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/cc.h | 7 ++++++- .../FEATURE_LWIP/lwip-interface/lwip/src/core/lwip_pbuf.c | 1 + features/netsocket/SocketAddress.cpp | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/cc.h b/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/cc.h index dc0d7a9bf63..7cf88c3d0c5 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/cc.h +++ b/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/cc.h @@ -54,7 +54,12 @@ typedef uintptr_t mem_ptr_t; #define SZT_F "uz" /* ARM/LPC17xx is little endian only */ +#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) +#ifdef BYTE_ORDER +#undef BYTE_ORDER +#endif #define BYTE_ORDER LITTLE_ENDIAN +#endif /* Use LWIP error codes */ #define LWIP_PROVIDE_ERRNO @@ -92,7 +97,7 @@ typedef uintptr_t mem_ptr_t; #define LWIP_CHKSUM_ALGORITHM 0 void* thumb2_memcpy(void* pDest, const void* pSource, size_t length); - u16_t thumb2_checksum(void* pData, int length); + u16_t thumb2_checksum(const void* pData, int length); #else /* Used with IP headers only */ #define LWIP_CHKSUM_ALGORITHM 1 diff --git a/features/FEATURE_LWIP/lwip-interface/lwip/src/core/lwip_pbuf.c b/features/FEATURE_LWIP/lwip-interface/lwip/src/core/lwip_pbuf.c index 671397cd929..42853b5d368 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip/src/core/lwip_pbuf.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip/src/core/lwip_pbuf.c @@ -1179,6 +1179,7 @@ pbuf_coalesce(struct pbuf *p, pbuf_layer layer) return p; } err = pbuf_copy(q, p); + LWIP_UNUSED_ARG(err); LWIP_ASSERT("pbuf_copy failed", err == ERR_OK); pbuf_free(p); return q; diff --git a/features/netsocket/SocketAddress.cpp b/features/netsocket/SocketAddress.cpp index 7e457007406..c7a8c91e102 100644 --- a/features/netsocket/SocketAddress.cpp +++ b/features/netsocket/SocketAddress.cpp @@ -290,6 +290,8 @@ bool operator==(const SocketAddress &a, const SocketAddress &b) } else if (a._addr.version == NSAPI_IPv6) { return memcmp(a._addr.bytes, b._addr.bytes, NSAPI_IPv6_BYTES) == 0; } + + MBED_UNREACHABLE; } bool operator!=(const SocketAddress &a, const SocketAddress &b) From 7657db4be9d0af9d6d9a2169bfbec387c3e7ce63 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Fri, 28 Oct 2016 11:41:33 -0500 Subject: [PATCH 050/107] nsapi - Added better heuristic for the default record of DNS queries Takes advantage of the get_ip_address function to predict the IP address version wanted by the underlying interface. The should avoid the need for most IPv6 interfaces to overload gethostbyname. suggested by @kjbracey-arm --- features/netsocket/NetworkStack.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/features/netsocket/NetworkStack.cpp b/features/netsocket/NetworkStack.cpp index 44419905f48..d59f4a9aa73 100644 --- a/features/netsocket/NetworkStack.cpp +++ b/features/netsocket/NetworkStack.cpp @@ -33,6 +33,15 @@ int NetworkStack::gethostbyname(const char *name, SocketAddress *address, nsapi_ return 0; } + // if the version is unspecified, try to guess the version from the + // ip address of the underlying stack + if (version == NSAPI_UNSPEC) { + SocketAddress testaddress; + if (testaddress.set_ip_address(this->get_ip_address())) { + version = testaddress.get_ip_version(); + } + } + return nsapi_dns_query(this, name, address, version); } From 8194427fcbf2640b5721af31f2b0116c338b4a23 Mon Sep 17 00:00:00 2001 From: Sarah Marsh Date: Mon, 31 Oct 2016 18:01:58 -0500 Subject: [PATCH 051/107] Add a device_name to microbit entry in targets.json --- targets/targets.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/targets/targets.json b/targets/targets.json index b9d3395ece7..31a6912723d 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1616,7 +1616,8 @@ "NRF51_MICROBIT": { "inherits": ["MCU_NRF51_16K_S110"], "macros_add": ["TARGET_NRF_LFCLK_RC"], - "release_versions": ["2"] + "release_versions": ["2"], + "device_name": "nRF51822_xxAA" }, "NRF51_MICROBIT_BOOT": { "inherits": ["MCU_NRF51_16K_BOOT_S110"], From f6ced8690c33858edd58e619ab9c3b39f705a86b Mon Sep 17 00:00:00 2001 From: jeromecoutant Date: Wed, 19 Oct 2016 11:15:38 +0200 Subject: [PATCH 052/107] i2c_loop tests update for STM32 --- .../tests/mbed/i2c_master_slave/main.cpp | 78 +++++++++++++++---- .../mbed/i2c_master_slave_asynch/main.cpp | 34 ++++++-- tools/tests.py | 12 +-- 3 files changed, 94 insertions(+), 30 deletions(-) diff --git a/features/unsupported/tests/mbed/i2c_master_slave/main.cpp b/features/unsupported/tests/mbed/i2c_master_slave/main.cpp index b96da0e609b..820daf196a1 100644 --- a/features/unsupported/tests/mbed/i2c_master_slave/main.cpp +++ b/features/unsupported/tests/mbed/i2c_master_slave/main.cpp @@ -2,29 +2,79 @@ #include "test_env.h" #include +#if !DEVICE_I2C + #error [NOT_SUPPORTED] I2C is not supported +#endif + +#if !DEVICE_I2CSLAVE + #error [NOT_SUPPORTED] I2C Slave is not supported +#endif + +#if defined(TARGET_NUCLEO_F031K6) || \ + defined (TARGET_NUCLEO_L011K4) || \ + defined (TARGET_NUCLEO_L031K6) || \ + defined (TARGET_DISCO_F746NG) || \ + defined (TARGET_DISCO_L476VG) || \ + defined (TARGET_NUCLEO_F303K8) || \ + defined (TARGET_NUCLEO_F334R8) || \ + defined (TARGET_DISCO_F334C8) || \ + defined (TARGET_NUCLEO_F042K6) + #error [NOT_SUPPORTED] Target has only one I2C instance +#endif + #define ADDR (0xA0) #define FREQ 100000 // ******************************************************** // This tests data transfer between two I2C interfaces on // the same chip, one configured as master, the other as -// slave. Works on: -// -// *LPC1768 mbed -// p28 <-> p9 -// p27 <-> p10 -// pull-up resistors on both lines -// *STM32F4 boards -// cf below for wiring +// slave. // +// Wiring: connect master SCL to slave SCL, and master SDA to slave SDA // ******************************************************** -#if defined(TARGET_NUCLEO_F411RE) || defined (TARGET_NUCLEO_F446RE) || defined (TARGET_NUCLEO_F410RB) || defined (TARGET_NUCLEO_F401RE) -I2C master(PB_9, PB_8); // I2C_1 (Arduino: D14/D15) -I2CSlave slave(PB_3, PB_10); // I2C_2 (Arduino: D3/D6) -#elif defined (TARGET_NUCLEO_F429ZI) || defined (TARGET_DISCO_F429ZI) || defined (TARGET_NUCLEO_F446ZE) -I2C master(PB_9, PB_8); // I2C_1 (Arduino: D14/D15) -I2CSlave slave(PB_11, PB_10); // I2C_2 +#if defined (TARGET_DISCO_F429ZI) || \ + defined (TARGET_DISCO_L053C8) +I2C master(PB_9, PB_8); + +#elif defined(TARGET_FF_ARDUINO) +I2C master(D14, D15); // I2C_SDA, I2C_SCL +#endif + + +#if defined (TARGET_NUCLEO_F429ZI) || \ + defined (TARGET_NUCLEO_F767ZI) || \ + defined (TARGET_NUCLEO_L053R8) || \ + defined (TARGET_NUCLEO_L073RZ) || \ + defined (TARGET_NUCLEO_L152RE) || \ + defined (TARGET_NUCLEO_L476RG) || \ + defined (TARGET_NUCLEO_F207ZG) || \ + defined (TARGET_NUCLEO_F103RB) || \ + defined (TARGET_NUCLEO_F091RC) || \ + defined (TARGET_DISCO_F429ZI) || \ + defined (TARGET_DISCO_F469NI) || \ + defined (TARGET_DISCO_L053C8) || \ + defined (TARGET_NUCLEO_F446ZE) +I2CSlave slave(PB_11, PB_10); + +#elif defined (TARGET_NUCLEO_F303RE) || \ + defined (TARGET_NUCLEO_F302R8) +I2CSlave slave(D2, D8); + +#elif defined (TARGET_NUCLEO_F303ZE) +I2CSlave slave(PC_9, PA_8); + +#elif defined (TARGET_NUCLEO_F746ZG) +I2CSlave slave(D2, D4); + +#elif defined (TARGET_NUCLEO_F030R8) || \ + defined (TARGET_NUCLEO_F070RB) || \ + defined (TARGET_NUCLEO_F072RB) +I2CSlave slave(PB_11, D6); + +#else +I2CSlave slave(D3, D6); + #endif int main() diff --git a/features/unsupported/tests/mbed/i2c_master_slave_asynch/main.cpp b/features/unsupported/tests/mbed/i2c_master_slave_asynch/main.cpp index a8707064d10..1fc0bd59b7e 100644 --- a/features/unsupported/tests/mbed/i2c_master_slave_asynch/main.cpp +++ b/features/unsupported/tests/mbed/i2c_master_slave_asynch/main.cpp @@ -2,6 +2,18 @@ #include "test_env.h" #include +#if !DEVICE_I2C + #error [NOT_SUPPORTED] I2C is not supported +#endif + +#if !DEVICE_I2CSLAVE + #error [NOT_SUPPORTED] I2C Slave is not supported +#endif + +#if !DEVICE_I2C_ASYNCH + #error [NOT_SUPPORTED] I2C Async is not supported +#endif + #define ADDR (0x90) #define FREQ 100000 #define SIZE 10 @@ -11,15 +23,23 @@ // the same chip, one configured as master, the other as // slave. // -// Wiring: cf below +// Wiring: connect master SCL to slave SCL, and master SDA to slave SDA // ******************************************************** -#if defined (TARGET_NUCLEO_F411RE) || defined (TARGET_NUCLEO_F446RE) || defined (TARGET_NUCLEO_F410RB) || defined (TARGET_NUCLEO_F401RE) -I2C master(PB_9, PB_8); // I2C_1 (Arduino: D14/D15) -I2CSlave slave(PB_3, PB_10); // I2C_2 (Arduino: D3/D6) -#elif defined (TARGET_NUCLEO_F429ZI) || defined (TARGET_DISCO_F429ZI) || defined (TARGET_NUCLEO_F446ZE) -I2C master(PB_9, PB_8); // I2C_1 (Arduino: D14/D15) -I2CSlave slave(PB_11, PB_10); // I2C_2 +#if defined (TARGET_DISCO_F429ZI) +I2C master(PB_9, PB_8); +#elif defined(TARGET_FF_ARDUINO) +I2C master(D14, D15); // I2C_SDA, I2C_SCL +#endif + +#if defined (TARGET_NUCLEO_F429ZI) || \ + defined (TARGET_DISCO_F429ZI) || \ + defined (TARGET_NUCLEO_F446ZE) +I2CSlave slave(PB_11, PB_10); + +#else +I2CSlave slave(D3, D6); + #endif volatile int why; diff --git a/tools/tests.py b/tools/tests.py index 0c82bcf9369..7f9766ef55a 100644 --- a/tools/tests.py +++ b/tools/tests.py @@ -89,13 +89,8 @@ * i2c_loop: * LPC1768: (p28 <-> p9), (p27 <-> p10) - * NUCLEO_F401RE: (PB_9 <-> PB_3), (PB_8 <-> PB_10) - * NUCLEO_F410RB: (PB_9 <-> PB_3), (PB_8 <-> PB_10) - * NUCLEO_F411RE: (PB_9 <-> PB_3), (PB_8 <-> PB_10) - * NUCLEO_F446RE: (PB_9 <-> PB_3), (PB_8 <-> PB_10) - * NUCLEO_F429ZI: (PB_9 <-> PB_11), (PB_8 <-> PB_10) - * NUCLEO_F446ZE: (PB_9 <-> PB_11), (PB_8 <-> PB_10) - * DISCO_F429ZI: (PB_9 <-> PB_11), (PB_8 <-> PB_10) + * NUCLEO64: (D14 <-> D3), (D15 <-> D6) + * NUCLEO144: (D14 <-> PB_11), (D15 <-> PB_10) * i2c_eeprom: * LPC1*: (SDA=p28 , SCL=p27) @@ -271,7 +266,7 @@ "id": "MBED_A20", "description": "I2C master/slave test", "source_dir": join(TEST_DIR, "mbed", "i2c_master_slave"), "dependencies": [MBED_LIBRARIES, TEST_MBED_LIB,], - "mcu": ["LPC1768", "RZ_A1H", "NUCLEO_F411RE", "NUCLEO_F446RE", "NUCLEO_F429ZI", "DISCO_F429ZI", "NUCLEO_F446ZE", "NUCLEO_F410RB", "NUCLEO_F401RE"], + "automated": True, "peripherals": ["i2c_loop"] }, { @@ -346,7 +341,6 @@ "id": "MBED_A29", "description": "i2c_master_slave_asynch", "source_dir": join(TEST_DIR, "mbed", "i2c_master_slave_asynch"), "dependencies": [MBED_LIBRARIES, TEST_MBED_LIB], - "mcu": ["NUCLEO_F411RE", "NUCLEO_F446RE", "NUCLEO_F429ZI", "DISCO_F429ZI", "NUCLEO_F446ZE", "NUCLEO_F410RB", "NUCLEO_F401RE"], "automated": True, "peripherals": ["i2c_loop"] }, From efa90dedf098c07115c1ebbbe26bf2dae3f7aec6 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Thu, 6 Oct 2016 17:40:25 -0500 Subject: [PATCH 053/107] Allowing mbed_app.json files to be discovered for tests. Before, mbed_app.json files were explicitly ignored when building tests. This was mostly because you could have multiple mbed_app.json files in the tree (for instance, in test case folders) and the behavior would be undefined. Now the tools explicitly ensure that there aren't multiple mbed_app.json files in your source files. So auto discovery of mbed_app.json for testing is being reintroduced. --- docs/testing_mbed_OS_5.md | 4 +++- tools/test.py | 13 ++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/docs/testing_mbed_OS_5.md b/docs/testing_mbed_OS_5.md index f21565a913e..d119f745bca 100644 --- a/docs/testing_mbed_OS_5.md +++ b/docs/testing_mbed_OS_5.md @@ -78,7 +78,9 @@ The full build process is: When building an mbed application, the presence of a `mbed_app.json` file allows you to set or override different config settings from libraries and targets. However, because the tests share a common build, this can cause issues when tests have different configurations that affect the OS. -If you need to use app config, this must be set via the `--app-config` option when calling `mbed test`. **If this option is not specified, the build system will ignore all `mbed_app.json` files and use the default config values.** +The build system will look for an `mbed_app.json` file in your shared project files (any directory not inside of a `TESTS` folder). If this is found, this configuration file will be used for both the non-test code as well as each test case inside your project's source tree. If there is more than one `mbed_app.json` files in the source tree, the config system will error. + +If you need to test with multiple configurations, then you can use the `--app-config` option. This will override the search for an `mbed_app.json` file and use the config file you specify for the build. ### Running tests diff --git a/tools/test.py b/tools/test.py index 9e520d59b29..ec153d499a2 100644 --- a/tools/test.py +++ b/tools/test.py @@ -26,6 +26,7 @@ ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) sys.path.insert(0, ROOT) +from tools.config import ConfigException from tools.test_api import test_path_to_name, find_tests, print_tests, build_tests, test_spec_from_test_builds from tools.options import get_default_options_parser, extract_profile from tools.build_api import build_project, build_library @@ -121,15 +122,6 @@ "Currently set search path: %s" % (toolchain, search_path)) - # App config - # Disable finding `mbed_app.json` files in the source tree if not - # explicitly defined on the command line. Config system searches for - # `mbed_app.json` files if `app_config` is None, but will set the - # app config data to an empty dictionary if the path value is another - # falsey value besides None. - if options.app_config is None: - options.app_config = '' - # Find all tests in the relevant paths for path in all_paths: all_tests.update(find_tests(path, mcu, toolchain, @@ -261,6 +253,9 @@ except KeyboardInterrupt, e: print "\n[CTRL+c] exit" + except ConfigException, e: + # Catching ConfigException here to prevent a traceback + print "[ERROR] %s" % str(e) except Exception,e: import traceback traceback.print_exc(file=sys.stdout) From c268f978848ff85c5cb12fe78b4a2a6030bc2f90 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 10 Oct 2016 14:00:29 +0200 Subject: [PATCH 054/107] nRF52 - switch irq priorities of driver handlers to level (APP_IRQ_PRIORITY_LOWEST) 7. This is fix for bad settings inherited from nRF5 SDK. It might caused eroneus behavior when nrf_drv API were called form irq context etc. --- .../TARGET_MCU_NRF52832/analogin_api.c | 2 +- .../TARGET_MCU_NRF52832/pwmout_api.c | 2 +- .../TARGET_MCU_NRF52832/sdk/nrf_drv_config.h | 60 +++++++++---------- targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c | 9 ++- .../sdk/drivers_nrf/common/nrf_drv_common.c | 6 +- .../TARGET_NRF5/sdk/libraries/pwm/app_pwm.c | 4 ++ .../TARGET_NRF5/sdk/libraries/util/nrf_log.c | 6 +- .../TARGET_NORDIC/TARGET_NRF5/serial_api.c | 8 ++- targets/TARGET_NORDIC/TARGET_NRF5/spi_api.c | 4 +- targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c | 8 ++- 10 files changed, 69 insertions(+), 40 deletions(-) diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/analogin_api.c b/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/analogin_api.c index e730241c079..d33effecdf2 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/analogin_api.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/analogin_api.c @@ -35,7 +35,7 @@ static const nrf_drv_saadc_config_t saadc_config = { .resolution = NRF_SAADC_RESOLUTION_12BIT, .oversample = NRF_SAADC_OVERSAMPLE_DISABLED, - .interrupt_priority = APP_IRQ_PRIORITY_LOW + .interrupt_priority = SAADC_CONFIG_IRQ_PRIORITY }; void SAADC_IRQHandler(void); diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/pwmout_api.c b/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/pwmout_api.c index 095b5dd9435..97e29f256db 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/pwmout_api.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/pwmout_api.c @@ -369,7 +369,7 @@ static void internal_pwmout_exe(pwmout_t *obj, bool new_period, bool initializat NRF_DRV_PWM_PIN_NOT_USED, // channel 2 NRF_DRV_PWM_PIN_NOT_USED, // channel 3 }, - .irq_priority = APP_IRQ_PRIORITY_LOW, + .irq_priority = PWM0_CONFIG_IRQ_PRIORITY, .base_clock = pulsewidth_set.pwm_clk, .count_mode = NRF_PWM_MODE_UP, .top_value = pulsewidth_set.period_hwu, diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/sdk/nrf_drv_config.h b/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/sdk/nrf_drv_config.h index 127ef3dbdb8..4443e68e642 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/sdk/nrf_drv_config.h +++ b/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/sdk/nrf_drv_config.h @@ -59,7 +59,7 @@ #if (CLOCK_ENABLED == 1) #define CLOCK_CONFIG_XTAL_FREQ NRF_CLOCK_XTALFREQ_Default #define CLOCK_CONFIG_LF_SRC NRF_CLOCK_LFCLK_Xtal -#define CLOCK_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define CLOCK_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #endif /* GPIOTE */ @@ -67,7 +67,7 @@ #if (GPIOTE_ENABLED == 1) #define GPIOTE_CONFIG_USE_SWI_EGU false -#define GPIOTE_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define GPIOTE_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 8 #endif @@ -82,7 +82,7 @@ #define TIMER0_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz #define TIMER0_CONFIG_MODE TIMER_MODE_MODE_Timer #define TIMER0_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_32Bit -#define TIMER0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define TIMER0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define TIMER0_INSTANCE_INDEX 0 #endif @@ -93,7 +93,7 @@ #define TIMER1_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz #define TIMER1_CONFIG_MODE TIMER_MODE_MODE_Timer #define TIMER1_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit -#define TIMER1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define TIMER1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define TIMER1_INSTANCE_INDEX (TIMER0_ENABLED) #endif @@ -104,7 +104,7 @@ #define TIMER2_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz #define TIMER2_CONFIG_MODE TIMER_MODE_MODE_Timer #define TIMER2_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit -#define TIMER2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define TIMER2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define TIMER2_INSTANCE_INDEX (TIMER1_ENABLED+TIMER0_ENABLED) #endif @@ -115,7 +115,7 @@ #define TIMER3_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz #define TIMER3_CONFIG_MODE TIMER_MODE_MODE_Timer #define TIMER3_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit -#define TIMER3_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define TIMER3_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define TIMER3_INSTANCE_INDEX (TIMER2_ENABLED+TIMER1_ENABLED+TIMER0_ENABLED) #endif @@ -126,7 +126,7 @@ #define TIMER4_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz #define TIMER4_CONFIG_MODE TIMER_MODE_MODE_Timer #define TIMER4_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit -#define TIMER4_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define TIMER4_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define TIMER4_INSTANCE_INDEX (TIMER3_ENABLED+TIMER2_ENABLED+TIMER1_ENABLED+TIMER0_ENABLED) #endif @@ -139,7 +139,7 @@ #if (RTC0_ENABLED == 1) #define RTC0_CONFIG_FREQUENCY 32678 -#define RTC0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define RTC0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define RTC0_CONFIG_RELIABLE false #define RTC0_INSTANCE_INDEX 0 @@ -149,7 +149,7 @@ #if (RTC1_ENABLED == 1) #define RTC1_CONFIG_FREQUENCY 32768 -#define RTC1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define RTC1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define RTC1_CONFIG_RELIABLE false #define RTC1_INSTANCE_INDEX (RTC0_ENABLED) @@ -159,7 +159,7 @@ #if (RTC2_ENABLED == 1) #define RTC2_CONFIG_FREQUENCY 32768 -#define RTC2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define RTC2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define RTC2_CONFIG_RELIABLE false #define RTC2_INSTANCE_INDEX (RTC0_ENABLED+RTC1_ENABLED) @@ -176,7 +176,7 @@ #if (RNG_ENABLED == 1) #define RNG_CONFIG_ERROR_CORRECTION true #define RNG_CONFIG_POOL_SIZE 8 -#define RNG_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define RNG_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #endif /* PWM */ @@ -188,7 +188,7 @@ #define PWM0_CONFIG_OUT1_PIN 3 #define PWM0_CONFIG_OUT2_PIN 4 #define PWM0_CONFIG_OUT3_PIN 5 -#define PWM0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define PWM0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define PWM0_CONFIG_BASE_CLOCK NRF_PWM_CLK_1MHz #define PWM0_CONFIG_COUNT_MODE NRF_PWM_MODE_UP #define PWM0_CONFIG_TOP_VALUE 1000 @@ -205,7 +205,7 @@ #define PWM1_CONFIG_OUT1_PIN 3 #define PWM1_CONFIG_OUT2_PIN 4 #define PWM1_CONFIG_OUT3_PIN 5 -#define PWM1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define PWM1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define PWM1_CONFIG_BASE_CLOCK NRF_PWM_CLK_1MHz #define PWM1_CONFIG_COUNT_MODE NRF_PWM_MODE_UP #define PWM1_CONFIG_TOP_VALUE 1000 @@ -222,7 +222,7 @@ #define PWM2_CONFIG_OUT1_PIN 3 #define PWM2_CONFIG_OUT2_PIN 4 #define PWM2_CONFIG_OUT3_PIN 5 -#define PWM2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define PWM2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define PWM2_CONFIG_BASE_CLOCK NRF_PWM_CLK_1MHz #define PWM2_CONFIG_COUNT_MODE NRF_PWM_MODE_UP #define PWM2_CONFIG_TOP_VALUE 1000 @@ -243,7 +243,7 @@ #define SPI0_CONFIG_SCK_PIN 2 #define SPI0_CONFIG_MOSI_PIN 3 #define SPI0_CONFIG_MISO_PIN 4 -#define SPI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define SPI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define SPI0_INSTANCE_INDEX 0 #endif @@ -256,7 +256,7 @@ #define SPI1_CONFIG_SCK_PIN 2 #define SPI1_CONFIG_MOSI_PIN 3 #define SPI1_CONFIG_MISO_PIN 4 -#define SPI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define SPI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define SPI1_INSTANCE_INDEX (SPI0_ENABLED) #endif @@ -269,7 +269,7 @@ #define SPI2_CONFIG_SCK_PIN 2 #define SPI2_CONFIG_MOSI_PIN 3 #define SPI2_CONFIG_MISO_PIN 4 -#define SPI2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define SPI2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define SPI2_INSTANCE_INDEX (SPI0_ENABLED + SPI1_ENABLED) #endif @@ -283,7 +283,7 @@ #define SPIS0_CONFIG_SCK_PIN 2 #define SPIS0_CONFIG_MOSI_PIN 3 #define SPIS0_CONFIG_MISO_PIN 4 -#define SPIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define SPIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define SPIS0_INSTANCE_INDEX 0 #endif @@ -294,7 +294,7 @@ #define SPIS1_CONFIG_SCK_PIN 2 #define SPIS1_CONFIG_MOSI_PIN 3 #define SPIS1_CONFIG_MISO_PIN 4 -#define SPIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define SPIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define SPIS1_INSTANCE_INDEX SPIS0_ENABLED #endif @@ -305,7 +305,7 @@ #define SPIS2_CONFIG_SCK_PIN 2 #define SPIS2_CONFIG_MOSI_PIN 3 #define SPIS2_CONFIG_MISO_PIN 4 -#define SPIS2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define SPIS2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define SPIS2_INSTANCE_INDEX (SPIS0_ENABLED + SPIS1_ENABLED) #endif @@ -340,7 +340,7 @@ #define TWI0_CONFIG_FREQUENCY NRF_TWI_FREQ_100K #define TWI0_CONFIG_SCL 0 #define TWI0_CONFIG_SDA 1 -#define TWI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define TWI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define TWI0_INSTANCE_INDEX 0 #endif @@ -353,7 +353,7 @@ #define TWI1_CONFIG_FREQUENCY NRF_TWI_FREQ_100K #define TWI1_CONFIG_SCL 0 #define TWI1_CONFIG_SDA 1 -#define TWI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define TWI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define TWI1_INSTANCE_INDEX (TWI0_ENABLED) #endif @@ -368,7 +368,7 @@ #define TWIS0_CONFIG_ADDR1 0 /* 0: Disabled */ #define TWIS0_CONFIG_SCL 0 #define TWIS0_CONFIG_SDA 1 - #define TWIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + #define TWIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define TWIS0_INSTANCE_INDEX 0 #endif @@ -380,7 +380,7 @@ #define TWIS1_CONFIG_ADDR1 0 /* 0: Disabled */ #define TWIS1_CONFIG_SCL 0 #define TWIS1_CONFIG_SDA 1 - #define TWIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + #define TWIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define TWIS1_INSTANCE_INDEX (TWIS0_ENABLED) #endif @@ -402,7 +402,7 @@ #define QDEC_CONFIG_PIO_LED 3 #define QDEC_CONFIG_LEDPRE 511 #define QDEC_CONFIG_LEDPOL NRF_QDEC_LEPOL_ACTIVE_HIGH -#define QDEC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define QDEC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define QDEC_CONFIG_DBFEN false #define QDEC_CONFIG_SAMPLE_INTEN false #endif @@ -411,7 +411,7 @@ #define ADC_ENABLED 0 #if (ADC_ENABLED == 1) -#define ADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define ADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #endif @@ -421,7 +421,7 @@ #if (SAADC_ENABLED == 1) #define SAADC_CONFIG_RESOLUTION NRF_SAADC_RESOLUTION_10BIT #define SAADC_CONFIG_OVERSAMPLE NRF_SAADC_OVERSAMPLE_DISABLED -#define SAADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define SAADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #endif /* PDM */ @@ -431,7 +431,7 @@ #define PDM_CONFIG_MODE NRF_PDM_MODE_MONO #define PDM_CONFIG_EDGE NRF_PDM_EDGE_LEFTFALLING #define PDM_CONFIG_CLOCK_FREQ NRF_PDM_FREQ_1032K -#define PDM_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define PDM_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #endif /* COMP */ @@ -443,7 +443,7 @@ #define COMP_CONFIG_SPEED_MODE NRF_COMP_SP_MODE_High #define COMP_CONFIG_HYST NRF_COMP_HYST_NoHyst #define COMP_CONFIG_ISOURCE NRF_COMP_ISOURCE_Off -#define COMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define COMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define COMP_CONFIG_INPUT NRF_COMP_INPUT_0 #endif @@ -453,7 +453,7 @@ #if (LPCOMP_ENABLED == 1) #define LPCOMP_CONFIG_REFERENCE NRF_LPCOMP_REF_SUPPLY_4_8 #define LPCOMP_CONFIG_DETECTION NRF_LPCOMP_DETECT_DOWN -#define LPCOMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define LPCOMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST #define LPCOMP_CONFIG_INPUT NRF_LPCOMP_INPUT_0 #endif diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c b/targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c index 0c6d28ca33b..548aeebe9da 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c @@ -143,8 +143,13 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) nrf_drv_twi_config_t const config = { .scl = scl, .sda = sda, - .frequency = NRF_TWI_FREQ_100K, - .interrupt_priority = APP_IRQ_PRIORITY_LOW, + .frequency = NRF_TWI_FREQ_100K, +#ifdef NRF51 + .interrupt_priority = APP_IRQ_PRIORITY_LOW +#elif defined(NRF52) + .interrupt_priority = APP_IRQ_PRIORITY_LOWEST +#endif + }; for (i = 0; i < TWI_COUNT; ++i) { diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/common/nrf_drv_common.c b/targets/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/common/nrf_drv_common.c index 43efd35e30f..2150af05696 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/common/nrf_drv_common.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/common/nrf_drv_common.c @@ -226,7 +226,11 @@ void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority) { #ifdef SOFTDEVICE_PRESENT - ASSERT((priority == APP_IRQ_PRIORITY_LOW) || (priority == APP_IRQ_PRIORITY_HIGH)); + #ifdef NRF51 + ASSERT((priority == APP_IRQ_PRIORITY_LOW) || (priority == APP_IRQ_PRIORITY_HIGH)); + #elif defined(NRF52) + ASSERT((priority == APP_IRQ_PRIORITY_LOWEST) || (priority == APP_IRQ_PRIORITY_HIGH)); + #endif #endif NVIC_SetPriority(IRQn, priority); diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/sdk/libraries/pwm/app_pwm.c b/targets/TARGET_NORDIC/TARGET_NRF5/sdk/libraries/pwm/app_pwm.c index 760b410f20a..0a090efc65e 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/sdk/libraries/pwm/app_pwm.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/sdk/libraries/pwm/app_pwm.c @@ -789,7 +789,11 @@ ret_code_t app_pwm_init(app_pwm_t const * const p_instance, app_pwm_config_t con .frequency = timer_freq, .mode = NRF_TIMER_MODE_TIMER, .bit_width = NRF_TIMER_BIT_WIDTH_16, +#ifdef NRF51 .interrupt_priority = APP_IRQ_PRIORITY_LOW, +#elif defined(NRF52) + .interrupt_priority = APP_IRQ_PRIORITY_LOWEST, +#endif .p_context = (void *) (uint32_t) p_instance->p_timer->instance_id }; err_code = nrf_drv_timer_init(p_instance->p_timer, &timer_cfg, diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/sdk/libraries/util/nrf_log.c b/targets/TARGET_NORDIC/TARGET_NRF5/sdk/libraries/util/nrf_log.c index e3d16003879..3c26bf540e2 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/sdk/libraries/util/nrf_log.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/sdk/libraries/util/nrf_log.c @@ -181,7 +181,11 @@ uint32_t log_uart_init() UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_error_cb, - APP_IRQ_PRIORITY_LOW, +#ifdef NRF51 + APP_IRQ_PRIORITY_LOW +#elif defined(NRF52) + APP_IRQ_PRIORITY_LOWEST +#endif err_code); initialized = true; diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/serial_api.c b/targets/TARGET_NORDIC/TARGET_NRF5/serial_api.c index 5af3bccd3c6..c52fac72c31 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/serial_api.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/serial_api.c @@ -74,6 +74,12 @@ #define UART_DEFAULT_CTS UART0_CONFIG_PSEL_CTS #define UART_DEFAULT_RTS UART0_CONFIG_PSEL_RTS +#ifdef NRF51 + #define NRFx_MBED_UART_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#elif defined(NRF52) + #define NRFx_MBED_UART_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST +#endif + // Required by "retarget.cpp". int stdio_uart_inited = 0; serial_t stdio_uart; @@ -294,7 +300,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) { #if DEVICE_SERIAL_ASYNCH nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_ERROR); #endif - nrf_drv_common_irq_enable(UART_IRQn, APP_IRQ_PRIORITY_LOW); + nrf_drv_common_irq_enable(UART_IRQn, NRFx_MBED_UART_IRQ_PRIORITY); // TX interrupt needs to be signaled when transmitter buffer is empty, // so a dummy transmission is needed to get the TXDRDY event initially diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/spi_api.c b/targets/TARGET_NORDIC/TARGET_NRF5/spi_api.c index bd8aea839e2..985d24fcc6b 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/spi_api.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/spi_api.c @@ -228,7 +228,7 @@ static void prepare_master_config(nrf_drv_spi_config_t *p_config, p_config->frequency = p_spi_info->frequency; p_config->mode = (nrf_drv_spi_mode_t)p_spi_info->spi_mode; - p_config->irq_priority = APP_IRQ_PRIORITY_LOW; + p_config->irq_priority = SPI1_CONFIG_IRQ_PRIORITY; p_config->orc = 0xFF; p_config->bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST; } @@ -242,7 +242,7 @@ static void prepare_slave_config(nrf_drv_spis_config_t *p_config, p_config->csn_pin = p_spi_info->ss_pin; p_config->mode = (nrf_drv_spis_mode_t)p_spi_info->spi_mode; - p_config->irq_priority = APP_IRQ_PRIORITY_LOW; + p_config->irq_priority = SPIS1_CONFIG_IRQ_PRIORITY; p_config->orc = NRF_DRV_SPIS_DEFAULT_ORC; p_config->def = NRF_DRV_SPIS_DEFAULT_DEF; p_config->bit_order = NRF_DRV_SPIS_BIT_ORDER_MSB_FIRST; diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c b/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c index e1c028e3ab4..f4e9911569c 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c @@ -40,6 +40,7 @@ #include "common_rtc.h" #include "app_util.h" #include "nrf_drv_common.h" +#include "nrf_drv_config.h" #include "lp_ticker_api.h" @@ -132,7 +133,12 @@ void common_rtc_init(void) US_TICKER_INT_MASK); nrf_drv_common_irq_enable(nrf_drv_get_IRQn(COMMON_RTC_INSTANCE), - APP_IRQ_PRIORITY_LOW); +#ifdef NRF51 + APP_IRQ_PRIORITY_LOW +#elif defined(NRF52) + APP_IRQ_PRIORITY_LOWEST +#endif + ); nrf_rtc_task_trigger(COMMON_RTC_INSTANCE, NRF_RTC_TASK_START); From 9e25e1e07f75ddcb0afbced9172ab859b1f9f688 Mon Sep 17 00:00:00 2001 From: Colin Hogben Date: Mon, 3 Oct 2016 22:48:03 +0100 Subject: [PATCH 055/107] lwip: Allow several configuration macros to be set externally. Manually rebasing after the monster restructuring. --- features/FEATURE_LWIP/lwip-interface/lwipopts.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/features/FEATURE_LWIP/lwip-interface/lwipopts.h b/features/FEATURE_LWIP/lwip-interface/lwipopts.h index 48cb655b485..dc6f240d088 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwipopts.h +++ b/features/FEATURE_LWIP/lwip-interface/lwipopts.h @@ -105,12 +105,27 @@ #define LWIP_RAM_HEAP_POINTER lwip_ram_heap +#ifndef PBUF_POOL_SIZE #define PBUF_POOL_SIZE 5 +#endif +#ifndef MEMP_NUM_TCP_PCB_LISTEN #define MEMP_NUM_TCP_PCB_LISTEN 4 +#endif +#ifndef MEMP_NUM_TCP_PCB #define MEMP_NUM_TCP_PCB 4 +#endif +#ifndef MEMP_NUM_UDP_PCB #define MEMP_NUM_UDP_PCB 4 +#endif +#ifndef MEMP_NUM_PBUF #define MEMP_NUM_PBUF 8 +#endif +#ifndef MEMP_NUM_NETBUF #define MEMP_NUM_NETBUF 8 +#endif +#ifndef MEMP_NUM_NETCONN +#define MEMP_NUM_NETCONN 4 +#endif #define TCP_QUEUE_OOSEQ 0 #define TCP_OVERSIZE 0 From 3eefc86cceac9d5c0f37d5ede2f71db044329a1e Mon Sep 17 00:00:00 2001 From: Colin Hogben Date: Wed, 5 Oct 2016 16:28:29 +0100 Subject: [PATCH 056/107] lwip: Annotate with memory used by config parameters --- features/FEATURE_LWIP/lwip-interface/lwipopts.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/features/FEATURE_LWIP/lwip-interface/lwipopts.h b/features/FEATURE_LWIP/lwip-interface/lwipopts.h index dc6f240d088..ca5afcdd938 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwipopts.h +++ b/features/FEATURE_LWIP/lwip-interface/lwipopts.h @@ -106,24 +106,35 @@ #define LWIP_RAM_HEAP_POINTER lwip_ram_heap #ifndef PBUF_POOL_SIZE +/// Each requires 684 bytes of RAM. #define PBUF_POOL_SIZE 5 #endif #ifndef MEMP_NUM_TCP_PCB_LISTEN +/// One is needed for each TCPServer. +/// Each requires 72 bytes of RAM. #define MEMP_NUM_TCP_PCB_LISTEN 4 #endif #ifndef MEMP_NUM_TCP_PCB +/// One is needed for each TCPSocket. +/// Each requires 196 bytes of RAM. #define MEMP_NUM_TCP_PCB 4 #endif #ifndef MEMP_NUM_UDP_PCB +/// One is needed for each UDPSocket. +/// Each requires 84 bytes of RAM (rounded to multiple of 512). #define MEMP_NUM_UDP_PCB 4 #endif #ifndef MEMP_NUM_PBUF +/// Each requires 92 bytes of RAM. #define MEMP_NUM_PBUF 8 #endif #ifndef MEMP_NUM_NETBUF +/// Each requires 64 bytes of RAM. #define MEMP_NUM_NETBUF 8 #endif #ifndef MEMP_NUM_NETCONN +/// One netconn is needed for each UDPSocket, TCPSocket or TCPServer. +/// Each requires 236 bytes of RAM (rounded to multiple of 512). #define MEMP_NUM_NETCONN 4 #endif From d484d573abe584d43f549f50f31f013028f450fc Mon Sep 17 00:00:00 2001 From: Colin Hogben Date: Wed, 19 Oct 2016 21:37:52 +0100 Subject: [PATCH 057/107] lwip: Expose principal socket limits as configuration parameters. Allow the limits on numbers of sockets to be changed via the configuration system. The help texts show the RAM penalty from increasing each value. --- .../FEATURE_LWIP/lwip-interface/lwipopts.h | 46 +++++++++++++------ .../FEATURE_LWIP/lwip-interface/mbed_lib.json | 16 +++++++ 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/features/FEATURE_LWIP/lwip-interface/lwipopts.h b/features/FEATURE_LWIP/lwip-interface/lwipopts.h index ca5afcdd938..54e92eaa051 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwipopts.h +++ b/features/FEATURE_LWIP/lwip-interface/lwipopts.h @@ -105,36 +105,52 @@ #define LWIP_RAM_HEAP_POINTER lwip_ram_heap +// Number of pool pbufs. +// Each requires 684 bytes of RAM. #ifndef PBUF_POOL_SIZE -/// Each requires 684 bytes of RAM. #define PBUF_POOL_SIZE 5 #endif -#ifndef MEMP_NUM_TCP_PCB_LISTEN -/// One is needed for each TCPServer. -/// Each requires 72 bytes of RAM. + +// One tcp_pcb_listen is needed for each TCPServer. +// Each requires 72 bytes of RAM. +#ifdef MBED_CONF_LWIP_TCP_SERVER_MAX +#define MEMP_NUM_TCP_PCB_LISTEN MBED_CONF_LWIP_TCP_SERVER_MAX +#else #define MEMP_NUM_TCP_PCB_LISTEN 4 #endif -#ifndef MEMP_NUM_TCP_PCB -/// One is needed for each TCPSocket. -/// Each requires 196 bytes of RAM. + +// One is tcp_pcb needed for each TCPSocket. +// Each requires 196 bytes of RAM. +#ifdef MBED_CONF_LWIP_TCP_SOCKET_MAX +#define MEMP_NUM_TCP_PCB MBED_CONF_LWIP_TCP_SOCKET_MAX +#else #define MEMP_NUM_TCP_PCB 4 #endif -#ifndef MEMP_NUM_UDP_PCB -/// One is needed for each UDPSocket. -/// Each requires 84 bytes of RAM (rounded to multiple of 512). + +// One udp_pcb is needed for each UDPSocket. +// Each requires 84 bytes of RAM (total rounded to multiple of 512). +#ifdef MBED_CONF_LWIP_UDP_SOCKET_MAX +#define MEMP_NUM_UDP_PCB MBED_CONF_LWIP_UDP_SOCKET_MAX +#else #define MEMP_NUM_UDP_PCB 4 #endif + +// Number of non-pool pbufs. +// Each requires 92 bytes of RAM. #ifndef MEMP_NUM_PBUF -/// Each requires 92 bytes of RAM. #define MEMP_NUM_PBUF 8 #endif + +// Each netbuf requires 64 bytes of RAM. #ifndef MEMP_NUM_NETBUF -/// Each requires 64 bytes of RAM. #define MEMP_NUM_NETBUF 8 #endif -#ifndef MEMP_NUM_NETCONN -/// One netconn is needed for each UDPSocket, TCPSocket or TCPServer. -/// Each requires 236 bytes of RAM (rounded to multiple of 512). + +// One netconn is needed for each UDPSocket, TCPSocket or TCPServer. +// Each requires 236 bytes of RAM (total rounded to multiple of 512). +#ifdef MBED_CONF_LWIP_SOCKET_MAX +#define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX +#else #define MEMP_NUM_NETCONN 4 #endif diff --git a/features/FEATURE_LWIP/lwip-interface/mbed_lib.json b/features/FEATURE_LWIP/lwip-interface/mbed_lib.json index 5cb060e9bfe..a594e4e4a09 100644 --- a/features/FEATURE_LWIP/lwip-interface/mbed_lib.json +++ b/features/FEATURE_LWIP/lwip-interface/mbed_lib.json @@ -16,6 +16,22 @@ "addr-timeout": { "help": "On dual stack system how long to wait preferred stack's address in seconds", "value": 5 + }, + "socket-max": { + "help": "Maximum number of open TCPServer, TCPSocket and UDPSocket instances allowed, including one used internally for DNS. Each requires 236 bytes of pre-allocated RAM", + "value": 4 + }, + "tcp-server-max": { + "help": "Maximum number of open TCPServer instances allowed. Each requires 72 bytes of pre-allocated RAM", + "value": 4 + }, + "tcp-socket-max": { + "help": "Maximum number of open TCPSocket instances allowed. Each requires 196 bytes of pre-allocated RAM", + "value": 4 + }, + "udp-socket-max": { + "help": "Maximum number of open UDPSocket instances allowed, including one used internally for DNS. Each requires 84 bytes of pre-allocated RAM", + "value": 4 } } } From 7f4986f4cd2fb97a7b6c5dead6681a7fd90dfbd8 Mon Sep 17 00:00:00 2001 From: Jeremy Brodt Date: Wed, 31 Aug 2016 10:09:21 -0500 Subject: [PATCH 058/107] Adding new Maxim Integrated target. --- .../TARGET_MAX32625/PeripheralPins.c | 168 ++++ .../TARGET_MAX32625/PeripheralPins.h | 61 ++ .../TARGET_Maxim/TARGET_MAX32625/PortNames.h | 52 ++ .../TARGET_MAX32625NEXPAQ/PeripheralNames.h | 88 ++ .../TARGET_MAX32625NEXPAQ/PinNames.h | 145 +++ .../TARGET_MAX32625/analogin_api.c | 96 ++ targets/TARGET_Maxim/TARGET_MAX32625/device.h | 40 + .../TARGET_MAX32625NEXPAQ/MAX32625.sct | 16 + .../TOOLCHAIN_ARM_STD/startup_MAX32625.S | 297 ++++++ .../device/TOOLCHAIN_ARM_STD/sys.cpp | 57 ++ .../TARGET_MAX32625NEXPAQ/max32625.ld | 176 ++++ .../TOOLCHAIN_GCC_ARM/startup_max32625.S | 298 ++++++ .../TARGET_MAX32625NEXPAQ/MAX32625.icf | 29 + .../device/TOOLCHAIN_IAR/startup_MAX32625.S | 450 +++++++++ .../TARGET_MAX32625/device/adc_regs.h | 271 ++++++ .../TARGET_MAX32625/device/aes_regs.h | 165 ++++ .../TARGET_MAX32625/device/clkman_regs.h | 436 +++++++++ .../TARGET_MAX32625/device/cmsis.h | 41 + .../TARGET_MAX32625/device/cmsis_nvic.c | 65 ++ .../TARGET_MAX32625/device/cmsis_nvic.h | 53 ++ .../TARGET_MAX32625/device/crc_regs.h | 112 +++ .../TARGET_MAX32625/device/flc_regs.h | 298 ++++++ .../TARGET_MAX32625/device/gpio_regs.h | 470 ++++++++++ .../TARGET_MAX32625/device/i2cm_regs.h | 215 +++++ .../TARGET_MAX32625/device/i2cs_regs.h | 242 +++++ .../TARGET_MAX32625/device/icc_regs.h | 112 +++ .../TARGET_MAX32625/device/ioman_regs.h | 816 ++++++++++++++++ .../TARGET_MAX32625/device/maa_regs.h | 161 ++++ .../TARGET_MAX32625/device/max32625.h | 802 ++++++++++++++++ .../TARGET_MAX32625/device/mxc_device.h | 83 ++ .../TARGET_MAX32625/device/owm_regs.h | 165 ++++ .../TARGET_MAX32625/device/pmu_regs.h | 388 ++++++++ .../TARGET_MAX32625/device/prng_regs.h | 92 ++ .../TARGET_MAX32625/device/pt_regs.h | 330 +++++++ .../TARGET_MAX32625/device/pwrman_regs.h | 367 ++++++++ .../TARGET_MAX32625/device/pwrseq_regs.h | 425 +++++++++ .../TARGET_MAX32625/device/rtc_regs.h | 268 ++++++ .../TARGET_MAX32625/device/spim_regs.h | 245 +++++ .../TARGET_MAX32625/device/spis_regs.h | 165 ++++ .../TARGET_MAX32625/device/spix_regs.h | 218 +++++ .../TARGET_MAX32625/device/sysman_regs.h | 90 ++ .../TARGET_MAX32625/device/system_max32625.c | 263 ++++++ .../TARGET_MAX32625/device/system_max32625.h | 75 ++ .../TARGET_MAX32625/device/tmr_regs.h | 203 ++++ .../TARGET_MAX32625/device/tpu_regs.h | 89 ++ .../TARGET_MAX32625/device/trim_regs.h | 125 +++ .../TARGET_MAX32625/device/uart_regs.h | 240 +++++ .../TARGET_MAX32625/device/usb_regs.h | 293 ++++++ .../TARGET_MAX32625/device/wdt2_regs.h | 200 ++++ .../TARGET_MAX32625/device/wdt_regs.h | 238 +++++ .../TARGET_Maxim/TARGET_MAX32625/gpio_api.c | 128 +++ .../TARGET_MAX32625/gpio_irq_api.c | 175 ++++ .../TARGET_MAX32625/gpio_object.h | 73 ++ .../TARGET_Maxim/TARGET_MAX32625/i2c_api.c | 214 +++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/adc.c | 178 ++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/adc.h | 216 +++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/aes.c | 213 +++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/aes.h | 199 ++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/clkman.c | 172 ++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/clkman.h | 234 +++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/crc.c | 108 +++ .../TARGET_Maxim/TARGET_MAX32625/mxc/crc.h | 191 ++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/flc.c | 260 ++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/flc.h | 117 +++ .../TARGET_Maxim/TARGET_MAX32625/mxc/gpio.c | 186 ++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/gpio.h | 315 +++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/i2cm.c | 880 ++++++++++++++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/i2cm.h | 257 +++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/i2cs.c | 209 +++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/i2cs.h | 215 +++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/icc.c | 77 ++ .../TARGET_Maxim/TARGET_MAX32625/mxc/icc.h | 83 ++ .../TARGET_Maxim/TARGET_MAX32625/mxc/ioman.c | 71 ++ .../TARGET_Maxim/TARGET_MAX32625/mxc/ioman.h | 288 ++++++ targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.c | 413 ++++++++ targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.h | 185 ++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/maa.c | 236 +++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/maa.h | 220 +++++ .../TARGET_MAX32625/mxc/mxc_assert.c | 57 ++ .../TARGET_MAX32625/mxc/mxc_assert.h | 86 ++ .../TARGET_MAX32625/mxc/mxc_config.h | 43 + .../TARGET_MAX32625/mxc/mxc_errors.h | 87 ++ .../TARGET_MAX32625/mxc/mxc_lock.h | 100 ++ .../TARGET_MAX32625/mxc/mxc_sys.c | 845 +++++++++++++++++ .../TARGET_MAX32625/mxc/mxc_sys.h | 445 +++++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/owm.c | 591 ++++++++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/owm.h | 320 +++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/pmu.c | 236 +++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/pmu.h | 286 ++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/prng.c | 57 ++ .../TARGET_Maxim/TARGET_MAX32625/mxc/prng.h | 110 +++ targets/TARGET_Maxim/TARGET_MAX32625/mxc/pt.c | 134 +++ targets/TARGET_Maxim/TARGET_MAX32625/mxc/pt.h | 313 +++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/rtc.c | 195 ++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/rtc.h | 446 +++++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/spim.c | 720 ++++++++++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/spim.h | 263 ++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/spis.c | 457 +++++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/spis.h | 232 +++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/spix.c | 292 ++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/spix.h | 126 +++ .../TARGET_Maxim/TARGET_MAX32625/mxc/tmr.c | 389 ++++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/tmr.h | 619 ++++++++++++ .../TARGET_MAX32625/mxc/tmr_utils.c | 168 ++++ .../TARGET_MAX32625/mxc/tmr_utils.h | 126 +++ .../TARGET_Maxim/TARGET_MAX32625/mxc/uart.c | 653 +++++++++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/uart.h | 271 ++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/wdt.c | 286 ++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/wdt.h | 245 +++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/wdt2.c | 269 ++++++ .../TARGET_Maxim/TARGET_MAX32625/mxc/wdt2.h | 207 ++++ .../TARGET_Maxim/TARGET_MAX32625/objects.h | 115 +++ targets/TARGET_Maxim/TARGET_MAX32625/pinmap.c | 82 ++ .../TARGET_Maxim/TARGET_MAX32625/port_api.c | 98 ++ .../TARGET_Maxim/TARGET_MAX32625/pwmout_api.c | 221 +++++ .../TARGET_Maxim/TARGET_MAX32625/rtc_api.c | 253 +++++ .../TARGET_Maxim/TARGET_MAX32625/serial_api.c | 371 ++++++++ targets/TARGET_Maxim/TARGET_MAX32625/sleep.c | 46 + .../TARGET_Maxim/TARGET_MAX32625/spi_api.c | 181 ++++ .../TARGET_Maxim/TARGET_MAX32625/us_ticker.c | 257 +++++ targets/TARGET_Maxim/mbed_rtx.h | 15 + targets/targets.json | 10 + 122 files changed, 28230 insertions(+) create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/PeripheralPins.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/PeripheralPins.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/PortNames.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625NEXPAQ/PeripheralNames.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625NEXPAQ/PinNames.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/analogin_api.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/TARGET_MAX32625NEXPAQ/MAX32625.sct create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/startup_MAX32625.S create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/sys.cpp create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/TARGET_MAX32625NEXPAQ/max32625.ld create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/startup_max32625.S create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/TARGET_MAX32625NEXPAQ/MAX32625.icf create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/startup_MAX32625.S create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/adc_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/aes_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/clkman_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/crc_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/flc_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/gpio_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/i2cm_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/i2cs_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/icc_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/ioman_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/maa_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/max32625.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/mxc_device.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/owm_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/pmu_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/prng_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/pt_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/pwrman_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/pwrseq_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/rtc_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/spim_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/spis_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/spix_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/sysman_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/system_max32625.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/system_max32625.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/tmr_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/tpu_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/trim_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/uart_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/usb_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/wdt2_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/wdt_regs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/gpio_api.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/gpio_irq_api.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/gpio_object.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/i2c_api.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/adc.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/adc.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/aes.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/aes.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/clkman.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/clkman.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/crc.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/crc.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/flc.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/flc.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/gpio.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/gpio.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cm.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cm.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cs.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cs.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/icc.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/icc.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/ioman.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/ioman.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/maa.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/maa.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_assert.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_assert.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_config.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_errors.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_lock.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_sys.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_sys.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/owm.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/owm.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/pmu.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/pmu.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/prng.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/prng.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/pt.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/pt.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/rtc.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/rtc.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/spim.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/spim.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/spis.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/spis.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/spix.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/spix.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr_utils.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr_utils.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/uart.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/uart.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt2.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt2.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/objects.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/pinmap.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/port_api.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/pwmout_api.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/rtc_api.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/serial_api.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/sleep.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/spi_api.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/us_ticker.c diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/PeripheralPins.c b/targets/TARGET_Maxim/TARGET_MAX32625/PeripheralPins.c new file mode 100644 index 00000000000..488150ecf16 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/PeripheralPins.c @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "device.h" +#include "PeripheralPins.h" +#include "ioman_regs.h" +#include "ioman.h" +#include "adc.h" + +/* + * To select a peripheral function on Maxim microcontrollers, multiple + * configurations must be made. The mbed PinMap structure only includes one + * data member to hold this information. To extend the configuration storage, + * the "function" data member is used as a pointer to a pin_function_t + * structure. This structure is defined in objects.h. The definitions below + * include the creation of the pin_function_t structures and the assignment of + * the pointers to the "function" data members. + */ + +#ifdef TOOLCHAIN_ARM_STD +#pragma diag_suppress 1296 +#endif + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + { P1_6, I2C_0, (int)&((pin_function_t){&MXC_IOMAN->i2cm0_req, &MXC_IOMAN->i2cm0_ack, MXC_F_IOMAN_I2CM0_REQ_MAPPING_REQ, MXC_F_IOMAN_I2CM0_ACK_MAPPING_ACK}) }, + { P3_4, I2C_1, (int)&((pin_function_t){&MXC_IOMAN->i2cm1_req, &MXC_IOMAN->i2cm1_ack, MXC_F_IOMAN_I2CM1_REQ_MAPPING_REQ, MXC_F_IOMAN_I2CM1_ACK_MAPPING_ACK}) }, + { NC, NC, 0 } +}; + +const PinMap PinMap_I2C_SCL[] = { + { P1_7, I2C_0, (int)&((pin_function_t){&MXC_IOMAN->i2cm0_req, &MXC_IOMAN->i2cm0_ack, MXC_F_IOMAN_I2CM0_REQ_MAPPING_REQ, MXC_F_IOMAN_I2CM0_ACK_MAPPING_ACK}) }, + { P3_5, I2C_1, (int)&((pin_function_t){&MXC_IOMAN->i2cm1_req, &MXC_IOMAN->i2cm1_ack, MXC_F_IOMAN_I2CM1_REQ_MAPPING_REQ, MXC_F_IOMAN_I2CM1_ACK_MAPPING_ACK}) }, + { NC, NC, 0 } +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + { P0_1, UART_0, (int)&((pin_function_t){&MXC_IOMAN->uart0_req, &MXC_IOMAN->uart0_ack, ((uint32_t)IOMAN_MAP_A | MXC_F_IOMAN_UART0_REQ_IO_REQ), (MXC_F_IOMAN_UART0_ACK_IO_MAP | MXC_F_IOMAN_UART0_ACK_IO_ACK)}) }, + { P2_1, UART_1, (int)&((pin_function_t){&MXC_IOMAN->uart1_req, &MXC_IOMAN->uart1_ack, ((uint32_t)IOMAN_MAP_A | MXC_F_IOMAN_UART1_REQ_IO_REQ), (MXC_F_IOMAN_UART1_ACK_IO_MAP | MXC_F_IOMAN_UART1_ACK_IO_ACK)}) }, + { P3_1, UART_2, (int)&((pin_function_t){&MXC_IOMAN->uart2_req, &MXC_IOMAN->uart2_ack, ((uint32_t)IOMAN_MAP_A | MXC_F_IOMAN_UART2_REQ_IO_REQ), (MXC_F_IOMAN_UART2_ACK_IO_MAP | MXC_F_IOMAN_UART2_ACK_IO_ACK)}) }, + { P0_0, UART_0, (int)&((pin_function_t){&MXC_IOMAN->uart0_req, &MXC_IOMAN->uart0_ack, ((uint32_t)IOMAN_MAP_B | MXC_F_IOMAN_UART0_REQ_IO_REQ), (MXC_F_IOMAN_UART0_ACK_IO_MAP | MXC_F_IOMAN_UART0_ACK_IO_ACK)}) }, + { P2_0, UART_1, (int)&((pin_function_t){&MXC_IOMAN->uart1_req, &MXC_IOMAN->uart1_ack, ((uint32_t)IOMAN_MAP_B | MXC_F_IOMAN_UART1_REQ_IO_REQ), (MXC_F_IOMAN_UART1_ACK_IO_MAP | MXC_F_IOMAN_UART1_ACK_IO_ACK)}) }, + { P3_0, UART_2, (int)&((pin_function_t){&MXC_IOMAN->uart2_req, &MXC_IOMAN->uart2_ack, ((uint32_t)IOMAN_MAP_B | MXC_F_IOMAN_UART2_REQ_IO_REQ), (MXC_F_IOMAN_UART2_ACK_IO_MAP | MXC_F_IOMAN_UART2_ACK_IO_ACK)}) }, + { NC, NC, 0 } +}; + +const PinMap PinMap_UART_RX[] = { + { P0_0, UART_0, (int)&((pin_function_t){&MXC_IOMAN->uart0_req, &MXC_IOMAN->uart0_ack, ((uint32_t)IOMAN_MAP_A | MXC_F_IOMAN_UART0_REQ_IO_REQ), (MXC_F_IOMAN_UART0_ACK_IO_MAP | MXC_F_IOMAN_UART0_ACK_IO_ACK)}) }, + { P2_0, UART_1, (int)&((pin_function_t){&MXC_IOMAN->uart1_req, &MXC_IOMAN->uart1_ack, ((uint32_t)IOMAN_MAP_A | MXC_F_IOMAN_UART1_REQ_IO_REQ), (MXC_F_IOMAN_UART1_ACK_IO_MAP | MXC_F_IOMAN_UART1_ACK_IO_ACK)}) }, + { P3_0, UART_2, (int)&((pin_function_t){&MXC_IOMAN->uart2_req, &MXC_IOMAN->uart2_ack, ((uint32_t)IOMAN_MAP_A | MXC_F_IOMAN_UART2_REQ_IO_REQ), (MXC_F_IOMAN_UART2_ACK_IO_MAP | MXC_F_IOMAN_UART2_ACK_IO_ACK)}) }, + { P0_1, UART_0, (int)&((pin_function_t){&MXC_IOMAN->uart0_req, &MXC_IOMAN->uart0_ack, ((uint32_t)IOMAN_MAP_B | MXC_F_IOMAN_UART0_REQ_IO_REQ), (MXC_F_IOMAN_UART0_ACK_IO_MAP | MXC_F_IOMAN_UART0_ACK_IO_ACK)}) }, + { P2_1, UART_1, (int)&((pin_function_t){&MXC_IOMAN->uart1_req, &MXC_IOMAN->uart1_ack, ((uint32_t)IOMAN_MAP_B | MXC_F_IOMAN_UART1_REQ_IO_REQ), (MXC_F_IOMAN_UART1_ACK_IO_MAP | MXC_F_IOMAN_UART1_ACK_IO_ACK)}) }, + { P3_1, UART_2, (int)&((pin_function_t){&MXC_IOMAN->uart2_req, &MXC_IOMAN->uart2_ack, ((uint32_t)IOMAN_MAP_B | MXC_F_IOMAN_UART2_REQ_IO_REQ), (MXC_F_IOMAN_UART2_ACK_IO_MAP | MXC_F_IOMAN_UART2_ACK_IO_ACK)}) }, + { NC, NC, 0 } +}; + +const PinMap PinMap_UART_CTS[] = { + { P0_2, UART_0, (int)&((pin_function_t){&MXC_IOMAN->uart0_req, &MXC_IOMAN->uart0_ack, ((uint32_t)IOMAN_MAP_A | MXC_F_IOMAN_UART0_REQ_CTS_IO_REQ), (MXC_F_IOMAN_UART0_ACK_CTS_MAP | MXC_F_IOMAN_UART0_ACK_CTS_IO_ACK)}) }, + { P2_2, UART_1, (int)&((pin_function_t){&MXC_IOMAN->uart1_req, &MXC_IOMAN->uart1_ack, ((uint32_t)IOMAN_MAP_A | MXC_F_IOMAN_UART1_REQ_CTS_IO_REQ), (MXC_F_IOMAN_UART1_ACK_CTS_MAP | MXC_F_IOMAN_UART1_ACK_CTS_IO_ACK)}) }, + { P3_2, UART_2, (int)&((pin_function_t){&MXC_IOMAN->uart2_req, &MXC_IOMAN->uart2_ack, ((uint32_t)IOMAN_MAP_A | MXC_F_IOMAN_UART2_REQ_CTS_IO_REQ), (MXC_F_IOMAN_UART2_ACK_CTS_MAP | MXC_F_IOMAN_UART2_ACK_CTS_IO_ACK)}) }, + { P0_3, UART_0, (int)&((pin_function_t){&MXC_IOMAN->uart0_req, &MXC_IOMAN->uart0_ack, ((uint32_t)IOMAN_MAP_B | MXC_F_IOMAN_UART0_REQ_CTS_IO_REQ), (MXC_F_IOMAN_UART0_ACK_CTS_MAP | MXC_F_IOMAN_UART0_ACK_CTS_IO_ACK)}) }, + { P2_3, UART_1, (int)&((pin_function_t){&MXC_IOMAN->uart1_req, &MXC_IOMAN->uart1_ack, ((uint32_t)IOMAN_MAP_B | MXC_F_IOMAN_UART1_REQ_CTS_IO_REQ), (MXC_F_IOMAN_UART1_ACK_CTS_MAP | MXC_F_IOMAN_UART1_ACK_CTS_IO_ACK)}) }, + { P3_3, UART_2, (int)&((pin_function_t){&MXC_IOMAN->uart2_req, &MXC_IOMAN->uart2_ack, ((uint32_t)IOMAN_MAP_B | MXC_F_IOMAN_UART2_REQ_CTS_IO_REQ), (MXC_F_IOMAN_UART2_ACK_CTS_MAP | MXC_F_IOMAN_UART2_ACK_CTS_IO_ACK)}) }, + { NC, NC, 0 } +}; + +const PinMap PinMap_UART_RTS[] = { + { P0_3, UART_0, (int)&((pin_function_t){&MXC_IOMAN->uart0_req, &MXC_IOMAN->uart0_ack, ((uint32_t)IOMAN_MAP_A | MXC_F_IOMAN_UART0_REQ_RTS_IO_REQ), (MXC_F_IOMAN_UART0_ACK_RTS_MAP | MXC_F_IOMAN_UART0_ACK_RTS_IO_ACK)}) }, + { P2_3, UART_1, (int)&((pin_function_t){&MXC_IOMAN->uart1_req, &MXC_IOMAN->uart1_ack, ((uint32_t)IOMAN_MAP_A | MXC_F_IOMAN_UART1_REQ_RTS_IO_REQ), (MXC_F_IOMAN_UART1_ACK_RTS_MAP | MXC_F_IOMAN_UART1_ACK_RTS_IO_ACK)}) }, + { P3_3, UART_2, (int)&((pin_function_t){&MXC_IOMAN->uart2_req, &MXC_IOMAN->uart2_ack, ((uint32_t)IOMAN_MAP_A | MXC_F_IOMAN_UART2_REQ_RTS_IO_REQ), (MXC_F_IOMAN_UART2_ACK_RTS_MAP | MXC_F_IOMAN_UART2_ACK_RTS_IO_ACK)}) }, + { P0_2, UART_0, (int)&((pin_function_t){&MXC_IOMAN->uart0_req, &MXC_IOMAN->uart0_ack, ((uint32_t)IOMAN_MAP_B | MXC_F_IOMAN_UART0_REQ_RTS_IO_REQ), (MXC_F_IOMAN_UART0_ACK_RTS_MAP | MXC_F_IOMAN_UART0_ACK_RTS_IO_ACK)}) }, + { P2_2, UART_1, (int)&((pin_function_t){&MXC_IOMAN->uart1_req, &MXC_IOMAN->uart1_ack, ((uint32_t)IOMAN_MAP_B | MXC_F_IOMAN_UART1_REQ_RTS_IO_REQ), (MXC_F_IOMAN_UART1_ACK_RTS_MAP | MXC_F_IOMAN_UART1_ACK_RTS_IO_ACK)}) }, + { P3_2, UART_2, (int)&((pin_function_t){&MXC_IOMAN->uart2_req, &MXC_IOMAN->uart2_ack, ((uint32_t)IOMAN_MAP_B | MXC_F_IOMAN_UART2_REQ_RTS_IO_REQ), (MXC_F_IOMAN_UART2_ACK_RTS_MAP | MXC_F_IOMAN_UART2_ACK_RTS_IO_ACK)}) }, + { NC, NC, 0 } +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + { P0_4, SPI_0, (int)&((pin_function_t){&MXC_IOMAN->spim0_req, &MXC_IOMAN->spim0_ack, MXC_F_IOMAN_SPIM0_REQ_CORE_IO_REQ, MXC_F_IOMAN_SPIM0_ACK_CORE_IO_ACK}) }, + { P1_0, SPI_1, (int)&((pin_function_t){&MXC_IOMAN->spim1_req, &MXC_IOMAN->spim1_ack, MXC_F_IOMAN_SPIM1_REQ_CORE_IO_REQ, MXC_F_IOMAN_SPIM1_ACK_CORE_IO_ACK}) }, + { P2_4, SPI_2, (int)&((pin_function_t){&MXC_IOMAN->spim2_req, &MXC_IOMAN->spim2_ack, MXC_F_IOMAN_SPIM2_REQ_CORE_IO_REQ, MXC_F_IOMAN_SPIM2_ACK_CORE_IO_ACK}) }, + { NC, NC, 0 } +}; + +const PinMap PinMap_SPI_MOSI[] = { + { P0_5, SPI_0, (int)&((pin_function_t){&MXC_IOMAN->spim0_req, &MXC_IOMAN->spim0_ack, MXC_F_IOMAN_SPIM0_REQ_CORE_IO_REQ, MXC_F_IOMAN_SPIM0_ACK_CORE_IO_ACK}) }, + { P1_1, SPI_1, (int)&((pin_function_t){&MXC_IOMAN->spim1_req, &MXC_IOMAN->spim1_ack, MXC_F_IOMAN_SPIM1_REQ_CORE_IO_REQ, MXC_F_IOMAN_SPIM1_ACK_CORE_IO_ACK}) }, + { P2_5, SPI_2, (int)&((pin_function_t){&MXC_IOMAN->spim2_req, &MXC_IOMAN->spim2_ack, MXC_F_IOMAN_SPIM2_REQ_CORE_IO_REQ, MXC_F_IOMAN_SPIM2_ACK_CORE_IO_ACK}) }, + { NC, NC, 0 } +}; + +const PinMap PinMap_SPI_MISO[] = { + { P0_6, SPI_0, (int)&((pin_function_t){&MXC_IOMAN->spim0_req, &MXC_IOMAN->spim0_ack, MXC_F_IOMAN_SPIM0_REQ_CORE_IO_REQ, MXC_F_IOMAN_SPIM0_ACK_CORE_IO_ACK}) }, + { P1_2, SPI_1, (int)&((pin_function_t){&MXC_IOMAN->spim1_req, &MXC_IOMAN->spim1_ack, MXC_F_IOMAN_SPIM1_REQ_CORE_IO_REQ, MXC_F_IOMAN_SPIM1_ACK_CORE_IO_ACK}) }, + { P2_6, SPI_2, (int)&((pin_function_t){&MXC_IOMAN->spim2_req, &MXC_IOMAN->spim2_ack, MXC_F_IOMAN_SPIM2_REQ_CORE_IO_REQ, MXC_F_IOMAN_SPIM2_ACK_CORE_IO_ACK}) }, + { NC, NC, 0 } +}; + +const PinMap PinMap_SPI_SSEL[] = { + { P0_7, SPI_0, (int)&((pin_function_t){&MXC_IOMAN->spim0_req, &MXC_IOMAN->spim0_ack, MXC_F_IOMAN_SPIM0_REQ_SS0_IO_REQ, MXC_F_IOMAN_SPIM0_ACK_SS0_IO_ACK}) }, + { P1_3, SPI_1, (int)&((pin_function_t){&MXC_IOMAN->spim1_req, &MXC_IOMAN->spim1_ack, MXC_F_IOMAN_SPIM1_REQ_SS0_IO_REQ, MXC_F_IOMAN_SPIM1_ACK_SS0_IO_ACK}) }, + { P2_7, SPI_2, (int)&((pin_function_t){&MXC_IOMAN->spim2_req, &MXC_IOMAN->spim2_ack, MXC_F_IOMAN_SPIM2_REQ_SS0_IO_REQ, MXC_F_IOMAN_SPIM2_ACK_SS0_IO_ACK}) }, + { NC, NC, 0 } +}; + +/************PWM***************/ +const PinMap PinMap_PWM[] = { + { P0_0, PWM_0, 1 }, { P2_0, PWM_0, 1 }, { P4_0, PWM_0, 1 }, + { P0_1, PWM_1, 1 }, { P2_1, PWM_1, 1 }, { P4_1, PWM_1, 1 }, + { P0_2, PWM_2, 1 }, { P2_2, PWM_2, 1 }, { P4_2, PWM_2, 1 }, + { P0_3, PWM_3, 1 }, { P2_3, PWM_3, 1 }, { P4_3, PWM_3, 1 }, + { P0_4, PWM_4, 1 }, { P2_4, PWM_4, 1 }, { P4_4, PWM_4, 1 }, + { P0_5, PWM_5, 1 }, { P2_5, PWM_5, 1 }, { P4_5, PWM_5, 1 }, + { P0_6, PWM_6, 1 }, { P2_6, PWM_6, 1 }, { P4_6, PWM_6, 1 }, + { P0_7, PWM_7, 1 }, { P2_7, PWM_7, 1 }, { P4_7, PWM_7, 1 }, + { P1_0, PWM_8, 1 }, { P3_0, PWM_8, 1 }, + { P1_1, PWM_9, 1 }, { P3_1, PWM_9, 1 }, + { P1_2, PWM_10, 1 }, { P3_2, PWM_10, 1 }, + { P1_3, PWM_11, 1 }, { P3_3, PWM_11, 1 }, + { P1_4, PWM_12, 1 }, { P3_4, PWM_12, 1 }, + { P1_5, PWM_13, 1 }, { P3_5, PWM_13, 1 }, + { P1_6, PWM_14, 1 }, { P3_6, PWM_14, 1 }, + { P1_7, PWM_15, 1 }, { P3_7, PWM_15, 1 }, + { NC, NC, 0 } +}; + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + { AIN_0, ADC, ADC_CH_0 }, + { AIN_1, ADC, ADC_CH_1 }, + { AIN_2, ADC, ADC_CH_2 }, + { AIN_3, ADC, ADC_CH_3 }, + { AIN_4, ADC, ADC_CH_0_DIV_5 }, + { AIN_5, ADC, ADC_CH_1_DIV_5 }, + { NC, NC, 0 } +}; + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/PeripheralPins.h b/targets/TARGET_Maxim/TARGET_MAX32625/PeripheralPins.h new file mode 100644 index 00000000000..66b40c1fc2c --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/PeripheralPins.h @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_PERIPHERALPINS_H +#define MBED_PERIPHERALPINS_H + +#include "pinmap.h" + +//************I2C*************** +extern const PinMap PinMap_I2C_SDA[]; +extern const PinMap PinMap_I2C_SCL[]; + +//************UART*************** +extern const PinMap PinMap_UART_TX[]; +extern const PinMap PinMap_UART_RX[]; +extern const PinMap PinMap_UART_CTS[]; +extern const PinMap PinMap_UART_RTS[]; + +//************SPI*************** +extern const PinMap PinMap_SPI_SCLK[]; +extern const PinMap PinMap_SPI_MOSI[]; +extern const PinMap PinMap_SPI_MISO[]; +extern const PinMap PinMap_SPI_SSEL[]; + +//************PWM*************** +extern const PinMap PinMap_PWM[]; + +//************ADC*************** +extern const PinMap PinMap_ADC[]; +#endif + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/PortNames.h b/targets/TARGET_Maxim/TARGET_MAX32625/PortNames.h new file mode 100644 index 00000000000..ebd8e9708c6 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/PortNames.h @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, + Port1 = 1, + Port2 = 2, + Port3 = 3, + Port4 = 4, +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625NEXPAQ/PeripheralNames.h b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625NEXPAQ/PeripheralNames.h new file mode 100644 index 00000000000..4686ef9c91f --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625NEXPAQ/PeripheralNames.h @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = MXC_BASE_UART0, + UART_1 = MXC_BASE_UART1, + UART_2 = MXC_BASE_UART2, + STDIO_UART = UART_1 +} UARTName; + +typedef enum { + I2C_0 = MXC_BASE_I2CM0, + I2C_1 = MXC_BASE_I2CM1 +} I2CName; + +typedef enum { + SPI_0 = MXC_BASE_SPIM0, + SPI_1 = MXC_BASE_SPIM1, + SPI_2 = MXC_BASE_SPIM2 +} SPIName; + +typedef enum { + PWM_0 = MXC_BASE_PT0, + PWM_1 = MXC_BASE_PT1, + PWM_2 = MXC_BASE_PT2, + PWM_3 = MXC_BASE_PT3, + PWM_4 = MXC_BASE_PT4, + PWM_5 = MXC_BASE_PT5, + PWM_6 = MXC_BASE_PT6, + PWM_7 = MXC_BASE_PT7, + PWM_8 = MXC_BASE_PT8, + PWM_9 = MXC_BASE_PT9, + PWM_10 = MXC_BASE_PT10, + PWM_11 = MXC_BASE_PT11, + PWM_12 = MXC_BASE_PT12, + PWM_13 = MXC_BASE_PT13, + PWM_14 = MXC_BASE_PT14, + PWM_15 = MXC_BASE_PT15 +} PWMName; + +typedef enum { + ADC = MXC_BASE_ADC +} ADCName; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625NEXPAQ/PinNames.h b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625NEXPAQ/PinNames.h new file mode 100644 index 00000000000..9574edf1ec6 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625NEXPAQ/PinNames.h @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" +#include "gpio_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT = 0, /* MXC_V_GPIO_OUT_MODE_HIGH_Z,*/ + PIN_OUTPUT = 1 /* MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE */ +} PinDirection; + +#define PORT_SHIFT 12 +#define PINNAME_TO_PORT(name) ((unsigned int)(name) >> PORT_SHIFT) +#define PINNAME_TO_PIN(name) ((unsigned int)(name) & ~(0xFFFFFFFF << PORT_SHIFT)) + +#define NOT_CONNECTED (int)0xFFFFFFFF + +typedef enum { + P0_0 = (0 << PORT_SHIFT), P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, + P1_0 = (1 << PORT_SHIFT), P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, + P2_0 = (2 << PORT_SHIFT), P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, + P3_0 = (3 << PORT_SHIFT), P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, + P4_0 = (4 << PORT_SHIFT), P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, + + // Analog input pins + AIN_0 = (0xA << PORT_SHIFT), AIN_1, AIN_2, AIN_3, AIN_4, AIN_5, + + // LEDs + LED1 = P2_4, + LED2 = P2_5, + LED3 = P2_6, + LED4 = P2_7, + LED_RED = LED1, + LED_GREEN = LED2, + LED_BLUE = LED3, + + // Push button + SW1 = P4_2, + SW2 = P4_3, + SW3 = P4_4, + + // USB bridge connected UART pins + USBTX = P2_1, + USBRX = P2_0, + STDIO_UART_TX = USBTX, + STDIO_UART_RX = USBRX, + + // I2C pins + I2C0_SCL = P1_7, + I2C0_SDA = P1_6, + + I2C1_SCL = P3_5, + I2C1_SDA = P3_4, + + // UART pins + UART0_RX = P0_0, + UART0_TX = P0_1, + UART0_CTS = P0_2, + UART0_RTS = P0_3, + + UART1_RX = P2_0, + UART1_TX = P2_1, + UART1_CTS = P2_2, + UART1_RTS = P2_3, + + UART2_RX = P3_0, + UART2_TX = P3_1, + UART2_CTS = P3_2, + UART2_RTS = P3_3, + + // SPI pins + SPI0_SCK = P0_4, + SPI0_MOSI = P0_5, + SPI0_MISO = P0_6, + SPI0_SS = P0_7, + + SPI1_SCK = P1_0, + SPI1_MOSI = P1_1, + SPI1_MISO = P1_2, + SPI1_SS = P1_3, + + SPI2_SCK = P2_4, + SPI2_MOSI = P2_5, + SPI2_MISO = P2_6, + SPI2_SS = P2_7, + + // Not connected + NC = NOT_CONNECTED +} PinName; + +typedef enum { + PullUp, + PullDown, + OpenDrain, + PullNone, + PullDefault = PullUp +} PinMode; + +typedef enum { + LED_ON = 0, + LED_OFF = 1 +} LedStates; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/analogin_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/analogin_api.c new file mode 100644 index 00000000000..2f6d348d657 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/analogin_api.c @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "mbed_assert.h" +#include "analogin_api.h" +#include "adc.h" +#include "pinmap.h" +#include "PeripheralPins.h" + +#define ADC_FULL_SCALE 0x3FFU +#define INT_FULL_SCALE 0xFFFFU +#define FLOAT_FULL_SCALE 1.0f + +static int initialized = 0; + +//****************************************************************************** +void analogin_init(analogin_t *obj, PinName pin) +{ + // Make sure pin is an analog pin we can use for ADC + MBED_ASSERT((ADCName)pinmap_peripheral(pin, PinMap_ADC) != (ADCName)NC); + + // Set the object pointer and channel encoding + obj->adc = MXC_ADC; + obj->channel = pinmap_find_function(pin, PinMap_ADC); + + if (!initialized) { + MBED_ASSERT(ADC_Init() == E_NO_ERROR); + initialized = 1; + } +} + +//****************************************************************************** +float analogin_read(analogin_t *obj) +{ + uint16_t tmp; + float result; + + // Start conversion with no input scaling and no input buffer bypass + ADC_StartConvert(obj->channel, 0, 0); + + if (ADC_GetData(&tmp) == E_OVERFLOW) { + result = FLOAT_FULL_SCALE; + } else { + result = (float)tmp * (FLOAT_FULL_SCALE / (float)ADC_FULL_SCALE); + } + + return result; +} + +//****************************************************************************** +uint16_t analogin_read_u16(analogin_t *obj) +{ + uint16_t tmp; + uint16_t result; + + // Start conversion with no input scaling and no input buffer bypass + ADC_StartConvert(obj->channel, 0, 0); + + if (ADC_GetData(&tmp) == E_OVERFLOW) { + result = INT_FULL_SCALE; + } else { + result = ((tmp << 6) & 0xFFC0) | ((tmp >> 4) & 0x003F); + } + + return result; +} + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device.h b/targets/TARGET_Maxim/TARGET_MAX32625/device.h new file mode 100644 index 00000000000..3463dfe3f94 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device.h @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#include "objects.h" + +#endif + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/TARGET_MAX32625NEXPAQ/MAX32625.sct b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/TARGET_MAX32625NEXPAQ/MAX32625.sct new file mode 100644 index 00000000000..6ea0cb73ba2 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/TARGET_MAX32625NEXPAQ/MAX32625.sct @@ -0,0 +1,16 @@ +; MAX32625 +; 512KB FLASH (0x70000) @ 0x000010000 +; 160KB RAM (0x24F00) @ 0x20003100 + +LR_IROM1 0x000010000 0x70000 { ; load region size_region + ER_IROM1 0x000010000 0x70000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + + ; [RAM] Vector table dynamic copy: 68 vectors * 4 bytes = 272 (0x110) + RW_IRAM1 (0x20003100+0x110) (0x24F00-0x110) { ; RW data + .ANY (+RW +ZI) + } +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/startup_MAX32625.S b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/startup_MAX32625.S new file mode 100644 index 00000000000..d89f34b8eb2 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/startup_MAX32625.S @@ -0,0 +1,297 @@ +;******************************************************************************* +; Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. +; +; Permission is hereby granted, free of charge, to any person obtaining a +; copy of this software and associated documentation files (the "Software"), +; to deal in the Software without restriction, including without limitation +; the rights to use, copy, modify, merge, publish, distribute, sublicense, +; and/or sell copies of the Software, and to permit persons to whom the +; Software is furnished to do so, subject to the following conditions: +; +; The above copyright notice and this permission notice shall be included +; in all copies or substantial portions of the Software. +; +; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +; OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +; IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +; OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +; ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +; OTHER DEALINGS IN THE SOFTWARE. +; +; Except as contained in this notice, the name of Maxim Integrated +; Products, Inc. shall not be used except as stated in the Maxim Integrated +; Products, Inc. Branding Policy. +; +; The mere transfer of this software does not imply any licenses +; of trade secrets, proprietary technology, copyrights, patents, +; trademarks, maskwork rights, or any other form of intellectual +; property whatsoever. Maxim Integrated Products, Inc. retains all +; ownership rights. +;******************************************************************************* + +__initial_sp EQU 0x20028000 ; Top of RAM + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; Maxim 32625 Externals interrupts + DCD CLKMAN_IRQHandler ; 16:01 CLKMAN + DCD PWRMAN_IRQHandler ; 17:02 PWRMAN + DCD FLC_IRQHandler ; 18:03 Flash Controller + DCD RTC0_IRQHandler ; 19:04 RTC INT0 + DCD RTC1_IRQHandler ; 20:05 RTC INT1 + DCD RTC2_IRQHandler ; 21:06 RTC INT2 + DCD RTC3_IRQHandler ; 22:07 RTC INT3 + DCD PMU_IRQHandler ; 23:08 PMU + DCD USB_IRQHandler ; 24:09 USB + DCD AES_IRQHandler ; 25:10 AES + DCD MAA_IRQHandler ; 26:11 MAA + DCD WDT0_IRQHandler ; 27:12 WATCHDOG0 + DCD WDT0_P_IRQHandler ; 28:13 WATCHDOG0 PRE-WINDOW + DCD WDT1_IRQHandler ; 29:14 WATCHDOG1 + DCD WDT1_P_IRQHandler ; 30:15 WATCHDOG1 PRE-WINDOW + DCD GPIO_P0_IRQHandler ; 31:16 GPIO Port 0 + DCD GPIO_P1_IRQHandler ; 32:17 GPIO Port 1 + DCD GPIO_P2_IRQHandler ; 33:18 GPIO Port 2 + DCD GPIO_P3_IRQHandler ; 34:19 GPIO Port 3 + DCD GPIO_P4_IRQHandler ; 35:20 GPIO Port 4 + DCD GPIO_P5_IRQHandler ; 36:21 GPIO Port 5 + DCD GPIO_P6_IRQHandler ; 37:22 GPIO Port 6 + DCD TMR0_IRQHandler ; 38:23 Timer32-0 + DCD TMR16_0_IRQHandler ; 39:24 Timer16-s0 + DCD TMR1_IRQHandler ; 40:25 Timer32-1 + DCD TMR16_1_IRQHandler ; 41:26 Timer16-s1 + DCD TMR2_IRQHandler ; 42:27 Timer32-2 + DCD TMR16_2_IRQHandler ; 43:28 Timer16-s2 + DCD TMR3_IRQHandler ; 44:29 Timer32-3 + DCD TMR16_3_IRQHandler ; 45:30 Timer16-s3 + DCD TMR4_IRQHandler ; 46:31 Timer32-4 + DCD TMR16_4_IRQHandler ; 47:32 Timer16-s4 + DCD TMR5_IRQHandler ; 48:33 Timer32-5 + DCD TMR16_5_IRQHandler ; 49:34 Timer16-s5 + DCD PT_IRQHandler ; 50:35 PT + DCD UART0_IRQHandler ; 51:36 UART0 + DCD UART1_IRQHandler ; 52:37 UART1 + DCD UART2_IRQHandler ; 53:38 UART0 + DCD UART3_IRQHandler ; 54:39 UART1 + DCD I2CM0_IRQHandler ; 55:40 I2C Master 0 + DCD I2CM1_IRQHandler ; 56:41 I2C Master 1 + DCD I2CM2_IRQHandler ; 57:42 I2C Master 2 + DCD I2CS_IRQHandler ; 58:43 I2C Slave + DCD SPIM0_IRQHandler ; 59:44 SPIM0 + DCD SPIM1_IRQHandler ; 60:45 SPIM1 + DCD SPIM2_IRQHandler ; 61:46 SPIM2 + DCD SPIB_IRQHandler ; 62:47 SPI Bridge + DCD OWM_IRQHandler ; 63:48 SPI Bridge + DCD AFE_IRQHandler ; 64:49 AFE + DCD SPIS_IRQHandler ; 65:50 SPI Slave + DCD GPIO_P7_IRQHandler ; 66:51 GPIO Port 7 + DCD GPIO_P8_IRQHandler ; 67:52 GPIO Port 8 +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + IMPORT SystemInit + IMPORT PreInit + LDR R0, =PreInit + BLX R0 + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 +__SPIN + WFI + BL __SPIN + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B NMI_Handler + ENDP + +HardFault_Handler PROC + EXPORT HardFault_Handler [WEAK] + B HardFault_Handler + ENDP + +MemManage_Handler PROC + EXPORT MemManage_Handler [WEAK] + B MemManage_Handler + ENDP + +BusFault_Handler PROC + EXPORT BusFault_Handler [WEAK] + B BusFault_Handler + ENDP + +UsageFault_Handler PROC + EXPORT UsageFault_Handler [WEAK] + B UsageFault_Handler + ENDP + +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B SVC_Handler + ENDP + +DebugMon_Handler PROC + EXPORT DebugMon_Handler [WEAK] + B DebugMon_Handler + ENDP + +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B PendSV_Handler + ENDP + +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B SysTick_Handler + ENDP + +Default_Handler PROC + + ; MAX32625 Interrupts + EXPORT CLKMAN_IRQHandler [WEAK] ; 16:01 CLKMAN + EXPORT PWRMAN_IRQHandler [WEAK] ; 17:02 PWRMAN + EXPORT FLC_IRQHandler [WEAK] ; 18:03 Flash Controller + EXPORT RTC0_IRQHandler [WEAK] ; 19:04 RTC INT0 + EXPORT RTC1_IRQHandler [WEAK] ; 20:05 RTC INT1 + EXPORT RTC2_IRQHandler [WEAK] ; 21:06 RTC INT2 + EXPORT RTC3_IRQHandler [WEAK] ; 22:07 RTC INT3 + EXPORT PMU_IRQHandler [WEAK] ; 23:08 PMU + EXPORT USB_IRQHandler [WEAK] ; 24:09 USB + EXPORT AES_IRQHandler [WEAK] ; 25:10 AES + EXPORT MAA_IRQHandler [WEAK] ; 26:11 MAA + EXPORT WDT0_IRQHandler [WEAK] ; 27:12 WATCHDOG0 + EXPORT WDT0_P_IRQHandler [WEAK] ; 28:13 WATCHDOG0 PRE-WINDOW + EXPORT WDT1_IRQHandler [WEAK] ; 29:14 WATCHDOG1 + EXPORT WDT1_P_IRQHandler [WEAK] ; 30:15 WATCHDOG1 PRE-WINDOW + EXPORT GPIO_P0_IRQHandler [WEAK] ; 31:16 GPIO Port 0 + EXPORT GPIO_P1_IRQHandler [WEAK] ; 32:17 GPIO Port 1 + EXPORT GPIO_P2_IRQHandler [WEAK] ; 33:18 GPIO Port 2 + EXPORT GPIO_P3_IRQHandler [WEAK] ; 34:19 GPIO Port 3 + EXPORT GPIO_P4_IRQHandler [WEAK] ; 35:20 GPIO Port 4 + EXPORT GPIO_P5_IRQHandler [WEAK] ; 36:21 GPIO Port 5 + EXPORT GPIO_P6_IRQHandler [WEAK] ; 37:22 GPIO Port 6 + EXPORT TMR0_IRQHandler [WEAK] ; 38:23 Timer32-0 + EXPORT TMR16_0_IRQHandler [WEAK] ; 39:24 Timer16-s0 + EXPORT TMR1_IRQHandler [WEAK] ; 40:25 Timer32-1 + EXPORT TMR16_1_IRQHandler [WEAK] ; 41:26 Timer16-s1 + EXPORT TMR2_IRQHandler [WEAK] ; 42:27 Timer32-2 + EXPORT TMR16_2_IRQHandler [WEAK] ; 43:28 Timer16-s2 + EXPORT TMR3_IRQHandler [WEAK] ; 44:29 Timer32-3 + EXPORT TMR16_3_IRQHandler [WEAK] ; 45:30 Timer16-s3 + EXPORT TMR4_IRQHandler [WEAK] ; 46:31 Timer32-4 + EXPORT TMR16_4_IRQHandler [WEAK] ; 47:32 Timer16-s4 + EXPORT TMR5_IRQHandler [WEAK] ; 48:33 Timer32-5 + EXPORT TMR16_5_IRQHandler [WEAK] ; 49:34 Timer16-s5 + EXPORT PT_IRQHandler [WEAK] ; 50:35 PT + EXPORT UART0_IRQHandler [WEAK] ; 51:36 UART0 + EXPORT UART1_IRQHandler [WEAK] ; 52:37 UART1 + EXPORT UART2_IRQHandler [WEAK] ; 53:38 UART0 + EXPORT UART3_IRQHandler [WEAK] ; 54:39 UART1 + EXPORT I2CM0_IRQHandler [WEAK] ; 55:40 I2C Master 0 + EXPORT I2CM1_IRQHandler [WEAK] ; 56:41 I2C Master 1 + EXPORT I2CM2_IRQHandler [WEAK] ; 57:42 I2C Master 2 + EXPORT I2CS_IRQHandler [WEAK] ; 58:43 I2C Slave + EXPORT SPIM0_IRQHandler [WEAK] ; 59:44 SPIM0 + EXPORT SPIM1_IRQHandler [WEAK] ; 60:45 SPIM1 + EXPORT SPIM2_IRQHandler [WEAK] ; 61:46 SPIM2 + EXPORT SPIB_IRQHandler [WEAK] ; 62:47 SPI Bridge + EXPORT OWM_IRQHandler [WEAK] ; 63:48 SPI Bridge + EXPORT AFE_IRQHandler [WEAK] ; 64:49 AFE + EXPORT SPIS_IRQHandler [WEAK] ; 65:50 SPI Slave + EXPORT GPIO_P7_IRQHandler [WEAK] ; 66:51 GPIO Port 7 + EXPORT GPIO_P8_IRQHandler [WEAK] ; 67:52 GPIO Port 8 + +CLKMAN_IRQHandler +PWRMAN_IRQHandler +FLC_IRQHandler +RTC0_IRQHandler +RTC1_IRQHandler +RTC2_IRQHandler +RTC3_IRQHandler +PMU_IRQHandler +USB_IRQHandler +AES_IRQHandler +MAA_IRQHandler +WDT0_IRQHandler +WDT0_P_IRQHandler +WDT1_IRQHandler +WDT1_P_IRQHandler +GPIO_P0_IRQHandler +GPIO_P1_IRQHandler +GPIO_P2_IRQHandler +GPIO_P3_IRQHandler +GPIO_P4_IRQHandler +GPIO_P5_IRQHandler +GPIO_P6_IRQHandler +TMR0_IRQHandler +TMR16_0_IRQHandler +TMR1_IRQHandler +TMR16_1_IRQHandler +TMR2_IRQHandler +TMR16_2_IRQHandler +TMR3_IRQHandler +TMR16_3_IRQHandler +TMR4_IRQHandler +TMR16_4_IRQHandler +TMR5_IRQHandler +TMR16_5_IRQHandler +PT_IRQHandler +UART0_IRQHandler +UART1_IRQHandler +UART2_IRQHandler +UART3_IRQHandler +I2CM0_IRQHandler +I2CM1_IRQHandler +I2CM2_IRQHandler +I2CS_IRQHandler +SPIM0_IRQHandler +SPIM1_IRQHandler +SPIM2_IRQHandler +SPIB_IRQHandler +OWM_IRQHandler +AFE_IRQHandler +SPIS_IRQHandler +GPIO_P7_IRQHandler +GPIO_P8_IRQHandler + + B . + ENDP + ALIGN + END diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/sys.cpp b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/sys.cpp new file mode 100644 index 00000000000..b6c24b38364 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/sys.cpp @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern char Image$$RW_IRAM1$$ZI$$Limit[]; + +extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { + uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit; + uint32_t sp_limit = __current_sp(); + + zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned + + struct __initial_stackheap r; + r.heap_base = zi_limit; + r.heap_limit = sp_limit; + return r; +} + +#ifdef __cplusplus +} +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/TARGET_MAX32625NEXPAQ/max32625.ld b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/TARGET_MAX32625NEXPAQ/max32625.ld new file mode 100644 index 00000000000..f51f007f1ad --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/TARGET_MAX32625NEXPAQ/max32625.ld @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00010000, LENGTH = 0x00070000 + RAM (rwx) : ORIGIN = 0x20003100, LENGTH = 0x00024F00 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + __bss_start__ = .; + *(.bss*) + *(COMMON) + __bss_end__ = .; + } > RAM + + .heap : + { + __end__ = .; + end = __end__; + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy : + { + *(.stack) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/startup_max32625.S b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/startup_max32625.S new file mode 100644 index 00000000000..efe55855033 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/startup_max32625.S @@ -0,0 +1,298 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + + .syntax unified + .arch armv7-m + + .section .stack + .align 3 +#ifdef __STACK_SIZE + .equ Stack_Size, __STACK_SIZE +#else + .equ Stack_Size, 0x00005000 +#endif + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#ifdef __HEAP_SIZE + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 0x0000A000 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + + .section .isr_vector + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler /* Reset Handler */ + .long NMI_Handler /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long MemManage_Handler /* MPU Fault Handler */ + .long BusFault_Handler /* Bus Fault Handler */ + .long UsageFault_Handler /* Usage Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long DebugMon_Handler /* Debug Monitor Handler */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + + /* MAX32625 Interrupts */ + .long CLKMAN_IRQHandler /* 16:01 CLKMAN */ + .long PWRMAN_IRQHandler /* 17:02 PWRMAN */ + .long FLC_IRQHandler /* 18:03 Flash Controller */ + .long RTC0_IRQHandler /* 19:04 RTC INT0 */ + .long RTC1_IRQHandler /* 20:05 RTC INT1 */ + .long RTC2_IRQHandler /* 21:06 RTC INT2 */ + .long RTC3_IRQHandler /* 22:07 RTC INT3 */ + .long PMU_IRQHandler /* 23:08 PMU */ + .long USB_IRQHandler /* 24:09 USB */ + .long AES_IRQHandler /* 25:10 AES */ + .long MAA_IRQHandler /* 26:11 MAA */ + .long WDT0_IRQHandler /* 27:12 WATCHDOG0 */ + .long WDT0_P_IRQHandler /* 28:13 WATCHDOG0 PRE-WINDOW */ + .long WDT1_IRQHandler /* 29:14 WATCHDOG1 */ + .long WDT1_P_IRQHandler /* 30:15 WATCHDOG1 PRE-WINDOW */ + .long GPIO_P0_IRQHandler /* 31:16 GPIO Port 0 */ + .long GPIO_P1_IRQHandler /* 32:17 GPIO Port 1 */ + .long GPIO_P2_IRQHandler /* 33:18 GPIO Port 2 */ + .long GPIO_P3_IRQHandler /* 34:19 GPIO Port 3 */ + .long GPIO_P4_IRQHandler /* 35:20 GPIO Port 4 */ + .long GPIO_P5_IRQHandler /* 36:21 GPIO Port 5 */ + .long GPIO_P6_IRQHandler /* 37:22 GPIO Port 6 */ + .long TMR0_IRQHandler /* 38:23 Timer32-0 */ + .long TMR16_0_IRQHandler /* 39:24 Timer16-s0 */ + .long TMR1_IRQHandler /* 40:25 Timer32-1 */ + .long TMR16_1_IRQHandler /* 41:26 Timer16-s1 */ + .long TMR2_IRQHandler /* 42:27 Timer32-2 */ + .long TMR16_2_IRQHandler /* 43:28 Timer16-s2 */ + .long TMR3_IRQHandler /* 44:29 Timer32-3 */ + .long TMR16_3_IRQHandler /* 45:30 Timer16-s3 */ + .long TMR4_IRQHandler /* 46:31 Timer32-4 */ + .long TMR16_4_IRQHandler /* 47:32 Timer16-s4 */ + .long TMR5_IRQHandler /* 48:33 Timer32-5 */ + .long TMR16_5_IRQHandler /* 49:34 Timer16-s5 */ + .long UART0_IRQHandler /* 50:35 UART0 */ + .long UART1_IRQHandler /* 51:36 UART1 */ + .long UART2_IRQHandler /* 52:37 UART2 */ + .long UART3_IRQHandler /* 53:38 UART3 */ + .long PT_IRQHandler /* 54:39 PT */ + .long I2CM0_IRQHandler /* 55:40 I2C Master 0 */ + .long I2CM1_IRQHandler /* 56:41 I2C Master 1 */ + .long I2CM2_IRQHandler /* 57:42 I2C Master 2 */ + .long I2CS_IRQHandler /* 58:43 I2C Slave */ + .long SPIM0_IRQHandler /* 59:44 SPIM0 */ + .long SPIM1_IRQHandler /* 60:45 SPIM1 */ + .long SPIM2_IRQHandler /* 61:46 SPIM2 */ + .long SPIB_IRQHandler /* 62:47 SPI Bridge */ + .long OWM_IRQHandler /* 63:48 One-wire Master */ + .long AFE_IRQHandler /* 64:49 AFE */ + .long SPIS_IRQHandler /* 65:50 SPI Slave */ + .long GPIO_P7_IRQHandler /* 66:51 GPIO Port 7 */ + .long GPIO_P8_IRQHandler /* 67:52 GPIO Port 8 */ + + + .text + .thumb + .thumb_func + .align 2 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r0, =__StackTop + mov sp, r0 + + ldr r0, =PreInit + blx r0 + cbnz r0, .SKIPRAMINIT + +/* Loop to copy data from read only memory to RAM. The ranges + * of copy from/to are specified by following symbols evaluated in + * linker script. + * _etext: End of code section, i.e., begin of data sections to copy from. + * _data /_edata: RAM address range that data should be + * copied to. Both must be aligned to 4 bytes boundary. */ + + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + +#if 0 +/* Here are two copies of loop implemenations. First one favors code size + * and the second one favors performance. Default uses the first one. + * Change to "#if 0" to use the second one */ +.LC0: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .LC0 +#else + subs r3, r2 + ble .LC1 +.LC0: + subs r3, #4 + ldr r0, [r1, r3] + str r0, [r2, r3] + bgt .LC0 +.LC1: +#endif + +/* + * Loop to zero out BSS section, which uses following symbols + * in linker script: + * _bss : start of BSS section. Must align to 4 + * _ebss : end of BSS section. Must align to 4 + */ + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 +.LC2: + cmp r1, r2 + itt lt + strlt r0, [r1], #4 + blt .LC2 + +.SKIPRAMINIT: + + ldr r0, =SystemInit + blx r0 + + ldr r0, =_start + blx r0 + +.SPIN: + /* Enter LP2 if main() ever returns. */ + wfi + bl .SPIN + +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_irq_handler handler_name + .align 1 + .thumb_func + .weak \handler_name + .type \handler_name, %function +\handler_name : + b . + .size \handler_name, . - \handler_name + .endm + + def_irq_handler NMI_Handler + def_irq_handler HardFault_Handler + def_irq_handler MemManage_Handler + def_irq_handler BusFault_Handler + def_irq_handler UsageFault_Handler + def_irq_handler SVC_Handler + def_irq_handler DebugMon_Handler + def_irq_handler PendSV_Handler + def_irq_handler SysTick_Handler + def_irq_handler Default_Handler + + /* MAX32625 Interrupts */ + def_irq_handler CLKMAN_IRQHandler /* 16:01 CLKMAN */ + def_irq_handler PWRMAN_IRQHandler /* 17:02 PWRMAN */ + def_irq_handler FLC_IRQHandler /* 18:03 Flash Controller */ + def_irq_handler RTC0_IRQHandler /* 19:04 RTC INT0 */ + def_irq_handler RTC1_IRQHandler /* 20:05 RTC INT1 */ + def_irq_handler RTC2_IRQHandler /* 21:06 RTC INT2 */ + def_irq_handler RTC3_IRQHandler /* 22:07 RTC INT3 */ + def_irq_handler PMU_IRQHandler /* 23:08 PMU */ + def_irq_handler USB_IRQHandler /* 24:09 USB */ + def_irq_handler AES_IRQHandler /* 25:10 AES */ + def_irq_handler MAA_IRQHandler /* 26:11 MAA */ + def_irq_handler WDT0_IRQHandler /* 27:12 WATCHDOG0 */ + def_irq_handler WDT0_P_IRQHandler /* 28:13 WATCHDOG0 PRE-WINDOW */ + def_irq_handler WDT1_IRQHandler /* 29:14 WATCHDOG1 */ + def_irq_handler WDT1_P_IRQHandler /* 30:15 WATCHDOG1 PRE-WINDOW */ + def_irq_handler GPIO_P0_IRQHandler /* 31:16 GPIO Port 0 */ + def_irq_handler GPIO_P1_IRQHandler /* 32:17 GPIO Port 1 */ + def_irq_handler GPIO_P2_IRQHandler /* 33:18 GPIO Port 2 */ + def_irq_handler GPIO_P3_IRQHandler /* 34:19 GPIO Port 3 */ + def_irq_handler GPIO_P4_IRQHandler /* 35:20 GPIO Port 4 */ + def_irq_handler GPIO_P5_IRQHandler /* 36:21 GPIO Port 5 */ + def_irq_handler GPIO_P6_IRQHandler /* 37:22 GPIO Port 6 */ + def_irq_handler TMR0_IRQHandler /* 38:23 Timer32-0 */ + def_irq_handler TMR16_0_IRQHandler /* 39:24 Timer16-s0 */ + def_irq_handler TMR1_IRQHandler /* 40:25 Timer32-1 */ + def_irq_handler TMR16_1_IRQHandler /* 41:26 Timer16-s1 */ + def_irq_handler TMR2_IRQHandler /* 42:27 Timer32-2 */ + def_irq_handler TMR16_2_IRQHandler /* 43:28 Timer16-s2 */ + def_irq_handler TMR3_IRQHandler /* 44:29 Timer32-3 */ + def_irq_handler TMR16_3_IRQHandler /* 45:30 Timer16-s3 */ + def_irq_handler TMR4_IRQHandler /* 46:31 Timer32-4 */ + def_irq_handler TMR16_4_IRQHandler /* 47:32 Timer16-s4 */ + def_irq_handler TMR5_IRQHandler /* 48:33 Timer32-5 */ + def_irq_handler TMR16_5_IRQHandler /* 49:34 Timer16-s5 */ + def_irq_handler PT_IRQHandler /* 50:35 PT */ + def_irq_handler UART0_IRQHandler /* 51:36 UART0 */ + def_irq_handler UART1_IRQHandler /* 52:37 UART1 */ + def_irq_handler UART2_IRQHandler /* 53:38 UART0 */ + def_irq_handler UART3_IRQHandler /* 54:39 UART1 */ + def_irq_handler I2CM0_IRQHandler /* 55:40 I2C Master 0 */ + def_irq_handler I2CM1_IRQHandler /* 56:41 I2C Master 1 */ + def_irq_handler I2CM2_IRQHandler /* 57:42 I2C Master 2 */ + def_irq_handler I2CS_IRQHandler /* 58:43 I2C Slave */ + def_irq_handler SPIM0_IRQHandler /* 59:44 SPIM0 */ + def_irq_handler SPIM1_IRQHandler /* 60:45 SPIM1 */ + def_irq_handler SPIM2_IRQHandler /* 61:46 SPIM2 */ + def_irq_handler SPIB_IRQHandler /* 62:47 SPI Bridge */ + def_irq_handler OWM_IRQHandler /* 63:48 SPI Bridge */ + def_irq_handler AFE_IRQHandler /* 64:49 AFE */ + def_irq_handler SPIS_IRQHandler /* 65:50 SPI Slave */ + def_irq_handler GPIO_P7_IRQHandler /* 66:51 GPIO Port 7 */ + def_irq_handler GPIO_P8_IRQHandler /* 67:52 GPIO Port 8 */ + .end diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/TARGET_MAX32625NEXPAQ/MAX32625.icf b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/TARGET_MAX32625NEXPAQ/MAX32625.icf new file mode 100644 index 00000000000..bba1c8067e8 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/TARGET_MAX32625NEXPAQ/MAX32625.icf @@ -0,0 +1,29 @@ +/* [ROM] */ +define symbol __intvec_start__ = 0x00010000; +define symbol __region_ROM_start__ = 0x00010000; +define symbol __region_ROM_end__ = 0x0007FFFF; + +/* [RAM] Vector table dynamic copy: 68 vectors * 4 bytes = 272 (0x110) bytes */ +define symbol __NVIC_start__ = 0x00010000; +define symbol __NVIC_end__ = 0x00010110; /* to be aligned on 8 bytes */ +define symbol __region_RAM_start__ = 0x20003100; +define symbol __region_RAM_end__ = 0x20027FFF; + +/* Memory regions */ +define memory mem with size = 4G; +define region ROM_region = mem:[from __region_ROM_start__ to __region_ROM_end__]; +define region RAM_region = mem:[from __region_RAM_start__ to __region_RAM_end__]; + +/* Stack and Heap */ +define symbol __size_cstack__ = 0x5000; +define symbol __size_heap__ = 0xA000; +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/startup_MAX32625.S b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/startup_MAX32625.S new file mode 100644 index 00000000000..91a154db4f6 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/startup_MAX32625.S @@ -0,0 +1,450 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN PreInit + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __vector_table_modify + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler +__vector_table_modify + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + ; MAX32625 Specific Interrupts + DCD CLKMAN_IRQHandler ; 16:01 CLKMAN */ + DCD PWRMAN_IRQHandler ; 17:02 PWRMAN */ + DCD FLC_IRQHandler ; 18:03 Flash Controller */ + DCD RTC0_IRQHandler ; 19:04 RTC INT0 */ + DCD RTC1_IRQHandler ; 20:05 RTC INT1 */ + DCD RTC2_IRQHandler ; 21:06 RTC INT2 */ + DCD RTC3_IRQHandler ; 22:07 RTC INT3 */ + DCD PMU_IRQHandler ; 23:08 PMU */ + DCD USB_IRQHandler ; 24:09 USB */ + DCD AES_IRQHandler ; 25:10 AES */ + DCD MAA_IRQHandler ; 26:11 MAA */ + DCD WDT0_IRQHandler ; 27:12 WATCHDOG0 */ + DCD WDT0_P_IRQHandler ; 28:13 WATCHDOG0 PRE-WINDOW */ + DCD WDT1_IRQHandler ; 29:14 WATCHDOG1 */ + DCD WDT1_P_IRQHandler ; 30:15 WATCHDOG1 PRE-WINDOW */ + DCD GPIO_P0_IRQHandler ; 31:16 GPIO Port 0 */ + DCD GPIO_P1_IRQHandler ; 32:17 GPIO Port 1 */ + DCD GPIO_P2_IRQHandler ; 33:18 GPIO Port 2 */ + DCD GPIO_P3_IRQHandler ; 34:19 GPIO Port 3 */ + DCD GPIO_P4_IRQHandler ; 35:20 GPIO Port 4 */ + DCD GPIO_P5_IRQHandler ; 36:21 GPIO Port 5 */ + DCD GPIO_P6_IRQHandler ; 37:22 GPIO Port 6 */ + DCD TMR0_IRQHandler ; 38:23 Timer32-0 */ + DCD TMR16_0_IRQHandler ; 39:24 Timer16-s0 */ + DCD TMR1_IRQHandler ; 40:25 Timer32-1 */ + DCD TMR16_1_IRQHandler ; 41:26 Timer16-s1 */ + DCD TMR2_IRQHandler ; 42:27 Timer32-2 */ + DCD TMR16_2_IRQHandler ; 43:28 Timer16-s2 */ + DCD TMR3_IRQHandler ; 44:29 Timer32-3 */ + DCD TMR16_3_IRQHandler ; 45:30 Timer16-s3 */ + DCD TMR4_IRQHandler ; 46:31 Timer32-4 */ + DCD TMR16_4_IRQHandler ; 47:32 Timer16-s4 */ + DCD TMR5_IRQHandler ; 48:33 Timer32-5 */ + DCD TMR16_5_IRQHandler ; 49:34 Timer16-s5 */ + DCD UART0_IRQHandler ; 50:35 UART0 */ + DCD UART1_IRQHandler ; 51:36 UART1 */ + DCD UART2_IRQHandler ; 52:37 UART2 */ + DCD UART3_IRQHandler ; 53:38 UART3 */ + DCD PT_IRQHandler ; 54:39 PT */ + DCD I2CM0_IRQHandler ; 55:40 I2C Master 0 */ + DCD I2CM1_IRQHandler ; 56:41 I2C Master 1 */ + DCD I2CM2_IRQHandler ; 57:42 I2C Master 2 */ + DCD I2CS_IRQHandler ; 58:43 I2C Slave */ + DCD SPIM0_IRQHandler ; 59:44 SPI Master 0 */ + DCD SPIM1_IRQHandler ; 60:45 SPI Master 1 */ + DCD SPIM2_IRQHandler ; 61:46 SPI Master 2 */ + DCD SPIB_IRQHandler ; 62:47 SPI Bridge */ + DCD OWM_IRQHandler ; 63:48 One-wire Master */ + DCD AFE_IRQHandler ; 64:49 AFE */ + DCD SPIS_IRQHandler ; 65:50 SPI Slave + DCD GPIO_P7_IRQHandler ; 66:51 GPIO Port 7 + DCD GPIO_P8_IRQHandler ; 67:52 GPIO Port 8 + +__Vectors_End +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + + LDR R0, =PreInit + BLX R0 + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK CLKMAN_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +CLKMAN_IRQHandler + B CLKMAN_IRQHandler + + PUBWEAK PWRMAN_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PWRMAN_IRQHandler + B PWRMAN_IRQHandler + + PUBWEAK FLC_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +FLC_IRQHandler + B FLC_IRQHandler + + PUBWEAK RTC0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC0_IRQHandler + B RTC0_IRQHandler + + PUBWEAK RTC1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC1_IRQHandler + B RTC1_IRQHandler + + PUBWEAK RTC2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC2_IRQHandler + B RTC2_IRQHandler + + PUBWEAK RTC3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC3_IRQHandler + B RTC3_IRQHandler + + PUBWEAK PMU_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PMU_IRQHandler + B PMU_IRQHandler + + PUBWEAK USB_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +USB_IRQHandler + B USB_IRQHandler + + PUBWEAK AES_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +AES_IRQHandler + B AES_IRQHandler + + PUBWEAK MAA_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +MAA_IRQHandler + B MAA_IRQHandler + + PUBWEAK WDT0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +WDT0_IRQHandler + B WDT0_IRQHandler + + PUBWEAK WDT0_P_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +WDT0_P_IRQHandler + B WDT0_P_IRQHandler + + PUBWEAK WDT1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +WDT1_IRQHandler + B WDT1_IRQHandler + + PUBWEAK WDT1_P_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +WDT1_P_IRQHandler + B WDT1_P_IRQHandler + + PUBWEAK GPIO_P0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIO_P0_IRQHandler + B GPIO_P0_IRQHandler + + PUBWEAK GPIO_P1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIO_P1_IRQHandler + B GPIO_P1_IRQHandler + + PUBWEAK GPIO_P2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIO_P2_IRQHandler + B GPIO_P2_IRQHandler + + PUBWEAK GPIO_P3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIO_P3_IRQHandler + B GPIO_P3_IRQHandler + + PUBWEAK GPIO_P4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIO_P4_IRQHandler + B GPIO_P4_IRQHandler + + PUBWEAK GPIO_P5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIO_P5_IRQHandler + B GPIO_P5_IRQHandler + + PUBWEAK GPIO_P6_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIO_P6_IRQHandler + B GPIO_P6_IRQHandler + + PUBWEAK TMR0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR0_IRQHandler + B TMR0_IRQHandler + + PUBWEAK TMR16_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR16_0_IRQHandler + B TMR16_0_IRQHandler + + PUBWEAK TMR1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR1_IRQHandler + B TMR1_IRQHandler + + PUBWEAK TMR16_1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR16_1_IRQHandler + B TMR16_1_IRQHandler + + PUBWEAK TMR2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR2_IRQHandler + B TMR2_IRQHandler + + PUBWEAK TMR16_2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR16_2_IRQHandler + B TMR16_2_IRQHandler + + PUBWEAK TMR3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR3_IRQHandler + B TMR3_IRQHandler + + PUBWEAK TMR16_3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR16_3_IRQHandler + B TMR16_3_IRQHandler + + PUBWEAK TMR4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR4_IRQHandler + B TMR4_IRQHandler + + PUBWEAK TMR16_4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR16_4_IRQHandler + B TMR16_4_IRQHandler + + PUBWEAK TMR5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR5_IRQHandler + B TMR5_IRQHandler + + PUBWEAK TMR16_5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR16_5_IRQHandler + B TMR16_5_IRQHandler + + PUBWEAK UART0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +UART0_IRQHandler + B UART0_IRQHandler + + PUBWEAK UART1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +UART1_IRQHandler + B UART1_IRQHandler + + PUBWEAK UART2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +UART2_IRQHandler + B UART2_IRQHandler + + PUBWEAK UART3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +UART3_IRQHandler + B UART3_IRQHandler + + PUBWEAK PT_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PT_IRQHandler + B PT_IRQHandler + + PUBWEAK I2CM0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +I2CM0_IRQHandler + B I2CM0_IRQHandler + + PUBWEAK I2CM1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +I2CM1_IRQHandler + B I2CM1_IRQHandler + + PUBWEAK I2CM2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +I2CM2_IRQHandler + B I2CM2_IRQHandler + + PUBWEAK I2CS_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +I2CS_IRQHandler + B I2CS_IRQHandler + + PUBWEAK SPIM0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM0_IRQHandler + B SPIM0_IRQHandler + + PUBWEAK SPIM1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM1_IRQHandler + B SPIM1_IRQHandler + + PUBWEAK SPIM2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM2_IRQHandler + B SPIM2_IRQHandler + + PUBWEAK SPIB_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIB_IRQHandler + B SPIB_IRQHandler + + PUBWEAK OWM_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +OWM_IRQHandler + B OWM_IRQHandler + + PUBWEAK AFE_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +AFE_IRQHandler + B AFE_IRQHandler + + PUBWEAK SPIS_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIS_IRQHandler + B SPIS_IRQHandler + + PUBWEAK GPIO_P7_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIO_P7_IRQHandler + B GPIO_P7_IRQHandler + + PUBWEAK GPIO_P8_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIO_P8_IRQHandler + B GPIO_P8_IRQHandler + END diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/adc_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/adc_regs.h new file mode 100644 index 00000000000..a249d9851c7 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/adc_regs.h @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_ADC_REGS_H_ +#define _MXC_ADC_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t ctrl; /* 0x0000 ADC Control */ + __IO uint32_t status; /* 0x0004 ADC Status */ + __IO uint32_t data; /* 0x0008 ADC Output Data */ + __IO uint32_t intr; /* 0x000C ADC Interrupt Control Register */ + __IO uint32_t limit[4]; /* 0x0010-0x001C ADC Limit 0..3 */ + __IO uint32_t afe_ctrl; /* 0x0020 AFE Control Register */ + __IO uint32_t ro_cal0; /* 0x0024 RO Trim Calibration Register 0 */ + __IO uint32_t ro_cal1; /* 0x0028 RO Trim Calibration Register 1 */ + __IO uint32_t ro_cal2; /* 0x002C RO Trim Calibration Register 2 */ +} mxc_adc_regs_t; + + +/* + Register offsets for module ADC. +*/ + +#define MXC_R_ADC_OFFS_CTRL ((uint32_t)0x00000000UL) +#define MXC_R_ADC_OFFS_STATUS ((uint32_t)0x00000004UL) +#define MXC_R_ADC_OFFS_DATA ((uint32_t)0x00000008UL) +#define MXC_R_ADC_OFFS_INTR ((uint32_t)0x0000000CUL) +#define MXC_R_ADC_OFFS_LIMIT0 ((uint32_t)0x00000010UL) +#define MXC_R_ADC_OFFS_LIMIT1 ((uint32_t)0x00000014UL) +#define MXC_R_ADC_OFFS_LIMIT2 ((uint32_t)0x00000018UL) +#define MXC_R_ADC_OFFS_LIMIT3 ((uint32_t)0x0000001CUL) +#define MXC_R_ADC_OFFS_AFE_CTRL ((uint32_t)0x00000020UL) +#define MXC_R_ADC_OFFS_RO_CAL0 ((uint32_t)0x00000024UL) +#define MXC_R_ADC_OFFS_RO_CAL1 ((uint32_t)0x00000028UL) +#define MXC_R_ADC_OFFS_RO_CAL2 ((uint32_t)0x0000002CUL) + + +/* + Field positions and masks for module ADC. +*/ + +#define MXC_F_ADC_CTRL_CPU_ADC_START_POS 0 +#define MXC_F_ADC_CTRL_CPU_ADC_START ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_CPU_ADC_START_POS)) +#define MXC_F_ADC_CTRL_ADC_PU_POS 1 +#define MXC_F_ADC_CTRL_ADC_PU ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_ADC_PU_POS)) +#define MXC_F_ADC_CTRL_BUF_PU_POS 2 +#define MXC_F_ADC_CTRL_BUF_PU ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_BUF_PU_POS)) +#define MXC_F_ADC_CTRL_ADC_REFBUF_PU_POS 3 +#define MXC_F_ADC_CTRL_ADC_REFBUF_PU ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_ADC_REFBUF_PU_POS)) +#define MXC_F_ADC_CTRL_ADC_CHGPUMP_PU_POS 4 +#define MXC_F_ADC_CTRL_ADC_CHGPUMP_PU ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_ADC_CHGPUMP_PU_POS)) +#define MXC_F_ADC_CTRL_BUF_CHOP_DIS_POS 5 +#define MXC_F_ADC_CTRL_BUF_CHOP_DIS ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_BUF_CHOP_DIS_POS)) +#define MXC_F_ADC_CTRL_BUF_PUMP_DIS_POS 6 +#define MXC_F_ADC_CTRL_BUF_PUMP_DIS ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_BUF_PUMP_DIS_POS)) +#define MXC_F_ADC_CTRL_BUF_BYPASS_POS 7 +#define MXC_F_ADC_CTRL_BUF_BYPASS ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_BUF_BYPASS_POS)) +#define MXC_F_ADC_CTRL_ADC_REFSCL_POS 8 +#define MXC_F_ADC_CTRL_ADC_REFSCL ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_ADC_REFSCL_POS)) +#define MXC_F_ADC_CTRL_ADC_SCALE_POS 9 +#define MXC_F_ADC_CTRL_ADC_SCALE ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_ADC_SCALE_POS)) +#define MXC_F_ADC_CTRL_ADC_REFSEL_POS 10 +#define MXC_F_ADC_CTRL_ADC_REFSEL ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_ADC_REFSEL_POS)) +#define MXC_F_ADC_CTRL_ADC_CLK_EN_POS 11 +#define MXC_F_ADC_CTRL_ADC_CLK_EN ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_ADC_CLK_EN_POS)) +#define MXC_F_ADC_CTRL_ADC_CHSEL_POS 12 +#define MXC_F_ADC_CTRL_ADC_CHSEL ((uint32_t)(0x0000000FUL << MXC_F_ADC_CTRL_ADC_CHSEL_POS)) + +#if (MXC_ADC_REV == 0) +#define MXC_F_ADC_CTRL_ADC_XREF_POS 16 +#define MXC_F_ADC_CTRL_ADC_XREF ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_ADC_XREF_POS)) +#endif + +#define MXC_F_ADC_CTRL_ADC_DATAALIGN_POS 17 +#define MXC_F_ADC_CTRL_ADC_DATAALIGN ((uint32_t)(0x00000001UL << MXC_F_ADC_CTRL_ADC_DATAALIGN_POS)) +#define MXC_F_ADC_CTRL_AFE_PWR_UP_DLY_POS 24 +#define MXC_F_ADC_CTRL_AFE_PWR_UP_DLY ((uint32_t)(0x000000FFUL << MXC_F_ADC_CTRL_AFE_PWR_UP_DLY_POS)) + +#define MXC_F_ADC_STATUS_ADC_ACTIVE_POS 0 +#define MXC_F_ADC_STATUS_ADC_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_ADC_STATUS_ADC_ACTIVE_POS)) +#define MXC_F_ADC_STATUS_RO_CAL_ATOMIC_ACTIVE_POS 1 +#define MXC_F_ADC_STATUS_RO_CAL_ATOMIC_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_ADC_STATUS_RO_CAL_ATOMIC_ACTIVE_POS)) +#define MXC_F_ADC_STATUS_AFE_PWR_UP_ACTIVE_POS 2 +#define MXC_F_ADC_STATUS_AFE_PWR_UP_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_ADC_STATUS_AFE_PWR_UP_ACTIVE_POS)) +#define MXC_F_ADC_STATUS_ADC_OVERFLOW_POS 3 +#define MXC_F_ADC_STATUS_ADC_OVERFLOW ((uint32_t)(0x00000001UL << MXC_F_ADC_STATUS_ADC_OVERFLOW_POS)) + +#define MXC_F_ADC_DATA_ADC_DATA_POS 0 +#define MXC_F_ADC_DATA_ADC_DATA ((uint32_t)(0x0000FFFFUL << MXC_F_ADC_DATA_ADC_DATA_POS)) + +#define MXC_F_ADC_INTR_ADC_DONE_IE_POS 0 +#define MXC_F_ADC_INTR_ADC_DONE_IE ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_ADC_DONE_IE_POS)) +#define MXC_F_ADC_INTR_ADC_REF_READY_IE_POS 1 +#define MXC_F_ADC_INTR_ADC_REF_READY_IE ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_ADC_REF_READY_IE_POS)) +#define MXC_F_ADC_INTR_ADC_HI_LIMIT_IE_POS 2 +#define MXC_F_ADC_INTR_ADC_HI_LIMIT_IE ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_ADC_HI_LIMIT_IE_POS)) +#define MXC_F_ADC_INTR_ADC_LO_LIMIT_IE_POS 3 +#define MXC_F_ADC_INTR_ADC_LO_LIMIT_IE ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_ADC_LO_LIMIT_IE_POS)) +#define MXC_F_ADC_INTR_ADC_OVERFLOW_IE_POS 4 +#define MXC_F_ADC_INTR_ADC_OVERFLOW_IE ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_ADC_OVERFLOW_IE_POS)) +#define MXC_F_ADC_INTR_RO_CAL_DONE_IE_POS 5 +#define MXC_F_ADC_INTR_RO_CAL_DONE_IE ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_RO_CAL_DONE_IE_POS)) +#define MXC_F_ADC_INTR_ADC_DONE_IF_POS 16 +#define MXC_F_ADC_INTR_ADC_DONE_IF ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_ADC_DONE_IF_POS)) +#define MXC_F_ADC_INTR_ADC_REF_READY_IF_POS 17 +#define MXC_F_ADC_INTR_ADC_REF_READY_IF ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_ADC_REF_READY_IF_POS)) +#define MXC_F_ADC_INTR_ADC_HI_LIMIT_IF_POS 18 +#define MXC_F_ADC_INTR_ADC_HI_LIMIT_IF ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_ADC_HI_LIMIT_IF_POS)) +#define MXC_F_ADC_INTR_ADC_LO_LIMIT_IF_POS 19 +#define MXC_F_ADC_INTR_ADC_LO_LIMIT_IF ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_ADC_LO_LIMIT_IF_POS)) +#define MXC_F_ADC_INTR_ADC_OVERFLOW_IF_POS 20 +#define MXC_F_ADC_INTR_ADC_OVERFLOW_IF ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_ADC_OVERFLOW_IF_POS)) +#define MXC_F_ADC_INTR_RO_CAL_DONE_IF_POS 21 +#define MXC_F_ADC_INTR_RO_CAL_DONE_IF ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_RO_CAL_DONE_IF_POS)) +#define MXC_F_ADC_INTR_ADC_INT_PENDING_POS 22 +#define MXC_F_ADC_INTR_ADC_INT_PENDING ((uint32_t)(0x00000001UL << MXC_F_ADC_INTR_ADC_INT_PENDING_POS)) + +#define MXC_F_ADC_LIMIT0_CH_LO_LIMIT_POS 0 +#define MXC_F_ADC_LIMIT0_CH_LO_LIMIT ((uint32_t)(0x000003FFUL << MXC_F_ADC_LIMIT0_CH_LO_LIMIT_POS)) +#define MXC_F_ADC_LIMIT0_CH_HI_LIMIT_POS 12 +#define MXC_F_ADC_LIMIT0_CH_HI_LIMIT ((uint32_t)(0x000003FFUL << MXC_F_ADC_LIMIT0_CH_HI_LIMIT_POS)) +#define MXC_F_ADC_LIMIT0_CH_SEL_POS 24 +#define MXC_F_ADC_LIMIT0_CH_SEL ((uint32_t)(0x0000000FUL << MXC_F_ADC_LIMIT0_CH_SEL_POS)) +#define MXC_F_ADC_LIMIT0_CH_LO_LIMIT_EN_POS 28 +#define MXC_F_ADC_LIMIT0_CH_LO_LIMIT_EN ((uint32_t)(0x00000001UL << MXC_F_ADC_LIMIT0_CH_LO_LIMIT_EN_POS)) +#define MXC_F_ADC_LIMIT0_CH_HI_LIMIT_EN_POS 29 +#define MXC_F_ADC_LIMIT0_CH_HI_LIMIT_EN ((uint32_t)(0x00000001UL << MXC_F_ADC_LIMIT0_CH_HI_LIMIT_EN_POS)) + +#define MXC_F_ADC_LIMIT1_CH_LO_LIMIT_POS 0 +#define MXC_F_ADC_LIMIT1_CH_LO_LIMIT ((uint32_t)(0x000003FFUL << MXC_F_ADC_LIMIT1_CH_LO_LIMIT_POS)) +#define MXC_F_ADC_LIMIT1_CH_HI_LIMIT_POS 12 +#define MXC_F_ADC_LIMIT1_CH_HI_LIMIT ((uint32_t)(0x000003FFUL << MXC_F_ADC_LIMIT1_CH_HI_LIMIT_POS)) +#define MXC_F_ADC_LIMIT1_CH_SEL_POS 24 +#define MXC_F_ADC_LIMIT1_CH_SEL ((uint32_t)(0x0000000FUL << MXC_F_ADC_LIMIT1_CH_SEL_POS)) +#define MXC_F_ADC_LIMIT1_CH_LO_LIMIT_EN_POS 28 +#define MXC_F_ADC_LIMIT1_CH_LO_LIMIT_EN ((uint32_t)(0x00000001UL << MXC_F_ADC_LIMIT1_CH_LO_LIMIT_EN_POS)) +#define MXC_F_ADC_LIMIT1_CH_HI_LIMIT_EN_POS 29 +#define MXC_F_ADC_LIMIT1_CH_HI_LIMIT_EN ((uint32_t)(0x00000001UL << MXC_F_ADC_LIMIT1_CH_HI_LIMIT_EN_POS)) + +#define MXC_F_ADC_LIMIT2_CH_LO_LIMIT_POS 0 +#define MXC_F_ADC_LIMIT2_CH_LO_LIMIT ((uint32_t)(0x000003FFUL << MXC_F_ADC_LIMIT2_CH_LO_LIMIT_POS)) +#define MXC_F_ADC_LIMIT2_CH_HI_LIMIT_POS 12 +#define MXC_F_ADC_LIMIT2_CH_HI_LIMIT ((uint32_t)(0x000003FFUL << MXC_F_ADC_LIMIT2_CH_HI_LIMIT_POS)) +#define MXC_F_ADC_LIMIT2_CH_SEL_POS 24 +#define MXC_F_ADC_LIMIT2_CH_SEL ((uint32_t)(0x0000000FUL << MXC_F_ADC_LIMIT2_CH_SEL_POS)) +#define MXC_F_ADC_LIMIT2_CH_LO_LIMIT_EN_POS 28 +#define MXC_F_ADC_LIMIT2_CH_LO_LIMIT_EN ((uint32_t)(0x00000001UL << MXC_F_ADC_LIMIT2_CH_LO_LIMIT_EN_POS)) +#define MXC_F_ADC_LIMIT2_CH_HI_LIMIT_EN_POS 29 +#define MXC_F_ADC_LIMIT2_CH_HI_LIMIT_EN ((uint32_t)(0x00000001UL << MXC_F_ADC_LIMIT2_CH_HI_LIMIT_EN_POS)) + +#define MXC_F_ADC_LIMIT3_CH_LO_LIMIT_POS 0 +#define MXC_F_ADC_LIMIT3_CH_LO_LIMIT ((uint32_t)(0x000003FFUL << MXC_F_ADC_LIMIT3_CH_LO_LIMIT_POS)) +#define MXC_F_ADC_LIMIT3_CH_HI_LIMIT_POS 12 +#define MXC_F_ADC_LIMIT3_CH_HI_LIMIT ((uint32_t)(0x000003FFUL << MXC_F_ADC_LIMIT3_CH_HI_LIMIT_POS)) +#define MXC_F_ADC_LIMIT3_CH_SEL_POS 24 +#define MXC_F_ADC_LIMIT3_CH_SEL ((uint32_t)(0x0000000FUL << MXC_F_ADC_LIMIT3_CH_SEL_POS)) +#define MXC_F_ADC_LIMIT3_CH_LO_LIMIT_EN_POS 28 +#define MXC_F_ADC_LIMIT3_CH_LO_LIMIT_EN ((uint32_t)(0x00000001UL << MXC_F_ADC_LIMIT3_CH_LO_LIMIT_EN_POS)) +#define MXC_F_ADC_LIMIT3_CH_HI_LIMIT_EN_POS 29 +#define MXC_F_ADC_LIMIT3_CH_HI_LIMIT_EN ((uint32_t)(0x00000001UL << MXC_F_ADC_LIMIT3_CH_HI_LIMIT_EN_POS)) + +#define MXC_F_ADC_AFE_CTRL_TMON_INTBIAS_EN_POS 8 +#define MXC_F_ADC_AFE_CTRL_TMON_INTBIAS_EN ((uint32_t)(0x00000001UL << MXC_F_ADC_AFE_CTRL_TMON_INTBIAS_EN_POS)) +#define MXC_F_ADC_AFE_CTRL_TMON_EXTBIAS_EN_POS 9 +#define MXC_F_ADC_AFE_CTRL_TMON_EXTBIAS_EN ((uint32_t)(0x00000001UL << MXC_F_ADC_AFE_CTRL_TMON_EXTBIAS_EN_POS)) + +#define MXC_F_ADC_RO_CAL0_RO_CAL_EN_POS 0 +#define MXC_F_ADC_RO_CAL0_RO_CAL_EN ((uint32_t)(0x00000001UL << MXC_F_ADC_RO_CAL0_RO_CAL_EN_POS)) +#define MXC_F_ADC_RO_CAL0_RO_CAL_RUN_POS 1 +#define MXC_F_ADC_RO_CAL0_RO_CAL_RUN ((uint32_t)(0x00000001UL << MXC_F_ADC_RO_CAL0_RO_CAL_RUN_POS)) +#define MXC_F_ADC_RO_CAL0_RO_CAL_LOAD_POS 2 +#define MXC_F_ADC_RO_CAL0_RO_CAL_LOAD ((uint32_t)(0x00000001UL << MXC_F_ADC_RO_CAL0_RO_CAL_LOAD_POS)) +#define MXC_F_ADC_RO_CAL0_RO_CAL_ATOMIC_POS 4 +#define MXC_F_ADC_RO_CAL0_RO_CAL_ATOMIC ((uint32_t)(0x00000001UL << MXC_F_ADC_RO_CAL0_RO_CAL_ATOMIC_POS)) +#define MXC_F_ADC_RO_CAL0_DUMMY_POS 5 +#define MXC_F_ADC_RO_CAL0_DUMMY ((uint32_t)(0x00000007UL << MXC_F_ADC_RO_CAL0_DUMMY_POS)) +#define MXC_F_ADC_RO_CAL0_TRM_MU_POS 8 +#define MXC_F_ADC_RO_CAL0_TRM_MU ((uint32_t)(0x00000FFFUL << MXC_F_ADC_RO_CAL0_TRM_MU_POS)) +#define MXC_F_ADC_RO_CAL0_RO_TRM_POS 23 +#define MXC_F_ADC_RO_CAL0_RO_TRM ((uint32_t)(0x000001FFUL << MXC_F_ADC_RO_CAL0_RO_TRM_POS)) + +#define MXC_F_ADC_RO_CAL1_TRM_INIT_POS 0 +#define MXC_F_ADC_RO_CAL1_TRM_INIT ((uint32_t)(0x000001FFUL << MXC_F_ADC_RO_CAL1_TRM_INIT_POS)) +#define MXC_F_ADC_RO_CAL1_TRM_MIN_POS 10 +#define MXC_F_ADC_RO_CAL1_TRM_MIN ((uint32_t)(0x000001FFUL << MXC_F_ADC_RO_CAL1_TRM_MIN_POS)) +#define MXC_F_ADC_RO_CAL1_TRM_MAX_POS 20 +#define MXC_F_ADC_RO_CAL1_TRM_MAX ((uint32_t)(0x000001FFUL << MXC_F_ADC_RO_CAL1_TRM_MAX_POS)) + +#define MXC_F_ADC_RO_CAL2_AUTO_CAL_DONE_CNT_POS 0 +#define MXC_F_ADC_RO_CAL2_AUTO_CAL_DONE_CNT ((uint32_t)(0x000000FFUL << MXC_F_ADC_RO_CAL2_AUTO_CAL_DONE_CNT_POS)) + +#define MXC_V_ADC_CTRL_ADC_CHSEL_AIN0 ((uint32_t)(0x00000000UL)) +#define MXC_V_ADC_CTRL_ADC_CHSEL_AIN1 ((uint32_t)(0x00000001UL)) +#define MXC_V_ADC_CTRL_ADC_CHSEL_AIN2 ((uint32_t)(0x00000002UL)) +#define MXC_V_ADC_CTRL_ADC_CHSEL_AIN3 ((uint32_t)(0x00000003UL)) +#define MXC_V_ADC_CTRL_ADC_CHSEL_AIN0_DIV_5 ((uint32_t)(0x00000004UL)) +#define MXC_V_ADC_CTRL_ADC_CHSEL_AIN1_DIV_5 ((uint32_t)(0x00000005UL)) +#define MXC_V_ADC_CTRL_ADC_CHSEL_VDDB_DIV_4 ((uint32_t)(0x00000006UL)) +#define MXC_V_ADC_CTRL_ADC_CHSEL_VDD18 ((uint32_t)(0x00000007UL)) +#define MXC_V_ADC_CTRL_ADC_CHSEL_VDD12 ((uint32_t)(0x00000008UL)) +#define MXC_V_ADC_CTRL_ADC_CHSEL_VRTC_DIV_2 ((uint32_t)(0x00000009UL)) +#define MXC_V_ADC_CTRL_ADC_CHSEL_TMON ((uint32_t)(0x0000000AUL)) + +#if(MXC_ADC_REV > 0) +#define MXC_V_ADC_CTRL_ADC_CHSEL_VDDIO_DIV_4 ((uint32_t)(0x0000000BUL)) +#define MXC_V_ADC_CTRL_ADC_CHSEL_VDDIOH_DIV_4 ((uint32_t)(0x0000000CUL)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_ADC_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/aes_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/aes_regs.h new file mode 100644 index 00000000000..43527587200 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/aes_regs.h @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_AES_REGS_H_ +#define _MXC_AES_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t ctrl; /* 0x0000 AES Control and Status */ + __I uint32_t rsv004; /* 0x0004 */ + __IO uint32_t erase_all; /* 0x0008 Write to Trigger AES Memory Erase */ +} mxc_aes_regs_t; + + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t inp[4]; /* 0x0000-0x000C AES Input (128 bits) */ + __IO uint32_t key[8]; /* 0x0010-0x002C AES Symmetric Key (up to 256 bits) */ + __IO uint32_t out[4]; /* 0x0030-0x003C AES Output Data (128 bits) */ + __IO uint32_t expkey[8]; /* 0x0040-0x005C AES Expanded Key Data (256 bits) */ +} mxc_aes_mem_regs_t; + + +/* + Register offsets for module AES. +*/ + +#define MXC_R_AES_OFFS_CTRL ((uint32_t)0x00000000UL) +#define MXC_R_AES_OFFS_ERASE_ALL ((uint32_t)0x00000008UL) +#define MXC_R_AES_MEM_OFFS_INP0 ((uint32_t)0x00000000UL) +#define MXC_R_AES_MEM_OFFS_INP1 ((uint32_t)0x00000004UL) +#define MXC_R_AES_MEM_OFFS_INP2 ((uint32_t)0x00000008UL) +#define MXC_R_AES_MEM_OFFS_INP3 ((uint32_t)0x0000000CUL) +#define MXC_R_AES_MEM_OFFS_KEY0 ((uint32_t)0x00000010UL) +#define MXC_R_AES_MEM_OFFS_KEY1 ((uint32_t)0x00000014UL) +#define MXC_R_AES_MEM_OFFS_KEY2 ((uint32_t)0x00000018UL) +#define MXC_R_AES_MEM_OFFS_KEY3 ((uint32_t)0x0000001CUL) +#define MXC_R_AES_MEM_OFFS_KEY4 ((uint32_t)0x00000020UL) +#define MXC_R_AES_MEM_OFFS_KEY5 ((uint32_t)0x00000024UL) +#define MXC_R_AES_MEM_OFFS_KEY6 ((uint32_t)0x00000028UL) +#define MXC_R_AES_MEM_OFFS_KEY7 ((uint32_t)0x0000002CUL) +#define MXC_R_AES_MEM_OFFS_OUT0 ((uint32_t)0x00000030UL) +#define MXC_R_AES_MEM_OFFS_OUT1 ((uint32_t)0x00000034UL) +#define MXC_R_AES_MEM_OFFS_OUT2 ((uint32_t)0x00000038UL) +#define MXC_R_AES_MEM_OFFS_OUT3 ((uint32_t)0x0000003CUL) +#define MXC_R_AES_MEM_OFFS_EXPKEY0 ((uint32_t)0x00000040UL) +#define MXC_R_AES_MEM_OFFS_EXPKEY1 ((uint32_t)0x00000044UL) +#define MXC_R_AES_MEM_OFFS_EXPKEY2 ((uint32_t)0x00000048UL) +#define MXC_R_AES_MEM_OFFS_EXPKEY3 ((uint32_t)0x0000004CUL) +#define MXC_R_AES_MEM_OFFS_EXPKEY4 ((uint32_t)0x00000050UL) +#define MXC_R_AES_MEM_OFFS_EXPKEY5 ((uint32_t)0x00000054UL) +#define MXC_R_AES_MEM_OFFS_EXPKEY6 ((uint32_t)0x00000058UL) +#define MXC_R_AES_MEM_OFFS_EXPKEY7 ((uint32_t)0x0000005CUL) + + +/* + Field positions and masks for module AES. +*/ + +#define MXC_F_AES_CTRL_START_POS 0 +#define MXC_F_AES_CTRL_START ((uint32_t)(0x00000001UL << MXC_F_AES_CTRL_START_POS)) +#define MXC_F_AES_CTRL_CRYPT_MODE_POS 1 +#define MXC_F_AES_CTRL_CRYPT_MODE ((uint32_t)(0x00000001UL << MXC_F_AES_CTRL_CRYPT_MODE_POS)) +#define MXC_F_AES_CTRL_EXP_KEY_MODE_POS 2 +#define MXC_F_AES_CTRL_EXP_KEY_MODE ((uint32_t)(0x00000001UL << MXC_F_AES_CTRL_EXP_KEY_MODE_POS)) +#define MXC_F_AES_CTRL_KEY_SIZE_POS 3 +#define MXC_F_AES_CTRL_KEY_SIZE ((uint32_t)(0x00000003UL << MXC_F_AES_CTRL_KEY_SIZE_POS)) +#define MXC_F_AES_CTRL_INTEN_POS 5 +#define MXC_F_AES_CTRL_INTEN ((uint32_t)(0x00000001UL << MXC_F_AES_CTRL_INTEN_POS)) +#define MXC_F_AES_CTRL_INTFL_POS 6 +#define MXC_F_AES_CTRL_INTFL ((uint32_t)(0x00000001UL << MXC_F_AES_CTRL_INTFL_POS)) +#define MXC_F_AES_CTRL_LOAD_HW_KEY_POS 7 +#define MXC_F_AES_CTRL_LOAD_HW_KEY ((uint32_t)(0x00000001UL << MXC_F_AES_CTRL_LOAD_HW_KEY_POS)) + + + +/* + Field values and shifted values for module AES. +*/ + +#define MXC_V_AES_CTRL_ENCRYPT_MODE ((uint32_t)(0x00000000UL)) +#define MXC_V_AES_CTRL_DECRYPT_MODE ((uint32_t)(0x00000001UL)) + +#define MXC_S_AES_CTRL_ENCRYPT_MODE ((uint32_t)(MXC_V_AES_CTRL_ENCRYPT_MODE << MXC_F_AES_CTRL_CRYPT_MODE_POS)) +#define MXC_S_AES_CTRL_DECRYPT_MODE ((uint32_t)(MXC_V_AES_CTRL_DECRYPT_MODE << MXC_F_AES_CTRL_CRYPT_MODE_POS)) + +#define MXC_V_AES_CTRL_CALC_NEW_EXP_KEY ((uint32_t)(0x00000000UL)) +#define MXC_V_AES_CTRL_USE_LAST_EXP_KEY ((uint32_t)(0x00000001UL)) + +#define MXC_S_AES_CTRL_CALC_NEW_EXP_KEY ((uint32_t)(MXC_V_AES_CTRL_CALC_NEW_EXP_KEY << MXC_F_AES_CTRL_EXP_KEY_MODE_POS)) +#define MXC_S_AES_CTRL_USE_LAST_EXP_KEY ((uint32_t)(MXC_V_AES_CTRL_USE_LAST_EXP_KEY << MXC_F_AES_CTRL_EXP_KEY_MODE_POS)) + +#define MXC_V_AES_CTRL_KEY_SIZE_128 ((uint32_t)(0x00000000UL)) +#define MXC_V_AES_CTRL_KEY_SIZE_192 ((uint32_t)(0x00000001UL)) +#define MXC_V_AES_CTRL_KEY_SIZE_256 ((uint32_t)(0x00000002UL)) + +#define MXC_S_AES_CTRL_KEY_SIZE_128 ((uint32_t)(MXC_V_AES_CTRL_KEY_SIZE_128 << MXC_F_AES_CTRL_KEY_SIZE_POS)) +#define MXC_S_AES_CTRL_KEY_SIZE_192 ((uint32_t)(MXC_V_AES_CTRL_KEY_SIZE_192 << MXC_F_AES_CTRL_KEY_SIZE_POS)) +#define MXC_S_AES_CTRL_KEY_SIZE_256 ((uint32_t)(MXC_V_AES_CTRL_KEY_SIZE_256 << MXC_F_AES_CTRL_KEY_SIZE_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_AES_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/clkman_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/clkman_regs.h new file mode 100644 index 00000000000..27908fdab2b --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/clkman_regs.h @@ -0,0 +1,436 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_CLKMAN_REGS_H_ +#define _MXC_CLKMAN_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t clk_config; /* 0x0000 System Clock Configuration */ + __IO uint32_t clk_ctrl; /* 0x0004 System Clock Controls */ + __IO uint32_t intfl; /* 0x0008 Interrupt Flags */ + __IO uint32_t inten; /* 0x000C Interrupt Enable/Disable Controls */ + __IO uint32_t trim_calc; /* 0x0010 Trim Calculation Controls */ + __IO uint32_t i2c_timer_ctrl; /* 0x0014 I2C Timer Control */ + __IO uint32_t cm4_start_clk_en0; /* 0x0018 CM4 Start Clock on Interrupt Enable 0 */ + __IO uint32_t cm4_start_clk_en1; /* 0x001C CM4 Start Clock on Interrupt Enable 1 */ + __IO uint32_t cm4_start_clk_en2; /* 0x0020 CM4 Start Clock on Interrupt Enable 2 */ + __I uint32_t rsv024[7]; /* 0x0024-0x003C */ + __IO uint32_t sys_clk_ctrl_0_cm4; /* 0x0040 Control Settings for CLK0 - Cortex M4 Clock */ + __IO uint32_t sys_clk_ctrl_1_sync; /* 0x0044 Control Settings for CLK1 - Synchronizer Clock */ + __IO uint32_t sys_clk_ctrl_2_spix; /* 0x0048 Control Settings for CLK2 - SPI XIP Clock */ + __IO uint32_t sys_clk_ctrl_3_prng; /* 0x004C Control Settings for CLK3 - PRNG Clock */ + __IO uint32_t sys_clk_ctrl_4_wdt0; /* 0x0050 Control Settings for CLK4 - Watchdog Timer 0 */ + __IO uint32_t sys_clk_ctrl_5_wdt1; /* 0x0054 Control Settings for CLK5 - Watchdog Timer 1 */ + __IO uint32_t sys_clk_ctrl_6_gpio; /* 0x0058 Control Settings for CLK6 - Clock for GPIO Ports */ + __IO uint32_t sys_clk_ctrl_7_pt; /* 0x005C Control Settings for CLK7 - Source Clock for All Pulse Trains */ + __IO uint32_t sys_clk_ctrl_8_uart; /* 0x0060 Control Settings for CLK8 - Source Clock for All UARTs */ + __IO uint32_t sys_clk_ctrl_9_i2cm; /* 0x0064 Control Settings for CLK9 - Source Clock for All I2C Masters */ + __IO uint32_t sys_clk_ctrl_10_i2cs; /* 0x0068 Control Settings for CLK10 - Source Clock for I2C Slave */ + __IO uint32_t sys_clk_ctrl_11_spi0; /* 0x006C Control Settings for CLK11 - SPI Master 0 */ + __IO uint32_t sys_clk_ctrl_12_spi1; /* 0x0070 Control Settings for CLK12 - SPI Master 1 */ + __IO uint32_t sys_clk_ctrl_13_spi2; /* 0x0074 Control Settings for CLK13 - SPI Master 2 */ + __I uint32_t rsv078; /* 0x0078 */ + __IO uint32_t sys_clk_ctrl_15_owm; /* 0x007C Control Settings for CLK15 - 1-Wire Master Clock */ + __IO uint32_t sys_clk_ctrl_16_spis; /* 0x0080 Control Settings for CLK16 - SPI Slave Clock */ + __I uint32_t rsv084[31]; /* 0x0084-0x00FC */ + __IO uint32_t crypt_clk_ctrl_0_aes; /* 0x0100 Control Settings for Crypto Clock 0 - AES */ + __IO uint32_t crypt_clk_ctrl_1_maa; /* 0x0104 Control Settings for Crypto Clock 1 - MAA */ + __IO uint32_t crypt_clk_ctrl_2_prng; /* 0x0108 Control Settings for Crypto Clock 2 - PRNG */ + __I uint32_t rsv10C[13]; /* 0x010C-0x013C */ + __IO uint32_t clk_gate_ctrl0; /* 0x0140 Dynamic Clock Gating Control Register 0 */ + __IO uint32_t clk_gate_ctrl1; /* 0x0144 Dynamic Clock Gating Control Register 1 */ + __IO uint32_t clk_gate_ctrl2; /* 0x0148 Dynamic Clock Gating Control Register 2 */ +} mxc_clkman_regs_t; + + +/* + Register offsets for module CLKMAN. +*/ + +#define MXC_R_CLKMAN_OFFS_CLK_CONFIG ((uint32_t)0x00000000UL) +#define MXC_R_CLKMAN_OFFS_CLK_CTRL ((uint32_t)0x00000004UL) +#define MXC_R_CLKMAN_OFFS_INTFL ((uint32_t)0x00000008UL) +#define MXC_R_CLKMAN_OFFS_INTEN ((uint32_t)0x0000000CUL) +#define MXC_R_CLKMAN_OFFS_TRIM_CALC ((uint32_t)0x00000010UL) +#define MXC_R_CLKMAN_OFFS_I2C_TIMER_CTRL ((uint32_t)0x00000014UL) +#define MXC_R_CLKMAN_OFFS_CM4_START_CLK_EN0 ((uint32_t)0x00000018UL) +#define MXC_R_CLKMAN_OFFS_CM4_START_CLK_EN1 ((uint32_t)0x0000001CUL) +#define MXC_R_CLKMAN_OFFS_CM4_START_CLK_EN2 ((uint32_t)0x00000020UL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_0_CM4 ((uint32_t)0x00000040UL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_1_SYNC ((uint32_t)0x00000044UL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_2_SPIX ((uint32_t)0x00000048UL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_3_PRNG ((uint32_t)0x0000004CUL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_4_WDT0 ((uint32_t)0x00000050UL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_5_WDT1 ((uint32_t)0x00000054UL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_6_GPIO ((uint32_t)0x00000058UL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_7_PT ((uint32_t)0x0000005CUL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_8_UART ((uint32_t)0x00000060UL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_9_I2CM ((uint32_t)0x00000064UL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_10_I2CS ((uint32_t)0x00000068UL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_11_SPI0 ((uint32_t)0x0000006CUL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_12_SPI1 ((uint32_t)0x00000070UL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_13_SPI2 ((uint32_t)0x00000074UL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_15_OWM ((uint32_t)0x0000007CUL) +#define MXC_R_CLKMAN_OFFS_SYS_CLK_CTRL_16_SPIS ((uint32_t)0x00000080UL) +#define MXC_R_CLKMAN_OFFS_CRYPT_CLK_CTRL_0_AES ((uint32_t)0x00000100UL) +#define MXC_R_CLKMAN_OFFS_CRYPT_CLK_CTRL_1_MAA ((uint32_t)0x00000104UL) +#define MXC_R_CLKMAN_OFFS_CRYPT_CLK_CTRL_2_PRNG ((uint32_t)0x00000108UL) +#define MXC_R_CLKMAN_OFFS_CLK_GATE_CTRL0 ((uint32_t)0x00000140UL) +#define MXC_R_CLKMAN_OFFS_CLK_GATE_CTRL1 ((uint32_t)0x00000144UL) +#define MXC_R_CLKMAN_OFFS_CLK_GATE_CTRL2 ((uint32_t)0x00000148UL) + + +/* + Field positions and masks for module CLKMAN. +*/ + +#define MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_ENABLE_POS 0 +#define MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_ENABLE ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_ENABLE_POS)) +#define MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS 4 +#define MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) + +#define MXC_F_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT_POS 0 +#define MXC_F_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT_POS)) +#define MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_ENABLE_POS 4 +#define MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_ENABLE ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_ENABLE_POS)) +#define MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_SELECT_POS 5 +#define MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_SELECT ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_SELECT_POS)) +#define MXC_F_CLKMAN_CLK_CTRL_CRYPTO_CLOCK_ENABLE_POS 8 +#define MXC_F_CLKMAN_CLK_CTRL_CRYPTO_CLOCK_ENABLE ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_CLK_CTRL_CRYPTO_CLOCK_ENABLE_POS)) +#define MXC_F_CLKMAN_CLK_CTRL_RTOS_MODE_POS 12 +#define MXC_F_CLKMAN_CLK_CTRL_RTOS_MODE ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_CLK_CTRL_RTOS_MODE_POS)) +#define MXC_F_CLKMAN_CLK_CTRL_CPU_DYNAMIC_CLOCK_POS 13 +#define MXC_F_CLKMAN_CLK_CTRL_CPU_DYNAMIC_CLOCK ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_CLK_CTRL_CPU_DYNAMIC_CLOCK_POS)) +#define MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_ENABLE_POS 16 +#define MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_ENABLE ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_ENABLE_POS)) +#define MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_SELECT_POS 17 +#define MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_SELECT ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_SELECT_POS)) +#define MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_ENABLE_POS 20 +#define MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_ENABLE ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_ENABLE_POS)) +#define MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_SELECT_POS 21 +#define MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_SELECT ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_SELECT_POS)) +#define MXC_F_CLKMAN_CLK_CTRL_ADC_CLOCK_ENABLE_POS 24 +#define MXC_F_CLKMAN_CLK_CTRL_ADC_CLOCK_ENABLE ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_CLK_CTRL_ADC_CLOCK_ENABLE_POS)) + +#define MXC_F_CLKMAN_INTFL_CRYPTO_STABLE_POS 0 +#define MXC_F_CLKMAN_INTFL_CRYPTO_STABLE ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_INTFL_CRYPTO_STABLE_POS)) +#define MXC_F_CLKMAN_INTFL_SYS_RO_STABLE_POS 1 +#define MXC_F_CLKMAN_INTFL_SYS_RO_STABLE ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_INTFL_SYS_RO_STABLE_POS)) + +#define MXC_F_CLKMAN_INTEN_CRYPTO_STABLE_POS 0 +#define MXC_F_CLKMAN_INTEN_CRYPTO_STABLE ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_INTEN_CRYPTO_STABLE_POS)) +#define MXC_F_CLKMAN_INTEN_SYS_RO_STABLE_POS 1 +#define MXC_F_CLKMAN_INTEN_SYS_RO_STABLE ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_INTEN_SYS_RO_STABLE_POS)) + +#define MXC_F_CLKMAN_TRIM_CALC_TRIM_CLK_SEL_POS 0 +#define MXC_F_CLKMAN_TRIM_CALC_TRIM_CLK_SEL ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_TRIM_CALC_TRIM_CLK_SEL_POS)) +#define MXC_F_CLKMAN_TRIM_CALC_TRIM_CALC_START_POS 1 +#define MXC_F_CLKMAN_TRIM_CALC_TRIM_CALC_START ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_TRIM_CALC_TRIM_CALC_START_POS)) +#define MXC_F_CLKMAN_TRIM_CALC_TRIM_CALC_COMPLETED_POS 2 +#define MXC_F_CLKMAN_TRIM_CALC_TRIM_CALC_COMPLETED ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_TRIM_CALC_TRIM_CALC_COMPLETED_POS)) +#define MXC_F_CLKMAN_TRIM_CALC_TRIM_ENABLE_POS 3 +#define MXC_F_CLKMAN_TRIM_CALC_TRIM_ENABLE ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_TRIM_CALC_TRIM_ENABLE_POS)) +#define MXC_F_CLKMAN_TRIM_CALC_TRIM_CALC_LENGTH_POS 4 +#define MXC_F_CLKMAN_TRIM_CALC_TRIM_CALC_LENGTH ((uint32_t)(0x00000FFFUL << MXC_F_CLKMAN_TRIM_CALC_TRIM_CALC_LENGTH_POS)) +#define MXC_F_CLKMAN_TRIM_CALC_TRIM_CALC_RESULTS_POS 16 +#define MXC_F_CLKMAN_TRIM_CALC_TRIM_CALC_RESULTS ((uint32_t)(0x00003FFFUL << MXC_F_CLKMAN_TRIM_CALC_TRIM_CALC_RESULTS_POS)) + +#define MXC_F_CLKMAN_I2C_TIMER_CTRL_I2C_1MS_TIMER_EN_POS 0 +#define MXC_F_CLKMAN_I2C_TIMER_CTRL_I2C_1MS_TIMER_EN ((uint32_t)(0x00000001UL << MXC_F_CLKMAN_I2C_TIMER_CTRL_I2C_1MS_TIMER_EN_POS)) + +#define MXC_F_CLKMAN_CM4_START_CLK_EN0_INTS_POS 0 +#define MXC_F_CLKMAN_CM4_START_CLK_EN0_INTS ((uint32_t)(0xFFFFFFFFUL << MXC_F_CLKMAN_CM4_START_CLK_EN0_INTS_POS)) + +#define MXC_F_CLKMAN_CM4_START_CLK_EN1_INTS_POS 0 +#define MXC_F_CLKMAN_CM4_START_CLK_EN1_INTS ((uint32_t)(0xFFFFFFFFUL << MXC_F_CLKMAN_CM4_START_CLK_EN1_INTS_POS)) + +#define MXC_F_CLKMAN_CM4_START_CLK_EN2_INTS_POS 0 +#define MXC_F_CLKMAN_CM4_START_CLK_EN2_INTS ((uint32_t)(0xFFFFFFFFUL << MXC_F_CLKMAN_CM4_START_CLK_EN2_INTS_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_1_SYNC_SYNC_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_1_SYNC_SYNC_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_1_SYNC_SYNC_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_2_SPIX_SPIX_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_2_SPIX_SPIX_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_2_SPIX_SPIX_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_3_PRNG_PRNG_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_3_PRNG_PRNG_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_3_PRNG_PRNG_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_4_WDT0_WATCHDOG0_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_4_WDT0_WATCHDOG0_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_4_WDT0_WATCHDOG0_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_5_WDT1_WATCHDOG1_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_5_WDT1_WATCHDOG1_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_5_WDT1_WATCHDOG1_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_6_GPIO_GPIO_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_6_GPIO_GPIO_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_6_GPIO_GPIO_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_7_PT_PULSE_TRAIN_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_7_PT_PULSE_TRAIN_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_7_PT_PULSE_TRAIN_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_8_UART_UART_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_8_UART_UART_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_8_UART_UART_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_9_I2CM_I2CM_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_9_I2CM_I2CM_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_9_I2CM_I2CM_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_10_I2CS_I2CS_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_10_I2CS_I2CS_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_10_I2CS_I2CS_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_11_SPI0_SPI0_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_11_SPI0_SPI0_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_11_SPI0_SPI0_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_12_SPI1_SPI1_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_12_SPI1_SPI1_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_12_SPI1_SPI1_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_13_SPI2_SPI2_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_13_SPI2_SPI2_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_13_SPI2_SPI2_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_15_OWM_OWM_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_15_OWM_OWM_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_15_OWM_OWM_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_SYS_CLK_CTRL_16_SPIS_SPIS_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_SYS_CLK_CTRL_16_SPIS_SPIS_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_SYS_CLK_CTRL_16_SPIS_SPIS_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_CRYPT_CLK_CTRL_0_AES_AES_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_CRYPT_CLK_CTRL_0_AES_AES_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_CRYPT_CLK_CTRL_0_AES_AES_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_CRYPT_CLK_CTRL_1_MAA_MAA_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_CRYPT_CLK_CTRL_1_MAA_MAA_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_CRYPT_CLK_CTRL_1_MAA_MAA_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_CRYPT_CLK_CTRL_2_PRNG_PRNG_CLK_SCALE_POS 0 +#define MXC_F_CLKMAN_CRYPT_CLK_CTRL_2_PRNG_PRNG_CLK_SCALE ((uint32_t)(0x0000000FUL << MXC_F_CLKMAN_CRYPT_CLK_CTRL_2_PRNG_PRNG_CLK_SCALE_POS)) + +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_CM4_CLK_GATER_POS 0 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_CM4_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_CM4_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_AHB32_CLK_GATER_POS 2 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_AHB32_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_AHB32_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_ICACHE_CLK_GATER_POS 4 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_ICACHE_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_ICACHE_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_FLASH_CLK_GATER_POS 6 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_FLASH_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_FLASH_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_SRAM_CLK_GATER_POS 8 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_SRAM_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_SRAM_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_APB_BRIDGE_CLK_GATER_POS 10 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_APB_BRIDGE_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_APB_BRIDGE_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_SYSMAN_CLK_GATER_POS 12 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_SYSMAN_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_SYSMAN_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_PTP_CLK_GATER_POS 14 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_PTP_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_PTP_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_SSB_MUX_CLK_GATER_POS 16 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_SSB_MUX_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_SSB_MUX_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_PAD_CLK_GATER_POS 18 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_PAD_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_PAD_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_SPIX_CLK_GATER_POS 20 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_SPIX_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_SPIX_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_PMU_CLK_GATER_POS 22 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_PMU_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_PMU_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_USB_CLK_GATER_POS 24 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_USB_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_USB_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_CRC_CLK_GATER_POS 26 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_CRC_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_CRC_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_TPU_CLK_GATER_POS 28 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_TPU_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_TPU_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_WATCHDOG0_CLK_GATER_POS 30 +#define MXC_F_CLKMAN_CLK_GATE_CTRL0_WATCHDOG0_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL0_WATCHDOG0_CLK_GATER_POS)) + +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_WATCHDOG1_CLK_GATER_POS 0 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_WATCHDOG1_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_WATCHDOG1_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_GPIO_CLK_GATER_POS 2 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_GPIO_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_GPIO_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER0_CLK_GATER_POS 4 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER0_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER0_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER1_CLK_GATER_POS 6 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER1_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER1_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER2_CLK_GATER_POS 8 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER2_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER2_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER3_CLK_GATER_POS 10 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER3_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER3_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER4_CLK_GATER_POS 12 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER4_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER4_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER5_CLK_GATER_POS 14 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER5_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_TIMER5_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_PULSETRAIN_CLK_GATER_POS 16 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_PULSETRAIN_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_PULSETRAIN_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_UART0_CLK_GATER_POS 18 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_UART0_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_UART0_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_UART1_CLK_GATER_POS 20 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_UART1_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_UART1_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_UART2_CLK_GATER_POS 22 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_UART2_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_UART2_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_I2CM0_CLK_GATER_POS 26 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_I2CM0_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_I2CM0_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_I2CM1_CLK_GATER_POS 28 +#define MXC_F_CLKMAN_CLK_GATE_CTRL1_I2CM1_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_I2CM1_CLK_GATER_POS)) + +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_I2CS_CLK_GATER_POS 0 +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_I2CS_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL2_I2CS_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_SPI0_CLK_GATER_POS 2 +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_SPI0_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL2_SPI0_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_SPI1_CLK_GATER_POS 4 +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_SPI1_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL2_SPI1_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_SPI2_CLK_GATER_POS 6 +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_SPI2_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL2_SPI2_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_OWM_CLK_GATER_POS 10 +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_OWM_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL2_OWM_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_ADC_CLK_GATER_POS 12 +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_ADC_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL2_ADC_CLK_GATER_POS)) +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_SPIS_CLK_GATER_POS 14 +#define MXC_F_CLKMAN_CLK_GATE_CTRL2_SPIS_CLK_GATER ((uint32_t)(0x00000003UL << MXC_F_CLKMAN_CLK_GATE_CTRL2_SPIS_CLK_GATER_POS)) + + + +/* + Field values and shifted values for module CLKMAN. +*/ + +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_8_CLOCKS ((uint32_t)(0x00000000UL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_9_CLOCKS ((uint32_t)(0x00000001UL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_10_CLOCKS ((uint32_t)(0x00000002UL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_11_CLOCKS ((uint32_t)(0x00000003UL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_12_CLOCKS ((uint32_t)(0x00000004UL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_13_CLOCKS ((uint32_t)(0x00000005UL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_14_CLOCKS ((uint32_t)(0x00000006UL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_15_CLOCKS ((uint32_t)(0x00000007UL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_16_CLOCKS ((uint32_t)(0x00000008UL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_17_CLOCKS ((uint32_t)(0x00000009UL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_18_CLOCKS ((uint32_t)(0x0000000AUL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_19_CLOCKS ((uint32_t)(0x0000000BUL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_20_CLOCKS ((uint32_t)(0x0000000CUL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_21_CLOCKS ((uint32_t)(0x0000000DUL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_22_CLOCKS ((uint32_t)(0x0000000EUL)) +#define MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_23_CLOCKS ((uint32_t)(0x0000000FUL)) + +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_8_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_8_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_9_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_9_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_10_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_10_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_11_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_11_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_12_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_12_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_13_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_13_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_14_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_14_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_15_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_15_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_16_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_16_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_17_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_17_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_18_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_18_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_19_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_19_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_20_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_20_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_21_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_21_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_22_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_22_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) +#define MXC_S_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_23_CLOCKS ((uint32_t)(MXC_V_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_2_EXP_23_CLOCKS << MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_STABILITY_COUNT_POS)) + +#define MXC_V_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT_96MHZ_RO_DIV_2 ((uint32_t)(0x00000000UL)) +#define MXC_V_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT_96MHZ_RO ((uint32_t)(0x00000001UL)) + +#define MXC_S_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT_96MHZ_RO_DIV_2 ((uint32_t)(MXC_V_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT_96MHZ_RO_DIV_2 << MXC_F_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT_POS)) +#define MXC_S_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT_96MHZ_RO ((uint32_t)(MXC_V_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT_96MHZ_RO << MXC_F_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT_POS)) + +#define MXC_V_CLKMAN_WDT0_CLOCK_SELECT_SCALED_SYS_CLK_CTRL_4_WDT0 ((uint32_t)(0x00000000UL)) +#define MXC_V_CLKMAN_WDT0_CLOCK_SELECT_32KHZ_RTC_OSCILLATOR ((uint32_t)(0x00000001UL)) +#define MXC_V_CLKMAN_WDT0_CLOCK_SELECT_96MHZ_OSCILLATOR ((uint32_t)(0x00000002UL)) +#define MXC_V_CLKMAN_WDT0_CLOCK_SELECT_NANO_RING_OSCILLATOR ((uint32_t)(0x00000003UL)) + +#define MXC_S_CLKMAN_WDT0_CLOCK_SELECT_SCALED_SYS_CLK_CTRL_4_WDT0 ((uint32_t)(MXC_V_CLKMAN_WDT0_CLOCK_SELECT_SCALED_SYS_CLK_CTRL_4_WDT0 << MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_SELECT_POS)) +#define MXC_S_CLKMAN_WDT0_CLOCK_SELECT_32KHZ_RTC_OSCILLATOR ((uint32_t)(MXC_V_CLKMAN_WDT0_CLOCK_SELECT_32KHZ_RTC_OSCILLATOR << MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_SELECT_POS)) +#define MXC_S_CLKMAN_WDT0_CLOCK_SELECT_96MHZ_OSCILLATOR ((uint32_t)(MXC_V_CLKMAN_WDT0_CLOCK_SELECT_96MHZ_OSCILLATOR << MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_SELECT_POS)) +#define MXC_S_CLKMAN_WDT0_CLOCK_SELECT_NANO_RING_OSCILLATOR ((uint32_t)(MXC_V_CLKMAN_WDT0_CLOCK_SELECT_NANO_RING_OSCILLATOR << MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_SELECT_POS)) + +#define MXC_V_CLKMAN_WDT1_CLOCK_SELECT_SCALED_SYS_CLK_CTRL_4_WDT1 ((uint32_t)(0x00000000UL)) +#define MXC_V_CLKMAN_WDT1_CLOCK_SELECT_32KHZ_RTC_OSCILLATOR ((uint32_t)(0x00000001UL)) +#define MXC_V_CLKMAN_WDT1_CLOCK_SELECT_96MHZ_OSCILLATOR ((uint32_t)(0x00000002UL)) +#define MXC_V_CLKMAN_WDT1_CLOCK_SELECT_NANO_RING_OSCILLATOR ((uint32_t)(0x00000003UL)) + +#define MXC_S_CLKMAN_WDT1_CLOCK_SELECT_SCALED_SYS_CLK_CTRL_4_WDT1 ((uint32_t)(MXC_V_CLKMAN_WDT1_CLOCK_SELECT_SCALED_SYS_CLK_CTRL_4_WDT1 << MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_SELECT_POS)) +#define MXC_S_CLKMAN_WDT1_CLOCK_SELECT_32KHZ_RTC_OSCILLATOR ((uint32_t)(MXC_V_CLKMAN_WDT1_CLOCK_SELECT_32KHZ_RTC_OSCILLATOR << MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_SELECT_POS)) +#define MXC_S_CLKMAN_WDT1_CLOCK_SELECT_96MHZ_OSCILLATOR ((uint32_t)(MXC_V_CLKMAN_WDT1_CLOCK_SELECT_96MHZ_OSCILLATOR << MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_SELECT_POS)) +#define MXC_S_CLKMAN_WDT1_CLOCK_SELECT_NANO_RING_OSCILLATOR ((uint32_t)(MXC_V_CLKMAN_WDT1_CLOCK_SELECT_NANO_RING_OSCILLATOR << MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_SELECT_POS)) + +#define MXC_V_CLKMAN_CLK_SCALE_DISABLED ((uint32_t)(0x00000000UL)) +#define MXC_V_CLKMAN_CLK_SCALE_DIV_1 ((uint32_t)(0x00000001UL)) +#define MXC_V_CLKMAN_CLK_SCALE_DIV_2 ((uint32_t)(0x00000002UL)) +#define MXC_V_CLKMAN_CLK_SCALE_DIV_4 ((uint32_t)(0x00000003UL)) +#define MXC_V_CLKMAN_CLK_SCALE_DIV_8 ((uint32_t)(0x00000004UL)) +#define MXC_V_CLKMAN_CLK_SCALE_DIV_16 ((uint32_t)(0x00000005UL)) +#define MXC_V_CLKMAN_CLK_SCALE_DIV_32 ((uint32_t)(0x00000006UL)) +#define MXC_V_CLKMAN_CLK_SCALE_DIV_64 ((uint32_t)(0x00000007UL)) +#define MXC_V_CLKMAN_CLK_SCALE_DIV_128 ((uint32_t)(0x00000008UL)) +#define MXC_V_CLKMAN_CLK_SCALE_DIV_256 ((uint32_t)(0x00000009UL)) + +#define MXC_S_CLKMAN_CLK_SCALE_DISABLED ((uint32_t)(MXC_V_CLKMAN_CLK_SCALE_DISABLED << MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE_POS)) +#define MXC_S_CLKMAN_CLK_SCALE_DIV_1 ((uint32_t)(MXC_V_CLKMAN_CLK_SCALE_DIV_1 << MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE_POS)) +#define MXC_S_CLKMAN_CLK_SCALE_DIV_2 ((uint32_t)(MXC_V_CLKMAN_CLK_SCALE_DIV_2 << MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE_POS)) +#define MXC_S_CLKMAN_CLK_SCALE_DIV_4 ((uint32_t)(MXC_V_CLKMAN_CLK_SCALE_DIV_4 << MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE_POS)) +#define MXC_S_CLKMAN_CLK_SCALE_DIV_8 ((uint32_t)(MXC_V_CLKMAN_CLK_SCALE_DIV_8 << MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE_POS)) +#define MXC_S_CLKMAN_CLK_SCALE_DIV_16 ((uint32_t)(MXC_V_CLKMAN_CLK_SCALE_DIV_16 << MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE_POS)) +#define MXC_S_CLKMAN_CLK_SCALE_DIV_32 ((uint32_t)(MXC_V_CLKMAN_CLK_SCALE_DIV_32 << MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE_POS)) +#define MXC_S_CLKMAN_CLK_SCALE_DIV_64 ((uint32_t)(MXC_V_CLKMAN_CLK_SCALE_DIV_64 << MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE_POS)) +#define MXC_S_CLKMAN_CLK_SCALE_DIV_128 ((uint32_t)(MXC_V_CLKMAN_CLK_SCALE_DIV_128 << MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE_POS)) +#define MXC_S_CLKMAN_CLK_SCALE_DIV_256 ((uint32_t)(MXC_V_CLKMAN_CLK_SCALE_DIV_256 << MXC_F_CLKMAN_SYS_CLK_CTRL_0_CM4_CM4_CLK_SCALE_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_CLKMAN_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis.h new file mode 100644 index 00000000000..68bee5be580 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis.h @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_CMSIS_H +#define MBED_CMSIS_H + +#include "max32625.h" +#include "cmsis_nvic.h" + +#endif + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.c b/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.c new file mode 100644 index 00000000000..b3dbadaa5f4 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.c @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "cmsis_nvic.h" + +#if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_ARM_STD) +__attribute__((aligned(256))) +#endif +#if defined(TOOLCHAIN_IAR) +#pragma data_alignment=256 +#endif +static void (*ramVectorTable[MXC_IRQ_COUNT])(void); + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t*)SCB->VTOR; + uint32_t i; + + // Copy and switch to dynamic vectors if the first time called + if (SCB->VTOR != (uint32_t)ramVectorTable) { + uint32_t *old_vectors = (uint32_t*)SCB->VTOR; + vectors = (uint32_t*)ramVectorTable; + for (i = 0; i < NVIC_NUM_VECTORS; i++) { + vectors[i] = old_vectors[i]; + } + SCB->VTOR = (uint32_t)ramVectorTable; + } + vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + +uint32_t NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t*)SCB->VTOR; + return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.h new file mode 100644 index 00000000000..5f44cc56d9d --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.h @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +#include "cmsis.h" + +#define NVIC_NUM_VECTORS MXC_IRQ_COUNT +#define NVIC_USER_IRQ_OFFSET 16 + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif /* MBED_CMSIS_NVIC_H */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/crc_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/crc_regs.h new file mode 100644 index 00000000000..05388008f87 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/crc_regs.h @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_CRC_REGS_H_ +#define _MXC_CRC_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t reseed; /* 0x0000 CRC-16/CRC-32 Reseed Controls */ + __IO uint32_t seed16; /* 0x0004 Reseed Value for CRC-16 Calculations */ + __IO uint32_t seed32; /* 0x0008 Reseed Value for CRC-32 Calculations */ +} mxc_crc_regs_t; + + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t value16[512]; /* 0x0000-0x07FC Write Next CRC-16 Data Value / Read CRC-16 Result Value */ + __IO uint32_t value32[512]; /* 0x0800-0x0FFC Write Next CRC-32 Data Value / Read CRC-32 Result Value */ +} mxc_crc_data_regs_t; + + +/* + Register offsets for module CRC. +*/ + +#define MXC_R_CRC_OFFS_RESEED ((uint32_t)0x00000000UL) +#define MXC_R_CRC_OFFS_SEED16 ((uint32_t)0x00000004UL) +#define MXC_R_CRC_OFFS_SEED32 ((uint32_t)0x00000008UL) +#define MXC_R_CRC_DATA_OFFS_VALUE16 ((uint32_t)0x00000000UL) +#define MXC_R_CRC_DATA_OFFS_VALUE32 ((uint32_t)0x00000800UL) + + +/* + Field positions and masks for module CRC. +*/ + +#define MXC_F_CRC_RESEED_CRC16_POS 0 +#define MXC_F_CRC_RESEED_CRC16 ((uint32_t)(0x00000001UL << MXC_F_CRC_RESEED_CRC16_POS)) +#define MXC_F_CRC_RESEED_CRC32_POS 1 +#define MXC_F_CRC_RESEED_CRC32 ((uint32_t)(0x00000001UL << MXC_F_CRC_RESEED_CRC32_POS)) +#define MXC_F_CRC_RESEED_REV_ENDIAN16_POS 4 +#define MXC_F_CRC_RESEED_REV_ENDIAN16 ((uint32_t)(0x00000001UL << MXC_F_CRC_RESEED_REV_ENDIAN16_POS)) +#define MXC_F_CRC_RESEED_REV_ENDIAN32_POS 5 +#define MXC_F_CRC_RESEED_REV_ENDIAN32 ((uint32_t)(0x00000001UL << MXC_F_CRC_RESEED_REV_ENDIAN32_POS)) +#define MXC_F_CRC_RESEED_CCITT_MODE_POS 8 +#define MXC_F_CRC_RESEED_CCITT_MODE ((uint32_t)(0x00000001UL << MXC_F_CRC_RESEED_CCITT_MODE_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_CRC_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/flc_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/flc_regs.h new file mode 100644 index 00000000000..da1b949c71a --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/flc_regs.h @@ -0,0 +1,298 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_FLC_REGS_H_ +#define _MXC_FLC_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +#define MXC_V_FLC_ERASE_CODE_PAGE_ERASE ((uint8_t)0x55) +#define MXC_V_FLC_ERASE_CODE_MASS_ERASE ((uint8_t)0xAA) +#define MXC_V_FLC_FLSH_UNLOCK_KEY ((uint8_t)0x2) + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t faddr; /* 0x0000 Flash Operation Address */ + __IO uint32_t fckdiv; /* 0x0004 Flash Clock Pulse Divisor */ + __IO uint32_t ctrl; /* 0x0008 Flash Control Register */ + __I uint32_t rsv00C[6]; /* 0x000C-0x0020 */ + __IO uint32_t intr; /* 0x0024 Flash Controller Interrupt Flags and Enable/Disable 0 */ + __I uint32_t rsv028[2]; /* 0x0028-0x002C */ + __IO uint32_t fdata; /* 0x0030 Flash Operation Data Register */ + __I uint32_t rsv034[7]; /* 0x0034-0x004C */ + __IO uint32_t perform; /* 0x0050 Flash Performance Settings */ + __IO uint32_t tacc; /* 0x0054 Flash Read Cycle Config */ + __IO uint32_t tprog; /* 0x0058 Flash Write Cycle Config */ + __I uint32_t rsv05C[9]; /* 0x005C-0x007C */ + __IO uint32_t status; /* 0x0080 Security Status Flags */ + __I uint32_t rsv084; /* 0x0084 */ + __IO uint32_t security; /* 0x0088 Flash Controller Security Settings */ + __I uint32_t rsv08C[4]; /* 0x008C-0x0098 */ + __IO uint32_t bypass; /* 0x009C Status Flags for DSB Operations */ + __I uint32_t rsv0A0[24]; /* 0x00A0-0x00FC */ + __IO uint32_t user_option; /* 0x0100 Used to set DSB Access code and Auto-Lock in info block */ + __I uint32_t rsv104[15]; /* 0x0104-0x013C */ + __IO uint32_t ctrl2; /* 0x0140 Flash Control Register 2 */ + __IO uint32_t intfl1; /* 0x0144 Interrupt Flags Register 1 */ + __IO uint32_t inten1; /* 0x0148 Interrupt Enable/Disable Register 1 */ + __I uint32_t rsv14C[9]; /* 0x014C-0x016C */ + __IO uint32_t bl_ctrl; /* 0x0170 Bootloader Control Register */ + __IO uint32_t twk; /* 0x0174 PDM33 Register */ + __I uint32_t rsv178; /* 0x0178 */ + __IO uint32_t slm; /* 0x017C Sleep Mode Register */ + __I uint32_t rsv180[32]; /* 0x0180-0x01FC */ + __IO uint32_t disable_xr0; /* 0x0200 Disable Flash Page Exec/Read Register 0 */ + __IO uint32_t disable_xr1; /* 0x0204 Disable Flash Page Exec/Read Register 1 */ + __IO uint32_t disable_xr2; /* 0x0208 Disable Flash Page Exec/Read Register 2 */ + __IO uint32_t disable_xr3; /* 0x020C Disable Flash Page Exec/Read Register 3 */ + __IO uint32_t disable_xr4; /* 0x0210 Disable Flash Page Exec/Read Register 4 */ + __IO uint32_t disable_xr5; /* 0x0214 Disable Flash Page Exec/Read Register 5 */ + __IO uint32_t disable_xr6; /* 0x0218 Disable Flash Page Exec/Read Register 6 */ + __IO uint32_t disable_xr7; /* 0x021C Disable Flash Page Exec/Read Register 7 */ + __I uint32_t rsv220[56]; /* 0x0220-0x02FC */ + __IO uint32_t disable_we0; /* 0x0300 Disable Flash Page Write/Erase Register 0 */ + __IO uint32_t disable_we1; /* 0x0304 Disable Flash Page Write/Erase Register 1 */ + __IO uint32_t disable_we2; /* 0x0308 Disable Flash Page Write/Erase Register 2 */ + __IO uint32_t disable_we3; /* 0x030C Disable Flash Page Write/Erase Register 3 */ + __IO uint32_t disable_we4; /* 0x0310 Disable Flash Page Write/Erase Register 4 */ + __IO uint32_t disable_we5; /* 0x0314 Disable Flash Page Write/Erase Register 5 */ + __IO uint32_t disable_we6; /* 0x0318 Disable Flash Page Write/Erase Register 6 */ + __IO uint32_t disable_we7; /* 0x031C Disable Flash Page Write/Erase Register 7 */ +} mxc_flc_regs_t; + + +/* + Register offsets for module FLC. +*/ + +#define MXC_R_FLC_OFFS_FADDR ((uint32_t)0x00000000UL) +#define MXC_R_FLC_OFFS_FCKDIV ((uint32_t)0x00000004UL) +#define MXC_R_FLC_OFFS_CTRL ((uint32_t)0x00000008UL) +#define MXC_R_FLC_OFFS_INTR ((uint32_t)0x00000024UL) +#define MXC_R_FLC_OFFS_FDATA ((uint32_t)0x00000030UL) +#define MXC_R_FLC_OFFS_PERFORM ((uint32_t)0x00000050UL) +#define MXC_R_FLC_OFFS_TACC ((uint32_t)0x00000054UL) +#define MXC_R_FLC_OFFS_TPROG ((uint32_t)0x00000058UL) +#define MXC_R_FLC_OFFS_STATUS ((uint32_t)0x00000080UL) +#define MXC_R_FLC_OFFS_SECURITY ((uint32_t)0x00000088UL) +#define MXC_R_FLC_OFFS_BYPASS ((uint32_t)0x0000009CUL) +#define MXC_R_FLC_OFFS_USER_OPTION ((uint32_t)0x00000100UL) +#define MXC_R_FLC_OFFS_CTRL2 ((uint32_t)0x00000140UL) +#define MXC_R_FLC_OFFS_INTFL1 ((uint32_t)0x00000144UL) +#define MXC_R_FLC_OFFS_INTEN1 ((uint32_t)0x00000148UL) +#define MXC_R_FLC_OFFS_BL_CTRL ((uint32_t)0x00000170UL) +#define MXC_R_FLC_OFFS_TWK ((uint32_t)0x00000174UL) +#define MXC_R_FLC_OFFS_SLM ((uint32_t)0x0000017CUL) +#define MXC_R_FLC_OFFS_DISABLE_XR0 ((uint32_t)0x00000200UL) +#define MXC_R_FLC_OFFS_DISABLE_XR1 ((uint32_t)0x00000204UL) +#define MXC_R_FLC_OFFS_DISABLE_XR2 ((uint32_t)0x00000208UL) +#define MXC_R_FLC_OFFS_DISABLE_XR3 ((uint32_t)0x0000020CUL) +#define MXC_R_FLC_OFFS_DISABLE_XR4 ((uint32_t)0x00000210UL) +#define MXC_R_FLC_OFFS_DISABLE_XR5 ((uint32_t)0x00000214UL) +#define MXC_R_FLC_OFFS_DISABLE_XR6 ((uint32_t)0x00000218UL) +#define MXC_R_FLC_OFFS_DISABLE_XR7 ((uint32_t)0x0000021CUL) +#define MXC_R_FLC_OFFS_DISABLE_WE0 ((uint32_t)0x00000300UL) +#define MXC_R_FLC_OFFS_DISABLE_WE1 ((uint32_t)0x00000304UL) +#define MXC_R_FLC_OFFS_DISABLE_WE2 ((uint32_t)0x00000308UL) +#define MXC_R_FLC_OFFS_DISABLE_WE3 ((uint32_t)0x0000030CUL) +#define MXC_R_FLC_OFFS_DISABLE_WE4 ((uint32_t)0x00000310UL) +#define MXC_R_FLC_OFFS_DISABLE_WE5 ((uint32_t)0x00000314UL) +#define MXC_R_FLC_OFFS_DISABLE_WE6 ((uint32_t)0x00000318UL) +#define MXC_R_FLC_OFFS_DISABLE_WE7 ((uint32_t)0x0000031CUL) + + +/* + Field positions and masks for module FLC. +*/ + +#define MXC_F_FLC_FADDR_FADDR_POS 0 +#define MXC_F_FLC_FADDR_FADDR ((uint32_t)(0x003FFFFFUL << MXC_F_FLC_FADDR_FADDR_POS)) + +#define MXC_F_FLC_FCKDIV_FCKDIV_POS 0 +#define MXC_F_FLC_FCKDIV_FCKDIV ((uint32_t)(0x0000007FUL << MXC_F_FLC_FCKDIV_FCKDIV_POS)) +#define MXC_F_FLC_FCKDIV_AUTO_FCKDIV_RESULT_POS 16 +#define MXC_F_FLC_FCKDIV_AUTO_FCKDIV_RESULT ((uint32_t)(0x0000FFFFUL << MXC_F_FLC_FCKDIV_AUTO_FCKDIV_RESULT_POS)) + +#define MXC_F_FLC_CTRL_WRITE_POS 0 +#define MXC_F_FLC_CTRL_WRITE ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL_WRITE_POS)) +#define MXC_F_FLC_CTRL_MASS_ERASE_POS 1 +#define MXC_F_FLC_CTRL_MASS_ERASE ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL_MASS_ERASE_POS)) +#define MXC_F_FLC_CTRL_PAGE_ERASE_POS 2 +#define MXC_F_FLC_CTRL_PAGE_ERASE ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL_PAGE_ERASE_POS)) +#define MXC_F_FLC_CTRL_ERASE_CODE_POS 8 +#define MXC_F_FLC_CTRL_ERASE_CODE ((uint32_t)(0x000000FFUL << MXC_F_FLC_CTRL_ERASE_CODE_POS)) +#define MXC_F_FLC_CTRL_INFO_BLOCK_UNLOCK_POS 16 +#define MXC_F_FLC_CTRL_INFO_BLOCK_UNLOCK ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL_INFO_BLOCK_UNLOCK_POS)) +#define MXC_F_FLC_CTRL_WRITE_ENABLE_POS 17 +#define MXC_F_FLC_CTRL_WRITE_ENABLE ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL_WRITE_ENABLE_POS)) +#define MXC_F_FLC_CTRL_PENDING_POS 24 +#define MXC_F_FLC_CTRL_PENDING ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL_PENDING_POS)) +#define MXC_F_FLC_CTRL_INFO_BLOCK_VALID_POS 25 +#define MXC_F_FLC_CTRL_INFO_BLOCK_VALID ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL_INFO_BLOCK_VALID_POS)) +#define MXC_F_FLC_CTRL_AUTO_INCRE_MODE_POS 27 +#define MXC_F_FLC_CTRL_AUTO_INCRE_MODE ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL_AUTO_INCRE_MODE_POS)) +#define MXC_F_FLC_CTRL_FLSH_UNLOCK_POS 28 +#define MXC_F_FLC_CTRL_FLSH_UNLOCK ((uint32_t)(0x0000000FUL << MXC_F_FLC_CTRL_FLSH_UNLOCK_POS)) + +#define MXC_F_FLC_INTR_FINISHED_IF_POS 0 +#define MXC_F_FLC_INTR_FINISHED_IF ((uint32_t)(0x00000001UL << MXC_F_FLC_INTR_FINISHED_IF_POS)) +#define MXC_F_FLC_INTR_FAILED_IF_POS 1 +#define MXC_F_FLC_INTR_FAILED_IF ((uint32_t)(0x00000001UL << MXC_F_FLC_INTR_FAILED_IF_POS)) +#define MXC_F_FLC_INTR_FINISHED_IE_POS 8 +#define MXC_F_FLC_INTR_FINISHED_IE ((uint32_t)(0x00000001UL << MXC_F_FLC_INTR_FINISHED_IE_POS)) +#define MXC_F_FLC_INTR_FAILED_IE_POS 9 +#define MXC_F_FLC_INTR_FAILED_IE ((uint32_t)(0x00000001UL << MXC_F_FLC_INTR_FAILED_IE_POS)) +#define MXC_F_FLC_INTR_FAIL_FLAGS_POS 16 +#define MXC_F_FLC_INTR_FAIL_FLAGS ((uint32_t)(0x0000FFFFUL << MXC_F_FLC_INTR_FAIL_FLAGS_POS)) + +#define MXC_F_FLC_PERFORM_DELAY_SE_EN_POS 0 +#define MXC_F_FLC_PERFORM_DELAY_SE_EN ((uint32_t)(0x00000001UL << MXC_F_FLC_PERFORM_DELAY_SE_EN_POS)) +#define MXC_F_FLC_PERFORM_FAST_READ_MODE_EN_POS 8 +#define MXC_F_FLC_PERFORM_FAST_READ_MODE_EN ((uint32_t)(0x00000001UL << MXC_F_FLC_PERFORM_FAST_READ_MODE_EN_POS)) +#define MXC_F_FLC_PERFORM_EN_PREVENT_FAIL_POS 12 +#define MXC_F_FLC_PERFORM_EN_PREVENT_FAIL ((uint32_t)(0x00000001UL << MXC_F_FLC_PERFORM_EN_PREVENT_FAIL_POS)) +#define MXC_F_FLC_PERFORM_EN_BACK2BACK_RDS_POS 16 +#define MXC_F_FLC_PERFORM_EN_BACK2BACK_RDS ((uint32_t)(0x00000001UL << MXC_F_FLC_PERFORM_EN_BACK2BACK_RDS_POS)) +#define MXC_F_FLC_PERFORM_EN_BACK2BACK_WRS_POS 20 +#define MXC_F_FLC_PERFORM_EN_BACK2BACK_WRS ((uint32_t)(0x00000001UL << MXC_F_FLC_PERFORM_EN_BACK2BACK_WRS_POS)) +#define MXC_F_FLC_PERFORM_EN_MERGE_GRAB_GNT_POS 24 +#define MXC_F_FLC_PERFORM_EN_MERGE_GRAB_GNT ((uint32_t)(0x00000001UL << MXC_F_FLC_PERFORM_EN_MERGE_GRAB_GNT_POS)) +#define MXC_F_FLC_PERFORM_AUTO_TACC_POS 28 +#define MXC_F_FLC_PERFORM_AUTO_TACC ((uint32_t)(0x00000001UL << MXC_F_FLC_PERFORM_AUTO_TACC_POS)) +#define MXC_F_FLC_PERFORM_AUTO_CLKDIV_POS 29 +#define MXC_F_FLC_PERFORM_AUTO_CLKDIV ((uint32_t)(0x00000001UL << MXC_F_FLC_PERFORM_AUTO_CLKDIV_POS)) + +#define MXC_F_FLC_STATUS_JTAG_LOCK_WINDOW_POS 0 +#define MXC_F_FLC_STATUS_JTAG_LOCK_WINDOW ((uint32_t)(0x00000001UL << MXC_F_FLC_STATUS_JTAG_LOCK_WINDOW_POS)) +#define MXC_F_FLC_STATUS_JTAG_LOCK_STATIC_POS 1 +#define MXC_F_FLC_STATUS_JTAG_LOCK_STATIC ((uint32_t)(0x00000001UL << MXC_F_FLC_STATUS_JTAG_LOCK_STATIC_POS)) +#define MXC_F_FLC_STATUS_AUTO_LOCK_POS 3 +#define MXC_F_FLC_STATUS_AUTO_LOCK ((uint32_t)(0x00000001UL << MXC_F_FLC_STATUS_AUTO_LOCK_POS)) +#define MXC_F_FLC_STATUS_TRIM_UPDATE_DONE_POS 29 +#define MXC_F_FLC_STATUS_TRIM_UPDATE_DONE ((uint32_t)(0x00000001UL << MXC_F_FLC_STATUS_TRIM_UPDATE_DONE_POS)) +#define MXC_F_FLC_STATUS_INFO_BLOCK_VALID_POS 30 +#define MXC_F_FLC_STATUS_INFO_BLOCK_VALID ((uint32_t)(0x00000001UL << MXC_F_FLC_STATUS_INFO_BLOCK_VALID_POS)) + +#define MXC_F_FLC_SECURITY_DEBUG_DISABLE_POS 0 +#define MXC_F_FLC_SECURITY_DEBUG_DISABLE ((uint32_t)(0x000000FFUL << MXC_F_FLC_SECURITY_DEBUG_DISABLE_POS)) +#define MXC_F_FLC_SECURITY_MASS_ERASE_LOCK_POS 8 +#define MXC_F_FLC_SECURITY_MASS_ERASE_LOCK ((uint32_t)(0x0000000FUL << MXC_F_FLC_SECURITY_MASS_ERASE_LOCK_POS)) +#define MXC_F_FLC_SECURITY_DISABLE_AHB_WR_POS 16 +#define MXC_F_FLC_SECURITY_DISABLE_AHB_WR ((uint32_t)(0x0000000FUL << MXC_F_FLC_SECURITY_DISABLE_AHB_WR_POS)) +#define MXC_F_FLC_SECURITY_FLC_SETTINGS_LOCK_POS 24 +#define MXC_F_FLC_SECURITY_FLC_SETTINGS_LOCK ((uint32_t)(0x0000000FUL << MXC_F_FLC_SECURITY_FLC_SETTINGS_LOCK_POS)) +#define MXC_F_FLC_SECURITY_SECURITY_LOCK_POS 28 +#define MXC_F_FLC_SECURITY_SECURITY_LOCK ((uint32_t)(0x0000000FUL << MXC_F_FLC_SECURITY_SECURITY_LOCK_POS)) + +#define MXC_F_FLC_BYPASS_DESTRUCT_BYPASS_ERASE_POS 0 +#define MXC_F_FLC_BYPASS_DESTRUCT_BYPASS_ERASE ((uint32_t)(0x00000001UL << MXC_F_FLC_BYPASS_DESTRUCT_BYPASS_ERASE_POS)) +#define MXC_F_FLC_BYPASS_SUPERWIPE_ERASE_POS 1 +#define MXC_F_FLC_BYPASS_SUPERWIPE_ERASE ((uint32_t)(0x00000001UL << MXC_F_FLC_BYPASS_SUPERWIPE_ERASE_POS)) +#define MXC_F_FLC_BYPASS_DESTRUCT_BYPASS_COMPLETE_POS 2 +#define MXC_F_FLC_BYPASS_DESTRUCT_BYPASS_COMPLETE ((uint32_t)(0x00000001UL << MXC_F_FLC_BYPASS_DESTRUCT_BYPASS_COMPLETE_POS)) +#define MXC_F_FLC_BYPASS_SUPERWIPE_COMPLETE_POS 3 +#define MXC_F_FLC_BYPASS_SUPERWIPE_COMPLETE ((uint32_t)(0x00000001UL << MXC_F_FLC_BYPASS_SUPERWIPE_COMPLETE_POS)) + +#define MXC_F_FLC_CTRL2_FLASH_LVE_POS 0 +#define MXC_F_FLC_CTRL2_FLASH_LVE ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL2_FLASH_LVE_POS)) +#define MXC_F_FLC_CTRL2_FRC_FCLK1_ON_POS 1 +#define MXC_F_FLC_CTRL2_FRC_FCLK1_ON ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL2_FRC_FCLK1_ON_POS)) +#define MXC_F_FLC_CTRL2_EN_WRITE_ALL_ZEROES_POS 3 +#define MXC_F_FLC_CTRL2_EN_WRITE_ALL_ZEROES ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL2_EN_WRITE_ALL_ZEROES_POS)) +#define MXC_F_FLC_CTRL2_EN_CHANGE_POS 4 +#define MXC_F_FLC_CTRL2_EN_CHANGE ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL2_EN_CHANGE_POS)) +#define MXC_F_FLC_CTRL2_SLOW_CLK_POS 5 +#define MXC_F_FLC_CTRL2_SLOW_CLK ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL2_SLOW_CLK_POS)) +#define MXC_F_FLC_CTRL2_ENABLE_RAM_HRESP_POS 6 +#define MXC_F_FLC_CTRL2_ENABLE_RAM_HRESP ((uint32_t)(0x00000001UL << MXC_F_FLC_CTRL2_ENABLE_RAM_HRESP_POS)) +#define MXC_F_FLC_CTRL2_BYPASS_AHB_FAIL_POS 8 +#define MXC_F_FLC_CTRL2_BYPASS_AHB_FAIL ((uint32_t)(0x000000FFUL << MXC_F_FLC_CTRL2_BYPASS_AHB_FAIL_POS)) + +#define MXC_F_FLC_INTFL1_SRAM_ADDR_WRAPPED_POS 0 +#define MXC_F_FLC_INTFL1_SRAM_ADDR_WRAPPED ((uint32_t)(0x00000001UL << MXC_F_FLC_INTFL1_SRAM_ADDR_WRAPPED_POS)) +#define MXC_F_FLC_INTFL1_INVALID_FLASH_ADDR_POS 1 +#define MXC_F_FLC_INTFL1_INVALID_FLASH_ADDR ((uint32_t)(0x00000001UL << MXC_F_FLC_INTFL1_INVALID_FLASH_ADDR_POS)) +#define MXC_F_FLC_INTFL1_FLASH_READ_LOCKED_POS 2 +#define MXC_F_FLC_INTFL1_FLASH_READ_LOCKED ((uint32_t)(0x00000001UL << MXC_F_FLC_INTFL1_FLASH_READ_LOCKED_POS)) +#define MXC_F_FLC_INTFL1_TRIM_UPDATE_DONE_POS 3 +#define MXC_F_FLC_INTFL1_TRIM_UPDATE_DONE ((uint32_t)(0x00000001UL << MXC_F_FLC_INTFL1_TRIM_UPDATE_DONE_POS)) +#define MXC_F_FLC_INTFL1_FLC_STATE_DONE_POS 4 +#define MXC_F_FLC_INTFL1_FLC_STATE_DONE ((uint32_t)(0x00000001UL << MXC_F_FLC_INTFL1_FLC_STATE_DONE_POS)) +#define MXC_F_FLC_INTFL1_FLC_PROG_COMPLETE_POS 5 +#define MXC_F_FLC_INTFL1_FLC_PROG_COMPLETE ((uint32_t)(0x00000001UL << MXC_F_FLC_INTFL1_FLC_PROG_COMPLETE_POS)) + +#define MXC_F_FLC_INTEN1_SRAM_ADDR_WRAPPED_POS 0 +#define MXC_F_FLC_INTEN1_SRAM_ADDR_WRAPPED ((uint32_t)(0x00000001UL << MXC_F_FLC_INTEN1_SRAM_ADDR_WRAPPED_POS)) +#define MXC_F_FLC_INTEN1_INVALID_FLASH_ADDR_POS 1 +#define MXC_F_FLC_INTEN1_INVALID_FLASH_ADDR ((uint32_t)(0x00000001UL << MXC_F_FLC_INTEN1_INVALID_FLASH_ADDR_POS)) +#define MXC_F_FLC_INTEN1_FLASH_READ_LOCKED_POS 2 +#define MXC_F_FLC_INTEN1_FLASH_READ_LOCKED ((uint32_t)(0x00000001UL << MXC_F_FLC_INTEN1_FLASH_READ_LOCKED_POS)) +#define MXC_F_FLC_INTEN1_TRIM_UPDATE_DONE_POS 3 +#define MXC_F_FLC_INTEN1_TRIM_UPDATE_DONE ((uint32_t)(0x00000001UL << MXC_F_FLC_INTEN1_TRIM_UPDATE_DONE_POS)) +#define MXC_F_FLC_INTEN1_FLC_STATE_DONE_POS 4 +#define MXC_F_FLC_INTEN1_FLC_STATE_DONE ((uint32_t)(0x00000001UL << MXC_F_FLC_INTEN1_FLC_STATE_DONE_POS)) +#define MXC_F_FLC_INTEN1_FLC_PROG_COMPLETE_POS 5 +#define MXC_F_FLC_INTEN1_FLC_PROG_COMPLETE ((uint32_t)(0x00000001UL << MXC_F_FLC_INTEN1_FLC_PROG_COMPLETE_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_FLC_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/gpio_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/gpio_regs.h new file mode 100644 index 00000000000..24c11b358f9 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/gpio_regs.h @@ -0,0 +1,470 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_GPIO_REGS_H_ +#define _MXC_GPIO_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t rst_mode[16]; /* 0x0000-0x003C Port P[0..15] Default (Power-On Reset) Output Drive Mode */ + __IO uint32_t free[16]; /* 0x0040-0x007C Port P[0..15] Free for GPIO Operation Flags */ + __IO uint32_t out_mode[16]; /* 0x0080-0x00BC Port P[0..15] Output Drive Mode */ + __IO uint32_t out_val[16]; /* 0x00C0-0x00FC Port P[0..15] GPIO Output Value */ + __IO uint32_t func_sel[16]; /* 0x0100-0x013C Port P[0..15] GPIO Function Select */ + __IO uint32_t in_mode[16]; /* 0x0140-0x017C Port P[0..15] GPIO Input Monitoring Mode */ + __IO uint32_t in_val[16]; /* 0x0180-0x01BC Port P[0..15] GPIO Input Value */ + __IO uint32_t int_mode[16]; /* 0x01C0-0x01FC Port P[0..15] Interrupt Detection Mode */ + __IO uint32_t intfl[16]; /* 0x0200-0x023C Port P[0..15] Interrupt Flags */ + __IO uint32_t inten[16]; /* 0x0240-0x027C Port P[0..15] Interrupt Enables */ +} mxc_gpio_regs_t; + + +/* + Register offsets for module GPIO. +*/ + +#define MXC_R_GPIO_OFFS_RST_MODE_P0 ((uint32_t)0x00000000UL) +#define MXC_R_GPIO_OFFS_RST_MODE_P1 ((uint32_t)0x00000004UL) +#define MXC_R_GPIO_OFFS_RST_MODE_P2 ((uint32_t)0x00000008UL) +#define MXC_R_GPIO_OFFS_RST_MODE_P3 ((uint32_t)0x0000000CUL) +#define MXC_R_GPIO_OFFS_RST_MODE_P4 ((uint32_t)0x00000010UL) +#define MXC_R_GPIO_OFFS_RST_MODE_P5 ((uint32_t)0x00000014UL) +#define MXC_R_GPIO_OFFS_RST_MODE_P6 ((uint32_t)0x00000018UL) +#define MXC_R_GPIO_OFFS_RST_MODE_P7 ((uint32_t)0x0000001CUL) +#define MXC_R_GPIO_OFFS_RST_MODE_P8 ((uint32_t)0x00000020UL) +#define MXC_R_GPIO_OFFS_RST_MODE_P9 ((uint32_t)0x00000024UL) +#define MXC_R_GPIO_OFFS_RST_MODE_P10 ((uint32_t)0x00000028UL) +#define MXC_R_GPIO_OFFS_RST_MODE_P11 ((uint32_t)0x0000002CUL) +#define MXC_R_GPIO_OFFS_RST_MODE_P12 ((uint32_t)0x00000030UL) +#define MXC_R_GPIO_OFFS_RST_MODE_P13 ((uint32_t)0x00000034UL) +#define MXC_R_GPIO_OFFS_RST_MODE_P14 ((uint32_t)0x00000038UL) +#define MXC_R_GPIO_OFFS_RST_MODE_P15 ((uint32_t)0x0000003CUL) +#define MXC_R_GPIO_OFFS_FREE_P0 ((uint32_t)0x00000040UL) +#define MXC_R_GPIO_OFFS_FREE_P1 ((uint32_t)0x00000044UL) +#define MXC_R_GPIO_OFFS_FREE_P2 ((uint32_t)0x00000048UL) +#define MXC_R_GPIO_OFFS_FREE_P3 ((uint32_t)0x0000004CUL) +#define MXC_R_GPIO_OFFS_FREE_P4 ((uint32_t)0x00000050UL) +#define MXC_R_GPIO_OFFS_FREE_P5 ((uint32_t)0x00000054UL) +#define MXC_R_GPIO_OFFS_FREE_P6 ((uint32_t)0x00000058UL) +#define MXC_R_GPIO_OFFS_FREE_P7 ((uint32_t)0x0000005CUL) +#define MXC_R_GPIO_OFFS_FREE_P8 ((uint32_t)0x00000060UL) +#define MXC_R_GPIO_OFFS_FREE_P9 ((uint32_t)0x00000064UL) +#define MXC_R_GPIO_OFFS_FREE_P10 ((uint32_t)0x00000068UL) +#define MXC_R_GPIO_OFFS_FREE_P11 ((uint32_t)0x0000006CUL) +#define MXC_R_GPIO_OFFS_FREE_P12 ((uint32_t)0x00000070UL) +#define MXC_R_GPIO_OFFS_FREE_P13 ((uint32_t)0x00000074UL) +#define MXC_R_GPIO_OFFS_FREE_P14 ((uint32_t)0x00000078UL) +#define MXC_R_GPIO_OFFS_FREE_P15 ((uint32_t)0x0000007CUL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P0 ((uint32_t)0x00000080UL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P1 ((uint32_t)0x00000084UL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P2 ((uint32_t)0x00000088UL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P3 ((uint32_t)0x0000008CUL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P4 ((uint32_t)0x00000090UL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P5 ((uint32_t)0x00000094UL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P6 ((uint32_t)0x00000098UL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P7 ((uint32_t)0x0000009CUL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P8 ((uint32_t)0x000000A0UL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P9 ((uint32_t)0x000000A4UL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P10 ((uint32_t)0x000000A8UL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P11 ((uint32_t)0x000000ACUL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P12 ((uint32_t)0x000000B0UL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P13 ((uint32_t)0x000000B4UL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P14 ((uint32_t)0x000000B8UL) +#define MXC_R_GPIO_OFFS_OUT_MODE_P15 ((uint32_t)0x000000BCUL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P0 ((uint32_t)0x000000C0UL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P1 ((uint32_t)0x000000C4UL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P2 ((uint32_t)0x000000C8UL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P3 ((uint32_t)0x000000CCUL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P4 ((uint32_t)0x000000D0UL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P5 ((uint32_t)0x000000D4UL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P6 ((uint32_t)0x000000D8UL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P7 ((uint32_t)0x000000DCUL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P8 ((uint32_t)0x000000E0UL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P9 ((uint32_t)0x000000E4UL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P10 ((uint32_t)0x000000E8UL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P11 ((uint32_t)0x000000ECUL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P12 ((uint32_t)0x000000F0UL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P13 ((uint32_t)0x000000F4UL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P14 ((uint32_t)0x000000F8UL) +#define MXC_R_GPIO_OFFS_OUT_VAL_P15 ((uint32_t)0x000000FCUL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P0 ((uint32_t)0x00000100UL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P1 ((uint32_t)0x00000104UL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P2 ((uint32_t)0x00000108UL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P3 ((uint32_t)0x0000010CUL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P4 ((uint32_t)0x00000110UL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P5 ((uint32_t)0x00000114UL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P6 ((uint32_t)0x00000118UL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P7 ((uint32_t)0x0000011CUL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P8 ((uint32_t)0x00000120UL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P9 ((uint32_t)0x00000124UL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P10 ((uint32_t)0x00000128UL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P11 ((uint32_t)0x0000012CUL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P12 ((uint32_t)0x00000130UL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P13 ((uint32_t)0x00000134UL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P14 ((uint32_t)0x00000138UL) +#define MXC_R_GPIO_OFFS_FUNC_SEL_P15 ((uint32_t)0x0000013CUL) +#define MXC_R_GPIO_OFFS_IN_MODE_P0 ((uint32_t)0x00000140UL) +#define MXC_R_GPIO_OFFS_IN_MODE_P1 ((uint32_t)0x00000144UL) +#define MXC_R_GPIO_OFFS_IN_MODE_P2 ((uint32_t)0x00000148UL) +#define MXC_R_GPIO_OFFS_IN_MODE_P3 ((uint32_t)0x0000014CUL) +#define MXC_R_GPIO_OFFS_IN_MODE_P4 ((uint32_t)0x00000150UL) +#define MXC_R_GPIO_OFFS_IN_MODE_P5 ((uint32_t)0x00000154UL) +#define MXC_R_GPIO_OFFS_IN_MODE_P6 ((uint32_t)0x00000158UL) +#define MXC_R_GPIO_OFFS_IN_MODE_P7 ((uint32_t)0x0000015CUL) +#define MXC_R_GPIO_OFFS_IN_MODE_P8 ((uint32_t)0x00000160UL) +#define MXC_R_GPIO_OFFS_IN_MODE_P9 ((uint32_t)0x00000164UL) +#define MXC_R_GPIO_OFFS_IN_MODE_P10 ((uint32_t)0x00000168UL) +#define MXC_R_GPIO_OFFS_IN_MODE_P11 ((uint32_t)0x0000016CUL) +#define MXC_R_GPIO_OFFS_IN_MODE_P12 ((uint32_t)0x00000170UL) +#define MXC_R_GPIO_OFFS_IN_MODE_P13 ((uint32_t)0x00000174UL) +#define MXC_R_GPIO_OFFS_IN_MODE_P14 ((uint32_t)0x00000178UL) +#define MXC_R_GPIO_OFFS_IN_MODE_P15 ((uint32_t)0x0000017CUL) +#define MXC_R_GPIO_OFFS_IN_VAL_P0 ((uint32_t)0x00000180UL) +#define MXC_R_GPIO_OFFS_IN_VAL_P1 ((uint32_t)0x00000184UL) +#define MXC_R_GPIO_OFFS_IN_VAL_P2 ((uint32_t)0x00000188UL) +#define MXC_R_GPIO_OFFS_IN_VAL_P3 ((uint32_t)0x0000018CUL) +#define MXC_R_GPIO_OFFS_IN_VAL_P4 ((uint32_t)0x00000190UL) +#define MXC_R_GPIO_OFFS_IN_VAL_P5 ((uint32_t)0x00000194UL) +#define MXC_R_GPIO_OFFS_IN_VAL_P6 ((uint32_t)0x00000198UL) +#define MXC_R_GPIO_OFFS_IN_VAL_P7 ((uint32_t)0x0000019CUL) +#define MXC_R_GPIO_OFFS_IN_VAL_P8 ((uint32_t)0x000001A0UL) +#define MXC_R_GPIO_OFFS_IN_VAL_P9 ((uint32_t)0x000001A4UL) +#define MXC_R_GPIO_OFFS_IN_VAL_P10 ((uint32_t)0x000001A8UL) +#define MXC_R_GPIO_OFFS_IN_VAL_P11 ((uint32_t)0x000001ACUL) +#define MXC_R_GPIO_OFFS_IN_VAL_P12 ((uint32_t)0x000001B0UL) +#define MXC_R_GPIO_OFFS_IN_VAL_P13 ((uint32_t)0x000001B4UL) +#define MXC_R_GPIO_OFFS_IN_VAL_P14 ((uint32_t)0x000001B8UL) +#define MXC_R_GPIO_OFFS_IN_VAL_P15 ((uint32_t)0x000001BCUL) +#define MXC_R_GPIO_OFFS_INT_MODE_P0 ((uint32_t)0x000001C0UL) +#define MXC_R_GPIO_OFFS_INT_MODE_P1 ((uint32_t)0x000001C4UL) +#define MXC_R_GPIO_OFFS_INT_MODE_P2 ((uint32_t)0x000001C8UL) +#define MXC_R_GPIO_OFFS_INT_MODE_P3 ((uint32_t)0x000001CCUL) +#define MXC_R_GPIO_OFFS_INT_MODE_P4 ((uint32_t)0x000001D0UL) +#define MXC_R_GPIO_OFFS_INT_MODE_P5 ((uint32_t)0x000001D4UL) +#define MXC_R_GPIO_OFFS_INT_MODE_P6 ((uint32_t)0x000001D8UL) +#define MXC_R_GPIO_OFFS_INT_MODE_P7 ((uint32_t)0x000001DCUL) +#define MXC_R_GPIO_OFFS_INT_MODE_P8 ((uint32_t)0x000001E0UL) +#define MXC_R_GPIO_OFFS_INT_MODE_P9 ((uint32_t)0x000001E4UL) +#define MXC_R_GPIO_OFFS_INT_MODE_P10 ((uint32_t)0x000001E8UL) +#define MXC_R_GPIO_OFFS_INT_MODE_P11 ((uint32_t)0x000001ECUL) +#define MXC_R_GPIO_OFFS_INT_MODE_P12 ((uint32_t)0x000001F0UL) +#define MXC_R_GPIO_OFFS_INT_MODE_P13 ((uint32_t)0x000001F4UL) +#define MXC_R_GPIO_OFFS_INT_MODE_P14 ((uint32_t)0x000001F8UL) +#define MXC_R_GPIO_OFFS_INT_MODE_P15 ((uint32_t)0x000001FCUL) +#define MXC_R_GPIO_OFFS_INTFL_P0 ((uint32_t)0x00000200UL) +#define MXC_R_GPIO_OFFS_INTFL_P1 ((uint32_t)0x00000204UL) +#define MXC_R_GPIO_OFFS_INTFL_P2 ((uint32_t)0x00000208UL) +#define MXC_R_GPIO_OFFS_INTFL_P3 ((uint32_t)0x0000020CUL) +#define MXC_R_GPIO_OFFS_INTFL_P4 ((uint32_t)0x00000210UL) +#define MXC_R_GPIO_OFFS_INTFL_P5 ((uint32_t)0x00000214UL) +#define MXC_R_GPIO_OFFS_INTFL_P6 ((uint32_t)0x00000218UL) +#define MXC_R_GPIO_OFFS_INTFL_P7 ((uint32_t)0x0000021CUL) +#define MXC_R_GPIO_OFFS_INTFL_P8 ((uint32_t)0x00000220UL) +#define MXC_R_GPIO_OFFS_INTFL_P9 ((uint32_t)0x00000224UL) +#define MXC_R_GPIO_OFFS_INTFL_P10 ((uint32_t)0x00000228UL) +#define MXC_R_GPIO_OFFS_INTFL_P11 ((uint32_t)0x0000022CUL) +#define MXC_R_GPIO_OFFS_INTFL_P12 ((uint32_t)0x00000230UL) +#define MXC_R_GPIO_OFFS_INTFL_P13 ((uint32_t)0x00000234UL) +#define MXC_R_GPIO_OFFS_INTFL_P14 ((uint32_t)0x00000238UL) +#define MXC_R_GPIO_OFFS_INTFL_P15 ((uint32_t)0x0000023CUL) +#define MXC_R_GPIO_OFFS_INTEN_P0 ((uint32_t)0x00000240UL) +#define MXC_R_GPIO_OFFS_INTEN_P1 ((uint32_t)0x00000244UL) +#define MXC_R_GPIO_OFFS_INTEN_P2 ((uint32_t)0x00000248UL) +#define MXC_R_GPIO_OFFS_INTEN_P3 ((uint32_t)0x0000024CUL) +#define MXC_R_GPIO_OFFS_INTEN_P4 ((uint32_t)0x00000250UL) +#define MXC_R_GPIO_OFFS_INTEN_P5 ((uint32_t)0x00000254UL) +#define MXC_R_GPIO_OFFS_INTEN_P6 ((uint32_t)0x00000258UL) +#define MXC_R_GPIO_OFFS_INTEN_P7 ((uint32_t)0x0000025CUL) +#define MXC_R_GPIO_OFFS_INTEN_P8 ((uint32_t)0x00000260UL) +#define MXC_R_GPIO_OFFS_INTEN_P9 ((uint32_t)0x00000264UL) +#define MXC_R_GPIO_OFFS_INTEN_P10 ((uint32_t)0x00000268UL) +#define MXC_R_GPIO_OFFS_INTEN_P11 ((uint32_t)0x0000026CUL) +#define MXC_R_GPIO_OFFS_INTEN_P12 ((uint32_t)0x00000270UL) +#define MXC_R_GPIO_OFFS_INTEN_P13 ((uint32_t)0x00000274UL) +#define MXC_R_GPIO_OFFS_INTEN_P14 ((uint32_t)0x00000278UL) +#define MXC_R_GPIO_OFFS_INTEN_P15 ((uint32_t)0x0000027CUL) + + +/* + Field positions and masks for module GPIO. +*/ + +#define MXC_F_GPIO_RST_MODE_PIN0_POS 0 +#define MXC_F_GPIO_RST_MODE_PIN0 ((uint32_t)(0x00000007UL << MXC_F_GPIO_RST_MODE_PIN0_POS)) +#define MXC_F_GPIO_RST_MODE_PIN1_POS 4 +#define MXC_F_GPIO_RST_MODE_PIN1 ((uint32_t)(0x00000007UL << MXC_F_GPIO_RST_MODE_PIN1_POS)) +#define MXC_F_GPIO_RST_MODE_PIN2_POS 8 +#define MXC_F_GPIO_RST_MODE_PIN2 ((uint32_t)(0x00000007UL << MXC_F_GPIO_RST_MODE_PIN2_POS)) +#define MXC_F_GPIO_RST_MODE_PIN3_POS 12 +#define MXC_F_GPIO_RST_MODE_PIN3 ((uint32_t)(0x00000007UL << MXC_F_GPIO_RST_MODE_PIN3_POS)) +#define MXC_F_GPIO_RST_MODE_PIN4_POS 16 +#define MXC_F_GPIO_RST_MODE_PIN4 ((uint32_t)(0x00000007UL << MXC_F_GPIO_RST_MODE_PIN4_POS)) +#define MXC_F_GPIO_RST_MODE_PIN5_POS 20 +#define MXC_F_GPIO_RST_MODE_PIN5 ((uint32_t)(0x00000007UL << MXC_F_GPIO_RST_MODE_PIN5_POS)) +#define MXC_F_GPIO_RST_MODE_PIN6_POS 24 +#define MXC_F_GPIO_RST_MODE_PIN6 ((uint32_t)(0x00000007UL << MXC_F_GPIO_RST_MODE_PIN6_POS)) +#define MXC_F_GPIO_RST_MODE_PIN7_POS 28 +#define MXC_F_GPIO_RST_MODE_PIN7 ((uint32_t)(0x00000007UL << MXC_F_GPIO_RST_MODE_PIN7_POS)) + +#define MXC_F_GPIO_FREE_PIN0_POS 0 +#define MXC_F_GPIO_FREE_PIN0 ((uint32_t)(0x00000001UL << MXC_F_GPIO_FREE_PIN0_POS)) +#define MXC_F_GPIO_FREE_PIN1_POS 1 +#define MXC_F_GPIO_FREE_PIN1 ((uint32_t)(0x00000001UL << MXC_F_GPIO_FREE_PIN1_POS)) +#define MXC_F_GPIO_FREE_PIN2_POS 2 +#define MXC_F_GPIO_FREE_PIN2 ((uint32_t)(0x00000001UL << MXC_F_GPIO_FREE_PIN2_POS)) +#define MXC_F_GPIO_FREE_PIN3_POS 3 +#define MXC_F_GPIO_FREE_PIN3 ((uint32_t)(0x00000001UL << MXC_F_GPIO_FREE_PIN3_POS)) +#define MXC_F_GPIO_FREE_PIN4_POS 4 +#define MXC_F_GPIO_FREE_PIN4 ((uint32_t)(0x00000001UL << MXC_F_GPIO_FREE_PIN4_POS)) +#define MXC_F_GPIO_FREE_PIN5_POS 5 +#define MXC_F_GPIO_FREE_PIN5 ((uint32_t)(0x00000001UL << MXC_F_GPIO_FREE_PIN5_POS)) +#define MXC_F_GPIO_FREE_PIN6_POS 6 +#define MXC_F_GPIO_FREE_PIN6 ((uint32_t)(0x00000001UL << MXC_F_GPIO_FREE_PIN6_POS)) +#define MXC_F_GPIO_FREE_PIN7_POS 7 +#define MXC_F_GPIO_FREE_PIN7 ((uint32_t)(0x00000001UL << MXC_F_GPIO_FREE_PIN7_POS)) + +#define MXC_F_GPIO_OUT_MODE_PIN0_POS 0 +#define MXC_F_GPIO_OUT_MODE_PIN0 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_OUT_MODE_PIN0_POS)) +#define MXC_F_GPIO_OUT_MODE_PIN1_POS 4 +#define MXC_F_GPIO_OUT_MODE_PIN1 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_OUT_MODE_PIN1_POS)) +#define MXC_F_GPIO_OUT_MODE_PIN2_POS 8 +#define MXC_F_GPIO_OUT_MODE_PIN2 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_OUT_MODE_PIN2_POS)) +#define MXC_F_GPIO_OUT_MODE_PIN3_POS 12 +#define MXC_F_GPIO_OUT_MODE_PIN3 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_OUT_MODE_PIN3_POS)) +#define MXC_F_GPIO_OUT_MODE_PIN4_POS 16 +#define MXC_F_GPIO_OUT_MODE_PIN4 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_OUT_MODE_PIN4_POS)) +#define MXC_F_GPIO_OUT_MODE_PIN5_POS 20 +#define MXC_F_GPIO_OUT_MODE_PIN5 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_OUT_MODE_PIN5_POS)) +#define MXC_F_GPIO_OUT_MODE_PIN6_POS 24 +#define MXC_F_GPIO_OUT_MODE_PIN6 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_OUT_MODE_PIN6_POS)) +#define MXC_F_GPIO_OUT_MODE_PIN7_POS 28 +#define MXC_F_GPIO_OUT_MODE_PIN7 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_OUT_MODE_PIN7_POS)) + +#define MXC_F_GPIO_OUT_VAL_PIN0_POS 0 +#define MXC_F_GPIO_OUT_VAL_PIN0 ((uint32_t)(0x00000001UL << MXC_F_GPIO_OUT_VAL_PIN0_POS)) +#define MXC_F_GPIO_OUT_VAL_PIN1_POS 1 +#define MXC_F_GPIO_OUT_VAL_PIN1 ((uint32_t)(0x00000001UL << MXC_F_GPIO_OUT_VAL_PIN1_POS)) +#define MXC_F_GPIO_OUT_VAL_PIN2_POS 2 +#define MXC_F_GPIO_OUT_VAL_PIN2 ((uint32_t)(0x00000001UL << MXC_F_GPIO_OUT_VAL_PIN2_POS)) +#define MXC_F_GPIO_OUT_VAL_PIN3_POS 3 +#define MXC_F_GPIO_OUT_VAL_PIN3 ((uint32_t)(0x00000001UL << MXC_F_GPIO_OUT_VAL_PIN3_POS)) +#define MXC_F_GPIO_OUT_VAL_PIN4_POS 4 +#define MXC_F_GPIO_OUT_VAL_PIN4 ((uint32_t)(0x00000001UL << MXC_F_GPIO_OUT_VAL_PIN4_POS)) +#define MXC_F_GPIO_OUT_VAL_PIN5_POS 5 +#define MXC_F_GPIO_OUT_VAL_PIN5 ((uint32_t)(0x00000001UL << MXC_F_GPIO_OUT_VAL_PIN5_POS)) +#define MXC_F_GPIO_OUT_VAL_PIN6_POS 6 +#define MXC_F_GPIO_OUT_VAL_PIN6 ((uint32_t)(0x00000001UL << MXC_F_GPIO_OUT_VAL_PIN6_POS)) +#define MXC_F_GPIO_OUT_VAL_PIN7_POS 7 +#define MXC_F_GPIO_OUT_VAL_PIN7 ((uint32_t)(0x00000001UL << MXC_F_GPIO_OUT_VAL_PIN7_POS)) + +#define MXC_F_GPIO_FUNC_SEL_PIN0_POS 0 +#define MXC_F_GPIO_FUNC_SEL_PIN0 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_FUNC_SEL_PIN0_POS)) +#define MXC_F_GPIO_FUNC_SEL_PIN1_POS 4 +#define MXC_F_GPIO_FUNC_SEL_PIN1 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_FUNC_SEL_PIN1_POS)) +#define MXC_F_GPIO_FUNC_SEL_PIN2_POS 8 +#define MXC_F_GPIO_FUNC_SEL_PIN2 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_FUNC_SEL_PIN2_POS)) +#define MXC_F_GPIO_FUNC_SEL_PIN3_POS 12 +#define MXC_F_GPIO_FUNC_SEL_PIN3 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_FUNC_SEL_PIN3_POS)) +#define MXC_F_GPIO_FUNC_SEL_PIN4_POS 16 +#define MXC_F_GPIO_FUNC_SEL_PIN4 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_FUNC_SEL_PIN4_POS)) +#define MXC_F_GPIO_FUNC_SEL_PIN5_POS 20 +#define MXC_F_GPIO_FUNC_SEL_PIN5 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_FUNC_SEL_PIN5_POS)) +#define MXC_F_GPIO_FUNC_SEL_PIN6_POS 24 +#define MXC_F_GPIO_FUNC_SEL_PIN6 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_FUNC_SEL_PIN6_POS)) +#define MXC_F_GPIO_FUNC_SEL_PIN7_POS 28 +#define MXC_F_GPIO_FUNC_SEL_PIN7 ((uint32_t)(0x0000000FUL << MXC_F_GPIO_FUNC_SEL_PIN7_POS)) + +#define MXC_F_GPIO_IN_MODE_PIN0_POS 0 +#define MXC_F_GPIO_IN_MODE_PIN0 ((uint32_t)(0x00000003UL << MXC_F_GPIO_IN_MODE_PIN0_POS)) +#define MXC_F_GPIO_IN_MODE_PIN1_POS 4 +#define MXC_F_GPIO_IN_MODE_PIN1 ((uint32_t)(0x00000003UL << MXC_F_GPIO_IN_MODE_PIN1_POS)) +#define MXC_F_GPIO_IN_MODE_PIN2_POS 8 +#define MXC_F_GPIO_IN_MODE_PIN2 ((uint32_t)(0x00000003UL << MXC_F_GPIO_IN_MODE_PIN2_POS)) +#define MXC_F_GPIO_IN_MODE_PIN3_POS 12 +#define MXC_F_GPIO_IN_MODE_PIN3 ((uint32_t)(0x00000003UL << MXC_F_GPIO_IN_MODE_PIN3_POS)) +#define MXC_F_GPIO_IN_MODE_PIN4_POS 16 +#define MXC_F_GPIO_IN_MODE_PIN4 ((uint32_t)(0x00000003UL << MXC_F_GPIO_IN_MODE_PIN4_POS)) +#define MXC_F_GPIO_IN_MODE_PIN5_POS 20 +#define MXC_F_GPIO_IN_MODE_PIN5 ((uint32_t)(0x00000003UL << MXC_F_GPIO_IN_MODE_PIN5_POS)) +#define MXC_F_GPIO_IN_MODE_PIN6_POS 24 +#define MXC_F_GPIO_IN_MODE_PIN6 ((uint32_t)(0x00000003UL << MXC_F_GPIO_IN_MODE_PIN6_POS)) +#define MXC_F_GPIO_IN_MODE_PIN7_POS 28 +#define MXC_F_GPIO_IN_MODE_PIN7 ((uint32_t)(0x00000003UL << MXC_F_GPIO_IN_MODE_PIN7_POS)) + +#define MXC_F_GPIO_IN_VAL_PIN0_POS 0 +#define MXC_F_GPIO_IN_VAL_PIN0 ((uint32_t)(0x00000001UL << MXC_F_GPIO_IN_VAL_PIN0_POS)) +#define MXC_F_GPIO_IN_VAL_PIN1_POS 1 +#define MXC_F_GPIO_IN_VAL_PIN1 ((uint32_t)(0x00000001UL << MXC_F_GPIO_IN_VAL_PIN1_POS)) +#define MXC_F_GPIO_IN_VAL_PIN2_POS 2 +#define MXC_F_GPIO_IN_VAL_PIN2 ((uint32_t)(0x00000001UL << MXC_F_GPIO_IN_VAL_PIN2_POS)) +#define MXC_F_GPIO_IN_VAL_PIN3_POS 3 +#define MXC_F_GPIO_IN_VAL_PIN3 ((uint32_t)(0x00000001UL << MXC_F_GPIO_IN_VAL_PIN3_POS)) +#define MXC_F_GPIO_IN_VAL_PIN4_POS 4 +#define MXC_F_GPIO_IN_VAL_PIN4 ((uint32_t)(0x00000001UL << MXC_F_GPIO_IN_VAL_PIN4_POS)) +#define MXC_F_GPIO_IN_VAL_PIN5_POS 5 +#define MXC_F_GPIO_IN_VAL_PIN5 ((uint32_t)(0x00000001UL << MXC_F_GPIO_IN_VAL_PIN5_POS)) +#define MXC_F_GPIO_IN_VAL_PIN6_POS 6 +#define MXC_F_GPIO_IN_VAL_PIN6 ((uint32_t)(0x00000001UL << MXC_F_GPIO_IN_VAL_PIN6_POS)) +#define MXC_F_GPIO_IN_VAL_PIN7_POS 7 +#define MXC_F_GPIO_IN_VAL_PIN7 ((uint32_t)(0x00000001UL << MXC_F_GPIO_IN_VAL_PIN7_POS)) + +#define MXC_F_GPIO_INT_MODE_PIN0_POS 0 +#define MXC_F_GPIO_INT_MODE_PIN0 ((uint32_t)(0x00000007UL << MXC_F_GPIO_INT_MODE_PIN0_POS)) +#define MXC_F_GPIO_INT_MODE_PIN1_POS 4 +#define MXC_F_GPIO_INT_MODE_PIN1 ((uint32_t)(0x00000007UL << MXC_F_GPIO_INT_MODE_PIN1_POS)) +#define MXC_F_GPIO_INT_MODE_PIN2_POS 8 +#define MXC_F_GPIO_INT_MODE_PIN2 ((uint32_t)(0x00000007UL << MXC_F_GPIO_INT_MODE_PIN2_POS)) +#define MXC_F_GPIO_INT_MODE_PIN3_POS 12 +#define MXC_F_GPIO_INT_MODE_PIN3 ((uint32_t)(0x00000007UL << MXC_F_GPIO_INT_MODE_PIN3_POS)) +#define MXC_F_GPIO_INT_MODE_PIN4_POS 16 +#define MXC_F_GPIO_INT_MODE_PIN4 ((uint32_t)(0x00000007UL << MXC_F_GPIO_INT_MODE_PIN4_POS)) +#define MXC_F_GPIO_INT_MODE_PIN5_POS 20 +#define MXC_F_GPIO_INT_MODE_PIN5 ((uint32_t)(0x00000007UL << MXC_F_GPIO_INT_MODE_PIN5_POS)) +#define MXC_F_GPIO_INT_MODE_PIN6_POS 24 +#define MXC_F_GPIO_INT_MODE_PIN6 ((uint32_t)(0x00000007UL << MXC_F_GPIO_INT_MODE_PIN6_POS)) +#define MXC_F_GPIO_INT_MODE_PIN7_POS 28 +#define MXC_F_GPIO_INT_MODE_PIN7 ((uint32_t)(0x00000007UL << MXC_F_GPIO_INT_MODE_PIN7_POS)) + +#define MXC_F_GPIO_INTFL_PIN0_POS 0 +#define MXC_F_GPIO_INTFL_PIN0 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTFL_PIN0_POS)) +#define MXC_F_GPIO_INTFL_PIN1_POS 1 +#define MXC_F_GPIO_INTFL_PIN1 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTFL_PIN1_POS)) +#define MXC_F_GPIO_INTFL_PIN2_POS 2 +#define MXC_F_GPIO_INTFL_PIN2 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTFL_PIN2_POS)) +#define MXC_F_GPIO_INTFL_PIN3_POS 3 +#define MXC_F_GPIO_INTFL_PIN3 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTFL_PIN3_POS)) +#define MXC_F_GPIO_INTFL_PIN4_POS 4 +#define MXC_F_GPIO_INTFL_PIN4 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTFL_PIN4_POS)) +#define MXC_F_GPIO_INTFL_PIN5_POS 5 +#define MXC_F_GPIO_INTFL_PIN5 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTFL_PIN5_POS)) +#define MXC_F_GPIO_INTFL_PIN6_POS 6 +#define MXC_F_GPIO_INTFL_PIN6 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTFL_PIN6_POS)) +#define MXC_F_GPIO_INTFL_PIN7_POS 7 +#define MXC_F_GPIO_INTFL_PIN7 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTFL_PIN7_POS)) + +#define MXC_F_GPIO_INTEN_PIN0_POS 0 +#define MXC_F_GPIO_INTEN_PIN0 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTEN_PIN0_POS)) +#define MXC_F_GPIO_INTEN_PIN1_POS 1 +#define MXC_F_GPIO_INTEN_PIN1 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTEN_PIN1_POS)) +#define MXC_F_GPIO_INTEN_PIN2_POS 2 +#define MXC_F_GPIO_INTEN_PIN2 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTEN_PIN2_POS)) +#define MXC_F_GPIO_INTEN_PIN3_POS 3 +#define MXC_F_GPIO_INTEN_PIN3 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTEN_PIN3_POS)) +#define MXC_F_GPIO_INTEN_PIN4_POS 4 +#define MXC_F_GPIO_INTEN_PIN4 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTEN_PIN4_POS)) +#define MXC_F_GPIO_INTEN_PIN5_POS 5 +#define MXC_F_GPIO_INTEN_PIN5 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTEN_PIN5_POS)) +#define MXC_F_GPIO_INTEN_PIN6_POS 6 +#define MXC_F_GPIO_INTEN_PIN6 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTEN_PIN6_POS)) +#define MXC_F_GPIO_INTEN_PIN7_POS 7 +#define MXC_F_GPIO_INTEN_PIN7 ((uint32_t)(0x00000001UL << MXC_F_GPIO_INTEN_PIN7_POS)) + + + +/* + Field values and shifted values for module GPIO. +*/ + +#define MXC_V_GPIO_RST_MODE_DRIVE_0 ((uint32_t)(0x00000000UL)) +#define MXC_V_GPIO_RST_MODE_WEAK_PULLDOWN ((uint32_t)(0x00000001UL)) +#define MXC_V_GPIO_RST_MODE_WEAK_PULLUP ((uint32_t)(0x00000002UL)) +#define MXC_V_GPIO_RST_MODE_DRIVE_1 ((uint32_t)(0x00000003UL)) +#define MXC_V_GPIO_RST_MODE_HIGH_Z ((uint32_t)(0x00000004UL)) + +#define MXC_V_GPIO_FREE_NOT_AVAILABLE ((uint32_t)(0x00000000UL)) +#define MXC_V_GPIO_FREE_AVAILABLE ((uint32_t)(0x00000001UL)) + +#define MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLUP ((uint32_t)(0x00000000UL)) +#define MXC_V_GPIO_OUT_MODE_OPEN_DRAIN ((uint32_t)(0x00000001UL)) +#define MXC_V_GPIO_OUT_MODE_OPEN_DRAIN_WEAK_PULLUP ((uint32_t)(0x00000002UL)) +#define MXC_V_GPIO_OUT_MODE_NORMAL_HIGH_Z ((uint32_t)(0x00000004UL)) +#define MXC_V_GPIO_OUT_MODE_NORMAL ((uint32_t)(0x00000005UL)) +#define MXC_V_GPIO_OUT_MODE_SLOW_HIGH_Z ((uint32_t)(0x00000006UL)) +#define MXC_V_GPIO_OUT_MODE_SLOW_DRIVE ((uint32_t)(0x00000007UL)) +#define MXC_V_GPIO_OUT_MODE_FAST_HIGH_Z ((uint32_t)(0x00000008UL)) +#define MXC_V_GPIO_OUT_MODE_FAST_DRIVE ((uint32_t)(0x00000009UL)) +#define MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLDOWN ((uint32_t)(0x0000000AUL)) +#define MXC_V_GPIO_OUT_MODE_OPEN_SOURCE ((uint32_t)(0x0000000BUL)) +#define MXC_V_GPIO_OUT_MODE_OPEN_SOURCE_WEAK_PULLDOWN ((uint32_t)(0x0000000CUL)) +#define MXC_V_GPIO_OUT_MODE_HIGH_Z_INPUT_DISABLED ((uint32_t)(0x0000000FUL)) + +#define MXC_V_GPIO_FUNC_SEL_MODE_GPIO ((uint32_t)(0x00000000UL)) +#define MXC_V_GPIO_FUNC_SEL_MODE_PT ((uint32_t)(0x00000001UL)) +#define MXC_V_GPIO_FUNC_SEL_MODE_TMR ((uint32_t)(0x00000002UL)) + +#define MXC_V_GPIO_IN_MODE_NORMAL ((uint32_t)(0x00000000UL)) +#define MXC_V_GPIO_IN_MODE_INVERTED ((uint32_t)(0x00000001UL)) +#define MXC_V_GPIO_IN_MODE_ALWAYS_ZERO ((uint32_t)(0x00000002UL)) +#define MXC_V_GPIO_IN_MODE_ALWAYS_ONE ((uint32_t)(0x00000003UL)) + +#define MXC_V_GPIO_INT_MODE_DISABLE ((uint32_t)(0x00000000UL)) +#define MXC_V_GPIO_INT_MODE_FALLING_EDGE ((uint32_t)(0x00000001UL)) +#define MXC_V_GPIO_INT_MODE_RISING_EDGE ((uint32_t)(0x00000002UL)) +#define MXC_V_GPIO_INT_MODE_ANY_EDGE ((uint32_t)(0x00000003UL)) +#define MXC_V_GPIO_INT_MODE_LOW_LVL ((uint32_t)(0x00000004UL)) +#define MXC_V_GPIO_INT_MODE_HIGH_LVL ((uint32_t)(0x00000005UL)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_GPIO_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/i2cm_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/i2cm_regs.h new file mode 100644 index 00000000000..63d94cf47c9 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/i2cm_regs.h @@ -0,0 +1,215 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_I2CM_REGS_H_ +#define _MXC_I2CM_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +#define MXC_S_I2CM_TRANS_TAG_START 0x000 +#define MXC_S_I2CM_TRANS_TAG_TXDATA_ACK 0x100 +#define MXC_S_I2CM_TRANS_TAG_TXDATA_NACK 0x200 +#define MXC_S_I2CM_TRANS_TAG_RXDATA_COUNT 0x400 +#define MXC_S_I2CM_TRANS_TAG_RXDATA_NACK 0x500 +#define MXC_S_I2CM_TRANS_TAG_STOP 0x700 +#define MXC_S_I2CM_RSTLS_TAG_DATA 0x100 +#define MXC_S_I2CM_RSTLS_TAG_EMPTY 0x200 + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t fs_clk_div; /* 0x0000 I2C Master Full Speed SCL Clock Settings */ + __I uint32_t rsv004[2]; /* 0x0004-0x0008 */ + __IO uint32_t timeout; /* 0x000C I2C Master Timeout and Auto-Stop Settings */ + __IO uint32_t ctrl; /* 0x0010 I2C Master Control Register */ + __IO uint32_t trans; /* 0x0014 I2C Master Transaction Start and Status Flags */ + __IO uint32_t intfl; /* 0x0018 I2C Master Interrupt Flags */ + __IO uint32_t inten; /* 0x001C I2C Master Interrupt Enable/Disable Controls */ + __I uint32_t rsv020[2]; /* 0x0020-0x0024 */ + __IO uint32_t bb; /* 0x0028 I2C Master Bit-Bang Control Register */ +} mxc_i2cm_regs_t; + + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + union { /* 0x0000-0x07FC FIFO Write Point for Data to Transmit */ + __IO uint16_t tx; + __IO uint8_t tx_8[2048]; + __IO uint16_t tx_16[1024]; + __IO uint32_t tx_32[512]; + }; + union { /* 0x0800-0x0FFC FIFO Read Point for Received Data */ + __IO uint16_t rx; + __IO uint8_t rx_8[2048]; + __IO uint16_t rx_16[1024]; + __IO uint32_t rx_32[512]; + }; +} mxc_i2cm_fifo_regs_t; + + +/* + Register offsets for module I2CM. +*/ + +#define MXC_R_I2CM_OFFS_FS_CLK_DIV ((uint32_t)0x00000000UL) +#define MXC_R_I2CM_OFFS_TIMEOUT ((uint32_t)0x0000000CUL) +#define MXC_R_I2CM_OFFS_CTRL ((uint32_t)0x00000010UL) +#define MXC_R_I2CM_OFFS_TRANS ((uint32_t)0x00000014UL) +#define MXC_R_I2CM_OFFS_INTFL ((uint32_t)0x00000018UL) +#define MXC_R_I2CM_OFFS_INTEN ((uint32_t)0x0000001CUL) +#define MXC_R_I2CM_OFFS_BB ((uint32_t)0x00000028UL) +#define MXC_R_I2CM_FIFO_OFFS_TRANS ((uint32_t)0x00000000UL) +#define MXC_R_I2CM_FIFO_OFFS_RSLTS ((uint32_t)0x00000800UL) + + +/* + Field positions and masks for module I2CM. +*/ + +#define MXC_F_I2CM_FS_CLK_DIV_FS_FILTER_CLK_DIV_POS 0 +#define MXC_F_I2CM_FS_CLK_DIV_FS_FILTER_CLK_DIV ((uint32_t)(0x000000FFUL << MXC_F_I2CM_FS_CLK_DIV_FS_FILTER_CLK_DIV_POS)) +#define MXC_F_I2CM_FS_CLK_DIV_FS_SCL_LO_CNT_POS 8 +#define MXC_F_I2CM_FS_CLK_DIV_FS_SCL_LO_CNT ((uint32_t)(0x00000FFFUL << MXC_F_I2CM_FS_CLK_DIV_FS_SCL_LO_CNT_POS)) +#define MXC_F_I2CM_FS_CLK_DIV_FS_SCL_HI_CNT_POS 20 +#define MXC_F_I2CM_FS_CLK_DIV_FS_SCL_HI_CNT ((uint32_t)(0x00000FFFUL << MXC_F_I2CM_FS_CLK_DIV_FS_SCL_HI_CNT_POS)) + +#define MXC_F_I2CM_TIMEOUT_TX_TIMEOUT_POS 16 +#define MXC_F_I2CM_TIMEOUT_TX_TIMEOUT ((uint32_t)(0x000000FFUL << MXC_F_I2CM_TIMEOUT_TX_TIMEOUT_POS)) +#define MXC_F_I2CM_TIMEOUT_AUTO_STOP_EN_POS 24 +#define MXC_F_I2CM_TIMEOUT_AUTO_STOP_EN ((uint32_t)(0x00000001UL << MXC_F_I2CM_TIMEOUT_AUTO_STOP_EN_POS)) + +#define MXC_F_I2CM_CTRL_TX_FIFO_EN_POS 2 +#define MXC_F_I2CM_CTRL_TX_FIFO_EN ((uint32_t)(0x00000001UL << MXC_F_I2CM_CTRL_TX_FIFO_EN_POS)) +#define MXC_F_I2CM_CTRL_RX_FIFO_EN_POS 3 +#define MXC_F_I2CM_CTRL_RX_FIFO_EN ((uint32_t)(0x00000001UL << MXC_F_I2CM_CTRL_RX_FIFO_EN_POS)) +#define MXC_F_I2CM_CTRL_MSTR_RESET_EN_POS 7 +#define MXC_F_I2CM_CTRL_MSTR_RESET_EN ((uint32_t)(0x00000001UL << MXC_F_I2CM_CTRL_MSTR_RESET_EN_POS)) + +#define MXC_F_I2CM_TRANS_TX_START_POS 0 +#define MXC_F_I2CM_TRANS_TX_START ((uint32_t)(0x00000001UL << MXC_F_I2CM_TRANS_TX_START_POS)) +#define MXC_F_I2CM_TRANS_TX_IN_PROGRESS_POS 1 +#define MXC_F_I2CM_TRANS_TX_IN_PROGRESS ((uint32_t)(0x00000001UL << MXC_F_I2CM_TRANS_TX_IN_PROGRESS_POS)) +#define MXC_F_I2CM_TRANS_TX_DONE_POS 2 +#define MXC_F_I2CM_TRANS_TX_DONE ((uint32_t)(0x00000001UL << MXC_F_I2CM_TRANS_TX_DONE_POS)) +#define MXC_F_I2CM_TRANS_TX_NACKED_POS 3 +#define MXC_F_I2CM_TRANS_TX_NACKED ((uint32_t)(0x00000001UL << MXC_F_I2CM_TRANS_TX_NACKED_POS)) +#define MXC_F_I2CM_TRANS_TX_LOST_ARBITR_POS 4 +#define MXC_F_I2CM_TRANS_TX_LOST_ARBITR ((uint32_t)(0x00000001UL << MXC_F_I2CM_TRANS_TX_LOST_ARBITR_POS)) +#define MXC_F_I2CM_TRANS_TX_TIMEOUT_POS 5 +#define MXC_F_I2CM_TRANS_TX_TIMEOUT ((uint32_t)(0x00000001UL << MXC_F_I2CM_TRANS_TX_TIMEOUT_POS)) + +#define MXC_F_I2CM_INTFL_TX_DONE_POS 0 +#define MXC_F_I2CM_INTFL_TX_DONE ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTFL_TX_DONE_POS)) +#define MXC_F_I2CM_INTFL_TX_NACKED_POS 1 +#define MXC_F_I2CM_INTFL_TX_NACKED ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTFL_TX_NACKED_POS)) +#define MXC_F_I2CM_INTFL_TX_LOST_ARBITR_POS 2 +#define MXC_F_I2CM_INTFL_TX_LOST_ARBITR ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTFL_TX_LOST_ARBITR_POS)) +#define MXC_F_I2CM_INTFL_TX_TIMEOUT_POS 3 +#define MXC_F_I2CM_INTFL_TX_TIMEOUT ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTFL_TX_TIMEOUT_POS)) +#define MXC_F_I2CM_INTFL_TX_FIFO_EMPTY_POS 4 +#define MXC_F_I2CM_INTFL_TX_FIFO_EMPTY ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTFL_TX_FIFO_EMPTY_POS)) +#define MXC_F_I2CM_INTFL_TX_FIFO_3Q_EMPTY_POS 5 +#define MXC_F_I2CM_INTFL_TX_FIFO_3Q_EMPTY ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTFL_TX_FIFO_3Q_EMPTY_POS)) +#define MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY_POS 6 +#define MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY_POS)) +#define MXC_F_I2CM_INTFL_RX_FIFO_2Q_FULL_POS 7 +#define MXC_F_I2CM_INTFL_RX_FIFO_2Q_FULL ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTFL_RX_FIFO_2Q_FULL_POS)) +#define MXC_F_I2CM_INTFL_RX_FIFO_3Q_FULL_POS 8 +#define MXC_F_I2CM_INTFL_RX_FIFO_3Q_FULL ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTFL_RX_FIFO_3Q_FULL_POS)) +#define MXC_F_I2CM_INTFL_RX_FIFO_FULL_POS 9 +#define MXC_F_I2CM_INTFL_RX_FIFO_FULL ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTFL_RX_FIFO_FULL_POS)) + +#define MXC_F_I2CM_INTEN_TX_DONE_POS 0 +#define MXC_F_I2CM_INTEN_TX_DONE ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTEN_TX_DONE_POS)) +#define MXC_F_I2CM_INTEN_TX_NACKED_POS 1 +#define MXC_F_I2CM_INTEN_TX_NACKED ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTEN_TX_NACKED_POS)) +#define MXC_F_I2CM_INTEN_TX_LOST_ARBITR_POS 2 +#define MXC_F_I2CM_INTEN_TX_LOST_ARBITR ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTEN_TX_LOST_ARBITR_POS)) +#define MXC_F_I2CM_INTEN_TX_TIMEOUT_POS 3 +#define MXC_F_I2CM_INTEN_TX_TIMEOUT ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTEN_TX_TIMEOUT_POS)) +#define MXC_F_I2CM_INTEN_TX_FIFO_EMPTY_POS 4 +#define MXC_F_I2CM_INTEN_TX_FIFO_EMPTY ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTEN_TX_FIFO_EMPTY_POS)) +#define MXC_F_I2CM_INTEN_TX_FIFO_3Q_EMPTY_POS 5 +#define MXC_F_I2CM_INTEN_TX_FIFO_3Q_EMPTY ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTEN_TX_FIFO_3Q_EMPTY_POS)) +#define MXC_F_I2CM_INTEN_RX_FIFO_NOT_EMPTY_POS 6 +#define MXC_F_I2CM_INTEN_RX_FIFO_NOT_EMPTY ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTEN_RX_FIFO_NOT_EMPTY_POS)) +#define MXC_F_I2CM_INTEN_RX_FIFO_2Q_FULL_POS 7 +#define MXC_F_I2CM_INTEN_RX_FIFO_2Q_FULL ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTEN_RX_FIFO_2Q_FULL_POS)) +#define MXC_F_I2CM_INTEN_RX_FIFO_3Q_FULL_POS 8 +#define MXC_F_I2CM_INTEN_RX_FIFO_3Q_FULL ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTEN_RX_FIFO_3Q_FULL_POS)) +#define MXC_F_I2CM_INTEN_RX_FIFO_FULL_POS 9 +#define MXC_F_I2CM_INTEN_RX_FIFO_FULL ((uint32_t)(0x00000001UL << MXC_F_I2CM_INTEN_RX_FIFO_FULL_POS)) + +#define MXC_F_I2CM_BB_BB_SCL_OUT_POS 0 +#define MXC_F_I2CM_BB_BB_SCL_OUT ((uint32_t)(0x00000001UL << MXC_F_I2CM_BB_BB_SCL_OUT_POS)) +#define MXC_F_I2CM_BB_BB_SDA_OUT_POS 1 +#define MXC_F_I2CM_BB_BB_SDA_OUT ((uint32_t)(0x00000001UL << MXC_F_I2CM_BB_BB_SDA_OUT_POS)) +#define MXC_F_I2CM_BB_BB_SCL_IN_VAL_POS 2 +#define MXC_F_I2CM_BB_BB_SCL_IN_VAL ((uint32_t)(0x00000001UL << MXC_F_I2CM_BB_BB_SCL_IN_VAL_POS)) +#define MXC_F_I2CM_BB_BB_SDA_IN_VAL_POS 3 +#define MXC_F_I2CM_BB_BB_SDA_IN_VAL ((uint32_t)(0x00000001UL << MXC_F_I2CM_BB_BB_SDA_IN_VAL_POS)) +#define MXC_F_I2CM_BB_RX_FIFO_CNT_POS 16 +#define MXC_F_I2CM_BB_RX_FIFO_CNT ((uint32_t)(0x0000001FUL << MXC_F_I2CM_BB_RX_FIFO_CNT_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_I2CM_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/i2cs_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/i2cs_regs.h new file mode 100644 index 00000000000..89d8970ef48 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/i2cs_regs.h @@ -0,0 +1,242 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_I2CS_REGS_H_ +#define _MXC_I2CS_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t clk_div; /* 0x0000 I2C Slave Clock Divisor Control */ + __IO uint32_t dev_id; /* 0x0004 I2C Slave Device ID Register */ + __IO uint32_t intfl; /* 0x0008 I2CS Interrupt Flags */ + __IO uint32_t inten; /* 0x000C I2CS Interrupt Enable/Disable Controls */ + __IO uint32_t data_byte[32]; /* 0x0010-0x008C I2CS Data Byte */ +} mxc_i2cs_regs_t; + + +/* + Register offsets for module I2CS. +*/ + +#define MXC_R_I2CS_OFFS_CLK_DIV ((uint32_t)0x00000000UL) +#define MXC_R_I2CS_OFFS_DEV_ID ((uint32_t)0x00000004UL) +#define MXC_R_I2CS_OFFS_INTFL ((uint32_t)0x00000008UL) +#define MXC_R_I2CS_OFFS_INTEN ((uint32_t)0x0000000CUL) +#define MXC_R_I2CS_OFFS_DATA_BYTE ((uint32_t)0x00000010UL) + + +/* + Field positions and masks for module I2CS. +*/ + +#define MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS 0 +#define MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV ((uint32_t)(0x000000FFUL << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS)) + +#define MXC_F_I2CS_DEV_ID_SLAVE_DEV_ID_POS 0 +#define MXC_F_I2CS_DEV_ID_SLAVE_DEV_ID ((uint32_t)(0x000003FFUL << MXC_F_I2CS_DEV_ID_SLAVE_DEV_ID_POS)) +#define MXC_F_I2CS_DEV_ID_TEN_BIT_ID_MODE_POS 12 +#define MXC_F_I2CS_DEV_ID_TEN_BIT_ID_MODE ((uint32_t)(0x00000001UL << MXC_F_I2CS_DEV_ID_TEN_BIT_ID_MODE_POS)) +#define MXC_F_I2CS_DEV_ID_SLAVE_RESET_POS 14 +#define MXC_F_I2CS_DEV_ID_SLAVE_RESET ((uint32_t)(0x00000001UL << MXC_F_I2CS_DEV_ID_SLAVE_RESET_POS)) + +#define MXC_F_I2CS_INTFL_BYTE0_POS 0 +#define MXC_F_I2CS_INTFL_BYTE0 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE0_POS)) +#define MXC_F_I2CS_INTFL_BYTE1_POS 1 +#define MXC_F_I2CS_INTFL_BYTE1 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE1_POS)) +#define MXC_F_I2CS_INTFL_BYTE2_POS 2 +#define MXC_F_I2CS_INTFL_BYTE2 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE2_POS)) +#define MXC_F_I2CS_INTFL_BYTE3_POS 3 +#define MXC_F_I2CS_INTFL_BYTE3 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE3_POS)) +#define MXC_F_I2CS_INTFL_BYTE4_POS 4 +#define MXC_F_I2CS_INTFL_BYTE4 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE4_POS)) +#define MXC_F_I2CS_INTFL_BYTE5_POS 5 +#define MXC_F_I2CS_INTFL_BYTE5 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE5_POS)) +#define MXC_F_I2CS_INTFL_BYTE6_POS 6 +#define MXC_F_I2CS_INTFL_BYTE6 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE6_POS)) +#define MXC_F_I2CS_INTFL_BYTE7_POS 7 +#define MXC_F_I2CS_INTFL_BYTE7 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE7_POS)) +#define MXC_F_I2CS_INTFL_BYTE8_POS 8 +#define MXC_F_I2CS_INTFL_BYTE8 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE8_POS)) +#define MXC_F_I2CS_INTFL_BYTE9_POS 9 +#define MXC_F_I2CS_INTFL_BYTE9 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE9_POS)) +#define MXC_F_I2CS_INTFL_BYTE10_POS 10 +#define MXC_F_I2CS_INTFL_BYTE10 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE10_POS)) +#define MXC_F_I2CS_INTFL_BYTE11_POS 11 +#define MXC_F_I2CS_INTFL_BYTE11 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE11_POS)) +#define MXC_F_I2CS_INTFL_BYTE12_POS 12 +#define MXC_F_I2CS_INTFL_BYTE12 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE12_POS)) +#define MXC_F_I2CS_INTFL_BYTE13_POS 13 +#define MXC_F_I2CS_INTFL_BYTE13 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE13_POS)) +#define MXC_F_I2CS_INTFL_BYTE14_POS 14 +#define MXC_F_I2CS_INTFL_BYTE14 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE14_POS)) +#define MXC_F_I2CS_INTFL_BYTE15_POS 15 +#define MXC_F_I2CS_INTFL_BYTE15 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE15_POS)) +#define MXC_F_I2CS_INTFL_BYTE16_POS 16 +#define MXC_F_I2CS_INTFL_BYTE16 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE16_POS)) +#define MXC_F_I2CS_INTFL_BYTE17_POS 17 +#define MXC_F_I2CS_INTFL_BYTE17 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE17_POS)) +#define MXC_F_I2CS_INTFL_BYTE18_POS 18 +#define MXC_F_I2CS_INTFL_BYTE18 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE18_POS)) +#define MXC_F_I2CS_INTFL_BYTE19_POS 19 +#define MXC_F_I2CS_INTFL_BYTE19 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE19_POS)) +#define MXC_F_I2CS_INTFL_BYTE20_POS 20 +#define MXC_F_I2CS_INTFL_BYTE20 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE20_POS)) +#define MXC_F_I2CS_INTFL_BYTE21_POS 21 +#define MXC_F_I2CS_INTFL_BYTE21 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE21_POS)) +#define MXC_F_I2CS_INTFL_BYTE22_POS 22 +#define MXC_F_I2CS_INTFL_BYTE22 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE22_POS)) +#define MXC_F_I2CS_INTFL_BYTE23_POS 23 +#define MXC_F_I2CS_INTFL_BYTE23 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE23_POS)) +#define MXC_F_I2CS_INTFL_BYTE24_POS 24 +#define MXC_F_I2CS_INTFL_BYTE24 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE24_POS)) +#define MXC_F_I2CS_INTFL_BYTE25_POS 25 +#define MXC_F_I2CS_INTFL_BYTE25 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE25_POS)) +#define MXC_F_I2CS_INTFL_BYTE26_POS 26 +#define MXC_F_I2CS_INTFL_BYTE26 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE26_POS)) +#define MXC_F_I2CS_INTFL_BYTE27_POS 27 +#define MXC_F_I2CS_INTFL_BYTE27 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE27_POS)) +#define MXC_F_I2CS_INTFL_BYTE28_POS 28 +#define MXC_F_I2CS_INTFL_BYTE28 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE28_POS)) +#define MXC_F_I2CS_INTFL_BYTE29_POS 29 +#define MXC_F_I2CS_INTFL_BYTE29 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE29_POS)) +#define MXC_F_I2CS_INTFL_BYTE30_POS 30 +#define MXC_F_I2CS_INTFL_BYTE30 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE30_POS)) +#define MXC_F_I2CS_INTFL_BYTE31_POS 31 +#define MXC_F_I2CS_INTFL_BYTE31 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTFL_BYTE31_POS)) + +#define MXC_F_I2CS_INTEN_BYTE0_POS 0 +#define MXC_F_I2CS_INTEN_BYTE0 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE0_POS)) +#define MXC_F_I2CS_INTEN_BYTE1_POS 1 +#define MXC_F_I2CS_INTEN_BYTE1 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE1_POS)) +#define MXC_F_I2CS_INTEN_BYTE2_POS 2 +#define MXC_F_I2CS_INTEN_BYTE2 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE2_POS)) +#define MXC_F_I2CS_INTEN_BYTE3_POS 3 +#define MXC_F_I2CS_INTEN_BYTE3 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE3_POS)) +#define MXC_F_I2CS_INTEN_BYTE4_POS 4 +#define MXC_F_I2CS_INTEN_BYTE4 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE4_POS)) +#define MXC_F_I2CS_INTEN_BYTE5_POS 5 +#define MXC_F_I2CS_INTEN_BYTE5 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE5_POS)) +#define MXC_F_I2CS_INTEN_BYTE6_POS 6 +#define MXC_F_I2CS_INTEN_BYTE6 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE6_POS)) +#define MXC_F_I2CS_INTEN_BYTE7_POS 7 +#define MXC_F_I2CS_INTEN_BYTE7 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE7_POS)) +#define MXC_F_I2CS_INTEN_BYTE8_POS 8 +#define MXC_F_I2CS_INTEN_BYTE8 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE8_POS)) +#define MXC_F_I2CS_INTEN_BYTE9_POS 9 +#define MXC_F_I2CS_INTEN_BYTE9 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE9_POS)) +#define MXC_F_I2CS_INTEN_BYTE10_POS 10 +#define MXC_F_I2CS_INTEN_BYTE10 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE10_POS)) +#define MXC_F_I2CS_INTEN_BYTE11_POS 11 +#define MXC_F_I2CS_INTEN_BYTE11 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE11_POS)) +#define MXC_F_I2CS_INTEN_BYTE12_POS 12 +#define MXC_F_I2CS_INTEN_BYTE12 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE12_POS)) +#define MXC_F_I2CS_INTEN_BYTE13_POS 13 +#define MXC_F_I2CS_INTEN_BYTE13 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE13_POS)) +#define MXC_F_I2CS_INTEN_BYTE14_POS 14 +#define MXC_F_I2CS_INTEN_BYTE14 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE14_POS)) +#define MXC_F_I2CS_INTEN_BYTE15_POS 15 +#define MXC_F_I2CS_INTEN_BYTE15 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE15_POS)) +#define MXC_F_I2CS_INTEN_BYTE16_POS 16 +#define MXC_F_I2CS_INTEN_BYTE16 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE16_POS)) +#define MXC_F_I2CS_INTEN_BYTE17_POS 17 +#define MXC_F_I2CS_INTEN_BYTE17 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE17_POS)) +#define MXC_F_I2CS_INTEN_BYTE18_POS 18 +#define MXC_F_I2CS_INTEN_BYTE18 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE18_POS)) +#define MXC_F_I2CS_INTEN_BYTE19_POS 19 +#define MXC_F_I2CS_INTEN_BYTE19 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE19_POS)) +#define MXC_F_I2CS_INTEN_BYTE20_POS 20 +#define MXC_F_I2CS_INTEN_BYTE20 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE20_POS)) +#define MXC_F_I2CS_INTEN_BYTE21_POS 21 +#define MXC_F_I2CS_INTEN_BYTE21 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE21_POS)) +#define MXC_F_I2CS_INTEN_BYTE22_POS 22 +#define MXC_F_I2CS_INTEN_BYTE22 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE22_POS)) +#define MXC_F_I2CS_INTEN_BYTE23_POS 23 +#define MXC_F_I2CS_INTEN_BYTE23 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE23_POS)) +#define MXC_F_I2CS_INTEN_BYTE24_POS 24 +#define MXC_F_I2CS_INTEN_BYTE24 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE24_POS)) +#define MXC_F_I2CS_INTEN_BYTE25_POS 25 +#define MXC_F_I2CS_INTEN_BYTE25 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE25_POS)) +#define MXC_F_I2CS_INTEN_BYTE26_POS 26 +#define MXC_F_I2CS_INTEN_BYTE26 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE26_POS)) +#define MXC_F_I2CS_INTEN_BYTE27_POS 27 +#define MXC_F_I2CS_INTEN_BYTE27 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE27_POS)) +#define MXC_F_I2CS_INTEN_BYTE28_POS 28 +#define MXC_F_I2CS_INTEN_BYTE28 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE28_POS)) +#define MXC_F_I2CS_INTEN_BYTE29_POS 29 +#define MXC_F_I2CS_INTEN_BYTE29 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE29_POS)) +#define MXC_F_I2CS_INTEN_BYTE30_POS 30 +#define MXC_F_I2CS_INTEN_BYTE30 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE30_POS)) +#define MXC_F_I2CS_INTEN_BYTE31_POS 31 +#define MXC_F_I2CS_INTEN_BYTE31 ((uint32_t)(0x00000001UL << MXC_F_I2CS_INTEN_BYTE31_POS)) + +#define MXC_F_I2CS_DATA_BYTE_DATA_FIELD_POS 0 +#define MXC_F_I2CS_DATA_BYTE_DATA_FIELD ((uint32_t)(0x000000FFUL << MXC_F_I2CS_DATA_BYTE_DATA_FIELD_POS)) +#define MXC_F_I2CS_DATA_BYTE_READ_ONLY_FL_POS 8 +#define MXC_F_I2CS_DATA_BYTE_READ_ONLY_FL ((uint32_t)(0x00000001UL << MXC_F_I2CS_DATA_BYTE_READ_ONLY_FL_POS)) +#define MXC_F_I2CS_DATA_BYTE_DATA_UPDATED_FL_POS 9 +#define MXC_F_I2CS_DATA_BYTE_DATA_UPDATED_FL ((uint32_t)(0x00000001UL << MXC_F_I2CS_DATA_BYTE_DATA_UPDATED_FL_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_I2CS_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/icc_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/icc_regs.h new file mode 100644 index 00000000000..1d27ed5ddf4 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/icc_regs.h @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_ICC_REGS_H_ +#define _MXC_ICC_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t id; /* 0x0000 Cache ID Register (INTERNAL USE ONLY) */ + __IO uint32_t mem_cfg; /* 0x0004 Memory Configuration Register */ + __I uint32_t rsv008[62]; /* 0x0008-0x00FC */ + __IO uint32_t ctrl_stat; /* 0x0100 Control and Status */ + __I uint32_t rsv104[383]; /* 0x0104-0x06FC */ + __IO uint32_t invdt_all; /* 0x0700 Invalidate (Clear) Cache Control */ +} mxc_icc_regs_t; + + +/* + Register offsets for module ICC. +*/ + +#define MXC_R_ICC_OFFS_ID ((uint32_t)0x00000000UL) +#define MXC_R_ICC_OFFS_MEM_CFG ((uint32_t)0x00000004UL) +#define MXC_R_ICC_OFFS_CTRL_STAT ((uint32_t)0x00000100UL) +#define MXC_R_ICC_OFFS_INVDT_ALL ((uint32_t)0x00000700UL) + + +/* + Field positions and masks for module ICC. +*/ + +#define MXC_F_ICC_ID_RTL_VERSION_POS 0 +#define MXC_F_ICC_ID_RTL_VERSION ((uint32_t)(0x0000003FUL << MXC_F_ICC_ID_RTL_VERSION_POS)) +#define MXC_F_ICC_ID_PART_NUM_POS 6 +#define MXC_F_ICC_ID_PART_NUM ((uint32_t)(0x0000000FUL << MXC_F_ICC_ID_PART_NUM_POS)) +#define MXC_F_ICC_ID_CACHE_ID_POS 10 +#define MXC_F_ICC_ID_CACHE_ID ((uint32_t)(0x0000003FUL << MXC_F_ICC_ID_CACHE_ID_POS)) + +#define MXC_F_ICC_MEM_CFG_CACHE_SIZE_POS 0 +#define MXC_F_ICC_MEM_CFG_CACHE_SIZE ((uint32_t)(0x0000FFFFUL << MXC_F_ICC_MEM_CFG_CACHE_SIZE_POS)) +#define MXC_F_ICC_MEM_CFG_MAIN_MEMORY_SIZE_POS 16 +#define MXC_F_ICC_MEM_CFG_MAIN_MEMORY_SIZE ((uint32_t)(0x0000FFFFUL << MXC_F_ICC_MEM_CFG_MAIN_MEMORY_SIZE_POS)) + +#define MXC_F_ICC_CTRL_STAT_ENABLE_POS 0 +#define MXC_F_ICC_CTRL_STAT_ENABLE ((uint32_t)(0x00000001UL << MXC_F_ICC_CTRL_STAT_ENABLE_POS)) +#define MXC_F_ICC_CTRL_STAT_READY_POS 16 +#define MXC_F_ICC_CTRL_STAT_READY ((uint32_t)(0x00000001UL << MXC_F_ICC_CTRL_STAT_READY_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_ICC_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/ioman_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/ioman_regs.h new file mode 100644 index 00000000000..012488928c5 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/ioman_regs.h @@ -0,0 +1,816 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_IOMAN_REGS_H_ +#define _MXC_IOMAN_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Bitfield structs for registers in this module +*/ + +typedef struct { + uint32_t wud_req_p0 : 8; + uint32_t wud_req_p1 : 8; + uint32_t wud_req_p2 : 8; + uint32_t wud_req_p3 : 8; +} mxc_ioman_wud_req0_t; + +typedef struct { + uint32_t wud_req_p4 : 8; + uint32_t : 24; +} mxc_ioman_wud_req1_t; + +typedef struct { + uint32_t wud_ack_p0 : 8; + uint32_t wud_ack_p1 : 8; + uint32_t wud_ack_p2 : 8; + uint32_t wud_ack_p3 : 8; +} mxc_ioman_wud_ack0_t; + +typedef struct { + uint32_t wud_ack_p4 : 8; + uint32_t : 24; +} mxc_ioman_wud_ack1_t; + +typedef struct { + uint32_t ali_req_p0 : 8; + uint32_t ali_req_p1 : 8; + uint32_t ali_req_p2 : 8; + uint32_t ali_req_p3 : 8; +} mxc_ioman_ali_req0_t; + +typedef struct { + uint32_t ali_req_p4 : 8; + uint32_t : 24; +} mxc_ioman_ali_req1_t; + +typedef struct { + uint32_t ali_ack_p0 : 8; + uint32_t ali_ack_p1 : 8; + uint32_t ali_ack_p2 : 8; + uint32_t ali_ack_p3 : 8; +} mxc_ioman_ali_ack0_t; + +typedef struct { + uint32_t ali_ack_p4 : 8; + uint32_t : 24; +} mxc_ioman_ali_ack1_t; + +typedef struct { + uint32_t : 4; + uint32_t core_io_req : 1; + uint32_t : 3; + uint32_t ss0_io_req : 1; + uint32_t ss1_io_req : 1; + uint32_t ss2_io_req : 1; + uint32_t : 1; + uint32_t quad_io_req : 1; + uint32_t : 3; + uint32_t fast_mode : 1; + uint32_t : 15; +} mxc_ioman_spix_req_t; + +typedef struct { + uint32_t : 4; + uint32_t core_io_ack : 1; + uint32_t : 3; + uint32_t ss0_io_ack : 1; + uint32_t ss1_io_ack : 1; + uint32_t ss2_io_ack : 1; + uint32_t : 1; + uint32_t quad_io_ack : 1; + uint32_t : 3; + uint32_t fast_mode : 1; + uint32_t : 15; +} mxc_ioman_spix_ack_t; + +typedef struct { + uint32_t io_map : 1; + uint32_t cts_map : 1; + uint32_t rts_map : 1; + uint32_t : 1; + uint32_t io_req : 1; + uint32_t cts_io_req : 1; + uint32_t rts_io_req : 1; + uint32_t : 25; +} mxc_ioman_uart0_req_t; + +typedef struct { + uint32_t io_map : 1; + uint32_t cts_map : 1; + uint32_t rts_map : 1; + uint32_t : 1; + uint32_t io_ack : 1; + uint32_t cts_io_ack : 1; + uint32_t rts_io_ack : 1; + uint32_t : 25; +} mxc_ioman_uart0_ack_t; + +typedef struct { + uint32_t io_map : 1; + uint32_t cts_map : 1; + uint32_t rts_map : 1; + uint32_t : 1; + uint32_t io_req : 1; + uint32_t cts_io_req : 1; + uint32_t rts_io_req : 1; + uint32_t : 25; +} mxc_ioman_uart1_req_t; + +typedef struct { + uint32_t io_map : 1; + uint32_t cts_map : 1; + uint32_t rts_map : 1; + uint32_t : 1; + uint32_t io_ack : 1; + uint32_t cts_io_ack : 1; + uint32_t rts_io_ack : 1; + uint32_t : 25; +} mxc_ioman_uart1_ack_t; + +typedef struct { + uint32_t io_map : 1; + uint32_t cts_map : 1; + uint32_t rts_map : 1; + uint32_t : 1; + uint32_t io_req : 1; + uint32_t cts_io_req : 1; + uint32_t rts_io_req : 1; + uint32_t : 25; +} mxc_ioman_uart2_req_t; + +typedef struct { + uint32_t io_map : 1; + uint32_t cts_map : 1; + uint32_t rts_map : 1; + uint32_t : 1; + uint32_t io_ack : 1; + uint32_t cts_io_ack : 1; + uint32_t rts_io_ack : 1; + uint32_t : 25; +} mxc_ioman_uart2_ack_t; + +typedef struct { + uint32_t : 4; + uint32_t mapping_req : 1; + uint32_t scl_push_pull : 1; + uint32_t : 26; +} mxc_ioman_i2cm0_req_t; + +typedef struct { + uint32_t : 4; + uint32_t mapping_ack : 1; + uint32_t : 27; +} mxc_ioman_i2cm0_ack_t; + +typedef struct { + uint32_t : 4; + uint32_t mapping_req : 1; + uint32_t scl_push_pull : 1; + uint32_t : 26; +} mxc_ioman_i2cm1_req_t; + +typedef struct { + uint32_t : 4; + uint32_t mapping_ack : 1; + uint32_t : 27; +} mxc_ioman_i2cm1_ack_t; + +typedef struct { + uint32_t io_sel : 2; + uint32_t : 2; + uint32_t mapping_req : 1; + uint32_t : 27; +} mxc_ioman_i2cs_req_t; + +typedef struct { + uint32_t io_sel : 2; + uint32_t : 2; + uint32_t mapping_ack : 1; + uint32_t : 27; +} mxc_ioman_i2cs_ack_t; + +typedef struct { + uint32_t : 4; + uint32_t core_io_req : 1; + uint32_t : 3; + uint32_t ss0_io_req : 1; + uint32_t ss1_io_req : 1; + uint32_t ss2_io_req : 1; + uint32_t ss3_io_req : 1; + uint32_t ss4_io_req : 1; + uint32_t : 7; + uint32_t quad_io_req : 1; + uint32_t : 3; + uint32_t fast_mode : 1; + uint32_t : 7; +} mxc_ioman_spim0_req_t; + +typedef struct { + uint32_t : 4; + uint32_t core_io_ack : 1; + uint32_t : 3; + uint32_t ss0_io_ack : 1; + uint32_t ss1_io_ack : 1; + uint32_t ss2_io_ack : 1; + uint32_t ss3_io_ack : 1; + uint32_t ss4_io_ack : 1; + uint32_t : 7; + uint32_t quad_io_ack : 1; + uint32_t : 3; + uint32_t fast_mode : 1; + uint32_t : 7; +} mxc_ioman_spim0_ack_t; + +typedef struct { + uint32_t : 4; + uint32_t core_io_req : 1; + uint32_t : 3; + uint32_t ss0_io_req : 1; + uint32_t ss1_io_req : 1; + uint32_t ss2_io_req : 1; + uint32_t : 9; + uint32_t quad_io_req : 1; + uint32_t : 3; + uint32_t fast_mode : 1; + uint32_t : 7; +} mxc_ioman_spim1_req_t; + +typedef struct { + uint32_t : 4; + uint32_t core_io_ack : 1; + uint32_t : 3; + uint32_t ss0_io_ack : 1; + uint32_t ss1_io_ack : 1; + uint32_t ss2_io_ack : 1; + uint32_t : 9; + uint32_t quad_io_ack : 1; + uint32_t : 3; + uint32_t fast_mode : 1; + uint32_t : 7; +} mxc_ioman_spim1_ack_t; + +typedef struct { + uint32_t mapping_req : 2; // 1:0 + uint32_t : 1; // 2:3 + uint32_t core_io_req : 1; // 4 + uint32_t : 3; // 5:7 + uint32_t ss0_io_req : 1; // 8 + uint32_t ss1_io_req : 1; // 9 + uint32_t ss2_io_req : 1; // 10 + uint32_t : 5; // 11:15 + uint32_t sr0_io_req : 1; // 16 + uint32_t sr1_io_req : 1; // 17 + uint32_t : 2; // 18:19 + uint32_t quad_io_req : 1; // 20 + uint32_t : 3; // 21:23 + uint32_t fast_mode : 1; // 24 + uint32_t : 7; // 25:31 +} mxc_ioman_spim2_req_t; + +typedef struct { + uint32_t mapping_ack : 1; + uint32_t : 3; + uint32_t core_io_ack : 1; + uint32_t : 3; + uint32_t ss0_io_ack : 1; + uint32_t ss1_io_ack : 1; + uint32_t ss2_io_ack : 1; + uint32_t : 5; + uint32_t sr0_io_ack : 1; + uint32_t sr1_io_ack : 1; + uint32_t : 2; + uint32_t quad_io_ack : 1; + uint32_t : 3; + uint32_t fast_mode : 1; + uint32_t : 7; +} mxc_ioman_spim2_ack_t; + +typedef struct { + uint32_t : 4; + uint32_t mapping_req : 1; + uint32_t epu_io_req : 1; + uint32_t : 26; +} mxc_ioman_owm_req_t; + +typedef struct { + uint32_t : 4; + uint32_t mapping_ack : 1; + uint32_t epu_io_ack : 1; + uint32_t : 26; +} mxc_ioman_owm_ack_t; + +typedef struct { + uint32_t : 4; + uint32_t core_io_req : 1; + uint32_t : 3; + uint32_t quad_io_req : 1; + uint32_t : 3; + uint32_t fast_mode : 1; + uint32_t : 19; +} mxc_ioman_spis_req_t; + +typedef struct { + uint32_t : 4; + uint32_t core_io_ack : 1; + uint32_t : 3; + uint32_t quad_io_ack : 1; + uint32_t : 3; + uint32_t fast_mode : 1; + uint32_t : 19; +} mxc_ioman_spis_ack_t; + +typedef struct { + uint32_t slow_mode : 1; + uint32_t alt_rcvr_mode : 1; + uint32_t : 30; +} mxc_ioman_pad_mode_t; + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t wud_req0; /* 0x0000 Wakeup Detect Mode Request Register 0 (P0/P1/P2/P3) */ + __IO uint32_t wud_req1; /* 0x0004 Wakeup Detect Mode Request Register 1 (P4) */ + __IO uint32_t wud_ack0; /* 0x0008 Wakeup Detect Mode Acknowledge Register 0 (P0/P1/P2/P3) */ + __IO uint32_t wud_ack1; /* 0x000C Wakeup Detect Mode Acknowledge Register 1 (P4) */ + __IO uint32_t ali_req0; /* 0x0010 Analog Input Request Register 0 (P0/P1/P2/P3) */ + __IO uint32_t ali_req1; /* 0x0014 Analog Input Request Register 1 (P4) */ + __IO uint32_t ali_ack0; /* 0x0018 Analog Input Acknowledge Register 0 (P0/P1/P2/P3) */ + __IO uint32_t ali_ack1; /* 0x001C Analog Input Acknowledge Register 1 (P4) */ + __IO uint32_t ali_connect0; /* 0x0020 Analog I/O Connection Control Register 0 */ + __IO uint32_t ali_connect1; /* 0x0024 Analog I/O Connection Control Register 1 */ + __IO uint32_t spix_req; /* 0x0028 SPIX I/O Mode Request */ + __IO uint32_t spix_ack; /* 0x002C SPIX I/O Mode Acknowledge */ + __IO uint32_t uart0_req; /* 0x0030 UART0 I/O Mode Request */ + __IO uint32_t uart0_ack; /* 0x0034 UART0 I/O Mode Acknowledge */ + __IO uint32_t uart1_req; /* 0x0038 UART1 I/O Mode Request */ + __IO uint32_t uart1_ack; /* 0x003C UART1 I/O Mode Acknowledge */ + __IO uint32_t uart2_req; /* 0x0040 UART2 I/O Mode Request */ + __IO uint32_t uart2_ack; /* 0x0044 UART2 I/O Mode Acknowledge */ + __I uint32_t rsv048[2]; /* 0x0048-0x004C */ + __IO uint32_t i2cm0_req; /* 0x0050 I2C Master 0 I/O Request */ + __IO uint32_t i2cm0_ack; /* 0x0054 I2C Master 0 I/O Acknowledge */ + __IO uint32_t i2cm1_req; /* 0x0058 I2C Master 1 I/O Request */ + __IO uint32_t i2cm1_ack; /* 0x005C I2C Master 1 I/O Acknowledge */ + __I uint32_t rsv060[2]; /* 0x0060-0x0064 */ + __IO uint32_t i2cs_req; /* 0x0068 I2C Slave I/O Request */ + __IO uint32_t i2cs_ack; /* 0x006C I2C Slave I/O Acknowledge */ + __IO uint32_t spim0_req; /* 0x0070 SPI Master 0 I/O Mode Request */ + __IO uint32_t spim0_ack; /* 0x0074 SPI Master 0 I/O Mode Acknowledge */ + __IO uint32_t spim1_req; /* 0x0078 SPI Master 1 I/O Mode Request */ + __IO uint32_t spim1_ack; /* 0x007C SPI Master 1 I/O Mode Acknowledge */ + __IO uint32_t spim2_req; /* 0x0080 SPI Master 2 I/O Mode Request */ + __IO uint32_t spim2_ack; /* 0x0084 SPI Master 2 I/O Mode Acknowledge */ + __I uint32_t rsv088[2]; /* 0x0088-0x008C */ + __IO uint32_t owm_req; /* 0x0090 1-Wire Master I/O Mode Request */ + __IO uint32_t owm_ack; /* 0x0094 1-Wire Master I/O Mode Acknowledge */ + __IO uint32_t spis_req; /* 0x0098 SPI Slave I/O Mode Request */ + __IO uint32_t spis_ack; /* 0x009C SPI Slave I/O Mode Acknowledge */ + __I uint32_t rsv0A0[24]; /* 0x00A0-0x00FC */ + __IO uint32_t use_vddioh_0; /* 0x0100 Enable VDDIOH Register 0 */ + __IO uint32_t use_vddioh_1; /* 0x0104 Enable VDDIOH Register 1 */ + __I uint32_t rsv108[2]; /* 0x0108-0x010C */ + __IO uint32_t pad_mode; /* 0x0110 Pad Mode Control Register */ +} mxc_ioman_regs_t; + + +/* + Register offsets for module IOMAN. +*/ + +#define MXC_R_IOMAN_OFFS_WUD_REQ0 ((uint32_t)0x00000000UL) +#define MXC_R_IOMAN_OFFS_WUD_REQ1 ((uint32_t)0x00000004UL) +#define MXC_R_IOMAN_OFFS_WUD_ACK0 ((uint32_t)0x00000008UL) +#define MXC_R_IOMAN_OFFS_WUD_ACK1 ((uint32_t)0x0000000CUL) +#define MXC_R_IOMAN_OFFS_ALI_REQ0 ((uint32_t)0x00000010UL) +#define MXC_R_IOMAN_OFFS_ALI_REQ1 ((uint32_t)0x00000014UL) +#define MXC_R_IOMAN_OFFS_ALI_ACK0 ((uint32_t)0x00000018UL) +#define MXC_R_IOMAN_OFFS_ALI_ACK1 ((uint32_t)0x0000001CUL) +#define MXC_R_IOMAN_OFFS_ALI_CONNECT0 ((uint32_t)0x00000020UL) +#define MXC_R_IOMAN_OFFS_ALI_CONNECT1 ((uint32_t)0x00000024UL) +#define MXC_R_IOMAN_OFFS_SPIX_REQ ((uint32_t)0x00000028UL) +#define MXC_R_IOMAN_OFFS_SPIX_ACK ((uint32_t)0x0000002CUL) +#define MXC_R_IOMAN_OFFS_UART0_REQ ((uint32_t)0x00000030UL) +#define MXC_R_IOMAN_OFFS_UART0_ACK ((uint32_t)0x00000034UL) +#define MXC_R_IOMAN_OFFS_UART1_REQ ((uint32_t)0x00000038UL) +#define MXC_R_IOMAN_OFFS_UART1_ACK ((uint32_t)0x0000003CUL) +#define MXC_R_IOMAN_OFFS_UART2_REQ ((uint32_t)0x00000040UL) +#define MXC_R_IOMAN_OFFS_UART2_ACK ((uint32_t)0x00000044UL) +#define MXC_R_IOMAN_OFFS_I2CM0_REQ ((uint32_t)0x00000050UL) +#define MXC_R_IOMAN_OFFS_I2CM0_ACK ((uint32_t)0x00000054UL) +#define MXC_R_IOMAN_OFFS_I2CM1_REQ ((uint32_t)0x00000058UL) +#define MXC_R_IOMAN_OFFS_I2CM1_ACK ((uint32_t)0x0000005CUL) +#define MXC_R_IOMAN_OFFS_I2CS_REQ ((uint32_t)0x00000068UL) +#define MXC_R_IOMAN_OFFS_I2CS_ACK ((uint32_t)0x0000006CUL) +#define MXC_R_IOMAN_OFFS_SPIM0_REQ ((uint32_t)0x00000070UL) +#define MXC_R_IOMAN_OFFS_SPIM0_ACK ((uint32_t)0x00000074UL) +#define MXC_R_IOMAN_OFFS_SPIM1_REQ ((uint32_t)0x00000078UL) +#define MXC_R_IOMAN_OFFS_SPIM1_ACK ((uint32_t)0x0000007CUL) +#define MXC_R_IOMAN_OFFS_SPIM2_REQ ((uint32_t)0x00000080UL) +#define MXC_R_IOMAN_OFFS_SPIM2_ACK ((uint32_t)0x00000084UL) +#define MXC_R_IOMAN_OFFS_OWM_REQ ((uint32_t)0x00000090UL) +#define MXC_R_IOMAN_OFFS_OWM_ACK ((uint32_t)0x00000094UL) +#define MXC_R_IOMAN_OFFS_SPIS_REQ ((uint32_t)0x00000098UL) +#define MXC_R_IOMAN_OFFS_SPIS_ACK ((uint32_t)0x0000009CUL) +#define MXC_R_IOMAN_OFFS_USE_VDDIOH_0 ((uint32_t)0x00000100UL) +#define MXC_R_IOMAN_OFFS_USE_VDDIOH_1 ((uint32_t)0x00000104UL) +#define MXC_R_IOMAN_OFFS_PAD_MODE ((uint32_t)0x00000110UL) + + +/* + Field positions and masks for module IOMAN. +*/ + +#define MXC_F_IOMAN_WUD_REQ0_WUD_REQ_P0_POS 0 +#define MXC_F_IOMAN_WUD_REQ0_WUD_REQ_P0 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_WUD_REQ0_WUD_REQ_P0_POS)) +#define MXC_F_IOMAN_WUD_REQ0_WUD_REQ_P1_POS 8 +#define MXC_F_IOMAN_WUD_REQ0_WUD_REQ_P1 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_WUD_REQ0_WUD_REQ_P1_POS)) +#define MXC_F_IOMAN_WUD_REQ0_WUD_REQ_P2_POS 16 +#define MXC_F_IOMAN_WUD_REQ0_WUD_REQ_P2 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_WUD_REQ0_WUD_REQ_P2_POS)) +#define MXC_F_IOMAN_WUD_REQ0_WUD_REQ_P3_POS 24 +#define MXC_F_IOMAN_WUD_REQ0_WUD_REQ_P3 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_WUD_REQ0_WUD_REQ_P3_POS)) + +#define MXC_F_IOMAN_WUD_REQ1_WUD_REQ_P4_POS 0 +#define MXC_F_IOMAN_WUD_REQ1_WUD_REQ_P4 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_WUD_REQ1_WUD_REQ_P4_POS)) + +#define MXC_F_IOMAN_WUD_ACK0_WUD_ACK_P0_POS 0 +#define MXC_F_IOMAN_WUD_ACK0_WUD_ACK_P0 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_WUD_ACK0_WUD_ACK_P0_POS)) +#define MXC_F_IOMAN_WUD_ACK0_WUD_ACK_P1_POS 8 +#define MXC_F_IOMAN_WUD_ACK0_WUD_ACK_P1 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_WUD_ACK0_WUD_ACK_P1_POS)) +#define MXC_F_IOMAN_WUD_ACK0_WUD_ACK_P2_POS 16 +#define MXC_F_IOMAN_WUD_ACK0_WUD_ACK_P2 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_WUD_ACK0_WUD_ACK_P2_POS)) +#define MXC_F_IOMAN_WUD_ACK0_WUD_ACK_P3_POS 24 +#define MXC_F_IOMAN_WUD_ACK0_WUD_ACK_P3 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_WUD_ACK0_WUD_ACK_P3_POS)) + +#define MXC_F_IOMAN_WUD_ACK1_WUD_ACK_P4_POS 0 +#define MXC_F_IOMAN_WUD_ACK1_WUD_ACK_P4 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_WUD_ACK1_WUD_ACK_P4_POS)) + +#define MXC_F_IOMAN_ALI_REQ0_ALI_REQ_P0_POS 0 +#define MXC_F_IOMAN_ALI_REQ0_ALI_REQ_P0 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_ALI_REQ0_ALI_REQ_P0_POS)) +#define MXC_F_IOMAN_ALI_REQ0_ALI_REQ_P1_POS 8 +#define MXC_F_IOMAN_ALI_REQ0_ALI_REQ_P1 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_ALI_REQ0_ALI_REQ_P1_POS)) +#define MXC_F_IOMAN_ALI_REQ0_ALI_REQ_P2_POS 16 +#define MXC_F_IOMAN_ALI_REQ0_ALI_REQ_P2 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_ALI_REQ0_ALI_REQ_P2_POS)) +#define MXC_F_IOMAN_ALI_REQ0_ALI_REQ_P3_POS 24 +#define MXC_F_IOMAN_ALI_REQ0_ALI_REQ_P3 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_ALI_REQ0_ALI_REQ_P3_POS)) + +#define MXC_F_IOMAN_ALI_REQ1_ALI_REQ_P4_POS 0 +#define MXC_F_IOMAN_ALI_REQ1_ALI_REQ_P4 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_ALI_REQ1_ALI_REQ_P4_POS)) + +#define MXC_F_IOMAN_ALI_ACK0_ALI_ACK_P0_POS 0 +#define MXC_F_IOMAN_ALI_ACK0_ALI_ACK_P0 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_ALI_ACK0_ALI_ACK_P0_POS)) +#define MXC_F_IOMAN_ALI_ACK0_ALI_ACK_P1_POS 8 +#define MXC_F_IOMAN_ALI_ACK0_ALI_ACK_P1 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_ALI_ACK0_ALI_ACK_P1_POS)) +#define MXC_F_IOMAN_ALI_ACK0_ALI_ACK_P2_POS 16 +#define MXC_F_IOMAN_ALI_ACK0_ALI_ACK_P2 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_ALI_ACK0_ALI_ACK_P2_POS)) +#define MXC_F_IOMAN_ALI_ACK0_ALI_ACK_P3_POS 24 +#define MXC_F_IOMAN_ALI_ACK0_ALI_ACK_P3 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_ALI_ACK0_ALI_ACK_P3_POS)) + +#define MXC_F_IOMAN_ALI_ACK1_ALI_ACK_P4_POS 0 +#define MXC_F_IOMAN_ALI_ACK1_ALI_ACK_P4 ((uint32_t)(0x000000FFUL << MXC_F_IOMAN_ALI_ACK1_ALI_ACK_P4_POS)) + +#define MXC_F_IOMAN_SPIX_REQ_CORE_IO_REQ_POS 4 +#define MXC_F_IOMAN_SPIX_REQ_CORE_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIX_REQ_CORE_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIX_REQ_SS0_IO_REQ_POS 8 +#define MXC_F_IOMAN_SPIX_REQ_SS0_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIX_REQ_SS0_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIX_REQ_SS1_IO_REQ_POS 9 +#define MXC_F_IOMAN_SPIX_REQ_SS1_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIX_REQ_SS1_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIX_REQ_SS2_IO_REQ_POS 10 +#define MXC_F_IOMAN_SPIX_REQ_SS2_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIX_REQ_SS2_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIX_REQ_QUAD_IO_REQ_POS 12 +#define MXC_F_IOMAN_SPIX_REQ_QUAD_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIX_REQ_QUAD_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIX_REQ_FAST_MODE_POS 16 +#define MXC_F_IOMAN_SPIX_REQ_FAST_MODE ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIX_REQ_FAST_MODE_POS)) + +#define MXC_F_IOMAN_SPIX_ACK_CORE_IO_ACK_POS 4 +#define MXC_F_IOMAN_SPIX_ACK_CORE_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIX_ACK_CORE_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIX_ACK_SS0_IO_ACK_POS 8 +#define MXC_F_IOMAN_SPIX_ACK_SS0_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIX_ACK_SS0_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIX_ACK_SS1_IO_ACK_POS 9 +#define MXC_F_IOMAN_SPIX_ACK_SS1_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIX_ACK_SS1_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIX_ACK_SS2_IO_ACK_POS 10 +#define MXC_F_IOMAN_SPIX_ACK_SS2_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIX_ACK_SS2_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIX_ACK_QUAD_IO_ACK_POS 12 +#define MXC_F_IOMAN_SPIX_ACK_QUAD_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIX_ACK_QUAD_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIX_ACK_FAST_MODE_POS 16 +#define MXC_F_IOMAN_SPIX_ACK_FAST_MODE ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIX_ACK_FAST_MODE_POS)) + +#define MXC_F_IOMAN_UART0_REQ_IO_MAP_POS 0 +#define MXC_F_IOMAN_UART0_REQ_IO_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_REQ_IO_MAP_POS)) +#define MXC_F_IOMAN_UART0_REQ_CTS_MAP_POS 1 +#define MXC_F_IOMAN_UART0_REQ_CTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_REQ_CTS_MAP_POS)) +#define MXC_F_IOMAN_UART0_REQ_RTS_MAP_POS 2 +#define MXC_F_IOMAN_UART0_REQ_RTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_REQ_RTS_MAP_POS)) +#define MXC_F_IOMAN_UART0_REQ_IO_REQ_POS 4 +#define MXC_F_IOMAN_UART0_REQ_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_REQ_IO_REQ_POS)) +#define MXC_F_IOMAN_UART0_REQ_CTS_IO_REQ_POS 5 +#define MXC_F_IOMAN_UART0_REQ_CTS_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_REQ_CTS_IO_REQ_POS)) +#define MXC_F_IOMAN_UART0_REQ_RTS_IO_REQ_POS 6 +#define MXC_F_IOMAN_UART0_REQ_RTS_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_REQ_RTS_IO_REQ_POS)) + +#define MXC_F_IOMAN_UART0_ACK_IO_MAP_POS 0 +#define MXC_F_IOMAN_UART0_ACK_IO_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_ACK_IO_MAP_POS)) +#define MXC_F_IOMAN_UART0_ACK_CTS_MAP_POS 1 +#define MXC_F_IOMAN_UART0_ACK_CTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_ACK_CTS_MAP_POS)) +#define MXC_F_IOMAN_UART0_ACK_RTS_MAP_POS 2 +#define MXC_F_IOMAN_UART0_ACK_RTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_ACK_RTS_MAP_POS)) +#define MXC_F_IOMAN_UART0_ACK_IO_ACK_POS 4 +#define MXC_F_IOMAN_UART0_ACK_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_ACK_IO_ACK_POS)) +#define MXC_F_IOMAN_UART0_ACK_CTS_IO_ACK_POS 5 +#define MXC_F_IOMAN_UART0_ACK_CTS_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_ACK_CTS_IO_ACK_POS)) +#define MXC_F_IOMAN_UART0_ACK_RTS_IO_ACK_POS 6 +#define MXC_F_IOMAN_UART0_ACK_RTS_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_ACK_RTS_IO_ACK_POS)) + +#define MXC_F_IOMAN_UART1_REQ_IO_MAP_POS 0 +#define MXC_F_IOMAN_UART1_REQ_IO_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART1_REQ_IO_MAP_POS)) +#define MXC_F_IOMAN_UART1_REQ_CTS_MAP_POS 1 +#define MXC_F_IOMAN_UART1_REQ_CTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART1_REQ_CTS_MAP_POS)) +#define MXC_F_IOMAN_UART1_REQ_RTS_MAP_POS 2 +#define MXC_F_IOMAN_UART1_REQ_RTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART1_REQ_RTS_MAP_POS)) +#define MXC_F_IOMAN_UART1_REQ_IO_REQ_POS 4 +#define MXC_F_IOMAN_UART1_REQ_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART1_REQ_IO_REQ_POS)) +#define MXC_F_IOMAN_UART1_REQ_CTS_IO_REQ_POS 5 +#define MXC_F_IOMAN_UART1_REQ_CTS_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART1_REQ_CTS_IO_REQ_POS)) +#define MXC_F_IOMAN_UART1_REQ_RTS_IO_REQ_POS 6 +#define MXC_F_IOMAN_UART1_REQ_RTS_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART1_REQ_RTS_IO_REQ_POS)) + +#define MXC_F_IOMAN_UART1_ACK_IO_MAP_POS 0 +#define MXC_F_IOMAN_UART1_ACK_IO_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART1_ACK_IO_MAP_POS)) +#define MXC_F_IOMAN_UART1_ACK_CTS_MAP_POS 1 +#define MXC_F_IOMAN_UART1_ACK_CTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART1_ACK_CTS_MAP_POS)) +#define MXC_F_IOMAN_UART1_ACK_RTS_MAP_POS 2 +#define MXC_F_IOMAN_UART1_ACK_RTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART1_ACK_RTS_MAP_POS)) +#define MXC_F_IOMAN_UART1_ACK_IO_ACK_POS 4 +#define MXC_F_IOMAN_UART1_ACK_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART1_ACK_IO_ACK_POS)) +#define MXC_F_IOMAN_UART1_ACK_CTS_IO_ACK_POS 5 +#define MXC_F_IOMAN_UART1_ACK_CTS_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART1_ACK_CTS_IO_ACK_POS)) +#define MXC_F_IOMAN_UART1_ACK_RTS_IO_ACK_POS 6 +#define MXC_F_IOMAN_UART1_ACK_RTS_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART1_ACK_RTS_IO_ACK_POS)) + +#define MXC_F_IOMAN_UART2_REQ_IO_MAP_POS 0 +#define MXC_F_IOMAN_UART2_REQ_IO_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART2_REQ_IO_MAP_POS)) +#define MXC_F_IOMAN_UART2_REQ_CTS_MAP_POS 1 +#define MXC_F_IOMAN_UART2_REQ_CTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART2_REQ_CTS_MAP_POS)) +#define MXC_F_IOMAN_UART2_REQ_RTS_MAP_POS 2 +#define MXC_F_IOMAN_UART2_REQ_RTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART2_REQ_RTS_MAP_POS)) +#define MXC_F_IOMAN_UART2_REQ_IO_REQ_POS 4 +#define MXC_F_IOMAN_UART2_REQ_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART2_REQ_IO_REQ_POS)) +#define MXC_F_IOMAN_UART2_REQ_CTS_IO_REQ_POS 5 +#define MXC_F_IOMAN_UART2_REQ_CTS_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART2_REQ_CTS_IO_REQ_POS)) +#define MXC_F_IOMAN_UART2_REQ_RTS_IO_REQ_POS 6 +#define MXC_F_IOMAN_UART2_REQ_RTS_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART2_REQ_RTS_IO_REQ_POS)) + +#define MXC_F_IOMAN_UART2_ACK_IO_MAP_POS 0 +#define MXC_F_IOMAN_UART2_ACK_IO_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART2_ACK_IO_MAP_POS)) +#define MXC_F_IOMAN_UART2_ACK_CTS_MAP_POS 1 +#define MXC_F_IOMAN_UART2_ACK_CTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART2_ACK_CTS_MAP_POS)) +#define MXC_F_IOMAN_UART2_ACK_RTS_MAP_POS 2 +#define MXC_F_IOMAN_UART2_ACK_RTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART2_ACK_RTS_MAP_POS)) +#define MXC_F_IOMAN_UART2_ACK_IO_ACK_POS 4 +#define MXC_F_IOMAN_UART2_ACK_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART2_ACK_IO_ACK_POS)) +#define MXC_F_IOMAN_UART2_ACK_CTS_IO_ACK_POS 5 +#define MXC_F_IOMAN_UART2_ACK_CTS_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART2_ACK_CTS_IO_ACK_POS)) +#define MXC_F_IOMAN_UART2_ACK_RTS_IO_ACK_POS 6 +#define MXC_F_IOMAN_UART2_ACK_RTS_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART2_ACK_RTS_IO_ACK_POS)) + +#define MXC_F_IOMAN_I2CM0_REQ_MAPPING_REQ_POS 4 +#define MXC_F_IOMAN_I2CM0_REQ_MAPPING_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_I2CM0_REQ_MAPPING_REQ_POS)) +#define MXC_F_IOMAN_I2CM0_REQ_SCL_PUSH_PULL_POS 5 +#define MXC_F_IOMAN_I2CM0_REQ_SCL_PUSH_PULL ((uint32_t)(0x00000001UL << MXC_F_IOMAN_I2CM0_REQ_SCL_PUSH_PULL_POS)) + +#define MXC_F_IOMAN_I2CM0_ACK_MAPPING_ACK_POS 4 +#define MXC_F_IOMAN_I2CM0_ACK_MAPPING_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_I2CM0_ACK_MAPPING_ACK_POS)) + +#define MXC_F_IOMAN_I2CM1_REQ_MAPPING_REQ_POS 4 +#define MXC_F_IOMAN_I2CM1_REQ_MAPPING_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_I2CM1_REQ_MAPPING_REQ_POS)) +#define MXC_F_IOMAN_I2CM1_REQ_SCL_PUSH_PULL_POS 5 +#define MXC_F_IOMAN_I2CM1_REQ_SCL_PUSH_PULL ((uint32_t)(0x00000001UL << MXC_F_IOMAN_I2CM1_REQ_SCL_PUSH_PULL_POS)) + +#define MXC_F_IOMAN_I2CM1_ACK_MAPPING_ACK_POS 4 +#define MXC_F_IOMAN_I2CM1_ACK_MAPPING_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_I2CM1_ACK_MAPPING_ACK_POS)) + +#define MXC_F_IOMAN_I2CS_REQ_IO_SEL_POS 0 +#define MXC_F_IOMAN_I2CS_REQ_IO_SEL ((uint32_t)(0x00000003UL << MXC_F_IOMAN_I2CS_REQ_IO_SEL_POS)) +#define MXC_F_IOMAN_I2CS_REQ_MAPPING_REQ_POS 4 +#define MXC_F_IOMAN_I2CS_REQ_MAPPING_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_I2CS_REQ_MAPPING_REQ_POS)) + +#define MXC_F_IOMAN_I2CS_ACK_IO_SEL_POS 0 +#define MXC_F_IOMAN_I2CS_ACK_IO_SEL ((uint32_t)(0x00000003UL << MXC_F_IOMAN_I2CS_ACK_IO_SEL_POS)) +#define MXC_F_IOMAN_I2CS_ACK_MAPPING_ACK_POS 4 +#define MXC_F_IOMAN_I2CS_ACK_MAPPING_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_I2CS_ACK_MAPPING_ACK_POS)) + +#define MXC_F_IOMAN_SPIM0_REQ_CORE_IO_REQ_POS 4 +#define MXC_F_IOMAN_SPIM0_REQ_CORE_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_REQ_CORE_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM0_REQ_SS0_IO_REQ_POS 8 +#define MXC_F_IOMAN_SPIM0_REQ_SS0_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_REQ_SS0_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM0_REQ_SS1_IO_REQ_POS 9 +#define MXC_F_IOMAN_SPIM0_REQ_SS1_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_REQ_SS1_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM0_REQ_SS2_IO_REQ_POS 10 +#define MXC_F_IOMAN_SPIM0_REQ_SS2_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_REQ_SS2_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM0_REQ_SS3_IO_REQ_POS 11 +#define MXC_F_IOMAN_SPIM0_REQ_SS3_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_REQ_SS3_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM0_REQ_SS4_IO_REQ_POS 12 +#define MXC_F_IOMAN_SPIM0_REQ_SS4_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_REQ_SS4_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM0_REQ_QUAD_IO_REQ_POS 20 +#define MXC_F_IOMAN_SPIM0_REQ_QUAD_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_REQ_QUAD_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM0_REQ_FAST_MODE_POS 24 +#define MXC_F_IOMAN_SPIM0_REQ_FAST_MODE ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_REQ_FAST_MODE_POS)) + +#define MXC_F_IOMAN_SPIM0_ACK_CORE_IO_ACK_POS 4 +#define MXC_F_IOMAN_SPIM0_ACK_CORE_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_ACK_CORE_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM0_ACK_SS0_IO_ACK_POS 8 +#define MXC_F_IOMAN_SPIM0_ACK_SS0_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_ACK_SS0_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM0_ACK_SS1_IO_ACK_POS 9 +#define MXC_F_IOMAN_SPIM0_ACK_SS1_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_ACK_SS1_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM0_ACK_SS2_IO_ACK_POS 10 +#define MXC_F_IOMAN_SPIM0_ACK_SS2_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_ACK_SS2_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM0_ACK_SS3_IO_ACK_POS 11 +#define MXC_F_IOMAN_SPIM0_ACK_SS3_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_ACK_SS3_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM0_ACK_SS4_IO_ACK_POS 12 +#define MXC_F_IOMAN_SPIM0_ACK_SS4_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_ACK_SS4_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM0_ACK_QUAD_IO_ACK_POS 20 +#define MXC_F_IOMAN_SPIM0_ACK_QUAD_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_ACK_QUAD_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM0_ACK_FAST_MODE_POS 24 +#define MXC_F_IOMAN_SPIM0_ACK_FAST_MODE ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_ACK_FAST_MODE_POS)) + +#define MXC_F_IOMAN_SPIM1_REQ_CORE_IO_REQ_POS 4 +#define MXC_F_IOMAN_SPIM1_REQ_CORE_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM1_REQ_CORE_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM1_REQ_SS0_IO_REQ_POS 8 +#define MXC_F_IOMAN_SPIM1_REQ_SS0_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM1_REQ_SS0_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM1_REQ_SS1_IO_REQ_POS 9 +#define MXC_F_IOMAN_SPIM1_REQ_SS1_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM1_REQ_SS1_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM1_REQ_SS2_IO_REQ_POS 10 +#define MXC_F_IOMAN_SPIM1_REQ_SS2_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM1_REQ_SS2_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM1_REQ_QUAD_IO_REQ_POS 20 +#define MXC_F_IOMAN_SPIM1_REQ_QUAD_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM1_REQ_QUAD_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM1_REQ_FAST_MODE_POS 24 +#define MXC_F_IOMAN_SPIM1_REQ_FAST_MODE ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM1_REQ_FAST_MODE_POS)) + +#define MXC_F_IOMAN_SPIM1_ACK_CORE_IO_ACK_POS 4 +#define MXC_F_IOMAN_SPIM1_ACK_CORE_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM1_ACK_CORE_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM1_ACK_SS0_IO_ACK_POS 8 +#define MXC_F_IOMAN_SPIM1_ACK_SS0_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM1_ACK_SS0_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM1_ACK_SS1_IO_ACK_POS 9 +#define MXC_F_IOMAN_SPIM1_ACK_SS1_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM1_ACK_SS1_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM1_ACK_SS2_IO_ACK_POS 10 +#define MXC_F_IOMAN_SPIM1_ACK_SS2_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM1_ACK_SS2_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM1_ACK_QUAD_IO_ACK_POS 20 +#define MXC_F_IOMAN_SPIM1_ACK_QUAD_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM1_ACK_QUAD_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM1_ACK_FAST_MODE_POS 24 +#define MXC_F_IOMAN_SPIM1_ACK_FAST_MODE ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM1_ACK_FAST_MODE_POS)) + +#define MXC_F_IOMAN_SPIM2_REQ_MAPPING_REQ_POS 0 +#define MXC_F_IOMAN_SPIM2_REQ_MAPPING_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_REQ_MAPPING_REQ_POS)) +#define MXC_F_IOMAN_SPIM2_REQ_CORE_IO_REQ_POS 4 +#define MXC_F_IOMAN_SPIM2_REQ_CORE_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_REQ_CORE_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM2_REQ_SS0_IO_REQ_POS 8 +#define MXC_F_IOMAN_SPIM2_REQ_SS0_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_REQ_SS0_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM2_REQ_SS1_IO_REQ_POS 9 +#define MXC_F_IOMAN_SPIM2_REQ_SS1_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_REQ_SS1_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM2_REQ_SS2_IO_REQ_POS 10 +#define MXC_F_IOMAN_SPIM2_REQ_SS2_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_REQ_SS2_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM2_REQ_SR0_IO_REQ_POS 16 +#define MXC_F_IOMAN_SPIM2_REQ_SR0_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_REQ_SR0_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM2_REQ_SR1_IO_REQ_POS 17 +#define MXC_F_IOMAN_SPIM2_REQ_SR1_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_REQ_SR1_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM2_REQ_FAST_MODE_POS 24 +#define MXC_F_IOMAN_SPIM2_REQ_FAST_MODE ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_REQ_FAST_MODE_POS)) + +#define MXC_F_IOMAN_SPIM2_ACK_MAPPING_ACK_POS 0 +#define MXC_F_IOMAN_SPIM2_ACK_MAPPING_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_ACK_MAPPING_ACK_POS)) +#define MXC_F_IOMAN_SPIM2_ACK_CORE_IO_ACK_POS 4 +#define MXC_F_IOMAN_SPIM2_ACK_CORE_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_ACK_CORE_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM2_ACK_SS0_IO_ACK_POS 8 +#define MXC_F_IOMAN_SPIM2_ACK_SS0_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_ACK_SS0_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM2_ACK_SS1_IO_ACK_POS 9 +#define MXC_F_IOMAN_SPIM2_ACK_SS1_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_ACK_SS1_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM2_ACK_SS2_IO_ACK_POS 10 +#define MXC_F_IOMAN_SPIM2_ACK_SS2_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_ACK_SS2_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM2_ACK_SR0_IO_ACK_POS 16 +#define MXC_F_IOMAN_SPIM2_ACK_SR0_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_ACK_SR0_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM2_ACK_SR1_IO_ACK_POS 17 +#define MXC_F_IOMAN_SPIM2_ACK_SR1_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_ACK_SR1_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM2_ACK_FAST_MODE_POS 24 +#define MXC_F_IOMAN_SPIM2_ACK_FAST_MODE ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_ACK_FAST_MODE_POS)) + +#define MXC_F_IOMAN_OWM_REQ_MAPPING_REQ_POS 4 +#define MXC_F_IOMAN_OWM_REQ_MAPPING_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_OWM_REQ_MAPPING_REQ_POS)) +#define MXC_F_IOMAN_OWM_REQ_EPU_IO_REQ_POS 5 +#define MXC_F_IOMAN_OWM_REQ_EPU_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_OWM_REQ_EPU_IO_REQ_POS)) + +#define MXC_F_IOMAN_OWM_ACK_MAPPING_ACK_POS 4 +#define MXC_F_IOMAN_OWM_ACK_MAPPING_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_OWM_ACK_MAPPING_ACK_POS)) +#define MXC_F_IOMAN_OWM_ACK_EPU_IO_ACK_POS 5 +#define MXC_F_IOMAN_OWM_ACK_EPU_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_OWM_ACK_EPU_IO_ACK_POS)) + +#define MXC_F_IOMAN_SPIS_REQ_CORE_IO_REQ_POS 4 +#define MXC_F_IOMAN_SPIS_REQ_CORE_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIS_REQ_CORE_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIS_REQ_QUAD_IO_REQ_POS 8 +#define MXC_F_IOMAN_SPIS_REQ_QUAD_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIS_REQ_QUAD_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIS_REQ_FAST_MODE_POS 12 +#define MXC_F_IOMAN_SPIS_REQ_FAST_MODE ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIS_REQ_FAST_MODE_POS)) + +#define MXC_F_IOMAN_SPIS_ACK_CORE_IO_ACK_POS 4 +#define MXC_F_IOMAN_SPIS_ACK_CORE_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIS_ACK_CORE_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIS_ACK_QUAD_IO_ACK_POS 8 +#define MXC_F_IOMAN_SPIS_ACK_QUAD_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIS_ACK_QUAD_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIS_ACK_FAST_MODE_POS 12 +#define MXC_F_IOMAN_SPIS_ACK_FAST_MODE ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIS_ACK_FAST_MODE_POS)) + +#define MXC_F_IOMAN_PAD_MODE_SLOW_MODE_POS 0 +#define MXC_F_IOMAN_PAD_MODE_SLOW_MODE ((uint32_t)(0x00000001UL << MXC_F_IOMAN_PAD_MODE_SLOW_MODE_POS)) +#define MXC_F_IOMAN_PAD_MODE_ALT_RCVR_MODE_POS 1 +#define MXC_F_IOMAN_PAD_MODE_ALT_RCVR_MODE ((uint32_t)(0x00000001UL << MXC_F_IOMAN_PAD_MODE_ALT_RCVR_MODE_POS)) + +/* + Generic field positions and masks for module IOMAN. +*/ +#define MXC_F_IOMAN_UART_REQ_IO_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_REQ_IO_MAP_POS)) +#define MXC_F_IOMAN_UART_REQ_CTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_REQ_CTS_MAP_POS)) +#define MXC_F_IOMAN_UART_REQ_RTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_REQ_RTS_MAP_POS)) +#define MXC_F_IOMAN_UART_REQ_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_REQ_IO_REQ_POS)) +#define MXC_F_IOMAN_UART_REQ_CTS_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_REQ_CTS_IO_REQ_POS)) +#define MXC_F_IOMAN_UART_REQ_RTS_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_REQ_RTS_IO_REQ_POS)) + +#define MXC_F_IOMAN_UART_ACK_IO_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_ACK_IO_MAP_POS)) +#define MXC_F_IOMAN_UART_ACK_CTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_ACK_CTS_MAP_POS)) +#define MXC_F_IOMAN_UART_ACK_RTS_MAP ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_ACK_RTS_MAP_POS)) +#define MXC_F_IOMAN_UART_ACK_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_ACK_IO_ACK_POS)) +#define MXC_F_IOMAN_UART_ACK_CTS_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_ACK_CTS_IO_ACK_POS)) +#define MXC_F_IOMAN_UART_ACK_RTS_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_UART0_ACK_RTS_IO_ACK_POS)) + +#define MXC_F_IOMAN_I2CM_REQ_MAPPING_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_I2CM0_REQ_MAPPING_REQ_POS)) +#define MXC_F_IOMAN_I2CM_ACK_MAPPING_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_I2CM0_ACK_MAPPING_ACK_POS)) + +#define MXC_F_IOMAN_SPIM_REQ_CORE_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_REQ_CORE_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM_REQ_SS0_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_REQ_SS0_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM_REQ_SR0_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_REQ_SR0_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM_REQ_QUAD_IO_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_REQ_QUAD_IO_REQ_POS)) +#define MXC_F_IOMAN_SPIM_ACK_CORE_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_ACK_CORE_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM_ACK_SS0_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_ACK_SS0_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM_ACK_SR0_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_ACK_SR0_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM_ACK_QUAD_IO_ACK ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM0_ACK_QUAD_IO_ACK_POS)) +#define MXC_F_IOMAN_SPIM_REQ_MAPPING_REQ ((uint32_t)(0x00000001UL << MXC_F_IOMAN_SPIM2_REQ_MAPPING_REQ_POS)) + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_IOMAN_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/maa_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/maa_regs.h new file mode 100644 index 00000000000..58c33f1b350 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/maa_regs.h @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_MAA_REGS_H_ +#define _MXC_MAA_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t ctrl; /* 0x0000 MAA Control, Configuration and Status */ + __IO uint32_t maws; /* 0x0004 MAA Word (Operand) Size, Big/Little Endian Mode Select */ +} mxc_maa_regs_t; + + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t seg0[32]; /* 0x0000-0x007C [128 bytes] MAA Memory Segment 0 */ + __IO uint32_t seg1[32]; /* 0x0080-0x00FC [128 bytes] MAA Memory Segment 1 */ + __IO uint32_t seg2[32]; /* 0x0100-0x017C [128 bytes] MAA Memory Segment 2 */ + __IO uint32_t seg3[32]; /* 0x0180-0x01FC [128 bytes] MAA Memory Segment 3 */ + __IO uint32_t seg4[32]; /* 0x0200-0x027C [128 bytes] MAA Memory Segment 4 */ + __IO uint32_t seg5[32]; /* 0x0280-0x02FC [128 bytes] MAA Memory Segment 5 */ +} mxc_maa_mem_regs_t; + + +/* + Register offsets for module MAA. +*/ + +#define MXC_R_MAA_OFFS_CTRL ((uint32_t)0x00000000UL) +#define MXC_R_MAA_OFFS_MAWS ((uint32_t)0x00000004UL) +#define MXC_R_MAA_MEM_OFFS_SEG0 ((uint32_t)0x00000000UL) +#define MXC_R_MAA_MEM_OFFS_SEG1 ((uint32_t)0x00000080UL) +#define MXC_R_MAA_MEM_OFFS_SEG2 ((uint32_t)0x00000100UL) +#define MXC_R_MAA_MEM_OFFS_SEG3 ((uint32_t)0x00000180UL) +#define MXC_R_MAA_MEM_OFFS_SEG4 ((uint32_t)0x00000200UL) +#define MXC_R_MAA_MEM_OFFS_SEG5 ((uint32_t)0x00000280UL) + + +/* + Field positions and masks for module MAA. +*/ + +#define MXC_F_MAA_CTRL_START_POS 0 +#define MXC_F_MAA_CTRL_START ((uint32_t)(0x00000001UL << MXC_F_MAA_CTRL_START_POS)) +#define MXC_F_MAA_CTRL_OPSEL_POS 1 +#define MXC_F_MAA_CTRL_OPSEL ((uint32_t)(0x00000007UL << MXC_F_MAA_CTRL_OPSEL_POS)) +#define MXC_F_MAA_CTRL_OCALC_POS 4 +#define MXC_F_MAA_CTRL_OCALC ((uint32_t)(0x00000001UL << MXC_F_MAA_CTRL_OCALC_POS)) +#define MXC_F_MAA_CTRL_IF_DONE_POS 5 +#define MXC_F_MAA_CTRL_IF_DONE ((uint32_t)(0x00000001UL << MXC_F_MAA_CTRL_IF_DONE_POS)) +#define MXC_F_MAA_CTRL_INTEN_POS 6 +#define MXC_F_MAA_CTRL_INTEN ((uint32_t)(0x00000001UL << MXC_F_MAA_CTRL_INTEN_POS)) +#define MXC_F_MAA_CTRL_IF_ERROR_POS 7 +#define MXC_F_MAA_CTRL_IF_ERROR ((uint32_t)(0x00000001UL << MXC_F_MAA_CTRL_IF_ERROR_POS)) +#define MXC_F_MAA_CTRL_OFS_A_POS 8 +#define MXC_F_MAA_CTRL_OFS_A ((uint32_t)(0x00000003UL << MXC_F_MAA_CTRL_OFS_A_POS)) +#define MXC_F_MAA_CTRL_OFS_B_POS 10 +#define MXC_F_MAA_CTRL_OFS_B ((uint32_t)(0x00000003UL << MXC_F_MAA_CTRL_OFS_B_POS)) +#define MXC_F_MAA_CTRL_OFS_EXP_POS 12 +#define MXC_F_MAA_CTRL_OFS_EXP ((uint32_t)(0x00000003UL << MXC_F_MAA_CTRL_OFS_EXP_POS)) +#define MXC_F_MAA_CTRL_OFS_MOD_POS 14 +#define MXC_F_MAA_CTRL_OFS_MOD ((uint32_t)(0x00000003UL << MXC_F_MAA_CTRL_OFS_MOD_POS)) +#define MXC_F_MAA_CTRL_SEG_A_POS 16 +#define MXC_F_MAA_CTRL_SEG_A ((uint32_t)(0x0000000FUL << MXC_F_MAA_CTRL_SEG_A_POS)) +#define MXC_F_MAA_CTRL_SEG_B_POS 20 +#define MXC_F_MAA_CTRL_SEG_B ((uint32_t)(0x0000000FUL << MXC_F_MAA_CTRL_SEG_B_POS)) +#define MXC_F_MAA_CTRL_SEG_RES_POS 24 +#define MXC_F_MAA_CTRL_SEG_RES ((uint32_t)(0x0000000FUL << MXC_F_MAA_CTRL_SEG_RES_POS)) +#define MXC_F_MAA_CTRL_SEG_TMP_POS 28 +#define MXC_F_MAA_CTRL_SEG_TMP ((uint32_t)(0x0000000FUL << MXC_F_MAA_CTRL_SEG_TMP_POS)) + +#define MXC_F_MAA_MAWS_MODLEN_POS 0 +#define MXC_F_MAA_MAWS_MODLEN ((uint32_t)(0x000007FFUL << MXC_F_MAA_MAWS_MODLEN_POS)) +#define MXC_F_MAA_MAWS_BYTESWAP_POS 15 +#define MXC_F_MAA_MAWS_BYTESWAP ((uint32_t)(0x00000001UL << MXC_F_MAA_MAWS_BYTESWAP_POS)) + + + +/* + Field values and shifted values for module MAA. +*/ + +#define MXC_V_MAA_OPSEL_EXP ((uint32_t)(0x00000000UL)) +#define MXC_V_MAA_OPSEL_SQR ((uint32_t)(0x00000001UL)) +#define MXC_V_MAA_OPSEL_MUL ((uint32_t)(0x00000002UL)) +#define MXC_V_MAA_OPSEL_SQRMUL ((uint32_t)(0x00000003UL)) +#define MXC_V_MAA_OPSEL_ADD ((uint32_t)(0x00000004UL)) +#define MXC_V_MAA_OPSEL_SUB ((uint32_t)(0x00000005UL)) + +#define MXC_S_MAA_OPSEL_EXP ((uint32_t)(MXC_V_MAA_OPSEL_EXP << MXC_F_MAA_CTRL_OPSEL_POS)) +#define MXC_S_MAA_OPSEL_SQR ((uint32_t)(MXC_V_MAA_OPSEL_SQR << MXC_F_MAA_CTRL_OPSEL_POS)) +#define MXC_S_MAA_OPSEL_MUL ((uint32_t)(MXC_V_MAA_OPSEL_MUL << MXC_F_MAA_CTRL_OPSEL_POS)) +#define MXC_S_MAA_OPSEL_SQRMUL ((uint32_t)(MXC_V_MAA_OPSEL_SQRMUL << MXC_F_MAA_CTRL_OPSEL_POS)) +#define MXC_S_MAA_OPSEL_ADD ((uint32_t)(MXC_V_MAA_OPSEL_ADD << MXC_F_MAA_CTRL_OPSEL_POS)) +#define MXC_S_MAA_OPSEL_SUB ((uint32_t)(MXC_V_MAA_OPSEL_SUB << MXC_F_MAA_CTRL_OPSEL_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_MAA_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/max32625.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/max32625.h new file mode 100644 index 00000000000..32beddc58a6 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/max32625.h @@ -0,0 +1,802 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MAX32625_H_ +#define _MAX32625_H_ + +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (1) +#endif + +/* COMPILER SPECIFIC DEFINES (IAR, ARMCC and GNUC) */ +#if defined ( __GNUC__ ) +#define __weak __attribute__((weak)) + +#elif defined ( __CC_ARM) + +#define inline __inline +#pragma anon_unions + +#endif + +typedef enum { + NonMaskableInt_IRQn = -14, + HardFault_IRQn = -13, + MemoryManagement_IRQn = -12, + BusFault_IRQn = -11, + UsageFault_IRQn = -10, + SVCall_IRQn = -5, + DebugMonitor_IRQn = -4, + PendSV_IRQn = -2, + SysTick_IRQn = -1, + + /* Device-specific interrupt sources (external to ARM core) */ + /* table entry number */ + /* |||| */ + /* |||| table offset address */ + /* vvvv vvvvvv */ + + CLKMAN_IRQn = 0, /* 0x10 0x0040,CLKMAN */ + PWRMAN_IRQn = 1, /* 0x11 0x0044 PWRMAN */ + FLC_IRQn = 2, /* 0x12 0x0048 Flash Controller */ + RTC0_IRQn = 3, /* 0x13 0x004C RTC Counter match with Compare 0 */ + RTC1_IRQn = 4, /* 0x14 0x0050 RTC Counter match with Compare 1 */ + RTC2_IRQn = 5, /* 0x15 0x0054 RTC Prescaler interval compare match */ + RTC3_IRQn = 6, /* 0x16 0x0058 RTC Overflow */ + PMU_IRQn = 7, /* 0x17 0x005C Peripheral Management Unit (PMU/DMA) */ + USB_IRQn = 8, /* 0x18 0x0060 USB */ + AES_IRQn = 9, /* 0x19 0x0064 AES */ + MAA_IRQn = 10, /* 0x1A 0x0068 MAA */ + WDT0_IRQn = 11, /* 0x1B 0x006C Watchdog 0 timeout */ + WDT0_P_IRQn = 12, /* 0x1C 0x0070 Watchdog 0 pre-window (fed too early) */ + WDT1_IRQn = 13, /* 0x1D 0x0074 Watchdog 1 timeout */ + WDT1_P_IRQn = 14, /* 0x1E 0x0078 Watchdog 1 pre-window (fed too early) */ + GPIO_P0_IRQn = 15, /* 0x1F 0x007C GPIO Port 0 */ + GPIO_P1_IRQn = 16, /* 0x20 0x0080 GPIO Port 1 */ + GPIO_P2_IRQn = 17, /* 0x21 0x0084 GPIO Port 2 */ + GPIO_P3_IRQn = 18, /* 0x22 0x0088 GPIO Port 3 */ + GPIO_P4_IRQn = 19, /* 0x23 0x008C GPIO Port 4 */ + GPIO_P5_IRQn = 20, /* 0x24 0x0090 GPIO Port 5 (Unused) */ + GPIO_P6_IRQn = 21, /* 0x25 0x0094 GPIO Port 6 (Unused) */ + TMR0_0_IRQn = 22, /* 0x26 0x0098 Timer 0 (32-bit, 16-bit #0) */ + TMR0_1_IRQn = 23, /* 0x27 0x009C Timer 0 (16-bit #1) */ + TMR1_0_IRQn = 24, /* 0x28 0x00A0 Timer 1 (32-bit, 16-bit #0) */ + TMR1_1_IRQn = 25, /* 0x29 0x00A4 Timer 1 (16-bit #1) */ + TMR2_0_IRQn = 26, /* 0x2A 0x00A8 Timer 2 (32-bit, 16-bit #0) */ + TMR2_1_IRQn = 27, /* 0x2B 0x00AC Timer 2 (16-bit #1) */ + TMR3_0_IRQn = 28, /* 0x2C 0x00B0 Timer 3 (32-bit, 16-bit #0) */ + TMR3_1_IRQn = 29, /* 0x2D 0x00B4 Timer 3 (16-bit #1) */ + TMR4_0_IRQn = 30, /* 0x2E 0x00B8 Timer 4 (32-bit, 16-bit #0) */ + TMR4_1_IRQn = 31, /* 0x2F 0x00BC Timer 4 (16-bit #1) */ + TMR5_0_IRQn = 32, /* 0x30 0x00C0 Timer 5 (32-bit, 16-bit #0) */ + TMR5_1_IRQn = 33, /* 0x31 0x00C4 Timer 5 (16-bit #1) */ + UART0_IRQn = 34, /* 0x32 0x00C8 UART 0 */ + UART1_IRQn = 35, /* 0x33 0x00CC UART 1 */ + UART2_IRQn = 36, /* 0x34 0x00D0 UART 2 */ + UART3_IRQn = 37, /* 0x35 0x00D4 UART 3 (Unused) */ + PT_IRQn = 38, /* 0x36 0x00D8 Pulse Trains */ + I2CM0_IRQn = 39, /* 0x37 0x00DC I2C Master 0 */ + I2CM1_IRQn = 40, /* 0x38 0x00E0 I2C Master 1 */ + I2CM2_IRQn = 41, /* 0x39 0x00E4 I2C Master 2 (Unused) */ + I2CS_IRQn = 42, /* 0x3A 0x00E8 I2C Slave */ + SPIM0_IRQn = 43, /* 0x3B 0x00EC SPI Master 0 */ + SPIM1_IRQn = 44, /* 0x3C 0x00F0 SPI Master 1 */ + SPIM2_IRQn = 45, /* 0x3D 0x00F4 SPI Master 2 */ + SPIB_IRQn = 46, /* 0x3E 0x00F8 SPI Bridge (Unused) */ + OWM_IRQn = 47, /* 0x3F 0x00FC 1-Wire Master */ + AFE_IRQn = 48, /* 0x40 0x0100 Analog Front End, ADC */ + SPIS_IRQn = 49, /* 0x41 0x0104 SPI Slave */ + MXC_IRQ_EXT_COUNT, +} IRQn_Type; + +#define MXC_IRQ_COUNT (MXC_IRQ_EXT_COUNT + 16) + + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* ---------------------- Configuration of the Cortex-M Processor and Core Peripherals ---------------------- */ +#define __CM4_REV 0x0100 /*!< Cortex-M4 Core Revision */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1 /*!< FPU present or not */ + +#include /*!< Cortex-M4 processor and core peripherals */ +#include "system_max32625.h" /*!< System Header */ + + +/* ================================================================================ */ +/* ================== Device Specific Memory Section ================== */ +/* ================================================================================ */ + +#define MXC_FLASH_MEM_BASE 0x00000000UL +#define MXC_FLASH_PAGE_SIZE 0x00002000UL +#define MXC_FLASH_FULL_MEM_SIZE 0x00080000UL +#define MXC_SYS_MEM_BASE 0x20000000UL +#define MXC_SRAM_FULL_MEM_SIZE 0x00028000UL +#define MXC_EXT_FLASH_MEM_BASE 0x10000000UL + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + + +/* + Base addresses and configuration settings for all MAX32625 peripheral modules. +*/ + + +/*******************************************************************************/ +/* System Manager Settings */ + +#define MXC_BASE_SYSMAN ((uint32_t)0x40000000UL) +#define MXC_SYSMAN ((mxc_sysman_regs_t *)MXC_BASE_SYSMAN) + + + +/*******************************************************************************/ +/* System Clock Manager */ + +#define MXC_BASE_CLKMAN ((uint32_t)0x40000400UL) +#define MXC_CLKMAN ((mxc_clkman_regs_t *)MXC_BASE_CLKMAN) + + + +/*******************************************************************************/ +/* System Power Manager */ + +#define MXC_BASE_PWRMAN ((uint32_t)0x40000800UL) +#define MXC_PWRMAN ((mxc_pwrman_regs_t *)MXC_BASE_PWRMAN) + + + +/*******************************************************************************/ +/* Real Time Clock */ + +#define MXC_BASE_RTCTMR ((uint32_t)0x40000A00UL) +#define MXC_RTCTMR ((mxc_rtctmr_regs_t *)MXC_BASE_RTCTMR) +#define MXC_BASE_RTCCFG ((uint32_t)0x40000A70UL) +#define MXC_RTCCFG ((mxc_rtccfg_regs_t *)MXC_BASE_RTCCFG) + +#define MXC_RTCTMR_GET_IRQ(i) (IRQn_Type)((i) == 0 ? RTC0_IRQn : \ + (i) == 1 ? RTC1_IRQn : \ + (i) == 2 ? RTC2_IRQn : \ + (i) == 3 ? RTC3_IRQn : 0) + + + +/*******************************************************************************/ +/* Power Sequencer */ + +#define MXC_BASE_PWRSEQ ((uint32_t)0x40000A30UL) +#define MXC_PWRSEQ ((mxc_pwrseq_regs_t *)MXC_BASE_PWRSEQ) + + + +/*******************************************************************************/ +/* System I/O Manager */ + +#define MXC_BASE_IOMAN ((uint32_t)0x40000C00UL) +#define MXC_IOMAN ((mxc_ioman_regs_t *)MXC_BASE_IOMAN) + + + +/*******************************************************************************/ +/* Shadow Trim Registers */ + +#define MXC_BASE_TRIM ((uint32_t)0x40001000UL) +#define MXC_TRIM ((mxc_trim_regs_t *)MXC_BASE_TRIM) + + + +/*******************************************************************************/ +/* Flash Controller */ + +#define MXC_BASE_FLC ((uint32_t)0x40002000UL) +#define MXC_FLC ((mxc_flc_regs_t *)MXC_BASE_FLC) + +#define MXC_FLC_PAGE_SIZE_SHIFT (13) +#define MXC_FLC_PAGE_SIZE (1 << MXC_FLC_PAGE_SIZE_SHIFT) +#define MXC_FLC_PAGE_ERASE_MSK ((~(1 << (MXC_FLC_PAGE_SIZE_SHIFT - 1))) >> MXC_FLC_PAGE_SIZE_SHIFT) << MXC_FLC_PAGE_SIZE_SHIFT + + + +/*******************************************************************************/ +/* Instruction Cache */ + +#define MXC_BASE_ICC ((uint32_t)0x40003000UL) +#define MXC_ICC ((mxc_icc_regs_t *)MXC_BASE_ICC) + + + +/*******************************************************************************/ +/* SPI XIP Interface */ + +#define MXC_BASE_SPIX ((uint32_t)0x40004000UL) +#define MXC_SPIX ((mxc_spix_regs_t *)MXC_BASE_SPIX) + + + +/*******************************************************************************/ +/* Peripheral Management Unit */ + +#define MXC_CFG_PMU_CHANNELS (6) + +#define MXC_BASE_PMU0 ((uint32_t)0x40005000UL) +#define MXC_PMU0 ((mxc_pmu_regs_t *)MXC_BASE_PMU0) +#define MXC_BASE_PMU1 ((uint32_t)0x40005020UL) +#define MXC_PMU1 ((mxc_pmu_regs_t *)MXC_BASE_PMU1) +#define MXC_BASE_PMU2 ((uint32_t)0x40005040UL) +#define MXC_PMU2 ((mxc_pmu_regs_t *)MXC_BASE_PMU2) +#define MXC_BASE_PMU3 ((uint32_t)0x40005060UL) +#define MXC_PMU3 ((mxc_pmu_regs_t *)MXC_BASE_PMU3) +#define MXC_BASE_PMU4 ((uint32_t)0x40005080UL) +#define MXC_PMU4 ((mxc_pmu_regs_t *)MXC_BASE_PMU4) +#define MXC_BASE_PMU5 ((uint32_t)0x400050A0UL) +#define MXC_PMU5 ((mxc_pmu_regs_t *)MXC_BASE_PMU5) + +#define MXC_PMU_GET_BASE(i) ((i) == 0 ? MXC_BASE_PMU0 : \ + (i) == 1 ? MXC_BASE_PMU1 : \ + (i) == 2 ? MXC_BASE_PMU2 : \ + (i) == 3 ? MXC_BASE_PMU3 : \ + (i) == 4 ? MXC_BASE_PMU4 : \ + (i) == 5 ? MXC_BASE_PMU5 : 0) + +#define MXC_PMU_GET_PMU(i) ((i) == 0 ? MXC_PMU0 : \ + (i) == 1 ? MXC_PMU1 : \ + (i) == 2 ? MXC_PMU2 : \ + (i) == 3 ? MXC_PMU3 : \ + (i) == 4 ? MXC_PMU4 : \ + (i) == 5 ? MXC_PMU5 : 0) + +#define MXC_PMU_GET_IDX(p) ((p) == MXC_PMU0 ? 0 : \ + (p) == MXC_PMU1 ? 1 : \ + (p) == MXC_PMU2 ? 2 : \ + (p) == MXC_PMU3 ? 3 : \ + (p) == MXC_PMU4 ? 4 : \ + (p) == MXC_PMU5 ? 5 : -1) + + +/*******************************************************************************/ +/* USB Device Controller */ + +#define MXC_BASE_USB ((uint32_t)0x40100000UL) +#define MXC_USB ((mxc_usb_regs_t *)MXC_BASE_USB) + +#define MXC_USB_MAX_PACKET (64) +#define MXC_USB_NUM_EP (8) + + + +/*******************************************************************************/ +/* CRC-16/CRC-32 Engine */ + +#define MXC_BASE_CRC ((uint32_t)0x40006000UL) +#define MXC_CRC ((mxc_crc_regs_t *)MXC_BASE_CRC) +#define MXC_BASE_CRC_DATA ((uint32_t)0x40101000UL) +#define MXC_CRC_DATA ((mxc_crc_data_regs_t *)MXC_BASE_CRC_DATA) + + + +/*******************************************************************************/ +/* Pseudo-random number generator (PRNG) */ + +#define MXC_BASE_PRNG ((uint32_t)0x40007000UL) +#define MXC_PRNG ((mxc_prng_regs_t *)MXC_BASE_PRNG) + +/*******************************************************************************/ +/* AES Cryptographic Engine */ + +#define MXC_BASE_AES ((uint32_t)0x40007400UL) +#define MXC_AES ((mxc_aes_regs_t *)MXC_BASE_AES) +#define MXC_BASE_AES_MEM ((uint32_t)0x40102000UL) +#define MXC_AES_MEM ((mxc_aes_mem_regs_t *)MXC_BASE_AES_MEM) + + + +/*******************************************************************************/ +/* MAA Cryptographic Engine */ + +#define MXC_BASE_MAA ((uint32_t)0x40007800UL) +#define MXC_MAA ((mxc_maa_regs_t *)MXC_BASE_MAA) +#define MXC_BASE_MAA_MEM ((uint32_t)0x40102800UL) +#define MXC_MAA_MEM ((mxc_maa_mem_regs_t *)MXC_BASE_MAA_MEM) + +/*******************************************************************************/ +/* Trust Protection Unit (TPU) */ + +#define MXC_BASE_TPU ((uint32_t)0x40007000UL) +#define MXC_TPU ((mxc_tpu_regs_t *)MXC_BASE_TPU) +#define MXC_BASE_TPU_TSR ((uint32_t)0x40007C00UL) +#define MXC_TPU_TSR ((mxc_tpu_tsr_regs_t *)MXC_BASE_TPU_TSR) + +/*******************************************************************************/ +/* Watchdog Timers */ + +#define MXC_CFG_WDT_INSTANCES (2) + +#define MXC_BASE_WDT0 ((uint32_t)0x40008000UL) +#define MXC_WDT0 ((mxc_wdt_regs_t *)MXC_BASE_WDT0) +#define MXC_BASE_WDT1 ((uint32_t)0x40009000UL) +#define MXC_WDT1 ((mxc_wdt_regs_t *)MXC_BASE_WDT1) + +#define MXC_WDT_GET_IRQ(i) (IRQn_Type)((i) == 0 ? WDT0_IRQn : \ + (i) == 1 ? WDT1_IRQn : 0) + +#define MXC_WDT_GET_IRQ_P(i) (IRQn_Type)((i) == 0 ? WDT0_P_IRQn : \ + (i) == 1 ? WDT1_P_IRQn : 0) + +#define MXC_WDT_GET_BASE(i) ((i) == 0 ? MXC_BASE_WDT0 : \ + (i) == 1 ? MXC_BASE_WDT1 : 0) + +#define MXC_WDT_GET_WDT(i) ((i) == 0 ? MXC_WDT0 : \ + (i) == 1 ? MXC_WDT1 : 0) + +#define MXC_WDT_GET_IDX(i) ((i) == MXC_WDT0 ? 0: \ + (i) == MXC_WDT1 ? 1: -1) + + +/*******************************************************************************/ +/* Low-Level Watchdog Timer */ + +#define MXC_BASE_WDT2 ((uint32_t)0x40007C60UL) +#define MXC_WDT2 ((mxc_wdt2_regs_t *)MXC_BASE_WDT2) + + + +/*******************************************************************************/ +/* General Purpose I/O Ports (GPIO) */ + +#define MXC_GPIO_NUM_PORTS (5) +#define MXC_GPIO_MAX_PINS_PER_PORT (8) + +#define MXC_BASE_GPIO ((uint32_t)0x4000A000UL) +#define MXC_GPIO ((mxc_gpio_regs_t *)MXC_BASE_GPIO) + +#define MXC_GPIO_GET_IRQ(i) (IRQn_Type)((i) == 0 ? GPIO_P0_IRQn : \ + (i) == 1 ? GPIO_P1_IRQn : \ + (i) == 2 ? GPIO_P2_IRQn : \ + (i) == 3 ? GPIO_P3_IRQn : \ + (i) == 4 ? GPIO_P4_IRQn : 0) + + + +/*******************************************************************************/ +/* 16/32 bit Timer/Counters */ + +#define MXC_CFG_TMR_INSTANCES (6) + +#define MXC_BASE_TMR0 ((uint32_t)0x4000B000UL) +#define MXC_TMR0 ((mxc_tmr_regs_t *)MXC_BASE_TMR0) +#define MXC_BASE_TMR1 ((uint32_t)0x4000C000UL) +#define MXC_TMR1 ((mxc_tmr_regs_t *)MXC_BASE_TMR1) +#define MXC_BASE_TMR2 ((uint32_t)0x4000D000UL) +#define MXC_TMR2 ((mxc_tmr_regs_t *)MXC_BASE_TMR2) +#define MXC_BASE_TMR3 ((uint32_t)0x4000E000UL) +#define MXC_TMR3 ((mxc_tmr_regs_t *)MXC_BASE_TMR3) +#define MXC_BASE_TMR4 ((uint32_t)0x4000F000UL) +#define MXC_TMR4 ((mxc_tmr_regs_t *)MXC_BASE_TMR4) +#define MXC_BASE_TMR5 ((uint32_t)0x40010000UL) +#define MXC_TMR5 ((mxc_tmr_regs_t *)MXC_BASE_TMR5) + +#define MXC_TMR_GET_IRQ_32(i) (IRQn_Type)((i) == 0 ? TMR0_0_IRQn : \ + (i) == 1 ? TMR1_0_IRQn : \ + (i) == 2 ? TMR2_0_IRQn : \ + (i) == 3 ? TMR3_0_IRQn : \ + (i) == 4 ? TMR4_0_IRQn : \ + (i) == 5 ? TMR5_0_IRQn : 0) + +#define MXC_TMR_GET_IRQ_16(i) (IRQn_Type)((i) == 0 ? TMR0_0_IRQn : \ + (i) == 1 ? TMR1_0_IRQn : \ + (i) == 2 ? TMR2_0_IRQn : \ + (i) == 3 ? TMR3_0_IRQn : \ + (i) == 4 ? TMR4_0_IRQn : \ + (i) == 5 ? TMR5_0_IRQn : \ + (i) == 6 ? TMR0_1_IRQn : \ + (i) == 7 ? TMR1_1_IRQn : \ + (i) == 8 ? TMR2_1_IRQn : \ + (i) == 9 ? TMR3_1_IRQn : \ + (i) == 10 ? TMR4_1_IRQn : \ + (i) == 11 ? TMR5_1_IRQn : 0) + +#define MXC_TMR_GET_BASE(i) ((i) == 0 ? MXC_BASE_TMR0 : \ + (i) == 1 ? MXC_BASE_TMR1 : \ + (i) == 2 ? MXC_BASE_TMR2 : \ + (i) == 3 ? MXC_BASE_TMR3 : \ + (i) == 4 ? MXC_BASE_TMR4 : \ + (i) == 5 ? MXC_BASE_TMR5 : 0) + +#define MXC_TMR_GET_TMR(i) ((i) == 0 ? MXC_TMR0 : \ + (i) == 1 ? MXC_TMR1 : \ + (i) == 2 ? MXC_TMR2 : \ + (i) == 3 ? MXC_TMR3 : \ + (i) == 4 ? MXC_TMR4 : \ + (i) == 5 ? MXC_TMR5 : 0) + +#define MXC_TMR_GET_IDX(p) ((p) == MXC_TMR0 ? 0 : \ + (p) == MXC_TMR1 ? 1 : \ + (p) == MXC_TMR2 ? 2 : \ + (p) == MXC_TMR3 ? 3 : \ + (p) == MXC_TMR4 ? 4 : \ + (p) == MXC_TMR5 ? 5 : -1) + + + + +/*******************************************************************************/ +/* Pulse Train Generation */ + +#define MXC_CFG_PT_INSTANCES (16) + +#define MXC_BASE_PTG ((uint32_t)0x40011000UL) +#define MXC_PTG ((mxc_ptg_regs_t *)MXC_BASE_PTG) +#define MXC_BASE_PT0 ((uint32_t)0x40011020UL) +#define MXC_PT0 ((mxc_pt_regs_t *)MXC_BASE_PT0) +#define MXC_BASE_PT1 ((uint32_t)0x40011040UL) +#define MXC_PT1 ((mxc_pt_regs_t *)MXC_BASE_PT1) +#define MXC_BASE_PT2 ((uint32_t)0x40011060UL) +#define MXC_PT2 ((mxc_pt_regs_t *)MXC_BASE_PT2) +#define MXC_BASE_PT3 ((uint32_t)0x40011080UL) +#define MXC_PT3 ((mxc_pt_regs_t *)MXC_BASE_PT3) +#define MXC_BASE_PT4 ((uint32_t)0x400110A0UL) +#define MXC_PT4 ((mxc_pt_regs_t *)MXC_BASE_PT4) +#define MXC_BASE_PT5 ((uint32_t)0x400110C0UL) +#define MXC_PT5 ((mxc_pt_regs_t *)MXC_BASE_PT5) +#define MXC_BASE_PT6 ((uint32_t)0x400110E0UL) +#define MXC_PT6 ((mxc_pt_regs_t *)MXC_BASE_PT6) +#define MXC_BASE_PT7 ((uint32_t)0x40011100UL) +#define MXC_PT7 ((mxc_pt_regs_t *)MXC_BASE_PT7) +#define MXC_BASE_PT8 ((uint32_t)0x40011120UL) +#define MXC_PT8 ((mxc_pt_regs_t *)MXC_BASE_PT8) +#define MXC_BASE_PT9 ((uint32_t)0x40011140UL) +#define MXC_PT9 ((mxc_pt_regs_t *)MXC_BASE_PT9) +#define MXC_BASE_PT10 ((uint32_t)0x40011160UL) +#define MXC_PT10 ((mxc_pt_regs_t *)MXC_BASE_PT10) +#define MXC_BASE_PT11 ((uint32_t)0x40011180UL) +#define MXC_PT11 ((mxc_pt_regs_t *)MXC_BASE_PT11) +#define MXC_BASE_PT12 ((uint32_t)0x400111A0UL) +#define MXC_PT12 ((mxc_pt_regs_t *)MXC_BASE_PT12) +#define MXC_BASE_PT13 ((uint32_t)0x400111C0UL) +#define MXC_PT13 ((mxc_pt_regs_t *)MXC_BASE_PT13) +#define MXC_BASE_PT14 ((uint32_t)0x400111E0UL) +#define MXC_PT14 ((mxc_pt_regs_t *)MXC_BASE_PT14) +#define MXC_BASE_PT15 ((uint32_t)0x40011200UL) +#define MXC_PT15 ((mxc_pt_regs_t *)MXC_BASE_PT15) + +#define MXC_PT_GET_BASE(i) ((i) == 0 ? MXC_BASE_PT0 : \ + (i) == 1 ? MXC_BASE_PT1 : \ + (i) == 2 ? MXC_BASE_PT2 : \ + (i) == 3 ? MXC_BASE_PT3 : \ + (i) == 4 ? MXC_BASE_PT4 : \ + (i) == 5 ? MXC_BASE_PT5 : \ + (i) == 6 ? MXC_BASE_PT6 : \ + (i) == 7 ? MXC_BASE_PT7 : \ + (i) == 8 ? MXC_BASE_PT8 : \ + (i) == 9 ? MXC_BASE_PT9 : \ + (i) == 10 ? MXC_BASE_PT10 : \ + (i) == 11 ? MXC_BASE_PT11 : \ + (i) == 12 ? MXC_BASE_PT12 : \ + (i) == 13 ? MXC_BASE_PT13 : \ + (i) == 14 ? MXC_BASE_PT14 : \ + (i) == 15 ? MXC_BASE_PT15 : 0) + +#define MXC_PT_GET_PT(i) ((i) == 0 ? MXC_PT0 : \ + (i) == 1 ? MXC_PT1 : \ + (i) == 2 ? MXC_PT2 : \ + (i) == 3 ? MXC_PT3 : \ + (i) == 4 ? MXC_PT4 : \ + (i) == 5 ? MXC_PT5 : \ + (i) == 6 ? MXC_PT6 : \ + (i) == 7 ? MXC_PT7 : \ + (i) == 8 ? MXC_PT8 : \ + (i) == 9 ? MXC_PT9 : \ + (i) == 10 ? MXC_PT10 : \ + (i) == 11 ? MXC_PT11 : \ + (i) == 12 ? MXC_PT12 : \ + (i) == 13 ? MXC_PT13 : \ + (i) == 14 ? MXC_PT14 : \ + (i) == 15 ? MXC_PT15 : 0) + +#define MXC_PT_GET_IDX(p) ((p) == MXC_PT0 ? 0 : \ + (p) == MXC_PT1 ? 1 : \ + (p) == MXC_PT2 ? 2 : \ + (p) == MXC_PT3 ? 3 : \ + (p) == MXC_PT4 ? 4 : \ + (p) == MXC_PT5 ? 5 : \ + (p) == MXC_PT6 ? 6 : \ + (p) == MXC_PT7 ? 7 : \ + (p) == MXC_PT8 ? 8 : \ + (p) == MXC_PT9 ? 9 : \ + (p) == MXC_PT10 ? 10 : \ + (p) == MXC_PT11 ? 11 : \ + (p) == MXC_PT12 ? 12 : \ + (p) == MXC_PT13 ? 13 : \ + (p) == MXC_PT14 ? 14 : \ + (p) == MXC_PT15 ? 15 : -1) + + + +/*******************************************************************************/ +/* UART / Serial Port Interface */ + +#define MXC_CFG_UART_INSTANCES (3) +#define MXC_UART_FIFO_DEPTH (32) + +#define MXC_BASE_UART0 ((uint32_t)0x40012000UL) +#define MXC_UART0 ((mxc_uart_regs_t *)MXC_BASE_UART0) +#define MXC_BASE_UART1 ((uint32_t)0x40013000UL) +#define MXC_UART1 ((mxc_uart_regs_t *)MXC_BASE_UART1) +#define MXC_BASE_UART2 ((uint32_t)0x40014000UL) +#define MXC_UART2 ((mxc_uart_regs_t *)MXC_BASE_UART2) +#define MXC_BASE_UART0_FIFO ((uint32_t)0x40103000UL) +#define MXC_UART0_FIFO ((mxc_uart_fifo_regs_t *)MXC_BASE_UART0_FIFO) +#define MXC_BASE_UART1_FIFO ((uint32_t)0x40104000UL) +#define MXC_UART1_FIFO ((mxc_uart_fifo_regs_t *)MXC_BASE_UART1_FIFO) +#define MXC_BASE_UART2_FIFO ((uint32_t)0x40105000UL) +#define MXC_UART2_FIFO ((mxc_uart_fifo_regs_t *)MXC_BASE_UART2_FIFO) + +#define MXC_UART_GET_IRQ(i) (IRQn_Type)((i) == 0 ? UART0_IRQn : \ + (i) == 1 ? UART1_IRQn : \ + (i) == 2 ? UART2_IRQn : 0) + +#define MXC_UART_GET_BASE(i) ((i) == 0 ? MXC_BASE_UART0 : \ + (i) == 1 ? MXC_BASE_UART1 : \ + (i) == 2 ? MXC_BASE_UART2 : 0) + +#define MXC_UART_GET_UART(i) ((i) == 0 ? MXC_UART0 : \ + (i) == 1 ? MXC_UART1 : \ + (i) == 2 ? MXC_UART2 : 0) + +#define MXC_UART_GET_IDX(p) ((p) == MXC_UART0 ? 0 : \ + (p) == MXC_UART1 ? 1 : \ + (p) == MXC_UART2 ? 2 : -1) + +#define MXC_UART_GET_BASE_FIFO(i) ((i) == 0 ? MXC_BASE_UART0_FIFO : \ + (i) == 1 ? MXC_BASE_UART1_FIFO : \ + (i) == 2 ? MXC_BASE_UART2_FIFO : 0) + +#define MXC_UART_GET_FIFO(i) ((i) == 0 ? MXC_UART0_FIFO : \ + (i) == 1 ? MXC_UART1_FIFO : \ + (i) == 2 ? MXC_UART2_FIFO : 0) + + + +/*******************************************************************************/ +/* I2C Master Interface */ + +#define MXC_CFG_I2CM_INSTANCES (2) +#define MXC_I2CM_FIFO_DEPTH (8) + +#define MXC_BASE_I2CM0 ((uint32_t)0x40016000UL) +#define MXC_I2CM0 ((mxc_i2cm_regs_t *)MXC_BASE_I2CM0) +#define MXC_BASE_I2CM1 ((uint32_t)0x40017000UL) +#define MXC_I2CM1 ((mxc_i2cm_regs_t *)MXC_BASE_I2CM1) +#define MXC_BASE_I2CM0_FIFO ((uint32_t)0x40107000UL) +#define MXC_I2CM0_FIFO ((mxc_i2cm_fifo_regs_t *)MXC_BASE_I2CM0_FIFO) +#define MXC_BASE_I2CM1_FIFO ((uint32_t)0x40108000UL) +#define MXC_I2CM1_FIFO ((mxc_i2cm_fifo_regs_t *)MXC_BASE_I2CM1_FIFO) + +#define MXC_I2CM_GET_IRQ(i) (IRQn_Type)((i) == 0 ? I2CM0_IRQn : \ + (i) == 1 ? I2CM1_IRQn : 0) + +#define MXC_I2CM_GET_BASE(i) ((i) == 0 ? MXC_BASE_I2CM0 : \ + (i) == 1 ? MXC_BASE_I2CM1 : 0) + +#define MXC_I2CM_GET_I2CM(i) ((i) == 0 ? MXC_I2CM0 : \ + (i) == 1 ? MXC_I2CM1 : 0) + +#define MXC_I2CM_GET_IDX(p) ((p) == MXC_I2CM0 ? 0 : \ + (p) == MXC_I2CM1 ? 1 : -1) + +#define MXC_I2CM_GET_BASE_FIFO(i) ((i) == 0 ? MXC_BASE_I2CM0_FIFO : \ + (i) == 1 ? MXC_BASE_I2CM1_FIFO : 0) + +#define MXC_I2CM_GET_FIFO(i) ((i) == 0 ? MXC_I2CM0_FIFO : \ + (i) == 1 ? MXC_I2CM1_FIFO : 0) + + + +/*******************************************************************************/ +/* I2C Slave Interface (Mailbox type) */ + +#define MXC_CFG_I2CS_INSTANCES (1) +#define MXC_CFG_I2CS_BUFFER_SIZE (32) + +#define MXC_BASE_I2CS ((uint32_t)0x40019000UL) +#define MXC_I2CS ((mxc_i2cs_regs_t *)MXC_BASE_I2CS) + +#define MXC_I2CS_GET_IRQ(i) (IRQn_Type)((i) == 0 ? I2CS_IRQn : 0) + +#define MXC_I2CS_GET_BASE(i) ((i) == 0 ? MXC_BASE_I2CS : 0) + +#define MXC_I2CS_GET_I2CS(i) ((i) == 0 ? MXC_I2CS : 0) + +#define MXC_I2CS_GET_IDX(p) ((p) == MXC_I2CS ? 0 : -1) + +/*******************************************************************************/ +/* SPI Master Interface */ + +#define MXC_CFG_SPIM_INSTANCES (3) +#define MXC_CFG_SPIM_FIFO_DEPTH (16) + +#define MXC_BASE_SPIM0 ((uint32_t)0x4001A000UL) +#define MXC_SPIM0 ((mxc_spim_regs_t *)MXC_BASE_SPIM0) +#define MXC_BASE_SPIM1 ((uint32_t)0x4001B000UL) +#define MXC_SPIM1 ((mxc_spim_regs_t *)MXC_BASE_SPIM1) +#define MXC_BASE_SPIM2 ((uint32_t)0x4001C000UL) +#define MXC_SPIM2 ((mxc_spim_regs_t *)MXC_BASE_SPIM2) +#define MXC_BASE_SPIM0_FIFO ((uint32_t)0x4010A000UL) +#define MXC_SPIM0_FIFO ((mxc_spim_fifo_regs_t *)MXC_BASE_SPIM0_FIFO) +#define MXC_BASE_SPIM1_FIFO ((uint32_t)0x4010B000UL) +#define MXC_SPIM1_FIFO ((mxc_spim_fifo_regs_t *)MXC_BASE_SPIM1_FIFO) +#define MXC_BASE_SPIM2_FIFO ((uint32_t)0x4010C000UL) +#define MXC_SPIM2_FIFO ((mxc_spim_fifo_regs_t *)MXC_BASE_SPIM2_FIFO) + +#define MXC_SPIM_GET_IRQ(i) (IRQn_Type)((i) == 0 ? SPIM0_IRQn : \ + (i) == 1 ? SPIM1_IRQn : \ + (i) == 2 ? SPIM2_IRQn : 0) + +#define MXC_SPIM_GET_BASE(i) ((i) == 0 ? MXC_BASE_SPIM0 : \ + (i) == 1 ? MXC_BASE_SPIM1 : \ + (i) == 2 ? MXC_BASE_SPIM2 : 0) + +#define MXC_SPIM_GET_SPIM(i) ((i) == 0 ? MXC_SPIM0 : \ + (i) == 1 ? MXC_SPIM1 : \ + (i) == 2 ? MXC_SPIM2 : 0) + +#define MXC_SPIM_GET_IDX(p) ((p) == MXC_SPIM0 ? 0 : \ + (p) == MXC_SPIM1 ? 1 : \ + (p) == MXC_SPIM2 ? 2 : -1) + +#define MXC_SPIM_GET_BASE_FIFO(i) ((i) == 0 ? MXC_BASE_SPIM0_FIFO : \ + (i) == 1 ? MXC_BASE_SPIM1_FIFO : \ + (i) == 2 ? MXC_BASE_SPIM2_FIFO : 0) + +#define MXC_SPIM_GET_SPIM_FIFO(i) ((i) == 0 ? MXC_SPIM0_FIFO : \ + (i) == 1 ? MXC_SPIM1_FIFO : \ + (i) == 2 ? MXC_SPIM2_FIFO : 0) + + + +/*******************************************************************************/ +/* 1-Wire Master Interface */ + +#define MXC_CFG_OWM_INSTANCES (1) + +#define MXC_BASE_OWM ((uint32_t)0x4001E000UL) +#define MXC_OWM ((mxc_owm_regs_t *)MXC_BASE_OWM) + +#define MXC_OWM_GET_IRQ(i) (IRQn_Type)((i) == 0 ? OWM_IRQn : 0) + +#define MXC_OWM_GET_BASE(i) ((i) == 0 ? MXC_BASE_OWM : 0) + +#define MXC_OWM_GET_OWM(i) ((i) == 0 ? MXC_OWM : 0) + +#define MXC_OWM_GET_IDX(p) ((p) == MXC_OWM ? 0 : -1) + +/*******************************************************************************/ +/* ADC / AFE */ + +#define MXC_CFG_ADC_FIFO_DEPTH (32) + +#define MXC_BASE_ADC ((uint32_t)0x4001F000UL) +#define MXC_ADC ((mxc_adc_regs_t *)MXC_BASE_ADC) + + + +/*******************************************************************************/ +/* SPI Slave Interface */ +#define MXC_CFG_SPIS_INSTANCES (1) +#define MXC_CFG_SPIS_FIFO_DEPTH (32) + +#define MXC_BASE_SPIS ((uint32_t)0x40020000UL) +#define MXC_SPIS ((mxc_spis_regs_t *)MXC_BASE_SPIS) +#define MXC_BASE_SPIS_FIFO ((uint32_t)0x4010E000UL) +#define MXC_SPIS_FIFO ((mxc_spis_fifo_regs_t *)MXC_BASE_SPIS_FIFO) + +#define MXC_SPIS_GET_IRQ(i) (IRQn_Type)((i) == 0 ? SPIS_IRQn : 0) + +#define MXC_SPIS_GET_BASE(i) ((i) == 0 ? MXC_BASE_SPIS : 0) + +#define MXC_SPIS_GET_SPIS(i) ((i) == 0 ? MXC_SPIS : 0) + +#define MXC_SPIS_GET_IDX(p) ((p) == MXC_SPIS ? 0 : -1) + +#define MXC_SPIS_GET_BASE_FIFO(i) ((i) == 0 ? MXC_BASE_SPIS_FIFO : 0) + +#define MXC_SPIS_GET_SPIS_FIFO(i) ((i) == 0 ? MXC_SPIS_FIFO :0) + +/*******************************************************************************/ +/* Bit Shifting */ + +#define MXC_F_BIT_0 (1 << 0) +#define MXC_F_BIT_1 (1 << 1) +#define MXC_F_BIT_2 (1 << 2) +#define MXC_F_BIT_3 (1 << 3) +#define MXC_F_BIT_4 (1 << 4) +#define MXC_F_BIT_5 (1 << 5) +#define MXC_F_BIT_6 (1 << 6) +#define MXC_F_BIT_7 (1 << 7) +#define MXC_F_BIT_8 (1 << 8) +#define MXC_F_BIT_9 (1 << 9) +#define MXC_F_BIT_10 (1 << 10) +#define MXC_F_BIT_11 (1 << 11) +#define MXC_F_BIT_12 (1 << 12) +#define MXC_F_BIT_13 (1 << 13) +#define MXC_F_BIT_14 (1 << 14) +#define MXC_F_BIT_15 (1 << 15) +#define MXC_F_BIT_16 (1 << 16) +#define MXC_F_BIT_17 (1 << 17) +#define MXC_F_BIT_18 (1 << 18) +#define MXC_F_BIT_19 (1 << 19) +#define MXC_F_BIT_20 (1 << 20) +#define MXC_F_BIT_21 (1 << 21) +#define MXC_F_BIT_22 (1 << 22) +#define MXC_F_BIT_23 (1 << 23) +#define MXC_F_BIT_24 (1 << 24) +#define MXC_F_BIT_25 (1 << 25) +#define MXC_F_BIT_26 (1 << 26) +#define MXC_F_BIT_27 (1 << 27) +#define MXC_F_BIT_28 (1 << 28) +#define MXC_F_BIT_29 (1 << 29) +#define MXC_F_BIT_30 (1 << 30) +#define MXC_F_BIT_31 (1 << 31) + + +/*******************************************************************************/ + +#define BITBAND(reg, bit) ((0xf0000000 & (uint32_t)(reg)) + 0x2000000 + (((uint32_t)(reg) & 0x0fffffff) << 5) + ((bit) << 2)) +#define MXC_CLRBIT(reg, bit) (*(volatile uint32_t *)BITBAND(reg, bit) = 0) +#define MXC_SETBIT(reg, bit) (*(volatile uint32_t *)BITBAND(reg, bit) = 1) +#define MXC_GETBIT(reg, bit) (*(volatile uint32_t *)BITBAND(reg, bit)) +#define MXC_SET_FIELD(reg, clr, set) (*(volatile uint32_t *)reg = ((*(volatile uint32_t *)reg & ~clr) | set)) + + +/*******************************************************************************/ + +/* SCB CPACR Register Definitions */ +/* Note: Added by Maxim Integrated, as these are missing from CMSIS/Core/Include/core_cm4.h */ +#define SCB_CPACR_CP10_Pos 20 /*!< SCB CPACR: Coprocessor 10 Position */ +#define SCB_CPACR_CP10_Msk (0x3UL << SCB_CPACR_CP10_Pos) /*!< SCB CPACR: Coprocessor 10 Mask */ +#define SCB_CPACR_CP11_Pos 22 /*!< SCB CPACR: Coprocessor 11 Position */ +#define SCB_CPACR_CP11_Msk (0x3UL << SCB_CPACR_CP11_Pos) /*!< SCB CPACR: Coprocessor 11 Mask */ + +#endif /* _MAX32625_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/mxc_device.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/mxc_device.h new file mode 100644 index 00000000000..534f6a1ed7f --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/mxc_device.h @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_DEVICE_H_ +#define _MXC_DEVICE_H_ + +#include "max32625.h" + + +#ifndef TARGET +#error TARGET NOT DEFINED +#endif + +// Create a string definition for the TARGET +#define STRING_ARG(arg) #arg +#define STRING_NAME(name) STRING_ARG(name) +#define TARGET_NAME STRING_NAME(TARGET) + +// Define which revisions of the IP we are using +#ifndef TARGET_REV +#error TARGET_REV NOT DEFINED +#endif + +#if(TARGET_REV == 0x4132) +#define MXC_ADC_REV 1 +#define MXC_AES_REV 0 +#define MXC_CRC_REV 0 +#define MXC_FLC_REV 0 +#define MXC_GPIO_REV 0 +#define MXC_I2CM_REV 0 +#define MXC_I2CS_REV 0 +#define MXC_ICC_REV 0 +#define MXC_MAA_REV 0 +#define MXC_OWM_REV 0 +#define MXC_PMU_REV 1 +#define MXC_PRNG_REV 0 +#define MXC_PT_REV 0 +#define MXC_RTC_REV 0 +#define MXC_SPIM_REV 1 +#define MXC_SPIS_REV 0 +#define MXC_SPIX_REV 1 +#define MXC_TMR_REV 0 +#define MXC_UART_REV 1 +#define MXC_USB_REV 0 +#define MXC_WDT2_REV 0 +#define MXC_WDT_REV 0 + +#else + +#error TARGET_REV NOT SUPPORTED + +#endif /* if(TARGET_REV == 0x4132) */ + +#endif /* _MXC_DEVICE_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/owm_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/owm_regs.h new file mode 100644 index 00000000000..e5dc2886374 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/owm_regs.h @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_OWM_REGS_H_ +#define _MXC_OWM_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t cfg; /* 0x0000 1-Wire Master Configuration */ + __IO uint32_t clk_div_1us; /* 0x0004 1-Wire Master Clock Divisor */ + __IO uint32_t ctrl_stat; /* 0x0008 1-Wire Master Control/Status */ + __IO uint32_t data; /* 0x000C 1-Wire Master Data Buffer */ + __IO uint32_t intfl; /* 0x0010 1-Wire Master Interrupt Flags */ + __IO uint32_t inten; /* 0x0014 1-Wire Master Interrupt Enables */ +} mxc_owm_regs_t; + + +/* + Register offsets for module OWM. +*/ + +#define MXC_R_OWM_OFFS_CFG ((uint32_t)0x00000000UL) +#define MXC_R_OWM_OFFS_CLK_DIV_1US ((uint32_t)0x00000004UL) +#define MXC_R_OWM_OFFS_CTRL_STAT ((uint32_t)0x00000008UL) +#define MXC_R_OWM_OFFS_DATA ((uint32_t)0x0000000CUL) +#define MXC_R_OWM_OFFS_INTFL ((uint32_t)0x00000010UL) +#define MXC_R_OWM_OFFS_INTEN ((uint32_t)0x00000014UL) + + +/* + Field positions and masks for module OWM. +*/ + +#define MXC_F_OWM_CFG_LONG_LINE_MODE_POS 0 +#define MXC_F_OWM_CFG_LONG_LINE_MODE ((uint32_t)(0x00000001UL << MXC_F_OWM_CFG_LONG_LINE_MODE_POS)) +#define MXC_F_OWM_CFG_FORCE_PRES_DET_POS 1 +#define MXC_F_OWM_CFG_FORCE_PRES_DET ((uint32_t)(0x00000001UL << MXC_F_OWM_CFG_FORCE_PRES_DET_POS)) +#define MXC_F_OWM_CFG_BIT_BANG_EN_POS 2 +#define MXC_F_OWM_CFG_BIT_BANG_EN ((uint32_t)(0x00000001UL << MXC_F_OWM_CFG_BIT_BANG_EN_POS)) +#define MXC_F_OWM_CFG_EXT_PULLUP_MODE_POS 3 +#define MXC_F_OWM_CFG_EXT_PULLUP_MODE ((uint32_t)(0x00000001UL << MXC_F_OWM_CFG_EXT_PULLUP_MODE_POS)) +#define MXC_F_OWM_CFG_EXT_PULLUP_ENABLE_POS 4 +#define MXC_F_OWM_CFG_EXT_PULLUP_ENABLE ((uint32_t)(0x00000001UL << MXC_F_OWM_CFG_EXT_PULLUP_ENABLE_POS)) +#define MXC_F_OWM_CFG_SINGLE_BIT_MODE_POS 5 +#define MXC_F_OWM_CFG_SINGLE_BIT_MODE ((uint32_t)(0x00000001UL << MXC_F_OWM_CFG_SINGLE_BIT_MODE_POS)) +#define MXC_F_OWM_CFG_OVERDRIVE_POS 6 +#define MXC_F_OWM_CFG_OVERDRIVE ((uint32_t)(0x00000001UL << MXC_F_OWM_CFG_OVERDRIVE_POS)) +#define MXC_F_OWM_CFG_INT_PULLUP_ENABLE_POS 7 +#define MXC_F_OWM_CFG_INT_PULLUP_ENABLE ((uint32_t)(0x00000001UL << MXC_F_OWM_CFG_INT_PULLUP_ENABLE_POS)) + +#define MXC_F_OWM_CLK_DIV_1US_DIVISOR_POS 0 +#define MXC_F_OWM_CLK_DIV_1US_DIVISOR ((uint32_t)(0x000000FFUL << MXC_F_OWM_CLK_DIV_1US_DIVISOR_POS)) + +#define MXC_F_OWM_CTRL_STAT_START_OW_RESET_POS 0 +#define MXC_F_OWM_CTRL_STAT_START_OW_RESET ((uint32_t)(0x00000001UL << MXC_F_OWM_CTRL_STAT_START_OW_RESET_POS)) +#define MXC_F_OWM_CTRL_STAT_SRA_MODE_POS 1 +#define MXC_F_OWM_CTRL_STAT_SRA_MODE ((uint32_t)(0x00000001UL << MXC_F_OWM_CTRL_STAT_SRA_MODE_POS)) +#define MXC_F_OWM_CTRL_STAT_BIT_BANG_OE_POS 2 +#define MXC_F_OWM_CTRL_STAT_BIT_BANG_OE ((uint32_t)(0x00000001UL << MXC_F_OWM_CTRL_STAT_BIT_BANG_OE_POS)) +#define MXC_F_OWM_CTRL_STAT_OW_INPUT_POS 3 +#define MXC_F_OWM_CTRL_STAT_OW_INPUT ((uint32_t)(0x00000001UL << MXC_F_OWM_CTRL_STAT_OW_INPUT_POS)) +#define MXC_F_OWM_CTRL_STAT_OD_SPEC_MODE_POS 4 +#define MXC_F_OWM_CTRL_STAT_OD_SPEC_MODE ((uint32_t)(0x00000001UL << MXC_F_OWM_CTRL_STAT_OD_SPEC_MODE_POS)) +#define MXC_F_OWM_CTRL_STAT_EXT_PULLUP_POL_POS 5 +#define MXC_F_OWM_CTRL_STAT_EXT_PULLUP_POL ((uint32_t)(0x00000001UL << MXC_F_OWM_CTRL_STAT_EXT_PULLUP_POL_POS)) +#define MXC_F_OWM_CTRL_STAT_PRESENCE_DETECT_POS 7 +#define MXC_F_OWM_CTRL_STAT_PRESENCE_DETECT ((uint32_t)(0x00000001UL << MXC_F_OWM_CTRL_STAT_PRESENCE_DETECT_POS)) + +#define MXC_F_OWM_DATA_TX_RX_POS 0 +#define MXC_F_OWM_DATA_TX_RX ((uint32_t)(0x000000FFUL << MXC_F_OWM_DATA_TX_RX_POS)) + +#define MXC_F_OWM_INTFL_OW_RESET_DONE_POS 0 +#define MXC_F_OWM_INTFL_OW_RESET_DONE ((uint32_t)(0x00000001UL << MXC_F_OWM_INTFL_OW_RESET_DONE_POS)) +#define MXC_F_OWM_INTFL_TX_DATA_EMPTY_POS 1 +#define MXC_F_OWM_INTFL_TX_DATA_EMPTY ((uint32_t)(0x00000001UL << MXC_F_OWM_INTFL_TX_DATA_EMPTY_POS)) +#define MXC_F_OWM_INTFL_RX_DATA_READY_POS 2 +#define MXC_F_OWM_INTFL_RX_DATA_READY ((uint32_t)(0x00000001UL << MXC_F_OWM_INTFL_RX_DATA_READY_POS)) +#define MXC_F_OWM_INTFL_LINE_SHORT_POS 3 +#define MXC_F_OWM_INTFL_LINE_SHORT ((uint32_t)(0x00000001UL << MXC_F_OWM_INTFL_LINE_SHORT_POS)) +#define MXC_F_OWM_INTFL_LINE_LOW_POS 4 +#define MXC_F_OWM_INTFL_LINE_LOW ((uint32_t)(0x00000001UL << MXC_F_OWM_INTFL_LINE_LOW_POS)) + +#define MXC_F_OWM_INTEN_OW_RESET_DONE_POS 0 +#define MXC_F_OWM_INTEN_OW_RESET_DONE ((uint32_t)(0x00000001UL << MXC_F_OWM_INTEN_OW_RESET_DONE_POS)) +#define MXC_F_OWM_INTEN_TX_DATA_EMPTY_POS 1 +#define MXC_F_OWM_INTEN_TX_DATA_EMPTY ((uint32_t)(0x00000001UL << MXC_F_OWM_INTEN_TX_DATA_EMPTY_POS)) +#define MXC_F_OWM_INTEN_RX_DATA_READY_POS 2 +#define MXC_F_OWM_INTEN_RX_DATA_READY ((uint32_t)(0x00000001UL << MXC_F_OWM_INTEN_RX_DATA_READY_POS)) +#define MXC_F_OWM_INTEN_LINE_SHORT_POS 3 +#define MXC_F_OWM_INTEN_LINE_SHORT ((uint32_t)(0x00000001UL << MXC_F_OWM_INTEN_LINE_SHORT_POS)) +#define MXC_F_OWM_INTEN_LINE_LOW_POS 4 +#define MXC_F_OWM_INTEN_LINE_LOW ((uint32_t)(0x00000001UL << MXC_F_OWM_INTEN_LINE_LOW_POS)) + +#define MXC_V_OWM_CFG_EXT_PULLUP_MODE_UNUSED ((uint32_t)(0x00000000UL)) +#define MXC_V_OWM_CFG_EXT_PULLUP_MODE_USED ((uint32_t)(0x00000001UL)) + +#define MXC_V_OWM_CTRL_STAT_OD_SPEC_MODE_12US ((uint32_t)(0x00000000UL)) +#define MXC_V_OWM_CTRL_STAT_OD_SPEC_MODE_10US ((uint32_t)(0x00000001UL)) + +#define MXC_V_OWM_CTRL_STAT_EXT_PULLUP_POL_ACT_HIGH ((uint32_t)(0x00000000UL)) +#define MXC_V_OWM_CTRL_STAT_EXT_PULLUP_POL_ACT_LOW ((uint32_t)(0x00000001UL)) + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_OWM_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/pmu_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/pmu_regs.h new file mode 100644 index 00000000000..931e8dc0b70 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/pmu_regs.h @@ -0,0 +1,388 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_PMU_REGS_H_ +#define _MXC_PMU_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t dscadr; /* 0x0000 PMU Channel Next Descriptor Address */ + __IO uint32_t cfg; /* 0x0004 PMU Channel Configuration */ + __IO uint32_t loop; /* 0x0008 PMU Channel Loop Counters */ + __I uint32_t rsv00C[5]; /* 0x000C-0x001C */ +} mxc_pmu_regs_t; + + +/* + Register offsets for module PMU. +*/ + +#define MXC_R_PMU_OFFS_DSCADR ((uint32_t)0x00000000UL) +#define MXC_R_PMU_OFFS_CFG ((uint32_t)0x00000004UL) +#define MXC_R_PMU_OFFS_LOOP ((uint32_t)0x00000008UL) + + +/* + Field positions and masks for module PMU. +*/ + +#define MXC_F_PMU_CFG_ENABLE_POS 0 +#define MXC_F_PMU_CFG_ENABLE ((uint32_t)(0x00000001UL << MXC_F_PMU_CFG_ENABLE_POS)) +#define MXC_F_PMU_CFG_LL_STOPPED_POS 2 +#define MXC_F_PMU_CFG_LL_STOPPED ((uint32_t)(0x00000001UL << MXC_F_PMU_CFG_LL_STOPPED_POS)) +#define MXC_F_PMU_CFG_MANUAL_POS 3 +#define MXC_F_PMU_CFG_MANUAL ((uint32_t)(0x00000001UL << MXC_F_PMU_CFG_MANUAL_POS)) +#define MXC_F_PMU_CFG_BUS_ERROR_POS 4 +#define MXC_F_PMU_CFG_BUS_ERROR ((uint32_t)(0x00000001UL << MXC_F_PMU_CFG_BUS_ERROR_POS)) +#define MXC_F_PMU_CFG_TO_STAT_POS 6 +#define MXC_F_PMU_CFG_TO_STAT ((uint32_t)(0x00000001UL << MXC_F_PMU_CFG_TO_STAT_POS)) +#define MXC_F_PMU_CFG_TO_SEL_POS 11 +#define MXC_F_PMU_CFG_TO_SEL ((uint32_t)(0x00000007UL << MXC_F_PMU_CFG_TO_SEL_POS)) +#define MXC_F_PMU_CFG_PS_SEL_POS 14 +#define MXC_F_PMU_CFG_PS_SEL ((uint32_t)(0x00000003UL << MXC_F_PMU_CFG_PS_SEL_POS)) +#define MXC_F_PMU_CFG_INTERRUPT_POS 16 +#define MXC_F_PMU_CFG_INTERRUPT ((uint32_t)(0x00000001UL << MXC_F_PMU_CFG_INTERRUPT_POS)) +#define MXC_F_PMU_CFG_INT_EN_POS 17 +#define MXC_F_PMU_CFG_INT_EN ((uint32_t)(0x00000001UL << MXC_F_PMU_CFG_INT_EN_POS)) +#define MXC_F_PMU_CFG_BURST_SIZE_POS 24 +#define MXC_F_PMU_CFG_BURST_SIZE ((uint32_t)(0x0000001FUL << MXC_F_PMU_CFG_BURST_SIZE_POS)) + +#define MXC_F_PMU_LOOP_COUNTER_0_POS 0 +#define MXC_F_PMU_LOOP_COUNTER_0 ((uint32_t)(0x0000FFFFUL << MXC_F_PMU_LOOP_COUNTER_0_POS)) +#define MXC_F_PMU_LOOP_COUNTER_1_POS 16 +#define MXC_F_PMU_LOOP_COUNTER_1 ((uint32_t)(0x0000FFFFUL << MXC_F_PMU_LOOP_COUNTER_1_POS)) + +/* + Field values +*/ + +#define MXC_V_PMU_CFG_TO_SEL_TICKS_4 ((uint32_t)(0x00000000UL)) +#define MXC_V_PMU_CFG_TO_SEL_TICKS_8 ((uint32_t)(0x00000001UL)) +#define MXC_V_PMU_CFG_TO_SEL_TICKS_16 ((uint32_t)(0x00000002UL)) +#define MXC_V_PMU_CFG_TO_SEL_TICKS_32 ((uint32_t)(0x00000003UL)) +#define MXC_V_PMU_CFG_TO_SEL_TICKS_64 ((uint32_t)(0x00000004UL)) +#define MXC_V_PMU_CFG_TO_SEL_TICKS_128 ((uint32_t)(0x00000005UL)) +#define MXC_V_PMU_CFG_TO_SEL_TICKS_256 ((uint32_t)(0x00000006UL)) +#define MXC_V_PMU_CFG_TO_SEL_TICKS_512 ((uint32_t)(0x00000007UL)) + +#define MXC_V_PMU_CFG_PS_SEL_DISABLE ((uint32_t)(0x00000000UL)) +#define MXC_V_PMU_CFG_PS_SEL_DIV_2_8 ((uint32_t)(0x00000001UL)) +#define MXC_V_PMU_CFG_PS_SEL_DIV_2_16 ((uint32_t)(0x00000002UL)) +#define MXC_V_PMU_CFG_PS_SEL_DIV_2_24 ((uint32_t)(0x00000003UL)) + +/* Op codes */ +#define PMU_MOVE_OP 0 +#define PMU_WRITE_OP 1 +#define PMU_WAIT_OP 2 +#define PMU_JUMP_OP 3 +#define PMU_LOOP_OP 4 +#define PMU_POLL_OP 5 +#define PMU_BRANCH_OP 6 +#define PMU_TRANSFER_OP 7 + +/* Bit values used in all decroptiors */ +#define PMU_NO_INTERRUPT 0 /* Interrupt flag is NOT set at end of channel execution */ +#define PMU_INTERRUPT 1 /* Interrupt flag is set at end of channel execution */ + +#define PMU_NO_STOP 0 /* Do not stop channel after this descriptor ends */ +#define PMU_STOP 1 /* Halt PMU channel after this descriptor ends */ + +/* Interrupt and Stop bit positions */ +#define PMU_INT_POS 3 +#define PMU_STOP_POS 4 + +/* MOVE descriptor bit values */ +#define PMU_MOVE_READ_8_BIT 0 /* Read size = 8 */ +#define PMU_MOVE_READ_16_BIT 1 /* Read size = 16 */ +#define PMU_MOVE_READ_32_BIT 2 /* Read size = 32 */ + +#define PMU_MOVE_READ_NO_INC 0 /* read address not incremented */ +#define PMU_MOVE_READ_INC 1 /* Auto-Increment read address */ + +#define PMU_MOVE_WRITE_8_BIT 0 /* Write Size = 8 */ +#define PMU_MOVE_WRITE_16_BIT 1 /* Write Size = 16 */ +#define PMU_MOVE_WRITE_32_BIT 2 /* Write Size = 32 */ + +#define PMU_MOVE_WRITE_NO_INC 0 /* Write address not incremented */ +#define PMU_MOVE_WRITE_INC 1 /* Auto_Increment write address */ + +#define PMU_MOVE_NO_CONT 0 /* MOVE does not rely on previous MOVE */ +#define PMU_MOVE_CONT 1 /* MOVE continues from read/write address */ + /* and INC values defined in previous MOVE */ + +/* MOVE bit positions */ +#define PMU_MOVE_READS_POS 5 +#define PMU_MOVE_READI_POS 7 +#define PMU_MOVE_WRITES_POS 8 +#define PMU_MOVE_WRITEI_POS 10 +#define PMU_MOVE_CONT_POS 11 +#define PMU_MOVE_LEN_POS 12 + +/* WRITE descriptor bit values */ +#define PMU_WRITE_MASKED_WRITE_VALUE 0 /* Value = READ_VALUE & (~WRITE_MASK) | WRITE_VALUE */ +#define PMU_WRITE_PLUS_1 1 /* Value = READ_VALUE + 1 */ +#define PMU_WRITE_MINUS_1 2 /* Value = READ_VALUE - 1 */ +#define PMU_WRITE_SHIFT_RT_1 3 /* Value = READ_VALUE >> 1 */ +#define PMU_WRITE_SHIFT_LT_1 4 /* Value = READ_VALUE << 1 */ +#define PMU_WRITE_ROTATE_RT_1 5 /* Value = READ_VALUE rotated right by 1 (bit 0 becomes bit 31) */ +#define PMU_WRITE_ROTATE_LT_1 6 /* Value = READ_VALUE rotated left by 1 (bit 31 becomes bit 0) */ +#define PMU_WRITE_NOT_READ_VAL 7 /* Value = ~READ_VALUE */ +#define PMU_WRITE_XOR_MASK 8 /* Value = READ_VALUE XOR WRITE_MASK */ +#define PMU_WRITE_OR_MASK 9 /* Value = READ_VALUE | WRITE_MASK */ +#define PMU_WRITE_AND_MASK 10 /* Value = READ_VALUE & WRITE_MASK */ + +/* WRITE bit positions */ +#define PMU_WRITE_METHOD_POS 8 + +/* WAIT descriptor bit values */ +#define PMU_WAIT_SEL_0 0 /* Select the interrupt source */ +#define PMU_WAIT_SEL_1 1 + +/* WAIT bit positions */ +#define PMU_WAIT_WAIT_POS 5 +#define PMU_WAIT_SEL_POS 6 + +/* LOOP descriptor bit values */ +#define PMU_LOOP_SEL_COUNTER0 0 /* select Counter0 to count down from */ +#define PMU_LOOP_SEL_COUNTER1 1 /* select Counter1 to count down from */ + +/* LOOP bit positions */ +#define PMU_LOOP_SEL_COUNTER_POS 5 + +/* POLL descriptor bit values */ +#define PMU_POLL_OR 0 /* polling ends when at least one mask bit matches expected data */ +#define PMU_POLL_AND 1 /* polling ends when all mask bits matches expected data */ + +/* POLL bit positions */ +#define PMU_POLL_AND_POS 7 + +/* BRANCH descriptor bit values */ +#define PMU_BRANCH_OR 0 /* branch when any mask bit = or != expected data (based on = or != branch type) */ +#define PMU_BRANCH_AND 1 /* branch when all mask bit = or != expected data (based on = or != branch type) */ + +#define PMU_BRANCH_TYPE_NOT_EQUAL 0 /* Branch when polled data != expected data */ +#define PMU_BRANCH_TYPE_EQUAL 1 /* Branch when polled data = expected data */ +#define PMU_BRANCH_TYPE_LESS_OR_EQUAL 2 /* Branch when polled data <= expected data */ +#define PMU_BRANCH_TYPE_GREAT_OR_EQUAL 3 /* Branch when polled data >= expected data */ +#define PMU_BRANCH_TYPE_LESSER 4 /* Branch when polled data < expected data */ +#define PMU_BRANCH_TYPE_GREATER 5 /* Branch when polled data > expected data */ + +/* BRANCH bit positions */ +#define PMU_BRANCH_AND_POS 7 +#define PMU_BRANCH_TYPE_POS 8 + +/* TRANSFER descriptor bit values */ +#define PMU_TX_READ_8_BIT 0 /* Read size = 8 */ +#define PMU_TX_READ_16_BIT 1 /* Read size = 16 */ +#define PMU_TX_READ_32_BIT 2 /* Read size = 32 */ + +#define PMU_TX_READ_NO_INC 0 /* read address not incremented */ +#define PMU_TX_READ_INC 1 /* Auto-Increment read address */ + +#define PMU_TX_WRITE_8_BIT 0 /* Write Size = 8 */ +#define PMU_TX_WRITE_16_BIT 1 /* Write Size = 16 */ +#define PMU_TX_WRITE_32_BIT 2 /* Write Size = 32 */ + +#define PMU_TX_WRITE_NO_INC 0 /* Write address not incremented */ +#define PMU_TX_WRITE_INC 1 /* Auto_Increment write address */ + +/* TRANSFER bit positions */ +#define PMU_TX_READS_POS 5 +#define PMU_TX_READI_POS 7 +#define PMU_TX_WRITES_POS 8 +#define PMU_TX_WRITEI_POS 10 +#define PMU_TX_LEN_POS 12 +#define PMU_TX_BS_POS 26 + +/* PMU interrupt sources for the WAIT opcode */ +#define PMU_WAIT_IRQ_MASK1_SEL0_UART0_TX_FIFO_AE ((uint32_t)(0x00000001UL << 0)) +#define PMU_WAIT_IRQ_MASK1_SEL0_UART0_RX_FIFO_AF ((uint32_t)(0x00000001UL << 1)) +#define PMU_WAIT_IRQ_MASK1_SEL0_UART1_TX_FIFO_AE ((uint32_t)(0x00000001UL << 2)) +#define PMU_WAIT_IRQ_MASK1_SEL0_UART1_RX_FIFO_AF ((uint32_t)(0x00000001UL << 3)) +#define PMU_WAIT_IRQ_MASK1_SEL0_UART2_TX_FIFO_AE ((uint32_t)(0x00000001UL << 4)) +#define PMU_WAIT_IRQ_MASK1_SEL0_UART2_RX_FIFO_AF ((uint32_t)(0x00000001UL << 5)) +#define PMU_WAIT_IRQ_MASK1_SEL0_UART3_TX_FIFO_AE ((uint32_t)(0x00000001UL << 6)) +#define PMU_WAIT_IRQ_MASK1_SEL0_UART3_RX_FIFO_AF ((uint32_t)(0x00000001UL << 7)) +#define PMU_WAIT_IRQ_MASK1_SEL0_SPI0_TX_FIFO_AE ((uint32_t)(0x00000001UL << 8)) +#define PMU_WAIT_IRQ_MASK1_SEL0_SPI0_RX_FIFO_AF ((uint32_t)(0x00000001UL << 9)) +#define PMU_WAIT_IRQ_MASK1_SEL0_SPI1_TX_FIFO_AE ((uint32_t)(0x00000001UL << 10)) +#define PMU_WAIT_IRQ_MASK1_SEL0_SPI1_RX_FIFO_AF ((uint32_t)(0x00000001UL << 11)) +#define PMU_WAIT_IRQ_MASK1_SEL0_SPI2_TX_FIFO_AE ((uint32_t)(0x00000001UL << 12)) +#define PMU_WAIT_IRQ_MASK1_SEL0_SPI2_RX_FIFO_AF ((uint32_t)(0x00000001UL << 13)) +#define PMU_WAIT_IRQ_MASK1_SEL0_I2CM0_TX_FIFO_EMPTY ((uint32_t)(0x00000001UL << 14)) +#define PMU_WAIT_IRQ_MASK1_SEL0_I2CM0_RX_FIFO_NOT_EMPTY ((uint32_t)(0x00000001UL << 15)) +#define PMU_WAIT_IRQ_MASK1_SEL0_I2CM1_TX_FIFO_EMPTY ((uint32_t)(0x00000001UL << 16)) +#define PMU_WAIT_IRQ_MASK1_SEL0_I2CM1_RX_FIFO_NOT_EMPTY ((uint32_t)(0x00000001UL << 17)) +#define PMU_WAIT_IRQ_MASK1_SEL0_I2CM2_TX_FIFO_EMPTY ((uint32_t)(0x00000001UL << 18)) +#define PMU_WAIT_IRQ_MASK1_SEL0_I2CM2_RX_FIFO_NOT_EMPTY ((uint32_t)(0x00000001UL << 19)) +#define PMU_WAIT_IRQ_MASK1_SEL0_SPI0_TX_RX_STALLED ((uint32_t)(0x00000001UL << 20)) +#define PMU_WAIT_IRQ_MASK1_SEL0_SPI1_TX_RX_STALLED ((uint32_t)(0x00000001UL << 21)) +#define PMU_WAIT_IRQ_MASK1_SEL0_SPI2_TX_RX_STALLED ((uint32_t)(0x00000001UL << 22)) +#define PMU_WAIT_IRQ_MASK1_SEL0_SPIB ((uint32_t)(0x00000001UL << 23)) +#define PMU_WAIT_IRQ_MASK1_SEL0_I2CM0_DONE ((uint32_t)(0x00000001UL << 24)) +#define PMU_WAIT_IRQ_MASK1_SEL0_I2CM1_DONE ((uint32_t)(0x00000001UL << 25)) +#define PMU_WAIT_IRQ_MASK1_SEL0_I2CM2_DONE ((uint32_t)(0x00000001UL << 26)) +#define PMU_WAIT_IRQ_MASK1_SEL0_I2CS ((uint32_t)(0x00000001UL << 27)) +#define PMU_WAIT_IRQ_MASK1_SEL0_ADC_DONE ((uint32_t)(0x00000001UL << 28)) +#define PMU_WAIT_IRQ_MASK1_SEL0_ADC_READY ((uint32_t)(0x00000001UL << 29)) +#define PMU_WAIT_IRQ_MASK1_SEL0_ADC_HI ((uint32_t)(0x00000001UL << 30)) +#define PMU_WAIT_IRQ_MASK1_SEL0_ADC_LOW ((uint32_t)(0x00000001UL << 31)) +#define PMU_WAIT_IRQ_MASK2_SEL0_RTC_COMP0 ((uint32_t)(0x00000001UL << 0)) +#define PMU_WAIT_IRQ_MASK2_SEL0_RTC_COMP1 ((uint32_t)(0x00000001UL << 1)) +#define PMU_WAIT_IRQ_MASK2_SEL0_RTC_PRESCALE ((uint32_t)(0x00000001UL << 2)) +#define PMU_WAIT_IRQ_MASK2_SEL0_RTC_OVERFLOW ((uint32_t)(0x00000001UL << 3)) +#define PMU_WAIT_IRQ_MASK2_SEL0_PT0_DISABLED ((uint32_t)(0x00000001UL << 4)) +#define PMU_WAIT_IRQ_MASK2_SEL0_PT1_DISABLED ((uint32_t)(0x00000001UL << 5)) +#define PMU_WAIT_IRQ_MASK2_SEL0_PT2_DISABLED ((uint32_t)(0x00000001UL << 6)) +#define PMU_WAIT_IRQ_MASK2_SEL0_PT3_DISABLED ((uint32_t)(0x00000001UL << 7)) +#define PMU_WAIT_IRQ_MASK2_SEL0_PT4_DISABLED ((uint32_t)(0x00000001UL << 8)) +#define PMU_WAIT_IRQ_MASK2_SEL0_PT5_DISABLED ((uint32_t)(0x00000001UL << 9)) +#define PMU_WAIT_IRQ_MASK2_SEL0_PT6_DISABLED ((uint32_t)(0x00000001UL << 10)) +#define PMU_WAIT_IRQ_MASK2_SEL0_PT7_DISABLED ((uint32_t)(0x00000001UL << 11)) +#define PMU_WAIT_IRQ_MASK2_SEL0_PT8_DISABLED ((uint32_t)(0x00000001UL << 12)) +#define PMU_WAIT_IRQ_MASK2_SEL0_PT9_DISABLED ((uint32_t)(0x00000001UL << 13)) +#define PMU_WAIT_IRQ_MASK2_SEL0_PT10_DISABLED ((uint32_t)(0x00000001UL << 14)) +#define PMU_WAIT_IRQ_MASK2_SEL0_PT11_DISABLED ((uint32_t)(0x00000001UL << 15)) +#define PMU_WAIT_IRQ_MASK2_SEL0_TMR0 ((uint32_t)(0x00000001UL << 16)) +#define PMU_WAIT_IRQ_MASK2_SEL0_TMR1 ((uint32_t)(0x00000001UL << 17)) +#define PMU_WAIT_IRQ_MASK2_SEL0_TMR2 ((uint32_t)(0x00000001UL << 18)) +#define PMU_WAIT_IRQ_MASK2_SEL0_TMR3 ((uint32_t)(0x00000001UL << 19)) +#define PMU_WAIT_IRQ_MASK2_SEL0_TMR4 ((uint32_t)(0x00000001UL << 20)) +#define PMU_WAIT_IRQ_MASK2_SEL0_TMR5 ((uint32_t)(0x00000001UL << 21)) +#define PMU_WAIT_IRQ_MASK2_SEL0_GPIO0 ((uint32_t)(0x00000001UL << 22)) +#define PMU_WAIT_IRQ_MASK2_SEL0_GPIO1 ((uint32_t)(0x00000001UL << 23)) +#define PMU_WAIT_IRQ_MASK2_SEL0_GPIO2 ((uint32_t)(0x00000001UL << 24)) +#define PMU_WAIT_IRQ_MASK2_SEL0_GPIO3 ((uint32_t)(0x00000001UL << 25)) +#define PMU_WAIT_IRQ_MASK2_SEL0_GPIO4 ((uint32_t)(0x00000001UL << 26)) +#define PMU_WAIT_IRQ_MASK2_SEL0_GPIO5 ((uint32_t)(0x00000001UL << 27)) +#define PMU_WAIT_IRQ_MASK2_SEL0_GPIO6 ((uint32_t)(0x00000001UL << 28)) +#define PMU_WAIT_IRQ_MASK2_SEL0_AES ((uint32_t)(0x00000001UL << 29)) +#define PMU_WAIT_IRQ_MASK2_SEL0_MAA_DONE ((uint32_t)(0x00000001UL << 30)) +#define PMU_WAIT_IRQ_MASK2_SEL0_OWM ((uint32_t)(0x00000001UL << 31)) +#define PMU_WAIT_IRQ_MASK1_SEL1_GPIO7 ((uint32_t)(0x00000001UL << 0)) +#define PMU_WAIT_IRQ_MASK1_SEL1_GPIO8 ((uint32_t)(0x00000001UL << 1)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT12_DISABLED ((uint32_t)(0x00000001UL << 2)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT13_DISABLED ((uint32_t)(0x00000001UL << 3)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT14_DISABLED ((uint32_t)(0x00000001UL << 4)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT15_DISABLED ((uint32_t)(0x00000001UL << 5)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT0_INT ((uint32_t)(0x00000001UL << 6)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT1_INT ((uint32_t)(0x00000001UL << 7)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT2_INT ((uint32_t)(0x00000001UL << 8)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT3_INT ((uint32_t)(0x00000001UL << 9)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT4_INT ((uint32_t)(0x00000001UL << 10)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT5_INT ((uint32_t)(0x00000001UL << 11)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT6_INT ((uint32_t)(0x00000001UL << 12)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT7_INT ((uint32_t)(0x00000001UL << 13)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT8_INT ((uint32_t)(0x00000001UL << 14)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT9_INT ((uint32_t)(0x00000001UL << 15)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT10_INT ((uint32_t)(0x00000001UL << 16)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT11_INT ((uint32_t)(0x00000001UL << 17)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT12_INT ((uint32_t)(0x00000001UL << 18)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT13_INT ((uint32_t)(0x00000001UL << 19)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT14_INT ((uint32_t)(0x00000001UL << 20)) +#define PMU_WAIT_IRQ_MASK1_SEL1_PT15_INT ((uint32_t)(0x00000001UL << 21)) +#define PMU_WAIT_IRQ_MASK1_SEL1_SPIS_TX_FIFO_AE ((uint32_t)(0x00000001UL << 22)) +#define PMU_WAIT_IRQ_MASK1_SEL1_SPIS_RX_FIFO_AF ((uint32_t)(0x00000001UL << 23)) +#define PMU_WAIT_IRQ_MASK1_SEL1_SPIS_TX_NO_DATA ((uint32_t)(0x00000001UL << 24)) +#define PMU_WAIT_IRQ_MASK1_SEL1_SPIS_RX_DATA_LOST ((uint32_t)(0x00000001UL << 25)) +#define PMU_WAIT_IRQ_MASK1_SEL1_SPI0_TX_READY ((uint32_t)(0x00000001UL << 26)) +#define PMU_WAIT_IRQ_MASK1_SEL1_SPI1_TX_READY ((uint32_t)(0x00000001UL << 27)) +#define PMU_WAIT_IRQ_MASK1_SEL1_SPI2_TX_READY ((uint32_t)(0x00000001UL << 28)) +#define PMU_WAIT_IRQ_MASK1_SEL1_UART0_TX_DONE ((uint32_t)(0x00000001UL << 29)) +#define PMU_WAIT_IRQ_MASK1_SEL1_UART1_TX_DONE ((uint32_t)(0x00000001UL << 30)) +#define PMU_WAIT_IRQ_MASK1_SEL1_UART2_TX_DONE ((uint32_t)(0x00000001UL << 31)) +#define PMU_WAIT_IRQ_MASK2_SEL1_UART3_TX_DONE ((uint32_t)(0x00000001UL << 0)) +#define PMU_WAIT_IRQ_MASK2_SEL1_UART0_RX_DATA_READY ((uint32_t)(0x00000001UL << 1)) +#define PMU_WAIT_IRQ_MASK2_SEL1_UART1_RX_DATA_READY ((uint32_t)(0x00000001UL << 2)) +#define PMU_WAIT_IRQ_MASK2_SEL1_UART2_RX_DATA_READY ((uint32_t)(0x00000001UL << 3)) +#define PMU_WAIT_IRQ_MASK2_SEL1_UART3_RX_DATA_READY ((uint32_t)(0x00000001UL << 4)) + +/* PMU interrupt sources for the TRANSFER opcode */ +#define PMU_TRANSFER_IRQ_UART0_TX_FIFO_AE ((uint32_t)(0x00000001UL << 0)) +#define PMU_TRANSFER_IRQ_UART0_RX_FIFO_AF ((uint32_t)(0x00000001UL << 1)) +#define PMU_TRANSFER_IRQ_UART1_TX_FIFO_AE ((uint32_t)(0x00000001UL << 2)) +#define PMU_TRANSFER_IRQ_UART1_RX_FIFO_AF ((uint32_t)(0x00000001UL << 3)) +#define PMU_TRANSFER_IRQ_UART2_TX_FIFO_AE ((uint32_t)(0x00000001UL << 4)) +#define PMU_TRANSFER_IRQ_UART2_RX_FIFO_AF ((uint32_t)(0x00000001UL << 5)) +#define PMU_TRANSFER_IRQ_UART3_TX_FIFO_AE ((uint32_t)(0x00000001UL << 6)) +#define PMU_TRANSFER_IRQ_UART3_RX_FIFO_AF ((uint32_t)(0x00000001UL << 7)) +#define PMU_TRANSFER_IRQ_SPI0_TX_FIFO_AE ((uint32_t)(0x00000001UL << 8)) +#define PMU_TRANSFER_IRQ_SPI0_RX_FIFO_AF ((uint32_t)(0x00000001UL << 9)) +#define PMU_TRANSFER_IRQ_SPI1_TX_FIFO_AE ((uint32_t)(0x00000001UL << 10)) +#define PMU_TRANSFER_IRQ_SPI1_RX_FIFO_AF ((uint32_t)(0x00000001UL << 11)) +#define PMU_TRANSFER_IRQ_SPI2_TX_FIFO_AE ((uint32_t)(0x00000001UL << 12)) +#define PMU_TRANSFER_IRQ_SPI2_RX_FIFO_AF ((uint32_t)(0x00000001UL << 13)) +#define PMU_TRANSFER_IRQ_I2CM0_TX_FIFO_EMPTY ((uint32_t)(0x00000001UL << 14)) +#define PMU_TRANSFER_IRQ_I2CM0_RX_FIFO_NOT_EMPTY ((uint32_t)(0x00000001UL << 15)) +#define PMU_TRANSFER_IRQ_I2CM0_RX_FIFO_FULL ((uint32_t)(0x00000001UL << 16)) +#define PMU_TRANSFER_IRQ_I2CM1_TX_FIFO_EMPTY ((uint32_t)(0x00000001UL << 17)) +#define PMU_TRANSFER_IRQ_I2CM1_RX_FIFO_NOT_EMPTY ((uint32_t)(0x00000001UL << 18)) +#define PMU_TRANSFER_IRQ_I2CM1_RX_FIFO_FULL ((uint32_t)(0x00000001UL << 19)) +#define PMU_TRANSFER_IRQ_I2CM2_TX_FIFO_EMPTY ((uint32_t)(0x00000001UL << 20)) +#define PMU_TRANSFER_IRQ_I2CM2_RX_FIFO_NOT_EMPTY ((uint32_t)(0x00000001UL << 21)) +#define PMU_TRANSFER_IRQ_I2CM2_RX_FIFO_FULL ((uint32_t)(0x00000001UL << 22)) +#define PMU_TRANSFER_IRQ_SPIS_TX_FIFO_AE ((uint32_t)(0x00000001UL << 23)) +#define PMU_TRANSFER_IRQ_SPIS_RX_FIFO_AF ((uint32_t)(0x00000001UL << 24)) + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_PMU_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/prng_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/prng_regs.h new file mode 100644 index 00000000000..eedec6e180c --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/prng_regs.h @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_PRNG_REGS_H_ +#define _MXC_PRNG_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t user_entropy; /* 0x0000 PRNG User Entropy and Status */ + __IO uint32_t rnd_num; /* 0x0004 PRNG Seed Output */ +} mxc_prng_regs_t; + +/* + Register offsets for module PRNG. +*/ + +#define MXC_R_PRNG_OFFS_USER_ENTROPY ((uint32_t)0x00000000UL) +#define MXC_R_PRNG_OFFS_RND_NUM ((uint32_t)0x00000004UL) + +/* + Field positions and masks for module PRNG. +*/ + +#define MXC_F_PRNG_USER_ENTROPY_VALUE_POS 0 +#define MXC_F_PRNG_USER_ENTROPY_VALUE ((uint32_t)(0x000000FFUL << MXC_F_PRNG_USER_ENTROPY_VALUE_POS)) +#define MXC_F_PRNG_USER_ENTROPY_RND_NUM_READY_POS 8 +#define MXC_F_PRNG_USER_ENTROPY_RND_NUM_READY ((uint32_t)(0x00000001UL << MXC_F_PRNG_USER_ENTROPY_RND_NUM_READY_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_PRNG_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/pt_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/pt_regs.h new file mode 100644 index 00000000000..12692ca96f5 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/pt_regs.h @@ -0,0 +1,330 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_PT_REGS_H_ +#define _MXC_PT_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t enable; /* 0x0000 Global Enable/Disable Controls for All Pulse Trains */ + __IO uint32_t resync; /* 0x0004 Global Resync (All Pulse Trains) Control */ + __IO uint32_t intfl; /* 0x0008 Pulse Train Interrupt Flags */ + __IO uint32_t inten; /* 0x000C Pulse Train Interrupt Enable/Disable */ +} mxc_ptg_regs_t; + + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t rate_length; /* 0x0000 Pulse Train Configuration */ + __IO uint32_t train; /* 0x0004 Pulse Train Output Pattern */ + __IO uint32_t loop; /* 0x0008 Pulse Train Loop Configuration */ + __IO uint32_t restart; /* 0x000C Pulse Train Auto-Restart Configuration */ +} mxc_pt_regs_t; + + +/* + Register offsets for module PT. +*/ + +#define MXC_R_PTG_OFFS_ENABLE ((uint32_t)0x00000000UL) +#define MXC_R_PTG_OFFS_RESYNC ((uint32_t)0x00000004UL) +#define MXC_R_PTG_OFFS_INTFL ((uint32_t)0x00000008UL) +#define MXC_R_PTG_OFFS_INTEN ((uint32_t)0x0000000CUL) +#define MXC_R_PT_OFFS_RATE_LENGTH ((uint32_t)0x00000000UL) +#define MXC_R_PT_OFFS_TRAIN ((uint32_t)0x00000004UL) +#define MXC_R_PT_OFFS_LOOP ((uint32_t)0x00000008UL) +#define MXC_R_PT_OFFS_RESTART ((uint32_t)0x0000000CUL) + + +/* + Field positions and masks for module PT. +*/ + +#define MXC_F_PT_ENABLE_PT0_POS 0 +#define MXC_F_PT_ENABLE_PT0 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT0_POS)) +#define MXC_F_PT_ENABLE_PT1_POS 1 +#define MXC_F_PT_ENABLE_PT1 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT1_POS)) +#define MXC_F_PT_ENABLE_PT2_POS 2 +#define MXC_F_PT_ENABLE_PT2 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT2_POS)) +#define MXC_F_PT_ENABLE_PT3_POS 3 +#define MXC_F_PT_ENABLE_PT3 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT3_POS)) +#define MXC_F_PT_ENABLE_PT4_POS 4 +#define MXC_F_PT_ENABLE_PT4 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT4_POS)) +#define MXC_F_PT_ENABLE_PT5_POS 5 +#define MXC_F_PT_ENABLE_PT5 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT5_POS)) +#define MXC_F_PT_ENABLE_PT6_POS 6 +#define MXC_F_PT_ENABLE_PT6 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT6_POS)) +#define MXC_F_PT_ENABLE_PT7_POS 7 +#define MXC_F_PT_ENABLE_PT7 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT7_POS)) +#define MXC_F_PT_ENABLE_PT8_POS 8 +#define MXC_F_PT_ENABLE_PT8 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT8_POS)) +#define MXC_F_PT_ENABLE_PT9_POS 9 +#define MXC_F_PT_ENABLE_PT9 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT9_POS)) +#define MXC_F_PT_ENABLE_PT10_POS 10 +#define MXC_F_PT_ENABLE_PT10 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT10_POS)) +#define MXC_F_PT_ENABLE_PT11_POS 11 +#define MXC_F_PT_ENABLE_PT11 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT11_POS)) +#define MXC_F_PT_ENABLE_PT12_POS 12 +#define MXC_F_PT_ENABLE_PT12 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT12_POS)) +#define MXC_F_PT_ENABLE_PT13_POS 13 +#define MXC_F_PT_ENABLE_PT13 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT13_POS)) +#define MXC_F_PT_ENABLE_PT14_POS 14 +#define MXC_F_PT_ENABLE_PT14 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT14_POS)) +#define MXC_F_PT_ENABLE_PT15_POS 15 +#define MXC_F_PT_ENABLE_PT15 ((uint32_t)(0x00000001UL << MXC_F_PT_ENABLE_PT15_POS)) + +#define MXC_F_PT_RESYNC_PT0_POS 0 +#define MXC_F_PT_RESYNC_PT0 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT0_POS)) +#define MXC_F_PT_RESYNC_PT1_POS 1 +#define MXC_F_PT_RESYNC_PT1 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT1_POS)) +#define MXC_F_PT_RESYNC_PT2_POS 2 +#define MXC_F_PT_RESYNC_PT2 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT2_POS)) +#define MXC_F_PT_RESYNC_PT3_POS 3 +#define MXC_F_PT_RESYNC_PT3 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT3_POS)) +#define MXC_F_PT_RESYNC_PT4_POS 4 +#define MXC_F_PT_RESYNC_PT4 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT4_POS)) +#define MXC_F_PT_RESYNC_PT5_POS 5 +#define MXC_F_PT_RESYNC_PT5 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT5_POS)) +#define MXC_F_PT_RESYNC_PT6_POS 6 +#define MXC_F_PT_RESYNC_PT6 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT6_POS)) +#define MXC_F_PT_RESYNC_PT7_POS 7 +#define MXC_F_PT_RESYNC_PT7 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT7_POS)) +#define MXC_F_PT_RESYNC_PT8_POS 8 +#define MXC_F_PT_RESYNC_PT8 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT8_POS)) +#define MXC_F_PT_RESYNC_PT9_POS 9 +#define MXC_F_PT_RESYNC_PT9 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT9_POS)) +#define MXC_F_PT_RESYNC_PT10_POS 10 +#define MXC_F_PT_RESYNC_PT10 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT10_POS)) +#define MXC_F_PT_RESYNC_PT11_POS 11 +#define MXC_F_PT_RESYNC_PT11 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT11_POS)) +#define MXC_F_PT_RESYNC_PT12_POS 12 +#define MXC_F_PT_RESYNC_PT12 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT12_POS)) +#define MXC_F_PT_RESYNC_PT13_POS 13 +#define MXC_F_PT_RESYNC_PT13 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT13_POS)) +#define MXC_F_PT_RESYNC_PT14_POS 14 +#define MXC_F_PT_RESYNC_PT14 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT14_POS)) +#define MXC_F_PT_RESYNC_PT15_POS 15 +#define MXC_F_PT_RESYNC_PT15 ((uint32_t)(0x00000001UL << MXC_F_PT_RESYNC_PT15_POS)) + +#define MXC_F_PT_INTFL_PT0_POS 0 +#define MXC_F_PT_INTFL_PT0 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT0_POS)) +#define MXC_F_PT_INTFL_PT1_POS 1 +#define MXC_F_PT_INTFL_PT1 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT1_POS)) +#define MXC_F_PT_INTFL_PT2_POS 2 +#define MXC_F_PT_INTFL_PT2 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT2_POS)) +#define MXC_F_PT_INTFL_PT3_POS 3 +#define MXC_F_PT_INTFL_PT3 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT3_POS)) +#define MXC_F_PT_INTFL_PT4_POS 4 +#define MXC_F_PT_INTFL_PT4 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT4_POS)) +#define MXC_F_PT_INTFL_PT5_POS 5 +#define MXC_F_PT_INTFL_PT5 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT5_POS)) +#define MXC_F_PT_INTFL_PT6_POS 6 +#define MXC_F_PT_INTFL_PT6 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT6_POS)) +#define MXC_F_PT_INTFL_PT7_POS 7 +#define MXC_F_PT_INTFL_PT7 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT7_POS)) +#define MXC_F_PT_INTFL_PT8_POS 8 +#define MXC_F_PT_INTFL_PT8 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT8_POS)) +#define MXC_F_PT_INTFL_PT9_POS 9 +#define MXC_F_PT_INTFL_PT9 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT9_POS)) +#define MXC_F_PT_INTFL_PT10_POS 10 +#define MXC_F_PT_INTFL_PT10 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT10_POS)) +#define MXC_F_PT_INTFL_PT11_POS 11 +#define MXC_F_PT_INTFL_PT11 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT11_POS)) +#define MXC_F_PT_INTFL_PT12_POS 12 +#define MXC_F_PT_INTFL_PT12 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT12_POS)) +#define MXC_F_PT_INTFL_PT13_POS 13 +#define MXC_F_PT_INTFL_PT13 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT13_POS)) +#define MXC_F_PT_INTFL_PT14_POS 14 +#define MXC_F_PT_INTFL_PT14 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT14_POS)) +#define MXC_F_PT_INTFL_PT15_POS 15 +#define MXC_F_PT_INTFL_PT15 ((uint32_t)(0x00000001UL << MXC_F_PT_INTFL_PT15_POS)) + +#define MXC_F_PT_INTEN_PT0_POS 0 +#define MXC_F_PT_INTEN_PT0 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT0_POS)) +#define MXC_F_PT_INTEN_PT1_POS 1 +#define MXC_F_PT_INTEN_PT1 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT1_POS)) +#define MXC_F_PT_INTEN_PT2_POS 2 +#define MXC_F_PT_INTEN_PT2 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT2_POS)) +#define MXC_F_PT_INTEN_PT3_POS 3 +#define MXC_F_PT_INTEN_PT3 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT3_POS)) +#define MXC_F_PT_INTEN_PT4_POS 4 +#define MXC_F_PT_INTEN_PT4 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT4_POS)) +#define MXC_F_PT_INTEN_PT5_POS 5 +#define MXC_F_PT_INTEN_PT5 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT5_POS)) +#define MXC_F_PT_INTEN_PT6_POS 6 +#define MXC_F_PT_INTEN_PT6 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT6_POS)) +#define MXC_F_PT_INTEN_PT7_POS 7 +#define MXC_F_PT_INTEN_PT7 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT7_POS)) +#define MXC_F_PT_INTEN_PT8_POS 8 +#define MXC_F_PT_INTEN_PT8 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT8_POS)) +#define MXC_F_PT_INTEN_PT9_POS 9 +#define MXC_F_PT_INTEN_PT9 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT9_POS)) +#define MXC_F_PT_INTEN_PT10_POS 10 +#define MXC_F_PT_INTEN_PT10 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT10_POS)) +#define MXC_F_PT_INTEN_PT11_POS 11 +#define MXC_F_PT_INTEN_PT11 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT11_POS)) +#define MXC_F_PT_INTEN_PT12_POS 12 +#define MXC_F_PT_INTEN_PT12 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT12_POS)) +#define MXC_F_PT_INTEN_PT13_POS 13 +#define MXC_F_PT_INTEN_PT13 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT13_POS)) +#define MXC_F_PT_INTEN_PT14_POS 14 +#define MXC_F_PT_INTEN_PT14 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT14_POS)) +#define MXC_F_PT_INTEN_PT15_POS 15 +#define MXC_F_PT_INTEN_PT15 ((uint32_t)(0x00000001UL << MXC_F_PT_INTEN_PT15_POS)) + +#define MXC_F_PT_RATE_LENGTH_RATE_CONTROL_POS 0 +#define MXC_F_PT_RATE_LENGTH_RATE_CONTROL ((uint32_t)(0x07FFFFFFUL << MXC_F_PT_RATE_LENGTH_RATE_CONTROL_POS)) +#define MXC_F_PT_RATE_LENGTH_MODE_POS 27 +#define MXC_F_PT_RATE_LENGTH_MODE ((uint32_t)(0x0000001FUL << MXC_F_PT_RATE_LENGTH_MODE_POS)) + +#define MXC_F_PT_LOOP_COUNT_POS 0 +#define MXC_F_PT_LOOP_COUNT ((uint32_t)(0x0000FFFFUL << MXC_F_PT_LOOP_COUNT_POS)) +#define MXC_F_PT_LOOP_DELAY_POS 16 +#define MXC_F_PT_LOOP_DELAY ((uint32_t)(0x00000FFFUL << MXC_F_PT_LOOP_DELAY_POS)) + +#define MXC_F_PT_RESTART_PT_X_SELECT_POS 0 +#define MXC_F_PT_RESTART_PT_X_SELECT ((uint32_t)(0x0000001FUL << MXC_F_PT_RESTART_PT_X_SELECT_POS)) +#define MXC_F_PT_RESTART_ON_PT_X_LOOP_EXIT_POS 7 +#define MXC_F_PT_RESTART_ON_PT_X_LOOP_EXIT ((uint32_t)(0x00000001UL << MXC_F_PT_RESTART_ON_PT_X_LOOP_EXIT_POS)) +#define MXC_F_PT_RESTART_PT_Y_SELECT_POS 8 +#define MXC_F_PT_RESTART_PT_Y_SELECT ((uint32_t)(0x0000001FUL << MXC_F_PT_RESTART_PT_Y_SELECT_POS)) +#define MXC_F_PT_RESTART_ON_PT_Y_LOOP_EXIT_POS 15 +#define MXC_F_PT_RESTART_ON_PT_Y_LOOP_EXIT ((uint32_t)(0x00000001UL << MXC_F_PT_RESTART_ON_PT_Y_LOOP_EXIT_POS)) + + + +/* + Field values and shifted values for module PT. +*/ + +#define MXC_V_PT_RATE_LENGTH_MODE_32_BIT ((uint32_t)(0x00000000UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_SQUARE_WAVE ((uint32_t)(0x00000001UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_2_BIT ((uint32_t)(0x00000002UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_3_BIT ((uint32_t)(0x00000003UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_4_BIT ((uint32_t)(0x00000004UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_5_BIT ((uint32_t)(0x00000005UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_6_BIT ((uint32_t)(0x00000006UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_7_BIT ((uint32_t)(0x00000007UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_8_BIT ((uint32_t)(0x00000008UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_9_BIT ((uint32_t)(0x00000009UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_10_BIT ((uint32_t)(0x0000000AUL)) +#define MXC_V_PT_RATE_LENGTH_MODE_11_BIT ((uint32_t)(0x0000000BUL)) +#define MXC_V_PT_RATE_LENGTH_MODE_12_BIT ((uint32_t)(0x0000000CUL)) +#define MXC_V_PT_RATE_LENGTH_MODE_13_BIT ((uint32_t)(0x0000000DUL)) +#define MXC_V_PT_RATE_LENGTH_MODE_14_BIT ((uint32_t)(0x0000000EUL)) +#define MXC_V_PT_RATE_LENGTH_MODE_15_BIT ((uint32_t)(0x0000000FUL)) +#define MXC_V_PT_RATE_LENGTH_MODE_16_BIT ((uint32_t)(0x00000010UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_17_BIT ((uint32_t)(0x00000011UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_18_BIT ((uint32_t)(0x00000012UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_19_BIT ((uint32_t)(0x00000013UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_20_BIT ((uint32_t)(0x00000014UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_21_BIT ((uint32_t)(0x00000015UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_22_BIT ((uint32_t)(0x00000016UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_23_BIT ((uint32_t)(0x00000017UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_24_BIT ((uint32_t)(0x00000018UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_25_BIT ((uint32_t)(0x00000019UL)) +#define MXC_V_PT_RATE_LENGTH_MODE_26_BIT ((uint32_t)(0x0000001AUL)) +#define MXC_V_PT_RATE_LENGTH_MODE_27_BIT ((uint32_t)(0x0000001BUL)) +#define MXC_V_PT_RATE_LENGTH_MODE_28_BIT ((uint32_t)(0x0000001CUL)) +#define MXC_V_PT_RATE_LENGTH_MODE_29_BIT ((uint32_t)(0x0000001DUL)) +#define MXC_V_PT_RATE_LENGTH_MODE_30_BIT ((uint32_t)(0x0000001EUL)) +#define MXC_V_PT_RATE_LENGTH_MODE_31_BIT ((uint32_t)(0x0000001FUL)) + +#define MXC_S_PT_RATE_LENGTH_MODE_32_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_32_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_SQUARE_WAVE ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_SQUARE_WAVE << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_2_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_2_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_3_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_3_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_4_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_4_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_5_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_5_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_6_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_6_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_7_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_7_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_8_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_8_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_9_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_9_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_10_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_10_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_11_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_11_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_12_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_12_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_13_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_13_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_14_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_14_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_15_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_15_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_16_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_16_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_17_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_17_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_18_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_18_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_19_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_19_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_20_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_20_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_21_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_21_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_22_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_22_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_23_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_23_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_24_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_24_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_25_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_25_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_26_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_26_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_27_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_27_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_28_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_28_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_29_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_29_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_30_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_30_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) +#define MXC_S_PT_RATE_LENGTH_MODE_31_BIT ((uint32_t)(MXC_V_PT_RATE_LENGTH_MODE_31_BIT << MXC_F_PT_RATE_LENGTH_MODE_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_PT_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/pwrman_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/pwrman_regs.h new file mode 100644 index 00000000000..ab4abecd522 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/pwrman_regs.h @@ -0,0 +1,367 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_PWRMAN_REGS_H_ +#define _MXC_PWRMAN_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/** + * @brief Defines PAD Modes for Wake Up Detection. + */ +typedef enum { + /** WUD Mode for Selected PAD = Clear/Activate */ + MXC_E_PWRMAN_PAD_MODE_CLEAR_SET, + /** WUD Mode for Selected PAD = Set WUD Act Hi/Set WUD Act Lo */ + MXC_E_PWRMAN_PAD_MODE_ACT_HI_LO, + /** WUD Mode for Selected PAD = Set Weak Hi/ Set Weak Lo */ + MXC_E_PWRMAN_PAD_MODE_WEAK_HI_LO, + /** WUD Mode for Selected PAD = No pad state change */ + MXC_E_PWRMAN_PAD_MODE_NONE +} mxc_pwrman_pad_mode_t; + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t pwr_rst_ctrl; /* 0x0000 Power Reset Control and Status */ + __IO uint32_t intfl; /* 0x0004 Interrupt Flags */ + __IO uint32_t inten; /* 0x0008 Interrupt Enable/Disable Controls */ + __IO uint32_t svm_events; /* 0x000C SVM Event Status Flags (read-only) */ + __IO uint32_t wud_ctrl; /* 0x0010 Wake-Up Detect Control */ + __IO uint32_t wud_pulse0; /* 0x0014 WUD Pulse To Mode Bit 0 */ + __IO uint32_t wud_pulse1; /* 0x0018 WUD Pulse To Mode Bit 1 */ + __IO uint32_t wud_seen0; /* 0x001C Wake-up Detect Status for P0/P1/P2/P3 */ + __IO uint32_t wud_seen1; /* 0x0020 Wake-up Detect Status for P4/P5/P6/P7 */ + __I uint32_t rsv024[3]; /* 0x0024-0x002C */ + __IO uint32_t pt_regmap_ctrl; /* 0x0030 PT Register Mapping Control */ + __I uint32_t rsv034; /* 0x0034 */ + __IO uint32_t die_type; /* 0x0038 Die Type ID Register */ + __IO uint32_t base_part_num; /* 0x003C Base Part Number */ + __IO uint32_t mask_id0; /* 0x0040 Mask ID Register 0 */ + __IO uint32_t mask_id1; /* 0x0044 Mask ID Register 1 */ + __IO uint32_t peripheral_reset; /* 0x0048 Peripheral Reset Control Register */ +} mxc_pwrman_regs_t; + + +/* + Register offsets for module PWRMAN. +*/ + +#define MXC_R_PWRMAN_OFFS_PWR_RST_CTRL ((uint32_t)0x00000000UL) +#define MXC_R_PWRMAN_OFFS_INTFL ((uint32_t)0x00000004UL) +#define MXC_R_PWRMAN_OFFS_INTEN ((uint32_t)0x00000008UL) +#define MXC_R_PWRMAN_OFFS_SVM_EVENTS ((uint32_t)0x0000000CUL) +#define MXC_R_PWRMAN_OFFS_WUD_CTRL ((uint32_t)0x00000010UL) +#define MXC_R_PWRMAN_OFFS_WUD_PULSE0 ((uint32_t)0x00000014UL) +#define MXC_R_PWRMAN_OFFS_WUD_PULSE1 ((uint32_t)0x00000018UL) +#define MXC_R_PWRMAN_OFFS_WUD_SEEN0 ((uint32_t)0x0000001CUL) +#define MXC_R_PWRMAN_OFFS_WUD_SEEN1 ((uint32_t)0x00000020UL) +#define MXC_R_PWRMAN_OFFS_PT_REGMAP_CTRL ((uint32_t)0x00000030UL) +#define MXC_R_PWRMAN_OFFS_DIE_TYPE ((uint32_t)0x00000038UL) +#define MXC_R_PWRMAN_OFFS_BASE_PART_NUM ((uint32_t)0x0000003CUL) +#define MXC_R_PWRMAN_OFFS_MASK_ID0 ((uint32_t)0x00000040UL) +#define MXC_R_PWRMAN_OFFS_MASK_ID1 ((uint32_t)0x00000044UL) +#define MXC_R_PWRMAN_OFFS_PERIPHERAL_RESET ((uint32_t)0x00000048UL) + + +/* + Field positions and masks for module PWRMAN. +*/ + +#define MXC_F_PWRMAN_PWR_RST_CTRL_AFE_POWERED_POS 2 +#define MXC_F_PWRMAN_PWR_RST_CTRL_AFE_POWERED ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_AFE_POWERED_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_IO_ACTIVE_POS 3 +#define MXC_F_PWRMAN_PWR_RST_CTRL_IO_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_IO_ACTIVE_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_USB_POWERED_POS 4 +#define MXC_F_PWRMAN_PWR_RST_CTRL_USB_POWERED ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_USB_POWERED_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_PULLUPS_ENABLED_POS 5 +#define MXC_F_PWRMAN_PWR_RST_CTRL_PULLUPS_ENABLED ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_PULLUPS_ENABLED_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_FIRMWARE_RESET_POS 8 +#define MXC_F_PWRMAN_PWR_RST_CTRL_FIRMWARE_RESET ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_FIRMWARE_RESET_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_ARM_LOCKUP_RESET_POS 9 +#define MXC_F_PWRMAN_PWR_RST_CTRL_ARM_LOCKUP_RESET ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_ARM_LOCKUP_RESET_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_TAMPER_DETECT_POS 16 +#define MXC_F_PWRMAN_PWR_RST_CTRL_TAMPER_DETECT ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_TAMPER_DETECT_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_ARM_LOCKUP_POS 17 +#define MXC_F_PWRMAN_PWR_RST_CTRL_ARM_LOCKUP ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_ARM_LOCKUP_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_FW_COMMAND_ARM_POS 18 +#define MXC_F_PWRMAN_PWR_RST_CTRL_FW_COMMAND_ARM ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_FW_COMMAND_ARM_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_WATCHDOG_TIMEOUT_POS 19 +#define MXC_F_PWRMAN_PWR_RST_CTRL_WATCHDOG_TIMEOUT ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_WATCHDOG_TIMEOUT_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_FW_COMMAND_SYSMAN_POS 20 +#define MXC_F_PWRMAN_PWR_RST_CTRL_FW_COMMAND_SYSMAN ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_FW_COMMAND_SYSMAN_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_SRSTN_ASSERTION_POS 21 +#define MXC_F_PWRMAN_PWR_RST_CTRL_SRSTN_ASSERTION ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_SRSTN_ASSERTION_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_POR_POS 22 +#define MXC_F_PWRMAN_PWR_RST_CTRL_POR ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_POR_POS)) +#define MXC_F_PWRMAN_PWR_RST_CTRL_LOW_POWER_MODE_POS 31 +#define MXC_F_PWRMAN_PWR_RST_CTRL_LOW_POWER_MODE ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PWR_RST_CTRL_LOW_POWER_MODE_POS)) + +#define MXC_F_PWRMAN_INTFL_V1_2_WARNING_POS 0 +#define MXC_F_PWRMAN_INTFL_V1_2_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTFL_V1_2_WARNING_POS)) +#define MXC_F_PWRMAN_INTFL_V1_8_WARNING_POS 1 +#define MXC_F_PWRMAN_INTFL_V1_8_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTFL_V1_8_WARNING_POS)) +#define MXC_F_PWRMAN_INTFL_RTC_WARNING_POS 2 +#define MXC_F_PWRMAN_INTFL_RTC_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTFL_RTC_WARNING_POS)) +#define MXC_F_PWRMAN_INTFL_VDDA_WARNING_POS 3 +#define MXC_F_PWRMAN_INTFL_VDDA_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTFL_VDDA_WARNING_POS)) +#define MXC_F_PWRMAN_INTFL_VDDB_WARNING_POS 4 +#define MXC_F_PWRMAN_INTFL_VDDB_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTFL_VDDB_WARNING_POS)) +#define MXC_F_PWRMAN_INTFL_VDDIO_WARNING_POS 5 +#define MXC_F_PWRMAN_INTFL_VDDIO_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTFL_VDDIO_WARNING_POS)) +#define MXC_F_PWRMAN_INTFL_VDDIOH_WARNING_POS 6 +#define MXC_F_PWRMAN_INTFL_VDDIOH_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTFL_VDDIOH_WARNING_POS)) + +#define MXC_F_PWRMAN_INTEN_V1_2_WARNING_POS 0 +#define MXC_F_PWRMAN_INTEN_V1_2_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTEN_V1_2_WARNING_POS)) +#define MXC_F_PWRMAN_INTEN_V1_8_WARNING_POS 1 +#define MXC_F_PWRMAN_INTEN_V1_8_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTEN_V1_8_WARNING_POS)) +#define MXC_F_PWRMAN_INTEN_RTC_WARNING_POS 2 +#define MXC_F_PWRMAN_INTEN_RTC_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTEN_RTC_WARNING_POS)) +#define MXC_F_PWRMAN_INTEN_VDDA_WARNING_POS 3 +#define MXC_F_PWRMAN_INTEN_VDDA_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTEN_VDDA_WARNING_POS)) +#define MXC_F_PWRMAN_INTEN_VDDB_WARNING_POS 4 +#define MXC_F_PWRMAN_INTEN_VDDB_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTEN_VDDB_WARNING_POS)) +#define MXC_F_PWRMAN_INTEN_VDDIO_WARNING_POS 5 +#define MXC_F_PWRMAN_INTEN_VDDIO_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTEN_VDDIO_WARNING_POS)) +#define MXC_F_PWRMAN_INTEN_VDDIOH_WARNING_POS 6 +#define MXC_F_PWRMAN_INTEN_VDDIOH_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_INTEN_VDDIOH_WARNING_POS)) + +#define MXC_F_PWRMAN_SVM_EVENTS_V1_2_WARNING_POS 0 +#define MXC_F_PWRMAN_SVM_EVENTS_V1_2_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_SVM_EVENTS_V1_2_WARNING_POS)) +#define MXC_F_PWRMAN_SVM_EVENTS_V1_8_WARNING_POS 1 +#define MXC_F_PWRMAN_SVM_EVENTS_V1_8_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_SVM_EVENTS_V1_8_WARNING_POS)) +#define MXC_F_PWRMAN_SVM_EVENTS_RTC_WARNING_POS 2 +#define MXC_F_PWRMAN_SVM_EVENTS_RTC_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_SVM_EVENTS_RTC_WARNING_POS)) +#define MXC_F_PWRMAN_SVM_EVENTS_VDDA_WARNING_POS 3 +#define MXC_F_PWRMAN_SVM_EVENTS_VDDA_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_SVM_EVENTS_VDDA_WARNING_POS)) +#define MXC_F_PWRMAN_SVM_EVENTS_VDDB_WARNING_POS 4 +#define MXC_F_PWRMAN_SVM_EVENTS_VDDB_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_SVM_EVENTS_VDDB_WARNING_POS)) +#define MXC_F_PWRMAN_SVM_EVENTS_VDDIO_WARNING_POS 5 +#define MXC_F_PWRMAN_SVM_EVENTS_VDDIO_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_SVM_EVENTS_VDDIO_WARNING_POS)) +#define MXC_F_PWRMAN_SVM_EVENTS_VDDIOH_WARNING_POS 6 +#define MXC_F_PWRMAN_SVM_EVENTS_VDDIOH_WARNING ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_SVM_EVENTS_VDDIOH_WARNING_POS)) + +#define MXC_F_PWRMAN_WUD_CTRL_PAD_SELECT_POS 0 +#define MXC_F_PWRMAN_WUD_CTRL_PAD_SELECT ((uint32_t)(0x0000003FUL << MXC_F_PWRMAN_WUD_CTRL_PAD_SELECT_POS)) +#define MXC_F_PWRMAN_WUD_CTRL_PAD_MODE_POS 8 +#define MXC_F_PWRMAN_WUD_CTRL_PAD_MODE ((uint32_t)(0x00000003UL << MXC_F_PWRMAN_WUD_CTRL_PAD_MODE_POS)) +#define MXC_F_PWRMAN_WUD_CTRL_CLEAR_ALL_POS 12 +#define MXC_F_PWRMAN_WUD_CTRL_CLEAR_ALL ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_CTRL_CLEAR_ALL_POS)) +#define MXC_F_PWRMAN_WUD_CTRL_CTRL_ENABLE_POS 16 +#define MXC_F_PWRMAN_WUD_CTRL_CTRL_ENABLE ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_CTRL_CTRL_ENABLE_POS)) + +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO0_POS 0 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO0 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO0_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO1_POS 1 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO1 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO1_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO2_POS 2 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO2 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO2_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO3_POS 3 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO3 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO3_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO4_POS 4 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO4 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO4_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO5_POS 5 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO5 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO5_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO6_POS 6 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO6 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO6_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO7_POS 7 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO7 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO7_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO8_POS 8 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO8 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO8_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO9_POS 9 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO9 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO9_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO10_POS 10 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO10 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO10_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO11_POS 11 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO11 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO11_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO12_POS 12 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO12 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO12_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO13_POS 13 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO13 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO13_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO14_POS 14 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO14 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO14_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO15_POS 15 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO15 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO15_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO16_POS 16 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO16 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO16_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO17_POS 17 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO17 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO17_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO18_POS 18 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO18 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO18_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO19_POS 19 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO19 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO19_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO20_POS 20 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO20 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO20_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO21_POS 21 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO21 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO21_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO22_POS 22 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO22 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO22_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO23_POS 23 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO23 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO23_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO24_POS 24 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO24 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO24_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO25_POS 25 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO25 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO25_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO26_POS 26 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO26 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO26_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO27_POS 27 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO27 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO27_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO28_POS 28 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO28 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO28_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO29_POS 29 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO29 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO29_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO30_POS 30 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO30 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO30_POS)) +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO31_POS 31 +#define MXC_F_PWRMAN_WUD_SEEN0_GPIO31 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN0_GPIO31_POS)) + +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO32_POS 0 +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO32 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN1_GPIO32_POS)) +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO33_POS 1 +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO33 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN1_GPIO33_POS)) +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO34_POS 2 +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO34 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN1_GPIO34_POS)) +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO35_POS 3 +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO35 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN1_GPIO35_POS)) +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO36_POS 4 +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO36 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN1_GPIO36_POS)) +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO37_POS 5 +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO37 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN1_GPIO37_POS)) +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO38_POS 6 +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO38 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN1_GPIO38_POS)) +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO39_POS 7 +#define MXC_F_PWRMAN_WUD_SEEN1_GPIO39 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_WUD_SEEN1_GPIO39_POS)) + +#define MXC_F_PWRMAN_PT_REGMAP_CTRL_ME02A_MODE_POS 0 +#define MXC_F_PWRMAN_PT_REGMAP_CTRL_ME02A_MODE ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PT_REGMAP_CTRL_ME02A_MODE_POS)) + +#define MXC_F_PWRMAN_BASE_PART_NUM_BASE_PART_NUMBER_POS 0 +#define MXC_F_PWRMAN_BASE_PART_NUM_BASE_PART_NUMBER ((uint32_t)(0x0000FFFFUL << MXC_F_PWRMAN_BASE_PART_NUM_BASE_PART_NUMBER_POS)) + +#define MXC_F_PWRMAN_MASK_ID0_REVISION_ID_POS 0 +#define MXC_F_PWRMAN_MASK_ID0_REVISION_ID ((uint32_t)(0x0000000FUL << MXC_F_PWRMAN_MASK_ID0_REVISION_ID_POS)) +#define MXC_F_PWRMAN_MASK_ID0_MASK_ID_POS 4 +#define MXC_F_PWRMAN_MASK_ID0_MASK_ID ((uint32_t)(0x0FFFFFFFUL << MXC_F_PWRMAN_MASK_ID0_MASK_ID_POS)) + +#define MXC_F_PWRMAN_MASK_ID1_MASK_ID_POS 0 +#define MXC_F_PWRMAN_MASK_ID1_MASK_ID ((uint32_t)(0x7FFFFFFFUL << MXC_F_PWRMAN_MASK_ID1_MASK_ID_POS)) +#define MXC_F_PWRMAN_MASK_ID1_MASK_ID_ENABLE_POS 31 +#define MXC_F_PWRMAN_MASK_ID1_MASK_ID_ENABLE ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_MASK_ID1_MASK_ID_ENABLE_POS)) + +#define MXC_F_PWRMAN_PERIPHERAL_RESET_SSB_POS 0 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_SSB ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_SSB_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_SPIX_POS 1 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_SPIX ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_SPIX_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_PMU_POS 2 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_PMU ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_PMU_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_USB_POS 3 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_USB ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_USB_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_CRC_POS 4 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_CRC ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_CRC_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TPU_POS 5 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TPU ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_TPU_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_WATCHDOG0_POS 6 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_WATCHDOG0 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_WATCHDOG0_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_GPIO_POS 7 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_GPIO ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_GPIO_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER0_POS 8 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER0 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER0_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER1_POS 9 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER1 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER1_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER2_POS 10 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER2 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER2_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER3_POS 11 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER3 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER3_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER4_POS 12 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER4 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER4_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER5_POS 13 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER5 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_TIMER5_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_PULSE_TRAIN_POS 14 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_PULSE_TRAIN ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_PULSE_TRAIN_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_UART0_POS 15 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_UART0 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_UART0_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_UART1_POS 16 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_UART1 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_UART1_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_UART2_POS 17 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_UART2 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_UART2_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_I2CM0_POS 19 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_I2CM0 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_I2CM0_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_I2CM1_POS 20 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_I2CM1 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_I2CM1_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_I2CS_POS 22 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_I2CS ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_I2CS_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_SPIM0_POS 23 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_SPIM0 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_SPIM0_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_SPIM1_POS 24 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_SPIM1 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_SPIM1_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_SPIM2_POS 25 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_SPIM2 ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_SPIM2_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_OWM_POS 27 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_OWM ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_OWM_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_ADC_POS 28 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_ADC ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_ADC_POS)) +#define MXC_F_PWRMAN_PERIPHERAL_RESET_SPIS_POS 29 +#define MXC_F_PWRMAN_PERIPHERAL_RESET_SPIS ((uint32_t)(0x00000001UL << MXC_F_PWRMAN_PERIPHERAL_RESET_SPIS_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_PWRMAN_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/pwrseq_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/pwrseq_regs.h new file mode 100644 index 00000000000..cacbe132dc6 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/pwrseq_regs.h @@ -0,0 +1,425 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_PWRSEQ_REGS_H_ +#define _MXC_PWRSEQ_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t reg0; /* 0x0000 Power Sequencer Control Register 0 */ + __IO uint32_t reg1; /* 0x0004 Power Sequencer Control Register 1 */ + __IO uint32_t reg2; /* 0x0008 Power Sequencer Control Register 2 */ + __IO uint32_t reg3; /* 0x000C Power Sequencer Control Register 3 */ + __IO uint32_t reg4; /* 0x0010 Power Sequencer Control Register 4 (Internal Test Only) */ + __IO uint32_t reg5; /* 0x0014 Power Sequencer Control Register 5 (Trim 0) */ + __IO uint32_t reg6; /* 0x0018 Power Sequencer Control Register 6 (Trim 1) */ + __IO uint32_t reg7; /* 0x001C Power Sequencer Control Register 7 (Trim 2) */ + __IO uint32_t flags; /* 0x0020 Power Sequencer Flags */ + __IO uint32_t msk_flags; /* 0x0024 Power Sequencer Flags Mask Register */ + __I uint32_t rsv028; /* 0x0028 */ + __IO uint32_t wr_protect; /* 0x002C Critical Setting Write Protect Register */ + __IO uint32_t retn_ctrl0; /* 0x0030 Retention Control Register 0 */ + __IO uint32_t retn_ctrl1; /* 0x0034 Retention Control Register 1 */ + __IO uint32_t pwr_misc; /* 0x0038 Power Misc Controls */ + __IO uint32_t rtc_ctrl2; /* 0x003C RTC Misc Controls */ +} mxc_pwrseq_regs_t; + + +/* + Register offsets for module PWRSEQ. +*/ + +#define MXC_R_PWRSEQ_OFFS_REG0 ((uint32_t)0x00000000UL) +#define MXC_R_PWRSEQ_OFFS_REG1 ((uint32_t)0x00000004UL) +#define MXC_R_PWRSEQ_OFFS_REG2 ((uint32_t)0x00000008UL) +#define MXC_R_PWRSEQ_OFFS_REG3 ((uint32_t)0x0000000CUL) +#define MXC_R_PWRSEQ_OFFS_REG4 ((uint32_t)0x00000010UL) +#define MXC_R_PWRSEQ_OFFS_REG5 ((uint32_t)0x00000014UL) +#define MXC_R_PWRSEQ_OFFS_REG6 ((uint32_t)0x00000018UL) +#define MXC_R_PWRSEQ_OFFS_REG7 ((uint32_t)0x0000001CUL) +#define MXC_R_PWRSEQ_OFFS_FLAGS ((uint32_t)0x00000020UL) +#define MXC_R_PWRSEQ_OFFS_MSK_FLAGS ((uint32_t)0x00000024UL) +#define MXC_R_PWRSEQ_OFFS_WR_PROTECT ((uint32_t)0x0000002CUL) +#define MXC_R_PWRSEQ_OFFS_RETN_CTRL0 ((uint32_t)0x00000030UL) +#define MXC_R_PWRSEQ_OFFS_RETN_CTRL1 ((uint32_t)0x00000034UL) +#define MXC_R_PWRSEQ_OFFS_PWR_MISC ((uint32_t)0x00000038UL) +#define MXC_R_PWRSEQ_OFFS_RTC_CTRL2 ((uint32_t)0x0000003CUL) + + +/* + Field positions and masks for module PWRSEQ. +*/ + +#define MXC_F_PWRSEQ_REG0_PWR_LP1_POS 0 +#define MXC_F_PWRSEQ_REG0_PWR_LP1 ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_LP1_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_FIRST_BOOT_POS 1 +#define MXC_F_PWRSEQ_REG0_PWR_FIRST_BOOT ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_FIRST_BOOT_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_SYS_REBOOT_POS 2 +#define MXC_F_PWRSEQ_REG0_PWR_SYS_REBOOT ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_SYS_REBOOT_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_FLASHEN_RUN_POS 3 +#define MXC_F_PWRSEQ_REG0_PWR_FLASHEN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_FLASHEN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_FLASHEN_SLP_POS 4 +#define MXC_F_PWRSEQ_REG0_PWR_FLASHEN_SLP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_FLASHEN_SLP_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_RETREGEN_RUN_POS 5 +#define MXC_F_PWRSEQ_REG0_PWR_RETREGEN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_RETREGEN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_RETREGEN_SLP_POS 6 +#define MXC_F_PWRSEQ_REG0_PWR_RETREGEN_SLP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_RETREGEN_SLP_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_ROEN_RUN_POS 7 +#define MXC_F_PWRSEQ_REG0_PWR_ROEN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_ROEN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_ROEN_SLP_POS 8 +#define MXC_F_PWRSEQ_REG0_PWR_ROEN_SLP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_ROEN_SLP_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_NREN_RUN_POS 9 +#define MXC_F_PWRSEQ_REG0_PWR_NREN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_NREN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_NREN_SLP_POS 10 +#define MXC_F_PWRSEQ_REG0_PWR_NREN_SLP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_NREN_SLP_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN_POS 11 +#define MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP_POS 12 +#define MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_SVM12EN_RUN_POS 13 +#define MXC_F_PWRSEQ_REG0_PWR_SVM12EN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_SVM12EN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_SVM18EN_RUN_POS 15 +#define MXC_F_PWRSEQ_REG0_PWR_SVM18EN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_SVM18EN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_SVMRTCEN_RUN_POS 17 +#define MXC_F_PWRSEQ_REG0_PWR_SVMRTCEN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_SVMRTCEN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_SVM_VDDB_RUN_POS 19 +#define MXC_F_PWRSEQ_REG0_PWR_SVM_VDDB_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_SVM_VDDB_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_SVMTVDD12EN_RUN_POS 21 +#define MXC_F_PWRSEQ_REG0_PWR_SVMTVDD12EN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_SVMTVDD12EN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_VDD12_SWEN_RUN_POS 23 +#define MXC_F_PWRSEQ_REG0_PWR_VDD12_SWEN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_VDD12_SWEN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_VDD12_SWEN_SLP_POS 24 +#define MXC_F_PWRSEQ_REG0_PWR_VDD12_SWEN_SLP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_VDD12_SWEN_SLP_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_VDD18_SWEN_RUN_POS 25 +#define MXC_F_PWRSEQ_REG0_PWR_VDD18_SWEN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_VDD18_SWEN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_VDD18_SWEN_SLP_POS 26 +#define MXC_F_PWRSEQ_REG0_PWR_VDD18_SWEN_SLP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_VDD18_SWEN_SLP_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_TVDD12_SWEN_RUN_POS 27 +#define MXC_F_PWRSEQ_REG0_PWR_TVDD12_SWEN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_TVDD12_SWEN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_TVDD12_SWEN_SLP_POS 28 +#define MXC_F_PWRSEQ_REG0_PWR_TVDD12_SWEN_SLP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_TVDD12_SWEN_SLP_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_RCEN_RUN_POS 29 +#define MXC_F_PWRSEQ_REG0_PWR_RCEN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_RCEN_RUN_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_RCEN_SLP_POS 30 +#define MXC_F_PWRSEQ_REG0_PWR_RCEN_SLP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_RCEN_SLP_POS)) +#define MXC_F_PWRSEQ_REG0_PWR_OSC_SELECT_POS 31 +#define MXC_F_PWRSEQ_REG0_PWR_OSC_SELECT ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG0_PWR_OSC_SELECT_POS)) + +#define MXC_F_PWRSEQ_REG1_PWR_CLR_IO_EVENT_LATCH_POS 0 +#define MXC_F_PWRSEQ_REG1_PWR_CLR_IO_EVENT_LATCH ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_CLR_IO_EVENT_LATCH_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_CLR_IO_CFG_LATCH_POS 1 +#define MXC_F_PWRSEQ_REG1_PWR_CLR_IO_CFG_LATCH ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_CLR_IO_CFG_LATCH_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_MBUS_GATE_POS 2 +#define MXC_F_PWRSEQ_REG1_PWR_MBUS_GATE ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_MBUS_GATE_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_DISCHARGE_EN_POS 3 +#define MXC_F_PWRSEQ_REG1_PWR_DISCHARGE_EN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_DISCHARGE_EN_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_TVDD12_WELL_POS 4 +#define MXC_F_PWRSEQ_REG1_PWR_TVDD12_WELL ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_TVDD12_WELL_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_SRAM_NWELL_SW_POS 5 +#define MXC_F_PWRSEQ_REG1_PWR_SRAM_NWELL_SW ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_SRAM_NWELL_SW_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_AUTO_MBUS_GATE_POS 6 +#define MXC_F_PWRSEQ_REG1_PWR_AUTO_MBUS_GATE ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_AUTO_MBUS_GATE_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_SVM_VDDIO_EN_RUN_POS 8 +#define MXC_F_PWRSEQ_REG1_PWR_SVM_VDDIO_EN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_SVM_VDDIO_EN_RUN_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_SVM_VDDIOH_EN_RUN_POS 10 +#define MXC_F_PWRSEQ_REG1_PWR_SVM_VDDIOH_EN_RUN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_SVM_VDDIOH_EN_RUN_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_RETREG_SRC_V12_POS 12 +#define MXC_F_PWRSEQ_REG1_PWR_RETREG_SRC_V12 ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_RETREG_SRC_V12_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_RETREG_SRC_VRTC_POS 13 +#define MXC_F_PWRSEQ_REG1_PWR_RETREG_SRC_VRTC ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_RETREG_SRC_VRTC_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_RETREG_SRC_V18_POS 14 +#define MXC_F_PWRSEQ_REG1_PWR_RETREG_SRC_V18 ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_RETREG_SRC_V18_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_VDDIO_EN_ISO_POR_POS 16 +#define MXC_F_PWRSEQ_REG1_PWR_VDDIO_EN_ISO_POR ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_VDDIO_EN_ISO_POR_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_VDDIOH_EN_ISO_POR_POS 17 +#define MXC_F_PWRSEQ_REG1_PWR_VDDIOH_EN_ISO_POR ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_VDDIOH_EN_ISO_POR_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_LP0_CORE_RESUME_EN_POS 18 +#define MXC_F_PWRSEQ_REG1_PWR_LP0_CORE_RESUME_EN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_LP0_CORE_RESUME_EN_POS)) +#define MXC_F_PWRSEQ_REG1_PWR_LP1_CORE_RSTN_EN_POS 19 +#define MXC_F_PWRSEQ_REG1_PWR_LP1_CORE_RSTN_EN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG1_PWR_LP1_CORE_RSTN_EN_POS)) + +#define MXC_F_PWRSEQ_REG2_PWR_VDD12_HYST_POS 0 +#define MXC_F_PWRSEQ_REG2_PWR_VDD12_HYST ((uint32_t)(0x00000003UL << MXC_F_PWRSEQ_REG2_PWR_VDD12_HYST_POS)) +#define MXC_F_PWRSEQ_REG2_PWR_VDD18_HYST_POS 2 +#define MXC_F_PWRSEQ_REG2_PWR_VDD18_HYST ((uint32_t)(0x00000003UL << MXC_F_PWRSEQ_REG2_PWR_VDD18_HYST_POS)) +#define MXC_F_PWRSEQ_REG2_PWR_VRTC_HYST_POS 4 +#define MXC_F_PWRSEQ_REG2_PWR_VRTC_HYST ((uint32_t)(0x00000003UL << MXC_F_PWRSEQ_REG2_PWR_VRTC_HYST_POS)) +#define MXC_F_PWRSEQ_REG2_PWR_VDDB_HYST_POS 6 +#define MXC_F_PWRSEQ_REG2_PWR_VDDB_HYST ((uint32_t)(0x00000003UL << MXC_F_PWRSEQ_REG2_PWR_VDDB_HYST_POS)) +#define MXC_F_PWRSEQ_REG2_PWR_TVDD12_HYST_POS 8 +#define MXC_F_PWRSEQ_REG2_PWR_TVDD12_HYST ((uint32_t)(0x00000003UL << MXC_F_PWRSEQ_REG2_PWR_TVDD12_HYST_POS)) +#define MXC_F_PWRSEQ_REG2_PWR_VDDIO_HYST_POS 10 +#define MXC_F_PWRSEQ_REG2_PWR_VDDIO_HYST ((uint32_t)(0x00000003UL << MXC_F_PWRSEQ_REG2_PWR_VDDIO_HYST_POS)) +#define MXC_F_PWRSEQ_REG2_PWR_VDDIOH_HYST_POS 12 +#define MXC_F_PWRSEQ_REG2_PWR_VDDIOH_HYST ((uint32_t)(0x00000003UL << MXC_F_PWRSEQ_REG2_PWR_VDDIOH_HYST_POS)) + +#define MXC_F_PWRSEQ_REG3_PWR_ROSEL_POS 0 +#define MXC_F_PWRSEQ_REG3_PWR_ROSEL ((uint32_t)(0x00000007UL << MXC_F_PWRSEQ_REG3_PWR_ROSEL_POS)) +#define MXC_F_PWRSEQ_REG3_PWR_FLTRROSEL_POS 3 +#define MXC_F_PWRSEQ_REG3_PWR_FLTRROSEL ((uint32_t)(0x00000007UL << MXC_F_PWRSEQ_REG3_PWR_FLTRROSEL_POS)) +#define MXC_F_PWRSEQ_REG3_PWR_SVM_CLK_MUX_POS 6 +#define MXC_F_PWRSEQ_REG3_PWR_SVM_CLK_MUX ((uint32_t)(0x00000003UL << MXC_F_PWRSEQ_REG3_PWR_SVM_CLK_MUX_POS)) +#define MXC_F_PWRSEQ_REG3_PWR_RO_CLK_MUX_POS 8 +#define MXC_F_PWRSEQ_REG3_PWR_RO_CLK_MUX ((uint32_t)(0x00000003UL << MXC_F_PWRSEQ_REG3_PWR_RO_CLK_MUX_POS)) +#define MXC_F_PWRSEQ_REG3_PWR_FAILSEL_POS 10 +#define MXC_F_PWRSEQ_REG3_PWR_FAILSEL ((uint32_t)(0x00000007UL << MXC_F_PWRSEQ_REG3_PWR_FAILSEL_POS)) +#define MXC_F_PWRSEQ_REG3_PWR_RO_DIV_POS 16 +#define MXC_F_PWRSEQ_REG3_PWR_RO_DIV ((uint32_t)(0x00000007UL << MXC_F_PWRSEQ_REG3_PWR_RO_DIV_POS)) +#define MXC_F_PWRSEQ_REG3_PWR_RC_DIV_POS 20 +#define MXC_F_PWRSEQ_REG3_PWR_RC_DIV ((uint32_t)(0x00000003UL << MXC_F_PWRSEQ_REG3_PWR_RC_DIV_POS)) + +#define MXC_F_PWRSEQ_REG4_PWR_TM_PS_2_GPIO_POS 0 +#define MXC_F_PWRSEQ_REG4_PWR_TM_PS_2_GPIO ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG4_PWR_TM_PS_2_GPIO_POS)) +#define MXC_F_PWRSEQ_REG4_PWR_TM_FAST_TIMERS_POS 1 +#define MXC_F_PWRSEQ_REG4_PWR_TM_FAST_TIMERS ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG4_PWR_TM_FAST_TIMERS_POS)) +#define MXC_F_PWRSEQ_REG4_PWR_USB_DIS_COMP_POS 3 +#define MXC_F_PWRSEQ_REG4_PWR_USB_DIS_COMP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG4_PWR_USB_DIS_COMP_POS)) +#define MXC_F_PWRSEQ_REG4_PWR_RO_TSTCLK_EN_POS 4 +#define MXC_F_PWRSEQ_REG4_PWR_RO_TSTCLK_EN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG4_PWR_RO_TSTCLK_EN_POS)) +#define MXC_F_PWRSEQ_REG4_PWR_NR_CLK_GATE_EN_POS 5 +#define MXC_F_PWRSEQ_REG4_PWR_NR_CLK_GATE_EN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG4_PWR_NR_CLK_GATE_EN_POS)) +#define MXC_F_PWRSEQ_REG4_PWR_EXT_CLK_IN_EN_POS 6 +#define MXC_F_PWRSEQ_REG4_PWR_EXT_CLK_IN_EN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG4_PWR_EXT_CLK_IN_EN_POS)) +#define MXC_F_PWRSEQ_REG4_PWR_PSEQ_32K_EN_POS 7 +#define MXC_F_PWRSEQ_REG4_PWR_PSEQ_32K_EN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG4_PWR_PSEQ_32K_EN_POS)) +#define MXC_F_PWRSEQ_REG4_PWR_RTC_MUX_POS 8 +#define MXC_F_PWRSEQ_REG4_PWR_RTC_MUX ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG4_PWR_RTC_MUX_POS)) +#define MXC_F_PWRSEQ_REG4_PWR_RETREG_TRIM_LP1_EN_POS 9 +#define MXC_F_PWRSEQ_REG4_PWR_RETREG_TRIM_LP1_EN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG4_PWR_RETREG_TRIM_LP1_EN_POS)) +#define MXC_F_PWRSEQ_REG4_PWR_USB_XVR_TST_EN_POS 10 +#define MXC_F_PWRSEQ_REG4_PWR_USB_XVR_TST_EN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG4_PWR_USB_XVR_TST_EN_POS)) + +#define MXC_F_PWRSEQ_REG5_PWR_TRIM_SVM_BG_POS 0 +#define MXC_F_PWRSEQ_REG5_PWR_TRIM_SVM_BG ((uint32_t)(0x000001FFUL << MXC_F_PWRSEQ_REG5_PWR_TRIM_SVM_BG_POS)) +#define MXC_F_PWRSEQ_REG5_PWR_TRIM_BIAS_POS 9 +#define MXC_F_PWRSEQ_REG5_PWR_TRIM_BIAS ((uint32_t)(0x0000003FUL << MXC_F_PWRSEQ_REG5_PWR_TRIM_BIAS_POS)) +#define MXC_F_PWRSEQ_REG5_PWR_TRIM_RETREG_5_0_POS 15 +#define MXC_F_PWRSEQ_REG5_PWR_TRIM_RETREG_5_0 ((uint32_t)(0x0000003FUL << MXC_F_PWRSEQ_REG5_PWR_TRIM_RETREG_5_0_POS)) +#define MXC_F_PWRSEQ_REG5_PWR_RTC_TRIM_POS 21 +#define MXC_F_PWRSEQ_REG5_PWR_RTC_TRIM ((uint32_t)(0x0000000FUL << MXC_F_PWRSEQ_REG5_PWR_RTC_TRIM_POS)) +#define MXC_F_PWRSEQ_REG5_PWR_TRIM_RETREG_7_6_POS 25 +#define MXC_F_PWRSEQ_REG5_PWR_TRIM_RETREG_7_6 ((uint32_t)(0x00000003UL << MXC_F_PWRSEQ_REG5_PWR_TRIM_RETREG_7_6_POS)) + +#define MXC_F_PWRSEQ_REG6_PWR_TRIM_USB_BIAS_POS 0 +#define MXC_F_PWRSEQ_REG6_PWR_TRIM_USB_BIAS ((uint32_t)(0x00000007UL << MXC_F_PWRSEQ_REG6_PWR_TRIM_USB_BIAS_POS)) +#define MXC_F_PWRSEQ_REG6_PWR_TRIM_USB_PM_RES_POS 3 +#define MXC_F_PWRSEQ_REG6_PWR_TRIM_USB_PM_RES ((uint32_t)(0x0000000FUL << MXC_F_PWRSEQ_REG6_PWR_TRIM_USB_PM_RES_POS)) +#define MXC_F_PWRSEQ_REG6_PWR_TRIM_USB_DM_RES_POS 7 +#define MXC_F_PWRSEQ_REG6_PWR_TRIM_USB_DM_RES ((uint32_t)(0x0000000FUL << MXC_F_PWRSEQ_REG6_PWR_TRIM_USB_DM_RES_POS)) +#define MXC_F_PWRSEQ_REG6_PWR_TRIM_OSC_VREF_POS 11 +#define MXC_F_PWRSEQ_REG6_PWR_TRIM_OSC_VREF ((uint32_t)(0x000001FFUL << MXC_F_PWRSEQ_REG6_PWR_TRIM_OSC_VREF_POS)) +#define MXC_F_PWRSEQ_REG6_PWR_TRIM_CRYPTO_OSC_POS 20 +#define MXC_F_PWRSEQ_REG6_PWR_TRIM_CRYPTO_OSC ((uint32_t)(0x000001FFUL << MXC_F_PWRSEQ_REG6_PWR_TRIM_CRYPTO_OSC_POS)) + +#define MXC_F_PWRSEQ_REG7_PWR_FLASH_PD_LOOKAHEAD_POS 0 +#define MXC_F_PWRSEQ_REG7_PWR_FLASH_PD_LOOKAHEAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_REG7_PWR_FLASH_PD_LOOKAHEAD_POS)) +#define MXC_F_PWRSEQ_REG7_PWR_TRIM_RC_POS 16 +#define MXC_F_PWRSEQ_REG7_PWR_TRIM_RC ((uint32_t)(0x0000FFFFUL << MXC_F_PWRSEQ_REG7_PWR_TRIM_RC_POS)) + +#define MXC_F_PWRSEQ_FLAGS_PWR_FIRST_BOOT_POS 0 +#define MXC_F_PWRSEQ_FLAGS_PWR_FIRST_BOOT ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_FIRST_BOOT_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_SYS_REBOOT_POS 1 +#define MXC_F_PWRSEQ_FLAGS_PWR_SYS_REBOOT ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_SYS_REBOOT_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_POWER_FAIL_POS 2 +#define MXC_F_PWRSEQ_FLAGS_PWR_POWER_FAIL ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_POWER_FAIL_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_BOOT_FAIL_POS 3 +#define MXC_F_PWRSEQ_FLAGS_PWR_BOOT_FAIL ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_BOOT_FAIL_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_FLASH_DISCHARGE_POS 4 +#define MXC_F_PWRSEQ_FLAGS_PWR_FLASH_DISCHARGE ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_FLASH_DISCHARGE_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_IOWAKEUP_POS 5 +#define MXC_F_PWRSEQ_FLAGS_PWR_IOWAKEUP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_IOWAKEUP_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_VDD12_RST_BAD_POS 6 +#define MXC_F_PWRSEQ_FLAGS_PWR_VDD12_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_VDD12_RST_BAD_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_VDD18_RST_BAD_POS 7 +#define MXC_F_PWRSEQ_FLAGS_PWR_VDD18_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_VDD18_RST_BAD_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_VRTC_RST_BAD_POS 8 +#define MXC_F_PWRSEQ_FLAGS_PWR_VRTC_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_VRTC_RST_BAD_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_VDDB_RST_BAD_POS 9 +#define MXC_F_PWRSEQ_FLAGS_PWR_VDDB_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_VDDB_RST_BAD_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_TVDD12_RST_BAD_POS 10 +#define MXC_F_PWRSEQ_FLAGS_PWR_TVDD12_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_TVDD12_RST_BAD_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_POR18Z_FAIL_LATCH_POS 11 +#define MXC_F_PWRSEQ_FLAGS_PWR_POR18Z_FAIL_LATCH ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_POR18Z_FAIL_LATCH_POS)) +#define MXC_F_PWRSEQ_FLAGS_RTC_CMPR0_POS 12 +#define MXC_F_PWRSEQ_FLAGS_RTC_CMPR0 ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_RTC_CMPR0_POS)) +#define MXC_F_PWRSEQ_FLAGS_RTC_CMPR1_POS 13 +#define MXC_F_PWRSEQ_FLAGS_RTC_CMPR1 ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_RTC_CMPR1_POS)) +#define MXC_F_PWRSEQ_FLAGS_RTC_PRESCALE_CMP_POS 14 +#define MXC_F_PWRSEQ_FLAGS_RTC_PRESCALE_CMP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_RTC_PRESCALE_CMP_POS)) +#define MXC_F_PWRSEQ_FLAGS_RTC_ROLLOVER_POS 15 +#define MXC_F_PWRSEQ_FLAGS_RTC_ROLLOVER ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_RTC_ROLLOVER_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_USB_PLUG_WAKEUP_POS 16 +#define MXC_F_PWRSEQ_FLAGS_PWR_USB_PLUG_WAKEUP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_USB_PLUG_WAKEUP_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_USB_REMOVE_WAKEUP_POS 17 +#define MXC_F_PWRSEQ_FLAGS_PWR_USB_REMOVE_WAKEUP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_USB_REMOVE_WAKEUP_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_TVDD12_BAD_POS 18 +#define MXC_F_PWRSEQ_FLAGS_PWR_TVDD12_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_TVDD12_BAD_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_VDDIO_RST_BAD_POS 19 +#define MXC_F_PWRSEQ_FLAGS_PWR_VDDIO_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_VDDIO_RST_BAD_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_VDDIOH_RST_BAD_POS 20 +#define MXC_F_PWRSEQ_FLAGS_PWR_VDDIOH_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_VDDIOH_RST_BAD_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_ISOZ_VDDIO_FAIL_POS 21 +#define MXC_F_PWRSEQ_FLAGS_PWR_ISOZ_VDDIO_FAIL ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_ISOZ_VDDIO_FAIL_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_ISOZ_VDDIOH_FAIL_POS 22 +#define MXC_F_PWRSEQ_FLAGS_PWR_ISOZ_VDDIOH_FAIL ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_ISOZ_VDDIOH_FAIL_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_NANORING_WAKEUP_FLAG_POS 23 +#define MXC_F_PWRSEQ_FLAGS_PWR_NANORING_WAKEUP_FLAG ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_NANORING_WAKEUP_FLAG_POS)) +#define MXC_F_PWRSEQ_FLAGS_PWR_WATCHDOG_RSTN_FLAG_POS 24 +#define MXC_F_PWRSEQ_FLAGS_PWR_WATCHDOG_RSTN_FLAG ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_FLAGS_PWR_WATCHDOG_RSTN_FLAG_POS)) + +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_SYS_REBOOT_POS 1 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_SYS_REBOOT ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_SYS_REBOOT_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_POWER_FAIL_POS 2 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_POWER_FAIL ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_POWER_FAIL_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_BOOT_FAIL_POS 3 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_BOOT_FAIL ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_BOOT_FAIL_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_FLASH_DISCHARGE_POS 4 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_FLASH_DISCHARGE ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_FLASH_DISCHARGE_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_IOWAKEUP_POS 5 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_IOWAKEUP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_IOWAKEUP_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDD12_RST_BAD_POS 6 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDD12_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDD12_RST_BAD_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDD18_RST_BAD_POS 7 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDD18_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDD18_RST_BAD_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_VRTC_RST_BAD_POS 8 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_VRTC_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_VRTC_RST_BAD_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDDB_RST_BAD_POS 9 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDDB_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDDB_RST_BAD_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_TVDD12_RST_BAD_POS 10 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_TVDD12_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_TVDD12_RST_BAD_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_POR18Z_FAIL_LATCH_POS 11 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_POR18Z_FAIL_LATCH ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_POR18Z_FAIL_LATCH_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_RTC_CMPR0_POS 12 +#define MXC_F_PWRSEQ_MSK_FLAGS_RTC_CMPR0 ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_RTC_CMPR0_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_RTC_CMPR1_POS 13 +#define MXC_F_PWRSEQ_MSK_FLAGS_RTC_CMPR1 ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_RTC_CMPR1_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_RTC_PRESCALE_CMP_POS 14 +#define MXC_F_PWRSEQ_MSK_FLAGS_RTC_PRESCALE_CMP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_RTC_PRESCALE_CMP_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_RTC_ROLLOVER_POS 15 +#define MXC_F_PWRSEQ_MSK_FLAGS_RTC_ROLLOVER ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_RTC_ROLLOVER_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_USB_PLUG_WAKEUP_POS 16 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_USB_PLUG_WAKEUP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_USB_PLUG_WAKEUP_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_USB_REMOVE_WAKEUP_POS 17 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_USB_REMOVE_WAKEUP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_USB_REMOVE_WAKEUP_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_TVDD12_BAD_POS 18 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_TVDD12_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_TVDD12_BAD_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDDIO_RST_BAD_POS 19 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDDIO_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDDIO_RST_BAD_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDDIOH_RST_BAD_POS 20 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDDIOH_RST_BAD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_VDDIOH_RST_BAD_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_ISOZ_VDDIO_FAIL_POS 21 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_ISOZ_VDDIO_FAIL ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_ISOZ_VDDIO_FAIL_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_ISOZ_VDDIOH_FAIL_POS 22 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_ISOZ_VDDIOH_FAIL ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_ISOZ_VDDIOH_FAIL_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_NANORING_WAKEUP_FLAG_POS 23 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_NANORING_WAKEUP_FLAG ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_NANORING_WAKEUP_FLAG_POS)) +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_WATCHDOG_RSTN_FLAG_POS 24 +#define MXC_F_PWRSEQ_MSK_FLAGS_PWR_WATCHDOG_RSTN_FLAG ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_MSK_FLAGS_PWR_WATCHDOG_RSTN_FLAG_POS)) + +#define MXC_F_PWRSEQ_WR_PROTECT_BYPASS_SEQ_POS 0 +#define MXC_F_PWRSEQ_WR_PROTECT_BYPASS_SEQ ((uint32_t)(0x000000FFUL << MXC_F_PWRSEQ_WR_PROTECT_BYPASS_SEQ_POS)) +#define MXC_F_PWRSEQ_WR_PROTECT_RTC_SEQ_POS 8 +#define MXC_F_PWRSEQ_WR_PROTECT_RTC_SEQ ((uint32_t)(0x000000FFUL << MXC_F_PWRSEQ_WR_PROTECT_RTC_SEQ_POS)) +#define MXC_F_PWRSEQ_WR_PROTECT_RTC_POS 28 +#define MXC_F_PWRSEQ_WR_PROTECT_RTC ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_WR_PROTECT_RTC_POS)) +#define MXC_F_PWRSEQ_WR_PROTECT_INFO_POS 29 +#define MXC_F_PWRSEQ_WR_PROTECT_INFO ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_WR_PROTECT_INFO_POS)) +#define MXC_F_PWRSEQ_WR_PROTECT_BYPASS_POS 30 +#define MXC_F_PWRSEQ_WR_PROTECT_BYPASS ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_WR_PROTECT_BYPASS_POS)) +#define MXC_F_PWRSEQ_WR_PROTECT_WP_POS 31 +#define MXC_F_PWRSEQ_WR_PROTECT_WP ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_WR_PROTECT_WP_POS)) + +#define MXC_F_PWRSEQ_RETN_CTRL0_RETN_CTRL_EN_POS 0 +#define MXC_F_PWRSEQ_RETN_CTRL0_RETN_CTRL_EN ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_RETN_CTRL0_RETN_CTRL_EN_POS)) +#define MXC_F_PWRSEQ_RETN_CTRL0_RC_REL_CCG_EARLY_POS 1 +#define MXC_F_PWRSEQ_RETN_CTRL0_RC_REL_CCG_EARLY ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_RETN_CTRL0_RC_REL_CCG_EARLY_POS)) +#define MXC_F_PWRSEQ_RETN_CTRL0_RC_USE_FLC_TWK_POS 2 +#define MXC_F_PWRSEQ_RETN_CTRL0_RC_USE_FLC_TWK ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_RETN_CTRL0_RC_USE_FLC_TWK_POS)) +#define MXC_F_PWRSEQ_RETN_CTRL0_RC_POLL_FLASH_POS 3 +#define MXC_F_PWRSEQ_RETN_CTRL0_RC_POLL_FLASH ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_RETN_CTRL0_RC_POLL_FLASH_POS)) +#define MXC_F_PWRSEQ_RETN_CTRL0_RESTORE_OVERRIDE_POS 4 +#define MXC_F_PWRSEQ_RETN_CTRL0_RESTORE_OVERRIDE ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_RETN_CTRL0_RESTORE_OVERRIDE_POS)) + +#define MXC_F_PWRSEQ_RETN_CTRL1_RC_TWK_POS 0 +#define MXC_F_PWRSEQ_RETN_CTRL1_RC_TWK ((uint32_t)(0x0000000FUL << MXC_F_PWRSEQ_RETN_CTRL1_RC_TWK_POS)) +#define MXC_F_PWRSEQ_RETN_CTRL1_SRAM_FMS_POS 4 +#define MXC_F_PWRSEQ_RETN_CTRL1_SRAM_FMS ((uint32_t)(0x0000000FUL << MXC_F_PWRSEQ_RETN_CTRL1_SRAM_FMS_POS)) + +#define MXC_F_PWRSEQ_PWR_MISC_INVERT_4_MASK_BITS_POS 0 +#define MXC_F_PWRSEQ_PWR_MISC_INVERT_4_MASK_BITS ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_PWR_MISC_INVERT_4_MASK_BITS_POS)) + +#define MXC_F_PWRSEQ_RTC_CTRL2_TIMER_ASYNC_RD_POS 0 +#define MXC_F_PWRSEQ_RTC_CTRL2_TIMER_ASYNC_RD ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_RTC_CTRL2_TIMER_ASYNC_RD_POS)) +#define MXC_F_PWRSEQ_RTC_CTRL2_TIMER_ASYNC_WR_POS 1 +#define MXC_F_PWRSEQ_RTC_CTRL2_TIMER_ASYNC_WR ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_RTC_CTRL2_TIMER_ASYNC_WR_POS)) +#define MXC_F_PWRSEQ_RTC_CTRL2_TIMER_AUTO_UPDATE_POS 2 +#define MXC_F_PWRSEQ_RTC_CTRL2_TIMER_AUTO_UPDATE ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_RTC_CTRL2_TIMER_AUTO_UPDATE_POS)) +#define MXC_F_PWRSEQ_RTC_CTRL2_SSB_PERFORMANCE_POS 3 +#define MXC_F_PWRSEQ_RTC_CTRL2_SSB_PERFORMANCE ((uint32_t)(0x00000001UL << MXC_F_PWRSEQ_RTC_CTRL2_SSB_PERFORMANCE_POS)) +#define MXC_F_PWRSEQ_RTC_CTRL2_CFG_LOCK_POS 24 +#define MXC_F_PWRSEQ_RTC_CTRL2_CFG_LOCK ((uint32_t)(0x000000FFUL << MXC_F_PWRSEQ_RTC_CTRL2_CFG_LOCK_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_PWRSEQ_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/rtc_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/rtc_regs.h new file mode 100644 index 00000000000..323e77d14ea --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/rtc_regs.h @@ -0,0 +1,268 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_RTC_REGS_H_ +#define _MXC_RTC_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t ctrl; /* 0x0000 RTC Timer Control */ + __IO uint32_t timer; /* 0x0004 RTC Timer Count Value */ + __IO uint32_t comp[2]; /* 0x0008-0x000C RTC Time of Day Alarm [0..1] Compare Register */ + __IO uint32_t flags; /* 0x0010 CPU Interrupt and RTC Domain Flags */ + __IO uint32_t snz_val; /* 0x0014 RTC Timer Alarm Snooze Value */ + __IO uint32_t inten; /* 0x0018 Interrupt Enable Controls */ + __IO uint32_t prescale; /* 0x001C RTC Timer Prescale Setting */ + __I uint32_t rsv020; /* 0x0020 */ + __IO uint32_t prescale_mask; /* 0x0024 RTC Timer Prescale Compare Mask */ + __IO uint32_t trim_ctrl; /* 0x0028 RTC Timer Trim Controls */ + __IO uint32_t trim_value; /* 0x002C RTC Timer Trim Adjustment Interval */ +} mxc_rtctmr_regs_t; + + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t nano_cntr; /* 0x0000 Nano Oscillator Counter Read Register */ + __IO uint32_t clk_ctrl; /* 0x0004 RTC Clock Control Settings */ + __I uint32_t rsv008; /* 0x0008 */ + __IO uint32_t osc_ctrl; /* 0x000C RTC Oscillator Control */ +} mxc_rtccfg_regs_t; + + +/* + Register offsets for module RTC. +*/ + +#define MXC_R_RTCTMR_OFFS_CTRL ((uint32_t)0x00000000UL) +#define MXC_R_RTCTMR_OFFS_TIMER ((uint32_t)0x00000004UL) +#define MXC_R_RTCTMR_OFFS_COMP0 ((uint32_t)0x00000008UL) +#define MXC_R_RTCTMR_OFFS_COMP1 ((uint32_t)0x0000000CUL) +#define MXC_R_RTCTMR_OFFS_FLAGS ((uint32_t)0x00000010UL) +#define MXC_R_RTCTMR_OFFS_SNZ_VAL ((uint32_t)0x00000014UL) +#define MXC_R_RTCTMR_OFFS_INTEN ((uint32_t)0x00000018UL) +#define MXC_R_RTCTMR_OFFS_PRESCALE ((uint32_t)0x0000001CUL) +#define MXC_R_RTCTMR_OFFS_PRESCALE_MASK ((uint32_t)0x00000024UL) +#define MXC_R_RTCTMR_OFFS_TRIM_CTRL ((uint32_t)0x00000028UL) +#define MXC_R_RTCTMR_OFFS_TRIM_VALUE ((uint32_t)0x0000002CUL) +#define MXC_R_RTCCFG_OFFS_NANO_CNTR ((uint32_t)0x00000000UL) +#define MXC_R_RTCCFG_OFFS_CLK_CTRL ((uint32_t)0x00000004UL) +#define MXC_R_RTCCFG_OFFS_OSC_CTRL ((uint32_t)0x0000000CUL) + + +/* + Field positions and masks for module RTC. +*/ + +#define MXC_F_RTC_CTRL_ENABLE_POS 0 +#define MXC_F_RTC_CTRL_ENABLE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_ENABLE_POS)) +#define MXC_F_RTC_CTRL_CLEAR_POS 1 +#define MXC_F_RTC_CTRL_CLEAR ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_CLEAR_POS)) +#define MXC_F_RTC_CTRL_PENDING_POS 2 +#define MXC_F_RTC_CTRL_PENDING ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_PENDING_POS)) +#define MXC_F_RTC_CTRL_USE_ASYNC_FLAGS_POS 3 +#define MXC_F_RTC_CTRL_USE_ASYNC_FLAGS ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_USE_ASYNC_FLAGS_POS)) +#define MXC_F_RTC_CTRL_AGGRESSIVE_RST_POS 4 +#define MXC_F_RTC_CTRL_AGGRESSIVE_RST ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_AGGRESSIVE_RST_POS)) +#define MXC_F_RTC_CTRL_AUTO_UPDATE_DISABLE_POS 5 +#define MXC_F_RTC_CTRL_AUTO_UPDATE_DISABLE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_AUTO_UPDATE_DISABLE_POS)) +#define MXC_F_RTC_CTRL_SNOOZE_ENABLE_POS 6 +#define MXC_F_RTC_CTRL_SNOOZE_ENABLE ((uint32_t)(0x00000003UL << MXC_F_RTC_CTRL_SNOOZE_ENABLE_POS)) +#define MXC_F_RTC_CTRL_RTC_ENABLE_ACTIVE_POS 16 +#define MXC_F_RTC_CTRL_RTC_ENABLE_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_RTC_ENABLE_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_OSC_GOTO_LOW_ACTIVE_POS 17 +#define MXC_F_RTC_CTRL_OSC_GOTO_LOW_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_OSC_GOTO_LOW_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_OSC_FRCE_SM_EN_ACTIVE_POS 18 +#define MXC_F_RTC_CTRL_OSC_FRCE_SM_EN_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_OSC_FRCE_SM_EN_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_OSC_FRCE_ST_ACTIVE_POS 19 +#define MXC_F_RTC_CTRL_OSC_FRCE_ST_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_OSC_FRCE_ST_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_RTC_SET_ACTIVE_POS 20 +#define MXC_F_RTC_CTRL_RTC_SET_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_RTC_SET_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_RTC_CLR_ACTIVE_POS 21 +#define MXC_F_RTC_CTRL_RTC_CLR_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_RTC_CLR_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_ROLLOVER_CLR_ACTIVE_POS 22 +#define MXC_F_RTC_CTRL_ROLLOVER_CLR_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_ROLLOVER_CLR_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_PRESCALE_CMPR0_ACTIVE_POS 23 +#define MXC_F_RTC_CTRL_PRESCALE_CMPR0_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_PRESCALE_CMPR0_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_PRESCALE_UPDATE_ACTIVE_POS 24 +#define MXC_F_RTC_CTRL_PRESCALE_UPDATE_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_PRESCALE_UPDATE_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_CMPR1_CLR_ACTIVE_POS 25 +#define MXC_F_RTC_CTRL_CMPR1_CLR_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_CMPR1_CLR_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_CMPR0_CLR_ACTIVE_POS 26 +#define MXC_F_RTC_CTRL_CMPR0_CLR_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_CMPR0_CLR_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_TRIM_ENABLE_ACTIVE_POS 27 +#define MXC_F_RTC_CTRL_TRIM_ENABLE_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_TRIM_ENABLE_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_TRIM_SLOWER_ACTIVE_POS 28 +#define MXC_F_RTC_CTRL_TRIM_SLOWER_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_TRIM_SLOWER_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_TRIM_CLR_ACTIVE_POS 29 +#define MXC_F_RTC_CTRL_TRIM_CLR_ACTIVE ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_TRIM_CLR_ACTIVE_POS)) +#define MXC_F_RTC_CTRL_ACTIVE_TRANS_0_POS 30 +#define MXC_F_RTC_CTRL_ACTIVE_TRANS_0 ((uint32_t)(0x00000001UL << MXC_F_RTC_CTRL_ACTIVE_TRANS_0_POS)) + +#define MXC_F_RTC_FLAGS_COMP0_POS 0 +#define MXC_F_RTC_FLAGS_COMP0 ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_COMP0_POS)) +#define MXC_F_RTC_FLAGS_COMP1_POS 1 +#define MXC_F_RTC_FLAGS_COMP1 ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_COMP1_POS)) +#define MXC_F_RTC_FLAGS_PRESCALE_COMP_POS 2 +#define MXC_F_RTC_FLAGS_PRESCALE_COMP ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_PRESCALE_COMP_POS)) +#define MXC_F_RTC_FLAGS_OVERFLOW_POS 3 +#define MXC_F_RTC_FLAGS_OVERFLOW ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_OVERFLOW_POS)) +#define MXC_F_RTC_FLAGS_TRIM_POS 4 +#define MXC_F_RTC_FLAGS_TRIM ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_TRIM_POS)) +#define MXC_F_RTC_FLAGS_SNOOZE_POS 5 +#define MXC_F_RTC_FLAGS_SNOOZE ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_SNOOZE_POS)) +#define MXC_F_RTC_FLAGS_COMP0_FLAG_A_POS 8 +#define MXC_F_RTC_FLAGS_COMP0_FLAG_A ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_COMP0_FLAG_A_POS)) +#define MXC_F_RTC_FLAGS_COMP1_FLAG_A_POS 9 +#define MXC_F_RTC_FLAGS_COMP1_FLAG_A ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_COMP1_FLAG_A_POS)) +#define MXC_F_RTC_FLAGS_PRESCL_FLAG_A_POS 10 +#define MXC_F_RTC_FLAGS_PRESCL_FLAG_A ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_PRESCL_FLAG_A_POS)) +#define MXC_F_RTC_FLAGS_OVERFLOW_FLAG_A_POS 11 +#define MXC_F_RTC_FLAGS_OVERFLOW_FLAG_A ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_OVERFLOW_FLAG_A_POS)) +#define MXC_F_RTC_FLAGS_TRIM_FLAG_A_POS 12 +#define MXC_F_RTC_FLAGS_TRIM_FLAG_A ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_TRIM_FLAG_A_POS)) +#define MXC_F_RTC_FLAGS_SNOOZE_A_POS 28 +#define MXC_F_RTC_FLAGS_SNOOZE_A ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_SNOOZE_A_POS)) +#define MXC_F_RTC_FLAGS_SNOOZE_B_POS 29 +#define MXC_F_RTC_FLAGS_SNOOZE_B ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_SNOOZE_B_POS)) +#define MXC_F_RTC_FLAGS_ASYNC_CLR_FLAGS_POS 31 +#define MXC_F_RTC_FLAGS_ASYNC_CLR_FLAGS ((uint32_t)(0x00000001UL << MXC_F_RTC_FLAGS_ASYNC_CLR_FLAGS_POS)) + +#define MXC_F_RTC_SNZ_VAL_VALUE_POS 0 +#define MXC_F_RTC_SNZ_VAL_VALUE ((uint32_t)(0x000003FFUL << MXC_F_RTC_SNZ_VAL_VALUE_POS)) + +#define MXC_F_RTC_INTEN_COMP0_POS 0 +#define MXC_F_RTC_INTEN_COMP0 ((uint32_t)(0x00000001UL << MXC_F_RTC_INTEN_COMP0_POS)) +#define MXC_F_RTC_INTEN_COMP1_POS 1 +#define MXC_F_RTC_INTEN_COMP1 ((uint32_t)(0x00000001UL << MXC_F_RTC_INTEN_COMP1_POS)) +#define MXC_F_RTC_INTEN_PRESCALE_COMP_POS 2 +#define MXC_F_RTC_INTEN_PRESCALE_COMP ((uint32_t)(0x00000001UL << MXC_F_RTC_INTEN_PRESCALE_COMP_POS)) +#define MXC_F_RTC_INTEN_OVERFLOW_POS 3 +#define MXC_F_RTC_INTEN_OVERFLOW ((uint32_t)(0x00000001UL << MXC_F_RTC_INTEN_OVERFLOW_POS)) +#define MXC_F_RTC_INTEN_TRIM_POS 4 +#define MXC_F_RTC_INTEN_TRIM ((uint32_t)(0x00000001UL << MXC_F_RTC_INTEN_TRIM_POS)) + +#define MXC_F_RTC_PRESCALE_PRESCALE_POS 0 +#define MXC_F_RTC_PRESCALE_PRESCALE ((uint32_t)(0x0000000FUL << MXC_F_RTC_PRESCALE_PRESCALE_POS)) + +#define MXC_F_RTC_PRESCALE_MASK_PRESCALE_MASK_POS 0 +#define MXC_F_RTC_PRESCALE_MASK_PRESCALE_MASK ((uint32_t)(0x0000000FUL << MXC_F_RTC_PRESCALE_MASK_PRESCALE_MASK_POS)) + +#define MXC_F_RTC_TRIM_CTRL_TRIM_ENABLE_R_POS 0 +#define MXC_F_RTC_TRIM_CTRL_TRIM_ENABLE_R ((uint32_t)(0x00000001UL << MXC_F_RTC_TRIM_CTRL_TRIM_ENABLE_R_POS)) +#define MXC_F_RTC_TRIM_CTRL_TRIM_FASTER_OVR_R_POS 1 +#define MXC_F_RTC_TRIM_CTRL_TRIM_FASTER_OVR_R ((uint32_t)(0x00000001UL << MXC_F_RTC_TRIM_CTRL_TRIM_FASTER_OVR_R_POS)) +#define MXC_F_RTC_TRIM_CTRL_TRIM_SLOWER_R_POS 2 +#define MXC_F_RTC_TRIM_CTRL_TRIM_SLOWER_R ((uint32_t)(0x00000001UL << MXC_F_RTC_TRIM_CTRL_TRIM_SLOWER_R_POS)) + +#define MXC_F_RTC_TRIM_VALUE_TRIM_VALUE_POS 0 +#define MXC_F_RTC_TRIM_VALUE_TRIM_VALUE ((uint32_t)(0x0003FFFFUL << MXC_F_RTC_TRIM_VALUE_TRIM_VALUE_POS)) +#define MXC_F_RTC_TRIM_VALUE_TRIM_SLOWER_CONTROL_POS 18 +#define MXC_F_RTC_TRIM_VALUE_TRIM_SLOWER_CONTROL ((uint32_t)(0x00000001UL << MXC_F_RTC_TRIM_VALUE_TRIM_SLOWER_CONTROL_POS)) + +#define MXC_F_RTC_NANO_CNTR_NANORING_COUNTER_POS 0 +#define MXC_F_RTC_NANO_CNTR_NANORING_COUNTER ((uint32_t)(0x0000FFFFUL << MXC_F_RTC_NANO_CNTR_NANORING_COUNTER_POS)) + +#define MXC_F_RTC_CLK_CTRL_OSC1_EN_POS 0 +#define MXC_F_RTC_CLK_CTRL_OSC1_EN ((uint32_t)(0x00000001UL << MXC_F_RTC_CLK_CTRL_OSC1_EN_POS)) +#define MXC_F_RTC_CLK_CTRL_OSC2_EN_POS 1 +#define MXC_F_RTC_CLK_CTRL_OSC2_EN ((uint32_t)(0x00000001UL << MXC_F_RTC_CLK_CTRL_OSC2_EN_POS)) +#define MXC_F_RTC_CLK_CTRL_NANO_EN_POS 2 +#define MXC_F_RTC_CLK_CTRL_NANO_EN ((uint32_t)(0x00000001UL << MXC_F_RTC_CLK_CTRL_NANO_EN_POS)) + +#define MXC_F_RTC_OSC_CTRL_OSC_BYPASS_POS 0 +#define MXC_F_RTC_OSC_CTRL_OSC_BYPASS ((uint32_t)(0x00000001UL << MXC_F_RTC_OSC_CTRL_OSC_BYPASS_POS)) +#define MXC_F_RTC_OSC_CTRL_OSC_DISABLE_R_POS 1 +#define MXC_F_RTC_OSC_CTRL_OSC_DISABLE_R ((uint32_t)(0x00000001UL << MXC_F_RTC_OSC_CTRL_OSC_DISABLE_R_POS)) +#define MXC_F_RTC_OSC_CTRL_OSC_DISABLE_SEL_POS 2 +#define MXC_F_RTC_OSC_CTRL_OSC_DISABLE_SEL ((uint32_t)(0x00000001UL << MXC_F_RTC_OSC_CTRL_OSC_DISABLE_SEL_POS)) +#define MXC_F_RTC_OSC_CTRL_OSC_DISABLE_O_POS 3 +#define MXC_F_RTC_OSC_CTRL_OSC_DISABLE_O ((uint32_t)(0x00000001UL << MXC_F_RTC_OSC_CTRL_OSC_DISABLE_O_POS)) +#define MXC_F_RTC_OSC_CTRL_OSC_WARMUP_ENABLE_POS 14 +#define MXC_F_RTC_OSC_CTRL_OSC_WARMUP_ENABLE ((uint32_t)(0x00000001UL << MXC_F_RTC_OSC_CTRL_OSC_WARMUP_ENABLE_POS)) + +/* + Field values +*/ + +#define MXC_V_RTC_CTRL_SNOOZE_DISABLE ((uint32_t)(0x00000000UL)) +#define MXC_V_RTC_CTRL_SNOOZE_MODE_A ((uint32_t)(0x00000001UL)) +#define MXC_V_RTC_CTRL_SNOOZE_MODE_B ((uint32_t)(0x00000002UL)) + +#define MXC_V_RTC_PRESCALE_DIV_2_0 ((uint32_t)(0x00000000UL)) +#define MXC_V_RTC_PRESCALE_DIV_2_1 ((uint32_t)(0x00000001UL)) +#define MXC_V_RTC_PRESCALE_DIV_2_2 ((uint32_t)(0x00000002UL)) +#define MXC_V_RTC_PRESCALE_DIV_2_3 ((uint32_t)(0x00000003UL)) +#define MXC_V_RTC_PRESCALE_DIV_2_4 ((uint32_t)(0x00000004UL)) +#define MXC_V_RTC_PRESCALE_DIV_2_5 ((uint32_t)(0x00000005UL)) +#define MXC_V_RTC_PRESCALE_DIV_2_6 ((uint32_t)(0x00000006UL)) +#define MXC_V_RTC_PRESCALE_DIV_2_7 ((uint32_t)(0x00000007UL)) +#define MXC_V_RTC_PRESCALE_DIV_2_8 ((uint32_t)(0x00000008UL)) +#define MXC_V_RTC_PRESCALE_DIV_2_9 ((uint32_t)(0x00000009UL)) +#define MXC_V_RTC_PRESCALE_DIV_2_10 ((uint32_t)(0x0000000AUL)) +#define MXC_V_RTC_PRESCALE_DIV_2_11 ((uint32_t)(0x0000000BUL)) +#define MXC_V_RTC_PRESCALE_DIV_2_12 ((uint32_t)(0x0000000CUL)) + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_RTC_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/spim_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/spim_regs.h new file mode 100644 index 00000000000..b86e354c39d --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/spim_regs.h @@ -0,0 +1,245 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_SPIM_REGS_H_ +#define _MXC_SPIM_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t mstr_cfg; /* 0x0000 SPI Master Configuration Register */ + __IO uint32_t ss_sr_polarity; /* 0x0004 SPI Master Polarity Control for SS and SR Signals */ + __IO uint32_t gen_ctrl; /* 0x0008 SPI Master General Control Register */ + __IO uint32_t fifo_ctrl; /* 0x000C SPI Master FIFO Control Register */ + __IO uint32_t spcl_ctrl; /* 0x0010 SPI Master Special Mode Controls */ + __IO uint32_t intfl; /* 0x0014 SPI Master Interrupt Flags */ + __IO uint32_t inten; /* 0x0018 SPI Master Interrupt Enable/Disable Settings */ + __IO uint32_t simple_headers; /* 0x001C SPI Master Simple Mode Transaction Headers */ +} mxc_spim_regs_t; + + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + union { /* 0x0000-0x07FC SPI Master FIFO Write Space for Transaction Setup */ + __IO uint8_t trans_8[2048]; + __IO uint16_t trans_16[1024]; + __IO uint32_t trans_32[512]; + }; + union { /* 0x0800-0x0FFC SPI Master FIFO Read Space for Results Data */ + __IO uint8_t rslts_8[2048]; + __IO uint16_t rslts_16[1024]; + __IO uint32_t rslts_32[512]; + }; +} mxc_spim_fifo_regs_t; + + +/* + Register offsets for module SPIM. +*/ + +#define MXC_R_SPIM_OFFS_MSTR_CFG ((uint32_t)0x00000000UL) +#define MXC_R_SPIM_OFFS_SS_SR_POLARITY ((uint32_t)0x00000004UL) +#define MXC_R_SPIM_OFFS_GEN_CTRL ((uint32_t)0x00000008UL) +#define MXC_R_SPIM_OFFS_FIFO_CTRL ((uint32_t)0x0000000CUL) +#define MXC_R_SPIM_OFFS_SPCL_CTRL ((uint32_t)0x00000010UL) +#define MXC_R_SPIM_OFFS_INTFL ((uint32_t)0x00000014UL) +#define MXC_R_SPIM_OFFS_INTEN ((uint32_t)0x00000018UL) +#define MXC_R_SPIM_OFFS_SIMPLE_HEADERS ((uint32_t)0x0000001CUL) +#define MXC_R_SPIM_FIFO_OFFS_TRANS ((uint32_t)0x00000000UL) +#define MXC_R_SPIM_FIFO_OFFS_RSLTS ((uint32_t)0x00000800UL) + + +/* + Field positions and masks for module SPIM. +*/ + +#define MXC_F_SPIM_MSTR_CFG_SLAVE_SEL_POS 0 +#define MXC_F_SPIM_MSTR_CFG_SLAVE_SEL ((uint32_t)(0x00000007UL << MXC_F_SPIM_MSTR_CFG_SLAVE_SEL_POS)) +#define MXC_F_SPIM_MSTR_CFG_THREE_WIRE_MODE_POS 3 +#define MXC_F_SPIM_MSTR_CFG_THREE_WIRE_MODE ((uint32_t)(0x00000001UL << MXC_F_SPIM_MSTR_CFG_THREE_WIRE_MODE_POS)) +#define MXC_F_SPIM_MSTR_CFG_SPI_MODE_POS 4 +#define MXC_F_SPIM_MSTR_CFG_SPI_MODE ((uint32_t)(0x00000003UL << MXC_F_SPIM_MSTR_CFG_SPI_MODE_POS)) +#define MXC_F_SPIM_MSTR_CFG_PAGE_SIZE_POS 6 +#define MXC_F_SPIM_MSTR_CFG_PAGE_SIZE ((uint32_t)(0x00000003UL << MXC_F_SPIM_MSTR_CFG_PAGE_SIZE_POS)) +#define MXC_F_SPIM_MSTR_CFG_SCK_HI_CLK_POS 8 +#define MXC_F_SPIM_MSTR_CFG_SCK_HI_CLK ((uint32_t)(0x0000000FUL << MXC_F_SPIM_MSTR_CFG_SCK_HI_CLK_POS)) +#define MXC_F_SPIM_MSTR_CFG_SCK_LO_CLK_POS 12 +#define MXC_F_SPIM_MSTR_CFG_SCK_LO_CLK ((uint32_t)(0x0000000FUL << MXC_F_SPIM_MSTR_CFG_SCK_LO_CLK_POS)) +#define MXC_F_SPIM_MSTR_CFG_ACT_DELAY_POS 16 +#define MXC_F_SPIM_MSTR_CFG_ACT_DELAY ((uint32_t)(0x00000003UL << MXC_F_SPIM_MSTR_CFG_ACT_DELAY_POS)) +#define MXC_F_SPIM_MSTR_CFG_INACT_DELAY_POS 18 +#define MXC_F_SPIM_MSTR_CFG_INACT_DELAY ((uint32_t)(0x00000003UL << MXC_F_SPIM_MSTR_CFG_INACT_DELAY_POS)) +#define MXC_F_SPIM_MSTR_CFG_SDIO_SAMPLE_POINT_POS 20 +#define MXC_F_SPIM_MSTR_CFG_SDIO_SAMPLE_POINT ((uint32_t)(0x0000000FUL << MXC_F_SPIM_MSTR_CFG_SDIO_SAMPLE_POINT_POS)) + +#define MXC_V_SPIM_MSTR_CFG_PAGE_SIZE_4B ((uint32_t)0x00000000UL) +#define MXC_V_SPIM_MSTR_CFG_PAGE_SIZE_8B ((uint32_t)0x00000001UL) +#define MXC_V_SPIM_MSTR_CFG_PAGE_SIZE_16B ((uint32_t)0x00000002UL) +#define MXC_V_SPIM_MSTR_CFG_PAGE_SIZE_32B ((uint32_t)0x00000003UL) + +#define MXC_S_SPIM_MSTR_CFG_PAGE_4B (MXC_V_SPIM_MSTR_CFG_PAGE_SIZE_4B << MXC_F_SPIM_MSTR_CFG_PAGE_SIZE_POS) +#define MXC_S_SPIM_MSTR_CFG_PAGE_8B (MXC_V_SPIM_MSTR_CFG_PAGE_SIZE_8B << MXC_F_SPIM_MSTR_CFG_PAGE_SIZE_POS) +#define MXC_S_SPIM_MSTR_CFG_PAGE_16B (MXC_V_SPIM_MSTR_CFG_PAGE_SIZE_16B << MXC_F_SPIM_MSTR_CFG_PAGE_SIZE_POS) +#define MXC_S_SPIM_MSTR_CFG_PAGE_32B (MXC_V_SPIM_MSTR_CFG_PAGE_SIZE_32B << MXC_F_SPIM_MSTR_CFG_PAGE_SIZE_POS) + +#define MXC_F_SPIM_SS_SR_POLARITY_SS_POLARITY_POS 0 +#define MXC_F_SPIM_SS_SR_POLARITY_SS_POLARITY ((uint32_t)(0x000000FFUL << MXC_F_SPIM_SS_SR_POLARITY_SS_POLARITY_POS)) +#define MXC_F_SPIM_SS_SR_POLARITY_FC_POLARITY_POS 8 +#define MXC_F_SPIM_SS_SR_POLARITY_FC_POLARITY ((uint32_t)(0x000000FFUL << MXC_F_SPIM_SS_SR_POLARITY_FC_POLARITY_POS)) + +#define MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN_POS 0 +#define MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN ((uint32_t)(0x00000001UL << MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN_POS)) +#define MXC_F_SPIM_GEN_CTRL_TX_FIFO_EN_POS 1 +#define MXC_F_SPIM_GEN_CTRL_TX_FIFO_EN ((uint32_t)(0x00000001UL << MXC_F_SPIM_GEN_CTRL_TX_FIFO_EN_POS)) +#define MXC_F_SPIM_GEN_CTRL_RX_FIFO_EN_POS 2 +#define MXC_F_SPIM_GEN_CTRL_RX_FIFO_EN ((uint32_t)(0x00000001UL << MXC_F_SPIM_GEN_CTRL_RX_FIFO_EN_POS)) +#define MXC_F_SPIM_GEN_CTRL_BIT_BANG_MODE_POS 3 +#define MXC_F_SPIM_GEN_CTRL_BIT_BANG_MODE ((uint32_t)(0x00000001UL << MXC_F_SPIM_GEN_CTRL_BIT_BANG_MODE_POS)) +#define MXC_F_SPIM_GEN_CTRL_BB_SS_IN_OUT_POS 4 +#define MXC_F_SPIM_GEN_CTRL_BB_SS_IN_OUT ((uint32_t)(0x00000001UL << MXC_F_SPIM_GEN_CTRL_BB_SS_IN_OUT_POS)) +#define MXC_F_SPIM_GEN_CTRL_BB_SR_IN_POS 5 +#define MXC_F_SPIM_GEN_CTRL_BB_SR_IN ((uint32_t)(0x00000001UL << MXC_F_SPIM_GEN_CTRL_BB_SR_IN_POS)) +#define MXC_F_SPIM_GEN_CTRL_BB_SCK_IN_OUT_POS 6 +#define MXC_F_SPIM_GEN_CTRL_BB_SCK_IN_OUT ((uint32_t)(0x00000001UL << MXC_F_SPIM_GEN_CTRL_BB_SCK_IN_OUT_POS)) +#define MXC_F_SPIM_GEN_CTRL_BB_SDIO_IN_POS 8 +#define MXC_F_SPIM_GEN_CTRL_BB_SDIO_IN ((uint32_t)(0x0000000FUL << MXC_F_SPIM_GEN_CTRL_BB_SDIO_IN_POS)) +#define MXC_F_SPIM_GEN_CTRL_BB_SDIO_OUT_POS 12 +#define MXC_F_SPIM_GEN_CTRL_BB_SDIO_OUT ((uint32_t)(0x0000000FUL << MXC_F_SPIM_GEN_CTRL_BB_SDIO_OUT_POS)) +#define MXC_F_SPIM_GEN_CTRL_BB_SDIO_DR_EN_POS 16 +#define MXC_F_SPIM_GEN_CTRL_BB_SDIO_DR_EN ((uint32_t)(0x0000000FUL << MXC_F_SPIM_GEN_CTRL_BB_SDIO_DR_EN_POS)) +#define MXC_F_SPIM_GEN_CTRL_SIMPLE_MODE_POS 20 +#define MXC_F_SPIM_GEN_CTRL_SIMPLE_MODE ((uint32_t)(0x00000001UL << MXC_F_SPIM_GEN_CTRL_SIMPLE_MODE_POS)) +#define MXC_F_SPIM_GEN_CTRL_START_RX_ONLY_POS 21 +#define MXC_F_SPIM_GEN_CTRL_START_RX_ONLY ((uint32_t)(0x00000001UL << MXC_F_SPIM_GEN_CTRL_START_RX_ONLY_POS)) +#define MXC_F_SPIM_GEN_CTRL_DEASSERT_ACT_SS_POS 22 +#define MXC_F_SPIM_GEN_CTRL_DEASSERT_ACT_SS ((uint32_t)(0x00000001UL << MXC_F_SPIM_GEN_CTRL_DEASSERT_ACT_SS_POS)) +#define MXC_F_SPIM_GEN_CTRL_ENABLE_SCK_FB_MODE_POS 24 +#define MXC_F_SPIM_GEN_CTRL_ENABLE_SCK_FB_MODE ((uint32_t)(0x00000001UL << MXC_F_SPIM_GEN_CTRL_ENABLE_SCK_FB_MODE_POS)) +#define MXC_F_SPIM_GEN_CTRL_INVERT_SCK_FB_CLK_POS 25 +#define MXC_F_SPIM_GEN_CTRL_INVERT_SCK_FB_CLK ((uint32_t)(0x00000001UL << MXC_F_SPIM_GEN_CTRL_INVERT_SCK_FB_CLK_POS)) + +#define MXC_F_SPIM_FIFO_CTRL_TX_FIFO_AE_LVL_POS 0 +#define MXC_F_SPIM_FIFO_CTRL_TX_FIFO_AE_LVL ((uint32_t)(0x0000000FUL << MXC_F_SPIM_FIFO_CTRL_TX_FIFO_AE_LVL_POS)) +#define MXC_F_SPIM_FIFO_CTRL_TX_FIFO_USED_POS 8 +#define MXC_F_SPIM_FIFO_CTRL_TX_FIFO_USED ((uint32_t)(0x0000001FUL << MXC_F_SPIM_FIFO_CTRL_TX_FIFO_USED_POS)) +#define MXC_F_SPIM_FIFO_CTRL_RX_FIFO_AF_LVL_POS 16 +#define MXC_F_SPIM_FIFO_CTRL_RX_FIFO_AF_LVL ((uint32_t)(0x0000001FUL << MXC_F_SPIM_FIFO_CTRL_RX_FIFO_AF_LVL_POS)) +#define MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED_POS 24 +#define MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED ((uint32_t)(0x0000003FUL << MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED_POS)) + +#define MXC_F_SPIM_SPCL_CTRL_SS_SAMPLE_MODE_POS 0 +#define MXC_F_SPIM_SPCL_CTRL_SS_SAMPLE_MODE ((uint32_t)(0x00000001UL << MXC_F_SPIM_SPCL_CTRL_SS_SAMPLE_MODE_POS)) +#define MXC_F_SPIM_SPCL_CTRL_MISO_FC_EN_POS 1 +#define MXC_F_SPIM_SPCL_CTRL_MISO_FC_EN ((uint32_t)(0x00000001UL << MXC_F_SPIM_SPCL_CTRL_MISO_FC_EN_POS)) +#define MXC_F_SPIM_SPCL_CTRL_SS_SA_SDIO_OUT_POS 4 +#define MXC_F_SPIM_SPCL_CTRL_SS_SA_SDIO_OUT ((uint32_t)(0x0000000FUL << MXC_F_SPIM_SPCL_CTRL_SS_SA_SDIO_OUT_POS)) +#define MXC_F_SPIM_SPCL_CTRL_SS_SA_SDIO_DR_EN_POS 8 +#define MXC_F_SPIM_SPCL_CTRL_SS_SA_SDIO_DR_EN ((uint32_t)(0x0000000FUL << MXC_F_SPIM_SPCL_CTRL_SS_SA_SDIO_DR_EN_POS)) + +#if (MXC_SPIM_REV == 0) +#define MXC_F_SPIM_SPCL_CTRL_SPECIAL_MODE_3_EN_POS 16 +#define MXC_F_SPIM_SPCL_CTRL_SPECIAL_MODE_3_EN ((uint32_t)(0x00000001UL << MXC_F_SPIM_SPCL_CTRL_SPECIAL_MODE_3_EN_POS)) +#else +#define MXC_F_SPIM_SPCL_CTRL_RX_FIFO_MARGIN_POS 12 +#define MXC_F_SPIM_SPCL_CTRL_RX_FIFO_MARGIN ((uint32_t)(0x00000007UL << MXC_F_SPIM_SPCL_CTRL_RX_FIFO_MARGIN_POS)) +#define MXC_F_SPIM_SPCL_CTRL_SCK_FB_DELAY_POS 16 +#define MXC_F_SPIM_SPCL_CTRL_SCK_FB_DELAY ((uint32_t)(0x0000000FUL << MXC_F_SPIM_SPCL_CTRL_SCK_FB_DELAY_POS)) +#define MXC_F_SPIM_SPCL_CTRL_SPARE_RESERVED_POS 20 +#define MXC_F_SPIM_SPCL_CTRL_SPARE_RESERVED ((uint32_t)(0x00000FFFUL << MXC_F_SPIM_SPCL_CTRL_SPARE_RESERVED_POS)) +#endif + +#define MXC_F_SPIM_INTFL_TX_STALLED_POS 0 +#define MXC_F_SPIM_INTFL_TX_STALLED ((uint32_t)(0x00000001UL << MXC_F_SPIM_INTFL_TX_STALLED_POS)) +#define MXC_F_SPIM_INTFL_RX_STALLED_POS 1 +#define MXC_F_SPIM_INTFL_RX_STALLED ((uint32_t)(0x00000001UL << MXC_F_SPIM_INTFL_RX_STALLED_POS)) +#define MXC_F_SPIM_INTFL_TX_READY_POS 2 +#define MXC_F_SPIM_INTFL_TX_READY ((uint32_t)(0x00000001UL << MXC_F_SPIM_INTFL_TX_READY_POS)) +#define MXC_F_SPIM_INTFL_RX_DONE_POS 3 +#define MXC_F_SPIM_INTFL_RX_DONE ((uint32_t)(0x00000001UL << MXC_F_SPIM_INTFL_RX_DONE_POS)) +#define MXC_F_SPIM_INTFL_TX_FIFO_AE_POS 4 +#define MXC_F_SPIM_INTFL_TX_FIFO_AE ((uint32_t)(0x00000001UL << MXC_F_SPIM_INTFL_TX_FIFO_AE_POS)) +#define MXC_F_SPIM_INTFL_RX_FIFO_AF_POS 5 +#define MXC_F_SPIM_INTFL_RX_FIFO_AF ((uint32_t)(0x00000001UL << MXC_F_SPIM_INTFL_RX_FIFO_AF_POS)) + +#define MXC_F_SPIM_INTEN_TX_STALLED_POS 0 +#define MXC_F_SPIM_INTEN_TX_STALLED ((uint32_t)(0x00000001UL << MXC_F_SPIM_INTEN_TX_STALLED_POS)) +#define MXC_F_SPIM_INTEN_RX_STALLED_POS 1 +#define MXC_F_SPIM_INTEN_RX_STALLED ((uint32_t)(0x00000001UL << MXC_F_SPIM_INTEN_RX_STALLED_POS)) +#define MXC_F_SPIM_INTEN_TX_READY_POS 2 +#define MXC_F_SPIM_INTEN_TX_READY ((uint32_t)(0x00000001UL << MXC_F_SPIM_INTEN_TX_READY_POS)) +#define MXC_F_SPIM_INTEN_RX_DONE_POS 3 +#define MXC_F_SPIM_INTEN_RX_DONE ((uint32_t)(0x00000001UL << MXC_F_SPIM_INTEN_RX_DONE_POS)) +#define MXC_F_SPIM_INTEN_TX_FIFO_AE_POS 4 +#define MXC_F_SPIM_INTEN_TX_FIFO_AE ((uint32_t)(0x00000001UL << MXC_F_SPIM_INTEN_TX_FIFO_AE_POS)) +#define MXC_F_SPIM_INTEN_RX_FIFO_AF_POS 5 +#define MXC_F_SPIM_INTEN_RX_FIFO_AF ((uint32_t)(0x00000001UL << MXC_F_SPIM_INTEN_RX_FIFO_AF_POS)) + +#define MXC_F_SPIM_SIMPLE_HEADERS_TX_BIDIR_HEADER_POS 0 +#define MXC_F_SPIM_SIMPLE_HEADERS_TX_BIDIR_HEADER ((uint32_t)(0x00003FFFUL << MXC_F_SPIM_SIMPLE_HEADERS_TX_BIDIR_HEADER_POS)) +#define MXC_F_SPIM_SIMPLE_HEADERS_RX_ONLY_HEADER_POS 16 +#define MXC_F_SPIM_SIMPLE_HEADERS_RX_ONLY_HEADER ((uint32_t)(0x00003FFFUL << MXC_F_SPIM_SIMPLE_HEADERS_RX_ONLY_HEADER_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_SPIM_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/spis_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/spis_regs.h new file mode 100644 index 00000000000..e5e6de89322 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/spis_regs.h @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_SPIS_REGS_H_ +#define _MXC_SPIS_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t gen_ctrl; /* 0x0000 SPI Slave General Control Register */ + __IO uint32_t fifo_ctrl; /* 0x0004 SPI Slave FIFO Control Register */ + __IO uint32_t fifo_stat; /* 0x0008 SPI Slave FIFO Status Register */ + __IO uint32_t intfl; /* 0x000C SPI Slave Interrupt Flags */ + __IO uint32_t inten; /* 0x0010 SPI Slave Interrupt Enable/Disable Settings */ +} mxc_spis_regs_t; + + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + union { /* 0x0000-0x07FC SPI Slave FIFO TX Write Space */ + __IO uint8_t tx_8[2048]; + __IO uint16_t tx_16[1024]; + __IO uint32_t tx_32[512]; + }; + union { /* 0x0800-0x0FFC FIFO Read Space for Results Data */ + __IO uint8_t rx_8[2048]; + __IO uint16_t rx_16[1024]; + __IO uint32_t rx_32[512]; + }; +} mxc_spis_fifo_regs_t; + + +/* + Register offsets for module SPIS. +*/ + +#define MXC_R_SPIS_OFFS_GEN_CTRL ((uint32_t)0x00000000UL) +#define MXC_R_SPIS_OFFS_FIFO_CTRL ((uint32_t)0x00000004UL) +#define MXC_R_SPIS_OFFS_FIFO_STAT ((uint32_t)0x00000008UL) +#define MXC_R_SPIS_OFFS_INTFL ((uint32_t)0x0000000CUL) +#define MXC_R_SPIS_OFFS_INTEN ((uint32_t)0x00000010UL) +#define MXC_R_SPIS_FIFO_OFFS_TX ((uint32_t)0x00000000UL) +#define MXC_R_SPIS_FIFO_OFFS_RX ((uint32_t)0x00000800UL) + + +/* + Field positions and masks for module SPIS. +*/ + +#define MXC_F_SPIS_GEN_CTRL_SPI_SLAVE_EN_POS 0 +#define MXC_F_SPIS_GEN_CTRL_SPI_SLAVE_EN ((uint32_t)(0x00000001UL << MXC_F_SPIS_GEN_CTRL_SPI_SLAVE_EN_POS)) +#define MXC_F_SPIS_GEN_CTRL_TX_FIFO_EN_POS 1 +#define MXC_F_SPIS_GEN_CTRL_TX_FIFO_EN ((uint32_t)(0x00000001UL << MXC_F_SPIS_GEN_CTRL_TX_FIFO_EN_POS)) +#define MXC_F_SPIS_GEN_CTRL_RX_FIFO_EN_POS 2 +#define MXC_F_SPIS_GEN_CTRL_RX_FIFO_EN ((uint32_t)(0x00000001UL << MXC_F_SPIS_GEN_CTRL_RX_FIFO_EN_POS)) +#define MXC_F_SPIS_GEN_CTRL_DATA_WIDTH_POS 4 +#define MXC_F_SPIS_GEN_CTRL_DATA_WIDTH ((uint32_t)(0x00000003UL << MXC_F_SPIS_GEN_CTRL_DATA_WIDTH_POS)) +#define MXC_F_SPIS_GEN_CTRL_SPI_MODE_POS 16 +#define MXC_F_SPIS_GEN_CTRL_SPI_MODE ((uint32_t)(0x00000003UL << MXC_F_SPIS_GEN_CTRL_SPI_MODE_POS)) +#define MXC_F_SPIS_GEN_CTRL_TX_CLK_INVERT_POS 20 +#define MXC_F_SPIS_GEN_CTRL_TX_CLK_INVERT ((uint32_t)(0x00000001UL << MXC_F_SPIS_GEN_CTRL_TX_CLK_INVERT_POS)) + +#define MXC_F_SPIS_FIFO_CTRL_TX_FIFO_AE_LVL_POS 0 +#define MXC_F_SPIS_FIFO_CTRL_TX_FIFO_AE_LVL ((uint32_t)(0x0000001FUL << MXC_F_SPIS_FIFO_CTRL_TX_FIFO_AE_LVL_POS)) +#define MXC_F_SPIS_FIFO_CTRL_RX_FIFO_AF_LVL_POS 8 +#define MXC_F_SPIS_FIFO_CTRL_RX_FIFO_AF_LVL ((uint32_t)(0x0000001FUL << MXC_F_SPIS_FIFO_CTRL_RX_FIFO_AF_LVL_POS)) + +#define MXC_F_SPIS_FIFO_STAT_TX_FIFO_USED_POS 0 +#define MXC_F_SPIS_FIFO_STAT_TX_FIFO_USED ((uint32_t)(0x0000003FUL << MXC_F_SPIS_FIFO_STAT_TX_FIFO_USED_POS)) +#define MXC_F_SPIS_FIFO_STAT_RX_FIFO_USED_POS 8 +#define MXC_F_SPIS_FIFO_STAT_RX_FIFO_USED ((uint32_t)(0x0000003FUL << MXC_F_SPIS_FIFO_STAT_RX_FIFO_USED_POS)) + +#define MXC_F_SPIS_INTFL_TX_FIFO_AE_POS 0 +#define MXC_F_SPIS_INTFL_TX_FIFO_AE ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTFL_TX_FIFO_AE_POS)) +#define MXC_F_SPIS_INTFL_RX_FIFO_AF_POS 1 +#define MXC_F_SPIS_INTFL_RX_FIFO_AF ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTFL_RX_FIFO_AF_POS)) +#define MXC_F_SPIS_INTFL_TX_NO_DATA_POS 2 +#define MXC_F_SPIS_INTFL_TX_NO_DATA ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTFL_TX_NO_DATA_POS)) +#define MXC_F_SPIS_INTFL_RX_LOST_DATA_POS 3 +#define MXC_F_SPIS_INTFL_RX_LOST_DATA ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTFL_RX_LOST_DATA_POS)) +#define MXC_F_SPIS_INTFL_TX_UNDERFLOW_POS 4 +#define MXC_F_SPIS_INTFL_TX_UNDERFLOW ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTFL_TX_UNDERFLOW_POS)) +#define MXC_F_SPIS_INTFL_SS_ASSERTED_POS 5 +#define MXC_F_SPIS_INTFL_SS_ASSERTED ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTFL_SS_ASSERTED_POS)) +#define MXC_F_SPIS_INTFL_SS_DEASSERTED_POS 6 +#define MXC_F_SPIS_INTFL_SS_DEASSERTED ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTFL_SS_DEASSERTED_POS)) + +#define MXC_F_SPIS_INTEN_TX_FIFO_AE_POS 0 +#define MXC_F_SPIS_INTEN_TX_FIFO_AE ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTEN_TX_FIFO_AE_POS)) +#define MXC_F_SPIS_INTEN_RX_FIFO_AF_POS 1 +#define MXC_F_SPIS_INTEN_RX_FIFO_AF ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTEN_RX_FIFO_AF_POS)) +#define MXC_F_SPIS_INTEN_TX_NO_DATA_POS 2 +#define MXC_F_SPIS_INTEN_TX_NO_DATA ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTEN_TX_NO_DATA_POS)) +#define MXC_F_SPIS_INTEN_RX_LOST_DATA_POS 3 +#define MXC_F_SPIS_INTEN_RX_LOST_DATA ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTEN_RX_LOST_DATA_POS)) +#define MXC_F_SPIS_INTEN_TX_UNDERFLOW_POS 4 +#define MXC_F_SPIS_INTEN_TX_UNDERFLOW ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTEN_TX_UNDERFLOW_POS)) +#define MXC_F_SPIS_INTEN_SS_ASSERTED_POS 5 +#define MXC_F_SPIS_INTEN_SS_ASSERTED ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTEN_SS_ASSERTED_POS)) +#define MXC_F_SPIS_INTEN_SS_DEASSERTED_POS 6 +#define MXC_F_SPIS_INTEN_SS_DEASSERTED ((uint32_t)(0x00000001UL << MXC_F_SPIS_INTEN_SS_DEASSERTED_POS)) + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_SPIS_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/spix_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/spix_regs.h new file mode 100644 index 00000000000..8fa9ab81388 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/spix_regs.h @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_SPIX_REGS_H_ +#define _MXC_SPIX_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t master_cfg; /* 0x0000 SPIX Master Configuration */ + __IO uint32_t fetch_ctrl; /* 0x0004 SPIX Fetch Control */ + __IO uint32_t mode_ctrl; /* 0x0008 SPIX Mode Control */ + __IO uint32_t mode_data; /* 0x000C SPIX Mode Data */ + __IO uint32_t sck_fb_ctrl; /* 0x0010 SPIX SCK_FB Control Register */ +} mxc_spix_regs_t; + + +/* + Register offsets for module SPIX. +*/ + +#define MXC_R_SPIX_OFFS_MASTER_CFG ((uint32_t)0x00000000UL) +#define MXC_R_SPIX_OFFS_FETCH_CTRL ((uint32_t)0x00000004UL) +#define MXC_R_SPIX_OFFS_MODE_CTRL ((uint32_t)0x00000008UL) +#define MXC_R_SPIX_OFFS_MODE_DATA ((uint32_t)0x0000000CUL) +#define MXC_R_SPIX_OFFS_SCK_FB_CTRL ((uint32_t)0x00000010UL) + + +/* + Field positions and masks for module SPIX. +*/ + +#define MXC_F_SPIX_MASTER_CFG_SPI_MODE_POS 0 +#define MXC_F_SPIX_MASTER_CFG_SPI_MODE ((uint32_t)(0x00000003UL << MXC_F_SPIX_MASTER_CFG_SPI_MODE_POS)) +#define MXC_F_SPIX_MASTER_CFG_SS_ACT_LO_POS 2 +#define MXC_F_SPIX_MASTER_CFG_SS_ACT_LO ((uint32_t)(0x00000001UL << MXC_F_SPIX_MASTER_CFG_SS_ACT_LO_POS)) +#define MXC_F_SPIX_MASTER_CFG_ALT_TIMING_EN_POS 3 +#define MXC_F_SPIX_MASTER_CFG_ALT_TIMING_EN ((uint32_t)(0x00000001UL << MXC_F_SPIX_MASTER_CFG_ALT_TIMING_EN_POS)) +#define MXC_F_SPIX_MASTER_CFG_SLAVE_SEL_POS 4 +#define MXC_F_SPIX_MASTER_CFG_SLAVE_SEL ((uint32_t)(0x00000007UL << MXC_F_SPIX_MASTER_CFG_SLAVE_SEL_POS)) +#define MXC_F_SPIX_MASTER_CFG_SCK_LO_CLK_POS 8 +#define MXC_F_SPIX_MASTER_CFG_SCK_LO_CLK ((uint32_t)(0x0000000FUL << MXC_F_SPIX_MASTER_CFG_SCK_LO_CLK_POS)) +#define MXC_F_SPIX_MASTER_CFG_SCK_HI_CLK_POS 12 +#define MXC_F_SPIX_MASTER_CFG_SCK_HI_CLK ((uint32_t)(0x0000000FUL << MXC_F_SPIX_MASTER_CFG_SCK_HI_CLK_POS)) +#define MXC_F_SPIX_MASTER_CFG_ACT_DELAY_POS 16 +#define MXC_F_SPIX_MASTER_CFG_ACT_DELAY ((uint32_t)(0x00000003UL << MXC_F_SPIX_MASTER_CFG_ACT_DELAY_POS)) +#define MXC_F_SPIX_MASTER_CFG_INACT_DELAY_POS 18 +#define MXC_F_SPIX_MASTER_CFG_INACT_DELAY ((uint32_t)(0x00000003UL << MXC_F_SPIX_MASTER_CFG_INACT_DELAY_POS)) +#define MXC_F_SPIX_MASTER_CFG_ALT_SCK_LO_CLK_POS 20 +#define MXC_F_SPIX_MASTER_CFG_ALT_SCK_LO_CLK ((uint32_t)(0x0000000FUL << MXC_F_SPIX_MASTER_CFG_ALT_SCK_LO_CLK_POS)) +#define MXC_F_SPIX_MASTER_CFG_ALT_SCK_HI_CLK_POS 24 +#define MXC_F_SPIX_MASTER_CFG_ALT_SCK_HI_CLK ((uint32_t)(0x0000000FUL << MXC_F_SPIX_MASTER_CFG_ALT_SCK_HI_CLK_POS)) +#define MXC_F_SPIX_MASTER_CFG_SDIO_SAMPLE_POINT_POS 28 +#define MXC_F_SPIX_MASTER_CFG_SDIO_SAMPLE_POINT ((uint32_t)(0x0000000FUL << MXC_F_SPIX_MASTER_CFG_SDIO_SAMPLE_POINT_POS)) + +#define MXC_F_SPIX_FETCH_CTRL_CMD_VALUE_POS 0 +#define MXC_F_SPIX_FETCH_CTRL_CMD_VALUE ((uint32_t)(0x000000FFUL << MXC_F_SPIX_FETCH_CTRL_CMD_VALUE_POS)) +#define MXC_F_SPIX_FETCH_CTRL_CMD_WIDTH_POS 8 +#define MXC_F_SPIX_FETCH_CTRL_CMD_WIDTH ((uint32_t)(0x00000003UL << MXC_F_SPIX_FETCH_CTRL_CMD_WIDTH_POS)) +#define MXC_F_SPIX_FETCH_CTRL_ADDR_WIDTH_POS 10 +#define MXC_F_SPIX_FETCH_CTRL_ADDR_WIDTH ((uint32_t)(0x00000003UL << MXC_F_SPIX_FETCH_CTRL_ADDR_WIDTH_POS)) +#define MXC_F_SPIX_FETCH_CTRL_DATA_WIDTH_POS 12 +#define MXC_F_SPIX_FETCH_CTRL_DATA_WIDTH ((uint32_t)(0x00000003UL << MXC_F_SPIX_FETCH_CTRL_DATA_WIDTH_POS)) +#define MXC_F_SPIX_FETCH_CTRL_FOUR_BYTE_ADDR_POS 16 +#define MXC_F_SPIX_FETCH_CTRL_FOUR_BYTE_ADDR ((uint32_t)(0x00000001UL << MXC_F_SPIX_FETCH_CTRL_FOUR_BYTE_ADDR_POS)) + +#define MXC_F_SPIX_MODE_CTRL_MODE_CLOCKS_POS 0 +#define MXC_F_SPIX_MODE_CTRL_MODE_CLOCKS ((uint32_t)(0x0000000FUL << MXC_F_SPIX_MODE_CTRL_MODE_CLOCKS_POS)) +#define MXC_F_SPIX_MODE_CTRL_NO_CMD_MODE_POS 8 +#define MXC_F_SPIX_MODE_CTRL_NO_CMD_MODE ((uint32_t)(0x00000001UL << MXC_F_SPIX_MODE_CTRL_NO_CMD_MODE_POS)) + +#define MXC_F_SPIX_MODE_DATA_MODE_DATA_BITS_POS 0 +#define MXC_F_SPIX_MODE_DATA_MODE_DATA_BITS ((uint32_t)(0x0000FFFFUL << MXC_F_SPIX_MODE_DATA_MODE_DATA_BITS_POS)) +#define MXC_F_SPIX_MODE_DATA_MODE_DATA_OE_POS 16 +#define MXC_F_SPIX_MODE_DATA_MODE_DATA_OE ((uint32_t)(0x0000FFFFUL << MXC_F_SPIX_MODE_DATA_MODE_DATA_OE_POS)) + +#define MXC_F_SPIX_SCK_FB_CTRL_ENABLE_SCK_FB_MODE_POS 0 +#define MXC_F_SPIX_SCK_FB_CTRL_ENABLE_SCK_FB_MODE ((uint32_t)(0x00000001UL << MXC_F_SPIX_SCK_FB_CTRL_ENABLE_SCK_FB_MODE_POS)) +#define MXC_F_SPIX_SCK_FB_CTRL_INVERT_SCK_FB_CLK_POS 1 +#define MXC_F_SPIX_SCK_FB_CTRL_INVERT_SCK_FB_CLK ((uint32_t)(0x00000001UL << MXC_F_SPIX_SCK_FB_CTRL_INVERT_SCK_FB_CLK_POS)) + +#if(MXC_SPIX_REV == 0) +#define MXC_F_SPIX_SCK_FB_CTRL_IGNORE_CLKS_POS 4 +#define MXC_F_SPIX_SCK_FB_CTRL_IGNORE_CLKS ((uint32_t)(0x0000003FUL << MXC_F_SPIX_SCK_FB_CTRL_IGNORE_CLKS_POS)) +#define MXC_F_SPIX_SCK_FB_CTRL_IGNORE_CLKS_NO_CMD_POS 12 +#define MXC_F_SPIX_SCK_FB_CTRL_IGNORE_CLKS_NO_CMD ((uint32_t)(0x0000003FUL << MXC_F_SPIX_SCK_FB_CTRL_IGNORE_CLKS_NO_CMD_POS)) +#endif + + +/* + Field values and shifted values for module SPIX. +*/ + +#define MXC_V_SPIX_MASTER_CFG_SPI_MODE_SCK_HI_SAMPLE_RISING ((uint32_t)(0x00000000UL)) +#define MXC_V_SPIX_MASTER_CFG_SPI_MODE_SCK_LO_SAMPLE_FALLING ((uint32_t)(0x00000003UL)) + +#define MXC_S_SPIX_MASTER_CFG_SPI_MODE_SCK_HI_SAMPLE_RISING ((uint32_t)(MXC_V_SPIX_MASTER_CFG_SPI_MODE_SCK_HI_SAMPLE_RISING << MXC_F_SPIX_MASTER_CFG_SPI_MODE_POS)) +#define MXC_S_SPIX_MASTER_CFG_SPI_MODE_SCK_LO_SAMPLE_FALLING ((uint32_t)(MXC_V_SPIX_MASTER_CFG_SPI_MODE_SCK_LO_SAMPLE_FALLING << MXC_F_SPIX_MASTER_CFG_SPI_MODE_POS)) + +#define MXC_V_SPIX_MASTER_CFG_SS_ACT_LO_ACTIVE_HIGH ((uint32_t)(0x00000000UL)) +#define MXC_V_SPIX_MASTER_CFG_SS_ACT_LO_ACTIVE_LOW ((uint32_t)(0x00000001UL)) + +#define MXC_S_SPIX_MASTER_CFG_SS_ACT_LO_ACTIVE_HIGH ((uint32_t)(MXC_V_SPIX_MASTER_CFG_SS_ACT_LO_ACTIVE_HIGH << MXC_F_SPIX_MASTER_CFG_SS_ACT_LO_POS)) +#define MXC_S_SPIX_MASTER_CFG_SS_ACT_LO_ACTIVE_LOW ((uint32_t)(MXC_V_SPIX_MASTER_CFG_SS_ACT_LO_ACTIVE_LOW << MXC_F_SPIX_MASTER_CFG_SS_ACT_LO_POS)) + +#define MXC_V_SPIX_MASTER_CFG_ALT_TIMING_EN_DISABLED ((uint32_t)(0x00000000UL)) +#define MXC_V_SPIX_MASTER_CFG_ALT_TIMING_EN_ENABLED_AS_NEEDED ((uint32_t)(0x00000001UL)) + +#define MXC_S_SPIX_MASTER_CFG_ALT_TIMING_EN_DISABLED ((uint32_t)(MXC_V_SPIX_MASTER_CFG_ALT_TIMING_EN_DISABLED << MXC_F_SPIX_MASTER_CFG_ALT_TIMING_EN_POS)) +#define MXC_S_SPIX_MASTER_CFG_ALT_TIMING_EN_ENABLED_AS_NEEDED ((uint32_t)(MXC_V_SPIX_MASTER_CFG_ALT_TIMING_EN_ENABLED_AS_NEEDED << MXC_F_SPIX_MASTER_CFG_ALT_TIMING_EN_POS)) + +#define MXC_V_SPIX_MASTER_CFG_ACT_DELAY_OFF ((uint32_t)(0x00000000UL)) +#define MXC_V_SPIX_MASTER_CFG_ACT_DELAY_FOR_2_MOD_CLK ((uint32_t)(0x00000001UL)) +#define MXC_V_SPIX_MASTER_CFG_ACT_DELAY_FOR_4_MOD_CLK ((uint32_t)(0x00000002UL)) +#define MXC_V_SPIX_MASTER_CFG_ACT_DELAY_FOR_8_MOD_CLK ((uint32_t)(0x00000003UL)) + +#define MXC_S_SPIX_MASTER_CFG_ACT_DELAY_OFF ((uint32_t)(MXC_V_SPIX_MASTER_CFG_ACT_DELAY_OFF << MXC_F_SPIX_MASTER_CFG_ACT_DELAY_POS)) +#define MXC_S_SPIX_MASTER_CFG_ACT_DELAY_FOR_2_MOD_CLK ((uint32_t)(MXC_V_SPIX_MASTER_CFG_ACT_DELAY_FOR_2_MOD_CLK << MXC_F_SPIX_MASTER_CFG_ACT_DELAY_POS)) +#define MXC_S_SPIX_MASTER_CFG_ACT_DELAY_FOR_4_MOD_CLK ((uint32_t)(MXC_V_SPIX_MASTER_CFG_ACT_DELAY_FOR_4_MOD_CLK << MXC_F_SPIX_MASTER_CFG_ACT_DELAY_POS)) +#define MXC_S_SPIX_MASTER_CFG_ACT_DELAY_FOR_8_MOD_CLK ((uint32_t)(MXC_V_SPIX_MASTER_CFG_ACT_DELAY_FOR_8_MOD_CLK << MXC_F_SPIX_MASTER_CFG_ACT_DELAY_POS)) + +#define MXC_V_SPIX_MASTER_CFG_INACT_DELAY_OFF ((uint32_t)(0x00000000UL)) +#define MXC_V_SPIX_MASTER_CFG_INACT_DELAY_FOR_2_MOD_CLK ((uint32_t)(0x00000001UL)) +#define MXC_V_SPIX_MASTER_CFG_INACT_DELAY_FOR_4_MOD_CLK ((uint32_t)(0x00000002UL)) +#define MXC_V_SPIX_MASTER_CFG_INACT_DELAY_FOR_8_MOD_CLK ((uint32_t)(0x00000003UL)) + +#define MXC_S_SPIX_MASTER_CFG_INACT_DELAY_OFF ((uint32_t)(MXC_V_SPIX_MASTER_CFG_INACT_DELAY_OFF << MXC_F_SPIX_MASTER_CFG_INACT_DELAY_POS)) +#define MXC_S_SPIX_MASTER_CFG_INACT_DELAY_FOR_2_MOD_CLK ((uint32_t)(MXC_V_SPIX_MASTER_CFG_INACT_DELAY_FOR_2_MOD_CLK << MXC_F_SPIX_MASTER_CFG_INACT_DELAY_POS)) +#define MXC_S_SPIX_MASTER_CFG_INACT_DELAY_FOR_4_MOD_CLK ((uint32_t)(MXC_V_SPIX_MASTER_CFG_INACT_DELAY_FOR_4_MOD_CLK << MXC_F_SPIX_MASTER_CFG_INACT_DELAY_POS)) +#define MXC_S_SPIX_MASTER_CFG_INACT_DELAY_FOR_8_MOD_CLK ((uint32_t)(MXC_V_SPIX_MASTER_CFG_INACT_DELAY_FOR_8_MOD_CLK << MXC_F_SPIX_MASTER_CFG_INACT_DELAY_POS)) + +#define MXC_V_SPIX_FETCH_CTRL_CMD_WIDTH_SINGLE ((uint32_t)(0x00000000UL)) +#define MXC_V_SPIX_FETCH_CTRL_CMD_WIDTH_DUAL_IO ((uint32_t)(0x00000001UL)) +#define MXC_V_SPIX_FETCH_CTRL_CMD_WIDTH_QUAD_IO ((uint32_t)(0x00000002UL)) + +#define MXC_S_SPIX_FETCH_CTRL_CMD_WIDTH_SINGLE ((uint32_t)(MXC_V_SPIX_FETCH_CTRL_CMD_WIDTH_SINGLE << MXC_F_SPIX_FETCH_CTRL_CMD_WIDTH_POS)) +#define MXC_S_SPIX_FETCH_CTRL_CMD_WIDTH_DUAL_IO ((uint32_t)(MXC_V_SPIX_FETCH_CTRL_CMD_WIDTH_DUAL_IO << MXC_F_SPIX_FETCH_CTRL_CMD_WIDTH_POS)) +#define MXC_S_SPIX_FETCH_CTRL_CMD_WIDTH_QUAD_IO ((uint32_t)(MXC_V_SPIX_FETCH_CTRL_CMD_WIDTH_QUAD_IO << MXC_F_SPIX_FETCH_CTRL_CMD_WIDTH_POS)) + +#define MXC_V_SPIX_FETCH_CTRL_ADDR_WIDTH_SINGLE ((uint32_t)(0x00000000UL)) +#define MXC_V_SPIX_FETCH_CTRL_ADDR_WIDTH_DUAL_IO ((uint32_t)(0x00000001UL)) +#define MXC_V_SPIX_FETCH_CTRL_ADDR_WIDTH_QUAD_IO ((uint32_t)(0x00000002UL)) + +#define MXC_S_SPIX_FETCH_CTRL_ADDR_WIDTH_SINGLE ((uint32_t)(MXC_V_SPIX_FETCH_CTRL_ADDR_WIDTH_SINGLE << MXC_F_SPIX_FETCH_CTRL_ADDR_WIDTH_POS)) +#define MXC_S_SPIX_FETCH_CTRL_ADDR_WIDTH_DUAL_IO ((uint32_t)(MXC_V_SPIX_FETCH_CTRL_ADDR_WIDTH_DUAL_IO << MXC_F_SPIX_FETCH_CTRL_ADDR_WIDTH_POS)) +#define MXC_S_SPIX_FETCH_CTRL_ADDR_WIDTH_QUAD_IO ((uint32_t)(MXC_V_SPIX_FETCH_CTRL_ADDR_WIDTH_QUAD_IO << MXC_F_SPIX_FETCH_CTRL_ADDR_WIDTH_POS)) + +#define MXC_V_SPIX_FETCH_CTRL_DATA_WIDTH_SINGLE ((uint32_t)(0x00000000UL)) +#define MXC_V_SPIX_FETCH_CTRL_DATA_WIDTH_DUAL_IO ((uint32_t)(0x00000001UL)) +#define MXC_V_SPIX_FETCH_CTRL_DATA_WIDTH_QUAD_IO ((uint32_t)(0x00000002UL)) + +#define MXC_S_SPIX_FETCH_CTRL_DATA_WIDTH_SINGLE ((uint32_t)(MXC_V_SPIX_FETCH_CTRL_DATA_WIDTH_SINGLE << MXC_F_SPIX_FETCH_CTRL_DATA_WIDTH_POS)) +#define MXC_S_SPIX_FETCH_CTRL_DATA_WIDTH_DUAL_IO ((uint32_t)(MXC_V_SPIX_FETCH_CTRL_DATA_WIDTH_DUAL_IO << MXC_F_SPIX_FETCH_CTRL_DATA_WIDTH_POS)) +#define MXC_S_SPIX_FETCH_CTRL_DATA_WIDTH_QUAD_IO ((uint32_t)(MXC_V_SPIX_FETCH_CTRL_DATA_WIDTH_QUAD_IO << MXC_F_SPIX_FETCH_CTRL_DATA_WIDTH_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_SPIX_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/sysman_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/sysman_regs.h new file mode 100644 index 00000000000..4af5a856c22 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/sysman_regs.h @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_SYSMAN_REGS_H_ +#define _MXC_SYSMAN_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t pvt_monitor; /* 0x0000 System Clock Configuration */ +} mxc_sysman_regs_t; + + +/* + Register offsets for module SYSMAN. +*/ + +#define MXC_R_SYSMAN_OFFS_PVT_MONITOR ((uint32_t)0x00000000UL) + + +/* + Field positions and masks for module SYSMAN. +*/ + +#define MXC_F_SYSMAN_PVT_MONITOR_CODE_POS 0 +#define MXC_F_SYSMAN_PVT_MONITOR_CODE ((uint32_t)(0xFFFFFFFFUL << MXC_F_SYSMAN_PVT_MONITOR_CODE_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_SYSMAN_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/system_max32625.c b/targets/TARGET_Maxim/TARGET_MAX32625/device/system_max32625.c new file mode 100644 index 00000000000..4f77b211671 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/system_max32625.c @@ -0,0 +1,263 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#include +#include +#include +#include "max32625.h" +#include "clkman_regs.h" +#include "adc_regs.h" +#include "pwrseq_regs.h" +#include "pwrman_regs.h" +#include "icc_regs.h" +#include "flc_regs.h" +#include "rtc_regs.h" +#include "trim_regs.h" + +#ifndef RO_FREQ +#define RO_FREQ 96000000 +#endif + +#ifndef LP0_POST_HOOK +#define LP0_POST_HOOK +#endif + +// NOTE: Setting the CMSIS SystemCoreClock value to the actual value it will +// be AFTER SystemInit() runs. This is required so the hal drivers will have +// the correct value when the DATA sections are initialized. +uint32_t SystemCoreClock = RO_FREQ; + +void SystemCoreClockUpdate(void) +{ + if (MXC_PWRSEQ->reg0 & MXC_F_PWRSEQ_REG0_PWR_RCEN_RUN) { + /* 4 MHz source */ + if (MXC_PWRSEQ->reg3 & MXC_F_PWRSEQ_REG3_PWR_RC_DIV) { + SystemCoreClock = (4000000 / (0x1 << ((MXC_PWRSEQ->reg3 & MXC_F_PWRSEQ_REG3_PWR_RC_DIV) >> + MXC_F_PWRSEQ_REG3_PWR_RC_DIV_POS))); + } else { + SystemCoreClock = 4000000; + } + } else { + /* 96 MHz source */ + if (MXC_PWRSEQ->reg3 & MXC_F_PWRSEQ_REG3_PWR_RO_DIV) { + SystemCoreClock = (RO_FREQ / (0x1 << ((MXC_PWRSEQ->reg3 & MXC_F_PWRSEQ_REG3_PWR_RO_DIV) >> + MXC_F_PWRSEQ_REG3_PWR_RO_DIV_POS))); + } else { + SystemCoreClock = RO_FREQ; + } + } +} + +void CLKMAN_TrimRO(void) +{ + uint32_t running; + uint32_t trim; + + /* Step 1: enable 32KHz RTC */ + running = MXC_PWRSEQ->reg0 & MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN; + MXC_PWRSEQ->reg0 |= MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN; + + /* Wait for RTC warm-up */ + while(MXC_RTCCFG->osc_ctrl & MXC_F_RTC_OSC_CTRL_OSC_WARMUP_ENABLE) {} + + /* Step 2: enable RO calibration complete interrupt */ + MXC_ADC->intr |= MXC_F_ADC_INTR_RO_CAL_DONE_IE; + + /* Step 3: clear RO calibration complete interrupt */ + MXC_ADC->intr |= MXC_F_ADC_INTR_RO_CAL_DONE_IF; + + /* Step 4: -- NO LONGER NEEDED / HANDLED BY STARTUP CODE -- */ + + /* Step 5: write initial trim to frequency calibration initial condition register */ + trim = (MXC_PWRSEQ->reg6 & MXC_F_PWRSEQ_REG6_PWR_TRIM_OSC_VREF) >> MXC_F_PWRSEQ_REG6_PWR_TRIM_OSC_VREF_POS; + MXC_ADC->ro_cal1 = (MXC_ADC->ro_cal1 & ~MXC_F_ADC_RO_CAL1_TRM_INIT) | + ((trim << MXC_F_ADC_RO_CAL1_TRM_INIT_POS) & MXC_F_ADC_RO_CAL1_TRM_INIT); + + /* Step 6: load initial trim to active frequency trim register */ + MXC_ADC->ro_cal0 |= MXC_F_ADC_RO_CAL0_RO_CAL_LOAD; + + /* Step 7: enable frequency loop to control RO trim */ + MXC_ADC->ro_cal0 |= MXC_F_ADC_RO_CAL0_RO_CAL_EN; + + /* Step 8: run frequency calibration in atomic mode */ + MXC_ADC->ro_cal0 |= MXC_F_ADC_RO_CAL0_RO_CAL_ATOMIC; + + /* Step 9: waiting for ro_cal_done flag */ + while(!(MXC_ADC->intr & MXC_F_ADC_INTR_RO_CAL_DONE_IF)); + + /* Step 10: stop frequency calibration */ + MXC_ADC->ro_cal0 &= ~MXC_F_ADC_RO_CAL0_RO_CAL_RUN; + + /* Step 11: disable RO calibration complete interrupt */ + MXC_ADC->intr &= ~MXC_F_ADC_INTR_RO_CAL_DONE_IE; + + /* Step 12: read final frequency trim value */ + trim = (MXC_ADC->ro_cal0 & MXC_F_ADC_RO_CAL0_RO_TRM) >> MXC_F_ADC_RO_CAL0_RO_TRM_POS; + + /* Step 13: write final trim to RO flash trim shadow register */ + MXC_PWRSEQ->reg6 = (MXC_PWRSEQ->reg6 & ~MXC_F_PWRSEQ_REG6_PWR_TRIM_OSC_VREF) | + ((trim << MXC_F_PWRSEQ_REG6_PWR_TRIM_OSC_VREF_POS) & MXC_F_PWRSEQ_REG6_PWR_TRIM_OSC_VREF); + + /* Step 14: restore RTC status */ + if (!running) { + MXC_PWRSEQ->reg0 &= ~MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN; + } + + /* Step 15: disable frequency loop to control RO trim */ + MXC_ADC->ro_cal0 &= ~MXC_F_ADC_RO_CAL0_RO_CAL_EN; +} + +static void ICC_Enable(void) +{ + /* Invalidate cache and wait until ready */ + MXC_ICC->invdt_all = 1; + while (!(MXC_ICC->ctrl_stat & MXC_F_ICC_CTRL_STAT_READY)); + + /* Enable cache */ + MXC_ICC->ctrl_stat |= MXC_F_ICC_CTRL_STAT_ENABLE; + + /* Must invalidate a second time for proper use */ + MXC_ICC->invdt_all = 1; +} + +/* This function is called before C runtime initialization and can be + * implemented by the application for early initializations. If a value other + * than '0' is returned, the C runtime initialization will be skipped. + * + * You may over-ride this function in your program by defining a custom + * PreInit(), but care should be taken to reproduce the initialization steps + * or a non-functional system may result. + */ +__weak int PreInit(void) +{ + /* Increase system clock to 96 MHz */ + MXC_CLKMAN->clk_ctrl = MXC_V_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT_96MHZ_RO; + + /* Performance-measurement hook, may be defined as nothing */ + LP0_POST_HOOK; + + /* Enable cache here to reduce boot time */ + ICC_Enable(); + + return 0; +} + +/* This function is called just before control is transferred to main(). + */ +void SystemInit(void) +{ + /* Copy trim information from shadow registers into power manager registers */ + /* NOTE: Checks have been added to prevent bad/missing trim values from being loaded */ + if ((MXC_FLC->ctrl & MXC_F_FLC_CTRL_INFO_BLOCK_VALID) && + (MXC_TRIM->for_pwr_reg5 != 0xffffffff) && + (MXC_TRIM->for_pwr_reg6 != 0xffffffff)) { + MXC_PWRSEQ->reg5 = MXC_TRIM->for_pwr_reg5; + MXC_PWRSEQ->reg6 = MXC_TRIM->for_pwr_reg6; + } else { + /* No valid info block, use some reasonable defaults */ + MXC_PWRSEQ->reg6 &= ~MXC_F_PWRSEQ_REG6_PWR_TRIM_OSC_VREF; + MXC_PWRSEQ->reg6 |= (0x1e0 << MXC_F_PWRSEQ_REG6_PWR_TRIM_OSC_VREF_POS); + } + + /* Improve flash access timing */ + MXC_FLC->perform |= (MXC_F_FLC_PERFORM_EN_BACK2BACK_RDS | + MXC_F_FLC_PERFORM_EN_MERGE_GRAB_GNT | + MXC_F_FLC_PERFORM_AUTO_TACC | + MXC_F_FLC_PERFORM_AUTO_CLKDIV); + + /* First, eliminate the unnecessary RTC handshake between clock domains. Must be set as a pair. */ + MXC_RTCTMR->ctrl |= (MXC_F_RTC_CTRL_USE_ASYNC_FLAGS | + MXC_F_RTC_CTRL_AGGRESSIVE_RST); + + /* Enable fast read of the RTC timer value, and fast write of all other RTC registers */ + MXC_PWRSEQ->rtc_ctrl2 |= (MXC_F_PWRSEQ_RTC_CTRL2_TIMER_AUTO_UPDATE | + MXC_F_PWRSEQ_RTC_CTRL2_TIMER_ASYNC_WR); + MXC_PWRSEQ->rtc_ctrl2 &= ~MXC_F_PWRSEQ_RTC_CTRL2_TIMER_ASYNC_RD; + + /* Clear the GPIO WUD event if not waking up from LP0 */ + /* this is necessary because WUD flops come up in undetermined state out of POR or SRST*/ + if ((MXC_PWRSEQ->reg0 & MXC_F_PWRSEQ_REG0_PWR_FIRST_BOOT) || + !(MXC_PWRMAN->pwr_rst_ctrl & MXC_F_PWRMAN_PWR_RST_CTRL_POR)) { + /* Clear GPIO WUD event and configuration registers, globally */ + MXC_PWRSEQ->reg1 |= (MXC_F_PWRSEQ_REG1_PWR_CLR_IO_EVENT_LATCH | + MXC_F_PWRSEQ_REG1_PWR_CLR_IO_CFG_LATCH); + MXC_PWRSEQ->reg1 &= ~(MXC_F_PWRSEQ_REG1_PWR_CLR_IO_EVENT_LATCH | + MXC_F_PWRSEQ_REG1_PWR_CLR_IO_CFG_LATCH); + } else { + /* Unfreeze the GPIO by clearing MBUS_GATE, when returning from LP0 */ + MXC_PWRSEQ->reg1 &= ~MXC_F_PWRSEQ_REG1_PWR_MBUS_GATE; + /* LP0 wake-up: Turn off special switch to eliminate ~50nA of leakage on VDD12 */ + MXC_PWRSEQ->reg1 &= ~MXC_F_PWRSEQ_REG1_PWR_SRAM_NWELL_SW; + } + + /* Turn on retention regulator */ + MXC_PWRSEQ->reg0 |= (MXC_F_PWRSEQ_REG0_PWR_RETREGEN_RUN | + MXC_F_PWRSEQ_REG0_PWR_RETREGEN_SLP); + + /* Turn on Auto GPIO Freeze/UnFreeze in sleep modes */ + MXC_PWRSEQ->reg1 |= MXC_F_PWRSEQ_REG1_PWR_AUTO_MBUS_GATE; + + /* Adjust settings in the retention controller for fastest wake-up time */ + MXC_PWRSEQ->retn_ctrl0 |= (MXC_F_PWRSEQ_RETN_CTRL0_RC_REL_CCG_EARLY | + MXC_F_PWRSEQ_RETN_CTRL0_RC_POLL_FLASH); + MXC_PWRSEQ->retn_ctrl0 &= ~MXC_F_PWRSEQ_RETN_CTRL0_RC_USE_FLC_TWK; + + + /* Set retention controller TWake cycle count to 1us to minimize the wake-up time */ + /* NOTE: flash polling (...PWRSEQ_RETN_CTRL0_RC_POLL_FLASH) must be enabled before changing POR default! */ + MXC_PWRSEQ->retn_ctrl1 = (MXC_PWRSEQ->retn_ctrl1 & ~MXC_F_PWRSEQ_RETN_CTRL1_RC_TWK) | + (1 << MXC_F_PWRSEQ_RETN_CTRL1_RC_TWK_POS); + + /* Improve wake-up time by changing ROSEL to 140ns */ + MXC_PWRSEQ->reg3 = (1 << MXC_F_PWRSEQ_REG3_PWR_ROSEL_POS) | + (1 << MXC_F_PWRSEQ_REG3_PWR_FAILSEL_POS) | + (MXC_PWRSEQ->reg3 & ~(MXC_F_PWRSEQ_REG3_PWR_ROSEL | + MXC_F_PWRSEQ_REG3_PWR_FLTRROSEL)); + + /* Enable RTOS Mode: Enable 32kHz clock synchronizer to SysTick external clock input */ + MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_RTOS_MODE; + + /* Set this so all bits of PWR_MSK_FLAGS are active low to mask the corresponding flags */ + MXC_PWRSEQ->pwr_misc |= MXC_F_PWRSEQ_PWR_MISC_INVERT_4_MASK_BITS; + +#if (__FPU_PRESENT == 1) + /* Enable FPU on Cortex-M4, which occupies coprocessor slots 10 & 11 */ + /* Grant full access, per "Table B3-24 CPACR bit assignments". */ + /* DDI0403D "ARMv7-M Architecture Reference Manual" */ + SCB->CPACR |= SCB_CPACR_CP10_Msk | SCB_CPACR_CP11_Msk; + __DSB(); + __ISB(); +#endif + + /* Perform an initial trim of the internal ring oscillator */ + CLKMAN_TrimRO(); +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/system_max32625.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/system_max32625.h new file mode 100644 index 00000000000..cfb45ad891d --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/system_max32625.h @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _SYSTEM_MAX32625_H_ +#define _SYSTEM_MAX32625_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ +#ifndef HFXIN_FREQ +#define HFXIN_FREQ 8000000 +#endif + +#ifndef RO_FREQ +#define RO_FREQ 96000000 +#endif + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/* + * Initialize the system + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit(void); + +/* + * Update SystemCoreClock variable + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYSTEM_MAX32625_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/tmr_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/tmr_regs.h new file mode 100644 index 00000000000..ea37cac1f30 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/tmr_regs.h @@ -0,0 +1,203 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_TMR_REGS_H_ +#define _MXC_TMR_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t ctrl; /* 0x0000 Timer Control Register */ + __IO uint32_t count32; /* 0x0004 Timer [32 bit] Current Count Value */ + __IO uint32_t term_cnt32; /* 0x0008 Timer [32 bit] Terminal Count Setting */ + __IO uint32_t pwm_cap32; /* 0x000C Timer [32 bit] PWM Compare Setting or Capture/Measure Value */ + __IO uint32_t count16_0; /* 0x0010 Timer [16 bit] Current Count Value, 16-bit Timer 0 */ + __IO uint32_t term_cnt16_0; /* 0x0014 Timer [16 bit] Terminal Count Setting, 16-bit Timer 0 */ + __IO uint32_t count16_1; /* 0x0018 Timer [16 bit] Current Count Value, 16-bit Timer 1 */ + __IO uint32_t term_cnt16_1; /* 0x001C Timer [16 bit] Terminal Count Setting, 16-bit Timer 1 */ + __IO uint32_t intfl; /* 0x0020 Timer Interrupt Flags */ + __IO uint32_t inten; /* 0x0024 Timer Interrupt Enable/Disable Settings */ +} mxc_tmr_regs_t; + + +/* + Register offsets for module TMR. +*/ + +#define MXC_R_TMR_OFFS_CTRL ((uint32_t)0x00000000UL) +#define MXC_R_TMR_OFFS_COUNT32 ((uint32_t)0x00000004UL) +#define MXC_R_TMR_OFFS_TERM_CNT32 ((uint32_t)0x00000008UL) +#define MXC_R_TMR_OFFS_PWM_CAP32 ((uint32_t)0x0000000CUL) +#define MXC_R_TMR_OFFS_COUNT16_0 ((uint32_t)0x00000010UL) +#define MXC_R_TMR_OFFS_TERM_CNT16_0 ((uint32_t)0x00000014UL) +#define MXC_R_TMR_OFFS_COUNT16_1 ((uint32_t)0x00000018UL) +#define MXC_R_TMR_OFFS_TERM_CNT16_1 ((uint32_t)0x0000001CUL) +#define MXC_R_TMR_OFFS_INTFL ((uint32_t)0x00000020UL) +#define MXC_R_TMR_OFFS_INTEN ((uint32_t)0x00000024UL) + + +/* + Field positions and masks for module TMR. +*/ + +#define MXC_F_TMR_CTRL_MODE_POS 0 +#define MXC_F_TMR_CTRL_MODE ((uint32_t)(0x00000007UL << MXC_F_TMR_CTRL_MODE_POS)) +#define MXC_F_TMR_CTRL_TMR2X16_POS 3 +#define MXC_F_TMR_CTRL_TMR2X16 ((uint32_t)(0x00000001UL << MXC_F_TMR_CTRL_TMR2X16_POS)) +#define MXC_F_TMR_CTRL_PRESCALE_POS 4 +#define MXC_F_TMR_CTRL_PRESCALE ((uint32_t)(0x0000000FUL << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_F_TMR_CTRL_POLARITY_POS 8 +#define MXC_F_TMR_CTRL_POLARITY ((uint32_t)(0x00000001UL << MXC_F_TMR_CTRL_POLARITY_POS)) +#define MXC_F_TMR_CTRL_ENABLE0_POS 12 +#define MXC_F_TMR_CTRL_ENABLE0 ((uint32_t)(0x00000001UL << MXC_F_TMR_CTRL_ENABLE0_POS)) +#define MXC_F_TMR_CTRL_ENABLE1_POS 13 +#define MXC_F_TMR_CTRL_ENABLE1 ((uint32_t)(0x00000001UL << MXC_F_TMR_CTRL_ENABLE1_POS)) + +#define MXC_F_TMR_COUNT16_0_VALUE_POS 0 +#define MXC_F_TMR_COUNT16_0_VALUE ((uint32_t)(0x0000FFFFUL << MXC_F_TMR_COUNT16_0_VALUE_POS)) + +#define MXC_F_TMR_TERM_CNT16_0_TERM_COUNT_POS 0 +#define MXC_F_TMR_TERM_CNT16_0_TERM_COUNT ((uint32_t)(0x0000FFFFUL << MXC_F_TMR_TERM_CNT16_0_TERM_COUNT_POS)) + +#define MXC_F_TMR_COUNT16_1_VALUE_POS 0 +#define MXC_F_TMR_COUNT16_1_VALUE ((uint32_t)(0x0000FFFFUL << MXC_F_TMR_COUNT16_1_VALUE_POS)) + +#define MXC_F_TMR_TERM_CNT16_1_TERM_COUNT_POS 0 +#define MXC_F_TMR_TERM_CNT16_1_TERM_COUNT ((uint32_t)(0x0000FFFFUL << MXC_F_TMR_TERM_CNT16_1_TERM_COUNT_POS)) + +#define MXC_F_TMR_INTFL_TIMER0_POS 0 +#define MXC_F_TMR_INTFL_TIMER0 ((uint32_t)(0x00000001UL << MXC_F_TMR_INTFL_TIMER0_POS)) +#define MXC_F_TMR_INTFL_TIMER1_POS 1 +#define MXC_F_TMR_INTFL_TIMER1 ((uint32_t)(0x00000001UL << MXC_F_TMR_INTFL_TIMER1_POS)) + +#define MXC_F_TMR_INTEN_TIMER0_POS 0 +#define MXC_F_TMR_INTEN_TIMER0 ((uint32_t)(0x00000001UL << MXC_F_TMR_INTEN_TIMER0_POS)) +#define MXC_F_TMR_INTEN_TIMER1_POS 1 +#define MXC_F_TMR_INTEN_TIMER1 ((uint32_t)(0x00000001UL << MXC_F_TMR_INTEN_TIMER1_POS)) + + + +/* + Field values and shifted values for module TMR. +*/ + +#define MXC_V_TMR_CTRL_MODE_ONE_SHOT ((uint32_t)(0x00000000UL)) +#define MXC_V_TMR_CTRL_MODE_CONTINUOUS ((uint32_t)(0x00000001UL)) +#define MXC_V_TMR_CTRL_MODE_COUNTER ((uint32_t)(0x00000002UL)) +#define MXC_V_TMR_CTRL_MODE_PWM ((uint32_t)(0x00000003UL)) +#define MXC_V_TMR_CTRL_MODE_CAPTURE ((uint32_t)(0x00000004UL)) +#define MXC_V_TMR_CTRL_MODE_COMPARE ((uint32_t)(0x00000005UL)) +#define MXC_V_TMR_CTRL_MODE_GATED ((uint32_t)(0x00000006UL)) +#define MXC_V_TMR_CTRL_MODE_MEASURE ((uint32_t)(0x00000007UL)) + +#define MXC_S_TMR_CTRL_MODE_ONE_SHOT ((uint32_t)(MXC_V_TMR_CTRL_MODE_ONE_SHOT << MXC_F_TMR_CTRL_MODE_POS)) +#define MXC_S_TMR_CTRL_MODE_CONTINUOUS ((uint32_t)(MXC_V_TMR_CTRL_MODE_CONTINUOUS << MXC_F_TMR_CTRL_MODE_POS)) +#define MXC_S_TMR_CTRL_MODE_COUNTER ((uint32_t)(MXC_V_TMR_CTRL_MODE_COUNTER << MXC_F_TMR_CTRL_MODE_POS)) +#define MXC_S_TMR_CTRL_MODE_PWM ((uint32_t)(MXC_V_TMR_CTRL_MODE_PWM << MXC_F_TMR_CTRL_MODE_POS)) +#define MXC_S_TMR_CTRL_MODE_CAPTURE ((uint32_t)(MXC_V_TMR_CTRL_MODE_CAPTURE << MXC_F_TMR_CTRL_MODE_POS)) +#define MXC_S_TMR_CTRL_MODE_COMPARE ((uint32_t)(MXC_V_TMR_CTRL_MODE_COMPARE << MXC_F_TMR_CTRL_MODE_POS)) +#define MXC_S_TMR_CTRL_MODE_GATED ((uint32_t)(MXC_V_TMR_CTRL_MODE_GATED << MXC_F_TMR_CTRL_MODE_POS)) +#define MXC_S_TMR_CTRL_MODE_MEASURE ((uint32_t)(MXC_V_TMR_CTRL_MODE_MEASURE << MXC_F_TMR_CTRL_MODE_POS)) + +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_1 ((uint32_t)(0x00000000UL)) +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_2 ((uint32_t)(0x00000001UL)) +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_4 ((uint32_t)(0x00000002UL)) +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_8 ((uint32_t)(0x00000003UL)) +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_16 ((uint32_t)(0x00000004UL)) +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_32 ((uint32_t)(0x00000005UL)) +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_64 ((uint32_t)(0x00000006UL)) +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_128 ((uint32_t)(0x00000007UL)) +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_256 ((uint32_t)(0x00000008UL)) +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_512 ((uint32_t)(0x00000009UL)) +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_1024 ((uint32_t)(0x0000000AUL)) +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_2048 ((uint32_t)(0x0000000BUL)) +#define MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_4096 ((uint32_t)(0x0000000CUL)) + +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_1 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_1 << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_2 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_2 << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_4 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_4 << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_8 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_8 << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_16 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_16 << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_32 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_32 << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_64 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_64 << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_128 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_128 << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_256 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_256 << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_512 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_512 << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_1024 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_1024 << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_2048 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_2048 << MXC_F_TMR_CTRL_PRESCALE_POS)) +#define MXC_S_TMR_CTRL_PRESCALE_DIVIDE_BY_4096 ((uint32_t)(MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_4096 << MXC_F_TMR_CTRL_PRESCALE_POS)) + + +/* + * These two 1-bit fields replace the standard 3-bit mode field when the associated TMR module + * is in dual 16-bit timer mode. + */ + +#define MXC_F_TMR_CTRL_MODE_16_0_POS 0 +#define MXC_F_TMR_CTRL_MODE_16_0 ((uint32_t)(0x00000001UL << MXC_F_TMR_CTRL_MODE_16_0_POS)) + +#define MXC_F_TMR_CTRL_MODE_16_1_POS 1 +#define MXC_F_TMR_CTRL_MODE_16_1 ((uint32_t)(0x00000001UL << MXC_F_TMR_CTRL_MODE_16_1_POS)) + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_TMR_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/tpu_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/tpu_regs.h new file mode 100644 index 00000000000..f115124ecbb --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/tpu_regs.h @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_TPU_REGS_H_ +#define _MXC_TPU_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __I uint32_t rsv000[4]; /* 0x0000-0x000C */ + __IO uint32_t sks0; /* 0x0010 TPU Secure Key Storage Register 0 (Cleared on Tamper Detect) */ + __IO uint32_t sks1; /* 0x0014 TPU Secure Key Storage Register 1 (Cleared on Tamper Detect) */ + __IO uint32_t sks2; /* 0x0018 TPU Secure Key Storage Register 2 (Cleared on Tamper Detect) */ + __IO uint32_t sks3; /* 0x001C TPU Secure Key Storage Register 3 (Cleared on Tamper Detect) */ +} mxc_tpu_tsr_regs_t; + + +/* + Register offsets for module TPU. +*/ + +#define MXC_R_TPU_TSR_OFFS_SKS0 ((uint32_t)0x00000010UL) +#define MXC_R_TPU_TSR_OFFS_SKS1 ((uint32_t)0x00000014UL) +#define MXC_R_TPU_TSR_OFFS_SKS2 ((uint32_t)0x00000018UL) +#define MXC_R_TPU_TSR_OFFS_SKS3 ((uint32_t)0x0000001CUL) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_TPU_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/trim_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/trim_regs.h new file mode 100644 index 00000000000..fa11fa838ad --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/trim_regs.h @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_TRIM_REGS_H_ +#define _MXC_TRIM_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __I uint32_t rsv000[10]; /* 0x0000-0x0024 */ + __IO uint32_t reg10_mem_size; /* 0x0028 Shadow Trim for Flash and SRAM Memory Size */ + __IO uint32_t reg11_adc_trim0; /* 0x002C Shadow Trim for ADC R0 */ + __IO uint32_t reg12_adc_trim1; /* 0x0030 Shadow Trim for ADC R1 */ + __IO uint32_t for_pwr_reg5; /* 0x0034 Shadow Trim for PWRSEQ Register REG5 */ + __IO uint32_t for_pwr_reg6; /* 0x0038 Shadow Trim for PWRSEQ Register REG6 */ + __IO uint32_t for_pwr_reg7; /* 0x003C Shadow Trim for PWRSEQ Register REG7 */ +} mxc_trim_regs_t; + + +/* + Register offsets for module TRIM. +*/ + +#define MXC_R_TRIM_OFFS_REG10_MEM_SIZE ((uint32_t)0x00000028UL) +#define MXC_R_TRIM_OFFS_REG11_ADC_TRIM0 ((uint32_t)0x0000002CUL) +#define MXC_R_TRIM_OFFS_REG12_ADC_TRIM1 ((uint32_t)0x00000030UL) +#define MXC_R_TRIM_OFFS_FOR_PWR_REG5 ((uint32_t)0x00000034UL) +#define MXC_R_TRIM_OFFS_FOR_PWR_REG6 ((uint32_t)0x00000038UL) +#define MXC_R_TRIM_OFFS_FOR_PWR_REG7 ((uint32_t)0x0000003CUL) + + +/* + Field positions and masks for module TRIM. +*/ + +#define MXC_F_TRIM_REG10_MEM_SIZE_SRAM_POS 0 +#define MXC_F_TRIM_REG10_MEM_SIZE_SRAM ((uint32_t)(0x00000003UL << MXC_F_TRIM_REG10_MEM_SIZE_SRAM_POS)) +#define MXC_F_TRIM_REG10_MEM_SIZE_FLASH_POS 2 +#define MXC_F_TRIM_REG10_MEM_SIZE_FLASH ((uint32_t)(0x00000007UL << MXC_F_TRIM_REG10_MEM_SIZE_FLASH_POS)) + +#define MXC_V_TRIM_REG10_MEM_SRAM_FULL_SIZE ((uint32_t)(0x00000000UL)) +#define MXC_V_TRIM_REG10_MEM_SRAM_THREE_FOURTHS_SIZE ((uint32_t)(0x00000001UL)) +#define MXC_V_TRIM_REG10_MEM_SRAM_HALF_SIZE ((uint32_t)(0x00000002UL)) + +#define MXC_V_TRIM_REG10_MEM_FLASH_FULL_SIZE ((uint32_t)(0x00000000UL)) +#define MXC_V_TRIM_REG10_MEM_FLASH_THREE_FOURTHS_SIZE ((uint32_t)(0x00000001UL)) +#define MXC_V_TRIM_REG10_MEM_FLASH_HALF_SIZE ((uint32_t)(0x00000002UL)) +#define MXC_V_TRIM_REG10_MEM_FLASH_THREE_EIGHTHS_SIZE ((uint32_t)(0x00000003UL)) +#define MXC_V_TRIM_REG10_MEM_FLASH_FOURTH_SIZE ((uint32_t)(0x00000004UL)) + +#define MXC_F_TRIM_REG11_ADC_TRIM0_ADCTRIM_X0R0_POS 0 +#define MXC_F_TRIM_REG11_ADC_TRIM0_ADCTRIM_X0R0 ((uint32_t)(0x000003FFUL << MXC_F_TRIM_REG11_ADC_TRIM0_ADCTRIM_X0R0_POS)) +#define MXC_F_TRIM_REG11_ADC_TRIM0_ADCTRIM_X1R0_POS 16 +#define MXC_F_TRIM_REG11_ADC_TRIM0_ADCTRIM_X1R0 ((uint32_t)(0x000003FFUL << MXC_F_TRIM_REG11_ADC_TRIM0_ADCTRIM_X1R0_POS)) + +#define MXC_F_TRIM_REG12_ADC_TRIM1_ADCTRIM_X0R1_POS 0 +#define MXC_F_TRIM_REG12_ADC_TRIM1_ADCTRIM_X0R1 ((uint32_t)(0x000003FFUL << MXC_F_TRIM_REG12_ADC_TRIM1_ADCTRIM_X0R1_POS)) +#define MXC_F_TRIM_REG12_ADC_TRIM1_ADCTRIM_X1R1_POS 16 +#define MXC_F_TRIM_REG12_ADC_TRIM1_ADCTRIM_X1R1 ((uint32_t)(0x000003FFUL << MXC_F_TRIM_REG12_ADC_TRIM1_ADCTRIM_X1R1_POS)) +#define MXC_F_TRIM_REG12_ADC_TRIM1_ADCTRIM_DC_POS 28 +#define MXC_F_TRIM_REG12_ADC_TRIM1_ADCTRIM_DC ((uint32_t)(0x0000000FUL << MXC_F_TRIM_REG12_ADC_TRIM1_ADCTRIM_DC_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_TRIM_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/uart_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/uart_regs.h new file mode 100644 index 00000000000..df320ea520a --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/uart_regs.h @@ -0,0 +1,240 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_UART_REGS_H_ +#define _MXC_UART_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t ctrl; /* 0x0000 UART Control Register */ + __IO uint32_t baud; /* 0x0004 UART Baud Control Register */ + __IO uint32_t tx_fifo_ctrl; /* 0x0008 UART TX FIFO Control Register */ + __IO uint32_t rx_fifo_ctrl; /* 0x000C UART RX FIFO Control Register */ + __IO uint32_t md_ctrl; /* 0x0010 UART Multidrop Control Register */ + __IO uint32_t intfl; /* 0x0014 UART Interrupt Flags */ + __IO uint32_t inten; /* 0x0018 UART Interrupt Enable/Disable Controls */ +#if (MXC_UART_REV > 0) + __I uint32_t idle; /* 0x001C UART Idle Status */ +#endif +} mxc_uart_regs_t; + + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + union { /* 0x0000-0x07FC FIFO Write Point for Data to Transmit */ + __IO uint8_t tx; + __IO uint8_t tx_8[2048]; + __IO uint16_t tx_16[1024]; + __IO uint32_t tx_32[512]; + }; + union { /* 0x0800-0x0FFC FIFO Read Point for Received Data */ + __IO uint8_t rx; + __IO uint8_t rx_8[2048]; + __IO uint16_t rx_16[1024]; + __IO uint32_t rx_32[512]; + }; +} mxc_uart_fifo_regs_t; + + +/* + Register offsets for module UART. +*/ + +#define MXC_R_UART_OFFS_CTRL ((uint32_t)0x00000000UL) +#define MXC_R_UART_OFFS_BAUD ((uint32_t)0x00000004UL) +#define MXC_R_UART_OFFS_TX_FIFO_CTRL ((uint32_t)0x00000008UL) +#define MXC_R_UART_OFFS_RX_FIFO_CTRL ((uint32_t)0x0000000CUL) +#define MXC_R_UART_OFFS_MD_CTRL ((uint32_t)0x00000010UL) +#define MXC_R_UART_OFFS_INTFL ((uint32_t)0x00000014UL) +#define MXC_R_UART_OFFS_INTEN ((uint32_t)0x00000018UL) +#define MXC_R_UART_FIFO_OFFS_TX ((uint32_t)0x00000000UL) +#define MXC_R_UART_FIFO_OFFS_RX ((uint32_t)0x00000800UL) + + +/* + Field positions and masks for module UART. +*/ + +#define MXC_F_UART_CTRL_UART_EN_POS 0 +#define MXC_F_UART_CTRL_UART_EN ((uint32_t)(0x00000001UL << MXC_F_UART_CTRL_UART_EN_POS)) +#define MXC_F_UART_CTRL_RX_FIFO_EN_POS 1 +#define MXC_F_UART_CTRL_RX_FIFO_EN ((uint32_t)(0x00000001UL << MXC_F_UART_CTRL_RX_FIFO_EN_POS)) +#define MXC_F_UART_CTRL_TX_FIFO_EN_POS 2 +#define MXC_F_UART_CTRL_TX_FIFO_EN ((uint32_t)(0x00000001UL << MXC_F_UART_CTRL_TX_FIFO_EN_POS)) +#define MXC_F_UART_CTRL_DATA_SIZE_POS 4 +#define MXC_F_UART_CTRL_DATA_SIZE ((uint32_t)(0x00000003UL << MXC_F_UART_CTRL_DATA_SIZE_POS)) +#define MXC_F_UART_CTRL_EXTRA_STOP_POS 8 +#define MXC_F_UART_CTRL_EXTRA_STOP ((uint32_t)(0x00000001UL << MXC_F_UART_CTRL_EXTRA_STOP_POS)) +#define MXC_F_UART_CTRL_PARITY_POS 12 +#define MXC_F_UART_CTRL_PARITY ((uint32_t)(0x00000003UL << MXC_F_UART_CTRL_PARITY_POS)) +#define MXC_F_UART_CTRL_CTS_EN_POS 16 +#define MXC_F_UART_CTRL_CTS_EN ((uint32_t)(0x00000001UL << MXC_F_UART_CTRL_CTS_EN_POS)) +#define MXC_F_UART_CTRL_CTS_POLARITY_POS 17 +#define MXC_F_UART_CTRL_CTS_POLARITY ((uint32_t)(0x00000001UL << MXC_F_UART_CTRL_CTS_POLARITY_POS)) +#define MXC_F_UART_CTRL_RTS_EN_POS 18 +#define MXC_F_UART_CTRL_RTS_EN ((uint32_t)(0x00000001UL << MXC_F_UART_CTRL_RTS_EN_POS)) +#define MXC_F_UART_CTRL_RTS_POLARITY_POS 19 +#define MXC_F_UART_CTRL_RTS_POLARITY ((uint32_t)(0x00000001UL << MXC_F_UART_CTRL_RTS_POLARITY_POS)) +#define MXC_F_UART_CTRL_RTS_LEVEL_POS 20 +#define MXC_F_UART_CTRL_RTS_LEVEL ((uint32_t)(0x0000003FUL << MXC_F_UART_CTRL_RTS_LEVEL_POS)) + +#define MXC_F_UART_BAUD_BAUD_DIVISOR_POS 0 +#define MXC_F_UART_BAUD_BAUD_DIVISOR ((uint32_t)(0x000000FFUL << MXC_F_UART_BAUD_BAUD_DIVISOR_POS)) +#define MXC_F_UART_BAUD_BAUD_MODE_POS 8 +#define MXC_F_UART_BAUD_BAUD_MODE ((uint32_t)(0x00000003UL << MXC_F_UART_BAUD_BAUD_MODE_POS)) + +#define MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY_POS 0 +#define MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY ((uint32_t)(0x0000003FUL << MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY_POS)) +#define MXC_F_UART_TX_FIFO_CTRL_FIFO_AE_LVL_POS 16 +#define MXC_F_UART_TX_FIFO_CTRL_FIFO_AE_LVL ((uint32_t)(0x0000001FUL << MXC_F_UART_TX_FIFO_CTRL_FIFO_AE_LVL_POS)) + +#define MXC_F_UART_RX_FIFO_CTRL_FIFO_ENTRY_POS 0 +#define MXC_F_UART_RX_FIFO_CTRL_FIFO_ENTRY ((uint32_t)(0x0000003FUL << MXC_F_UART_RX_FIFO_CTRL_FIFO_ENTRY_POS)) +#define MXC_F_UART_RX_FIFO_CTRL_FIFO_AF_LVL_POS 16 +#define MXC_F_UART_RX_FIFO_CTRL_FIFO_AF_LVL ((uint32_t)(0x0000001FUL << MXC_F_UART_RX_FIFO_CTRL_FIFO_AF_LVL_POS)) + +#define MXC_F_UART_MD_CTRL_SLAVE_ADDR_POS 0 +#define MXC_F_UART_MD_CTRL_SLAVE_ADDR ((uint32_t)(0x000000FFUL << MXC_F_UART_MD_CTRL_SLAVE_ADDR_POS)) +#define MXC_F_UART_MD_CTRL_SLAVE_ADDR_MSK_POS 8 +#define MXC_F_UART_MD_CTRL_SLAVE_ADDR_MSK ((uint32_t)(0x000000FFUL << MXC_F_UART_MD_CTRL_SLAVE_ADDR_MSK_POS)) +#define MXC_F_UART_MD_CTRL_MD_MSTR_POS 16 +#define MXC_F_UART_MD_CTRL_MD_MSTR ((uint32_t)(0x00000001UL << MXC_F_UART_MD_CTRL_MD_MSTR_POS)) +#define MXC_F_UART_MD_CTRL_TX_ADDR_MARK_POS 17 +#define MXC_F_UART_MD_CTRL_TX_ADDR_MARK ((uint32_t)(0x00000001UL << MXC_F_UART_MD_CTRL_TX_ADDR_MARK_POS)) + +#define MXC_F_UART_INTFL_TX_DONE_POS 0 +#define MXC_F_UART_INTFL_TX_DONE ((uint32_t)(0x00000001UL << MXC_F_UART_INTFL_TX_DONE_POS)) +#define MXC_F_UART_INTFL_TX_UNSTALLED_POS 1 +#define MXC_F_UART_INTFL_TX_UNSTALLED ((uint32_t)(0x00000001UL << MXC_F_UART_INTFL_TX_UNSTALLED_POS)) +#define MXC_F_UART_INTFL_TX_FIFO_AE_POS 2 +#define MXC_F_UART_INTFL_TX_FIFO_AE ((uint32_t)(0x00000001UL << MXC_F_UART_INTFL_TX_FIFO_AE_POS)) +#define MXC_F_UART_INTFL_RX_FIFO_NOT_EMPTY_POS 3 +#define MXC_F_UART_INTFL_RX_FIFO_NOT_EMPTY ((uint32_t)(0x00000001UL << MXC_F_UART_INTFL_RX_FIFO_NOT_EMPTY_POS)) +#define MXC_F_UART_INTFL_RX_STALLED_POS 4 +#define MXC_F_UART_INTFL_RX_STALLED ((uint32_t)(0x00000001UL << MXC_F_UART_INTFL_RX_STALLED_POS)) +#define MXC_F_UART_INTFL_RX_FIFO_AF_POS 5 +#define MXC_F_UART_INTFL_RX_FIFO_AF ((uint32_t)(0x00000001UL << MXC_F_UART_INTFL_RX_FIFO_AF_POS)) +#define MXC_F_UART_INTFL_RX_FIFO_OVERFLOW_POS 6 +#define MXC_F_UART_INTFL_RX_FIFO_OVERFLOW ((uint32_t)(0x00000001UL << MXC_F_UART_INTFL_RX_FIFO_OVERFLOW_POS)) +#define MXC_F_UART_INTFL_RX_FRAMING_ERR_POS 7 +#define MXC_F_UART_INTFL_RX_FRAMING_ERR ((uint32_t)(0x00000001UL << MXC_F_UART_INTFL_RX_FRAMING_ERR_POS)) +#define MXC_F_UART_INTFL_RX_PARITY_ERR_POS 8 +#define MXC_F_UART_INTFL_RX_PARITY_ERR ((uint32_t)(0x00000001UL << MXC_F_UART_INTFL_RX_PARITY_ERR_POS)) + +#define MXC_F_UART_INTEN_TX_DONE_POS 0 +#define MXC_F_UART_INTEN_TX_DONE ((uint32_t)(0x00000001UL << MXC_F_UART_INTEN_TX_DONE_POS)) +#define MXC_F_UART_INTEN_TX_UNSTALLED_POS 1 +#define MXC_F_UART_INTEN_TX_UNSTALLED ((uint32_t)(0x00000001UL << MXC_F_UART_INTEN_TX_UNSTALLED_POS)) +#define MXC_F_UART_INTEN_TX_FIFO_AE_POS 2 +#define MXC_F_UART_INTEN_TX_FIFO_AE ((uint32_t)(0x00000001UL << MXC_F_UART_INTEN_TX_FIFO_AE_POS)) +#define MXC_F_UART_INTEN_RX_FIFO_NOT_EMPTY_POS 3 +#define MXC_F_UART_INTEN_RX_FIFO_NOT_EMPTY ((uint32_t)(0x00000001UL << MXC_F_UART_INTEN_RX_FIFO_NOT_EMPTY_POS)) +#define MXC_F_UART_INTEN_RX_STALLED_POS 4 +#define MXC_F_UART_INTEN_RX_STALLED ((uint32_t)(0x00000001UL << MXC_F_UART_INTEN_RX_STALLED_POS)) +#define MXC_F_UART_INTEN_RX_FIFO_AF_POS 5 +#define MXC_F_UART_INTEN_RX_FIFO_AF ((uint32_t)(0x00000001UL << MXC_F_UART_INTEN_RX_FIFO_AF_POS)) +#define MXC_F_UART_INTEN_RX_FIFO_OVERFLOW_POS 6 +#define MXC_F_UART_INTEN_RX_FIFO_OVERFLOW ((uint32_t)(0x00000001UL << MXC_F_UART_INTEN_RX_FIFO_OVERFLOW_POS)) +#define MXC_F_UART_INTEN_RX_FRAMING_ERR_POS 7 +#define MXC_F_UART_INTEN_RX_FRAMING_ERR ((uint32_t)(0x00000001UL << MXC_F_UART_INTEN_RX_FRAMING_ERR_POS)) +#define MXC_F_UART_INTEN_RX_PARITY_ERR_POS 8 +#define MXC_F_UART_INTEN_RX_PARITY_ERR ((uint32_t)(0x00000001UL << MXC_F_UART_INTEN_RX_PARITY_ERR_POS)) + +#if (MXC_UART_REV > 0) +#define MXC_F_UART_IDLE_TX_RX_IDLE_POS 0 +#define MXC_F_UART_IDLE_TX_RX_IDLE ((uint32_t)(0x00000001UL << MXC_F_UART_IDLE_TX_RX_IDLE_POS)) +#define MXC_F_UART_IDLE_TX_IDLE_POS 1 +#define MXC_F_UART_IDLE_TX_IDLE ((uint32_t)(0x00000001UL << MXC_F_UART_IDLE_TX_IDLE_POS)) +#define MXC_F_UART_IDLE_RX_IDLE_POS 2 +#define MXC_F_UART_IDLE_RX_IDLE ((uint32_t)(0x00000001UL << MXC_F_UART_IDLE_RX_IDLE_POS)) +#endif + +/* + Field values and shifted values for module UART. +*/ + +#define MXC_V_UART_CTRL_DATA_SIZE_5_BITS ((uint32_t)(0x00000000UL)) +#define MXC_V_UART_CTRL_DATA_SIZE_6_BITS ((uint32_t)(0x00000001UL)) +#define MXC_V_UART_CTRL_DATA_SIZE_7_BITS ((uint32_t)(0x00000002UL)) +#define MXC_V_UART_CTRL_DATA_SIZE_8_BITS ((uint32_t)(0x00000003UL)) + +#define MXC_S_UART_CTRL_DATA_SIZE_5_BITS ((uint32_t)(MXC_V_UART_CTRL_DATA_SIZE_5_BITS << MXC_F_UART_CTRL_DATA_SIZE_POS)) +#define MXC_S_UART_CTRL_DATA_SIZE_6_BITS ((uint32_t)(MXC_V_UART_CTRL_DATA_SIZE_6_BITS << MXC_F_UART_CTRL_DATA_SIZE_POS)) +#define MXC_S_UART_CTRL_DATA_SIZE_7_BITS ((uint32_t)(MXC_V_UART_CTRL_DATA_SIZE_7_BITS << MXC_F_UART_CTRL_DATA_SIZE_POS)) +#define MXC_S_UART_CTRL_DATA_SIZE_8_BITS ((uint32_t)(MXC_V_UART_CTRL_DATA_SIZE_8_BITS << MXC_F_UART_CTRL_DATA_SIZE_POS)) + +#define MXC_V_UART_CTRL_PARITY_DISABLE ((uint32_t)(0x00000000UL)) +#define MXC_V_UART_CTRL_PARITY_ODD ((uint32_t)(0x00000001UL)) +#define MXC_V_UART_CTRL_PARITY_EVEN ((uint32_t)(0x00000002UL)) +#define MXC_V_UART_CTRL_PARITY_MARK ((uint32_t)(0x00000003UL)) + +#define MXC_S_UART_CTRL_PARITY_DISABLE ((uint32_t)(MXC_V_UART_CTRL_PARITY_DISABLE << MXC_F_UART_CTRL_PARITY_POS)) +#define MXC_S_UART_CTRL_PARITY_ODD ((uint32_t)(MXC_V_UART_CTRL_PARITY_ODD << MXC_F_UART_CTRL_PARITY_POS)) +#define MXC_S_UART_CTRL_PARITY_EVEN ((uint32_t)(MXC_V_UART_CTRL_PARITY_EVEN << MXC_F_UART_CTRL_PARITY_POS)) +#define MXC_S_UART_CTRL_PARITY_MARK ((uint32_t)(MXC_V_UART_CTRL_PARITY_MARK << MXC_F_UART_CTRL_PARITY_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_UART_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/usb_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/usb_regs.h new file mode 100644 index 00000000000..c764445c8a9 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/usb_regs.h @@ -0,0 +1,293 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_USB_REGS_H_ +#define _MXC_USB_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +#define MXC_V_USB_EP_DIR_DISABLE ((uint32_t)0x00000000UL) +#define MXC_V_USB_EP_DIR_OUT ((uint32_t)0x00000001UL) +#define MXC_V_USB_EP_DIR_IN ((uint32_t)0x00000002UL) +#define MXC_V_USB_EP_DIR_CONTROL ((uint32_t)0x00000003UL) + +#define MXC_S_USB_EP_DIR_DISABLE (MXC_V_USB_EP_DIR_DISABLE << MXC_F_USB_EP_DIR_POS) +#define MXC_S_USB_EP_DIR_OUT (MXC_V_USB_EP_DIR_OUT << MXC_F_USB_EP_DIR_POS) +#define MXC_S_USB_EP_DIR_IN (MXC_V_USB_EP_DIR_IN << MXC_F_USB_EP_DIR_POS) +#define MXC_S_USB_EP_DIR_CONTROL (MXC_V_USB_EP_DIR_CONTROL << MXC_F_USB_EP_DIR_POS) + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t cn; /* 0x0000 USB Control Register */ + __I uint32_t rsv004[127]; /* 0x0004-0x01FC */ + __IO uint32_t dev_addr; /* 0x0200 USB Device Address Register */ + __IO uint32_t dev_cn; /* 0x0204 USB Device Control Register */ + __IO uint32_t dev_intfl; /* 0x0208 USB Device Interrupt */ + __IO uint32_t dev_inten; /* 0x020C USB Device Interrupt Enable */ + __I uint32_t rsv210[4]; /* 0x0210-0x021C */ + __IO uint32_t ep_base; /* 0x0220 USB Endpoint Descriptor Table Base Address */ + __IO uint32_t cur_buf; /* 0x0224 USB Current Endpoint Buffer Register */ + __IO uint32_t in_owner; /* 0x0228 USB IN Endpoint Buffer Owner Register */ + __IO uint32_t out_owner; /* 0x022C USB OUT Endpoint Buffer Owner Register */ + __IO uint32_t in_int; /* 0x0230 USB IN Endpoint Buffer Available Interrupt */ + __IO uint32_t out_int; /* 0x0234 USB OUT Endpoint Data Available Interrupt */ + __IO uint32_t nak_int; /* 0x0238 USB IN Endpoint NAK Interrupt */ + __IO uint32_t dma_err_int; /* 0x023C USB DMA Error Interrupt */ + __IO uint32_t buf_ovr_int; /* 0x0240 USB Buffer Overflow Interrupt */ + __I uint32_t rsv244[7]; /* 0x0244-0x025C */ + __IO uint32_t setup0; /* 0x0260 USB SETUP Packet Bytes 0 to 3 */ + __IO uint32_t setup1; /* 0x0264 USB SETUP Packet Bytes 4 to 7 */ + __I uint32_t rsv268[6]; /* 0x0268-0x027C */ + __IO uint32_t ep[8]; /* 0x0280-0x029C USB Endpoint[n] Control Register */ +} mxc_usb_regs_t; + + +/* + Register offsets for module USB. +*/ + +#define MXC_R_USB_OFFS_CN ((uint32_t)0x00000000UL) +#define MXC_R_USB_OFFS_DEV_ADDR ((uint32_t)0x00000200UL) +#define MXC_R_USB_OFFS_DEV_CN ((uint32_t)0x00000204UL) +#define MXC_R_USB_OFFS_DEV_INTFL ((uint32_t)0x00000208UL) +#define MXC_R_USB_OFFS_DEV_INTEN ((uint32_t)0x0000020CUL) +#define MXC_R_USB_OFFS_EP_BASE ((uint32_t)0x00000220UL) +#define MXC_R_USB_OFFS_CUR_BUF ((uint32_t)0x00000224UL) +#define MXC_R_USB_OFFS_IN_OWNER ((uint32_t)0x00000228UL) +#define MXC_R_USB_OFFS_OUT_OWNER ((uint32_t)0x0000022CUL) +#define MXC_R_USB_OFFS_IN_INT ((uint32_t)0x00000230UL) +#define MXC_R_USB_OFFS_OUT_INT ((uint32_t)0x00000234UL) +#define MXC_R_USB_OFFS_NAK_INT ((uint32_t)0x00000238UL) +#define MXC_R_USB_OFFS_DMA_ERR_INT ((uint32_t)0x0000023CUL) +#define MXC_R_USB_OFFS_BUF_OVR_INT ((uint32_t)0x00000240UL) +#define MXC_R_USB_OFFS_SETUP0 ((uint32_t)0x00000260UL) +#define MXC_R_USB_OFFS_SETUP1 ((uint32_t)0x00000264UL) +#define MXC_R_USB_OFFS_EP0 ((uint32_t)0x00000280UL) +#define MXC_R_USB_OFFS_EP1 ((uint32_t)0x00000284UL) +#define MXC_R_USB_OFFS_EP2 ((uint32_t)0x00000288UL) +#define MXC_R_USB_OFFS_EP3 ((uint32_t)0x0000028CUL) +#define MXC_R_USB_OFFS_EP4 ((uint32_t)0x00000290UL) +#define MXC_R_USB_OFFS_EP5 ((uint32_t)0x00000294UL) +#define MXC_R_USB_OFFS_EP6 ((uint32_t)0x00000298UL) +#define MXC_R_USB_OFFS_EP7 ((uint32_t)0x0000029CUL) + + +/* + Field positions and masks for module USB. +*/ + +#define MXC_F_USB_CN_USB_EN_POS 0 +#define MXC_F_USB_CN_USB_EN ((uint32_t)(0x00000001UL << MXC_F_USB_CN_USB_EN_POS)) +#define MXC_F_USB_CN_HOST_POS 1 +#define MXC_F_USB_CN_HOST ((uint32_t)(0x00000001UL << MXC_F_USB_CN_HOST_POS)) + +#define MXC_F_USB_DEV_ADDR_DEV_ADDR_POS 0 +#define MXC_F_USB_DEV_ADDR_DEV_ADDR ((uint32_t)(0x0000007FUL << MXC_F_USB_DEV_ADDR_DEV_ADDR_POS)) + +#define MXC_F_USB_DEV_CN_SIGRWU_POS 2 +#define MXC_F_USB_DEV_CN_SIGRWU ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_CN_SIGRWU_POS)) +#define MXC_F_USB_DEV_CN_CONNECT_POS 3 +#define MXC_F_USB_DEV_CN_CONNECT ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_CN_CONNECT_POS)) +#define MXC_F_USB_DEV_CN_ULPM_POS 4 +#define MXC_F_USB_DEV_CN_ULPM ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_CN_ULPM_POS)) +#define MXC_F_USB_DEV_CN_URST_POS 5 +#define MXC_F_USB_DEV_CN_URST ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_CN_URST_POS)) +#define MXC_F_USB_DEV_CN_VBGATE_POS 6 +#define MXC_F_USB_DEV_CN_VBGATE ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_CN_VBGATE_POS)) +#define MXC_F_USB_DEV_CN_OSCEN_POS 7 +#define MXC_F_USB_DEV_CN_OSCEN ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_CN_OSCEN_POS)) +#define MXC_F_USB_DEV_CN_BACT_OE_POS 8 +#define MXC_F_USB_DEV_CN_BACT_OE ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_CN_BACT_OE_POS)) +#define MXC_F_USB_DEV_CN_FIFO_MODE_POS 9 +#define MXC_F_USB_DEV_CN_FIFO_MODE ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_CN_FIFO_MODE_POS)) + +#define MXC_F_USB_DEV_INTFL_DPACT_POS 0 +#define MXC_F_USB_DEV_INTFL_DPACT ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_DPACT_POS)) +#define MXC_F_USB_DEV_INTFL_RWU_DN_POS 1 +#define MXC_F_USB_DEV_INTFL_RWU_DN ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_RWU_DN_POS)) +#define MXC_F_USB_DEV_INTFL_BACT_POS 2 +#define MXC_F_USB_DEV_INTFL_BACT ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_BACT_POS)) +#define MXC_F_USB_DEV_INTFL_BRST_POS 3 +#define MXC_F_USB_DEV_INTFL_BRST ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_BRST_POS)) +#define MXC_F_USB_DEV_INTFL_SUSP_POS 4 +#define MXC_F_USB_DEV_INTFL_SUSP ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_SUSP_POS)) +#define MXC_F_USB_DEV_INTFL_NO_VBUS_POS 5 +#define MXC_F_USB_DEV_INTFL_NO_VBUS ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_NO_VBUS_POS)) +#define MXC_F_USB_DEV_INTFL_VBUS_POS 6 +#define MXC_F_USB_DEV_INTFL_VBUS ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_VBUS_POS)) +#define MXC_F_USB_DEV_INTFL_BRST_DN_POS 7 +#define MXC_F_USB_DEV_INTFL_BRST_DN ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_BRST_DN_POS)) +#define MXC_F_USB_DEV_INTFL_SETUP_POS 8 +#define MXC_F_USB_DEV_INTFL_SETUP ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_SETUP_POS)) +#define MXC_F_USB_DEV_INTFL_EP_IN_POS 9 +#define MXC_F_USB_DEV_INTFL_EP_IN ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_EP_IN_POS)) +#define MXC_F_USB_DEV_INTFL_EP_OUT_POS 10 +#define MXC_F_USB_DEV_INTFL_EP_OUT ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_EP_OUT_POS)) +#define MXC_F_USB_DEV_INTFL_EP_NAK_POS 11 +#define MXC_F_USB_DEV_INTFL_EP_NAK ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_EP_NAK_POS)) +#define MXC_F_USB_DEV_INTFL_DMA_ERR_POS 12 +#define MXC_F_USB_DEV_INTFL_DMA_ERR ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_DMA_ERR_POS)) +#define MXC_F_USB_DEV_INTFL_BUF_OVR_POS 13 +#define MXC_F_USB_DEV_INTFL_BUF_OVR ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_BUF_OVR_POS)) +#define MXC_F_USB_DEV_INTFL_VBUS_ST_POS 16 +#define MXC_F_USB_DEV_INTFL_VBUS_ST ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTFL_VBUS_ST_POS)) + +#define MXC_F_USB_DEV_INTEN_DPACT_POS 0 +#define MXC_F_USB_DEV_INTEN_DPACT ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_DPACT_POS)) +#define MXC_F_USB_DEV_INTEN_RWU_DN_POS 1 +#define MXC_F_USB_DEV_INTEN_RWU_DN ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_RWU_DN_POS)) +#define MXC_F_USB_DEV_INTEN_BACT_POS 2 +#define MXC_F_USB_DEV_INTEN_BACT ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_BACT_POS)) +#define MXC_F_USB_DEV_INTEN_BRST_POS 3 +#define MXC_F_USB_DEV_INTEN_BRST ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_BRST_POS)) +#define MXC_F_USB_DEV_INTEN_SUSP_POS 4 +#define MXC_F_USB_DEV_INTEN_SUSP ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_SUSP_POS)) +#define MXC_F_USB_DEV_INTEN_NO_VBUS_POS 5 +#define MXC_F_USB_DEV_INTEN_NO_VBUS ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_NO_VBUS_POS)) +#define MXC_F_USB_DEV_INTEN_VBUS_POS 6 +#define MXC_F_USB_DEV_INTEN_VBUS ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_VBUS_POS)) +#define MXC_F_USB_DEV_INTEN_BRST_DN_POS 7 +#define MXC_F_USB_DEV_INTEN_BRST_DN ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_BRST_DN_POS)) +#define MXC_F_USB_DEV_INTEN_SETUP_POS 8 +#define MXC_F_USB_DEV_INTEN_SETUP ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_SETUP_POS)) +#define MXC_F_USB_DEV_INTEN_EP_IN_POS 9 +#define MXC_F_USB_DEV_INTEN_EP_IN ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_EP_IN_POS)) +#define MXC_F_USB_DEV_INTEN_EP_OUT_POS 10 +#define MXC_F_USB_DEV_INTEN_EP_OUT ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_EP_OUT_POS)) +#define MXC_F_USB_DEV_INTEN_EP_NAK_POS 11 +#define MXC_F_USB_DEV_INTEN_EP_NAK ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_EP_NAK_POS)) +#define MXC_F_USB_DEV_INTEN_DMA_ERR_POS 12 +#define MXC_F_USB_DEV_INTEN_DMA_ERR ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_DMA_ERR_POS)) +#define MXC_F_USB_DEV_INTEN_BUF_OVR_POS 13 +#define MXC_F_USB_DEV_INTEN_BUF_OVR ((uint32_t)(0x00000001UL << MXC_F_USB_DEV_INTEN_BUF_OVR_POS)) + +#define MXC_F_USB_EP_BASE_EP_BASE_POS 9 +#define MXC_F_USB_EP_BASE_EP_BASE ((uint32_t)(0x007FFFFFUL << MXC_F_USB_EP_BASE_EP_BASE_POS)) + +#define MXC_F_USB_CUR_BUF_OUT_BUF_POS 0 +#define MXC_F_USB_CUR_BUF_OUT_BUF ((uint32_t)(0x0000FFFFUL << MXC_F_USB_CUR_BUF_OUT_BUF_POS)) +#define MXC_F_USB_CUR_BUF_IN_BUF_POS 16 +#define MXC_F_USB_CUR_BUF_IN_BUF ((uint32_t)(0x0000FFFFUL << MXC_F_USB_CUR_BUF_IN_BUF_POS)) + +#define MXC_F_USB_IN_OWNER_BUF0_OWNER_POS 0 +#define MXC_F_USB_IN_OWNER_BUF0_OWNER ((uint32_t)(0x0000FFFFUL << MXC_F_USB_IN_OWNER_BUF0_OWNER_POS)) +#define MXC_F_USB_IN_OWNER_BUF1_OWNER_POS 16 +#define MXC_F_USB_IN_OWNER_BUF1_OWNER ((uint32_t)(0x0000FFFFUL << MXC_F_USB_IN_OWNER_BUF1_OWNER_POS)) + +#define MXC_F_USB_OUT_OWNER_BUF0_OWNER_POS 0 +#define MXC_F_USB_OUT_OWNER_BUF0_OWNER ((uint32_t)(0x0000FFFFUL << MXC_F_USB_OUT_OWNER_BUF0_OWNER_POS)) +#define MXC_F_USB_OUT_OWNER_BUF1_OWNER_POS 16 +#define MXC_F_USB_OUT_OWNER_BUF1_OWNER ((uint32_t)(0x0000FFFFUL << MXC_F_USB_OUT_OWNER_BUF1_OWNER_POS)) + +#define MXC_F_USB_IN_INT_INBAV_POS 0 +#define MXC_F_USB_IN_INT_INBAV ((uint32_t)(0x000000FFUL << MXC_F_USB_IN_INT_INBAV_POS)) + +#define MXC_F_USB_OUT_INT_OUTDAV_POS 0 +#define MXC_F_USB_OUT_INT_OUTDAV ((uint32_t)(0x000000FFUL << MXC_F_USB_OUT_INT_OUTDAV_POS)) + +#define MXC_F_USB_NAK_INT_NAK_POS 0 +#define MXC_F_USB_NAK_INT_NAK ((uint32_t)(0x000000FFUL << MXC_F_USB_NAK_INT_NAK_POS)) + +#define MXC_F_USB_DMA_ERR_INT_DMA_ERR_POS 0 +#define MXC_F_USB_DMA_ERR_INT_DMA_ERR ((uint32_t)(0x000000FFUL << MXC_F_USB_DMA_ERR_INT_DMA_ERR_POS)) + +#define MXC_F_USB_BUF_OVR_INT_BUF_OVR_POS 0 +#define MXC_F_USB_BUF_OVR_INT_BUF_OVR ((uint32_t)(0x000000FFUL << MXC_F_USB_BUF_OVR_INT_BUF_OVR_POS)) + +#define MXC_F_USB_SETUP0_BYTE0_POS 0 +#define MXC_F_USB_SETUP0_BYTE0 ((uint32_t)(0x000000FFUL << MXC_F_USB_SETUP0_BYTE0_POS)) +#define MXC_F_USB_SETUP0_BYTE1_POS 8 +#define MXC_F_USB_SETUP0_BYTE1 ((uint32_t)(0x000000FFUL << MXC_F_USB_SETUP0_BYTE1_POS)) +#define MXC_F_USB_SETUP0_BYTE2_POS 16 +#define MXC_F_USB_SETUP0_BYTE2 ((uint32_t)(0x000000FFUL << MXC_F_USB_SETUP0_BYTE2_POS)) +#define MXC_F_USB_SETUP0_BYTE3_POS 24 +#define MXC_F_USB_SETUP0_BYTE3 ((uint32_t)(0x000000FFUL << MXC_F_USB_SETUP0_BYTE3_POS)) + +#define MXC_F_USB_SETUP1_BYTE0_POS 0 +#define MXC_F_USB_SETUP1_BYTE0 ((uint32_t)(0x000000FFUL << MXC_F_USB_SETUP1_BYTE0_POS)) +#define MXC_F_USB_SETUP1_BYTE1_POS 8 +#define MXC_F_USB_SETUP1_BYTE1 ((uint32_t)(0x000000FFUL << MXC_F_USB_SETUP1_BYTE1_POS)) +#define MXC_F_USB_SETUP1_BYTE2_POS 16 +#define MXC_F_USB_SETUP1_BYTE2 ((uint32_t)(0x000000FFUL << MXC_F_USB_SETUP1_BYTE2_POS)) +#define MXC_F_USB_SETUP1_BYTE3_POS 24 +#define MXC_F_USB_SETUP1_BYTE3 ((uint32_t)(0x000000FFUL << MXC_F_USB_SETUP1_BYTE3_POS)) + +#define MXC_F_USB_EP_DIR_POS 0 +#define MXC_F_USB_EP_DIR ((uint32_t)(0x00000003UL << MXC_F_USB_EP_DIR_POS)) +#define MXC_F_USB_EP_BUF2_POS 3 +#define MXC_F_USB_EP_BUF2 ((uint32_t)(0x00000001UL << MXC_F_USB_EP_BUF2_POS)) +#define MXC_F_USB_EP_INT_EN_POS 4 +#define MXC_F_USB_EP_INT_EN ((uint32_t)(0x00000001UL << MXC_F_USB_EP_INT_EN_POS)) +#define MXC_F_USB_EP_NAK_EN_POS 5 +#define MXC_F_USB_EP_NAK_EN ((uint32_t)(0x00000001UL << MXC_F_USB_EP_NAK_EN_POS)) +#define MXC_F_USB_EP_DT_POS 6 +#define MXC_F_USB_EP_DT ((uint32_t)(0x00000001UL << MXC_F_USB_EP_DT_POS)) +#define MXC_F_USB_EP_STALL_POS 8 +#define MXC_F_USB_EP_STALL ((uint32_t)(0x00000001UL << MXC_F_USB_EP_STALL_POS)) +#define MXC_F_USB_EP_ST_STALL_POS 9 +#define MXC_F_USB_EP_ST_STALL ((uint32_t)(0x00000001UL << MXC_F_USB_EP_ST_STALL_POS)) +#define MXC_F_USB_EP_ST_ACK_POS 10 +#define MXC_F_USB_EP_ST_ACK ((uint32_t)(0x00000001UL << MXC_F_USB_EP_ST_ACK_POS)) + + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_USB_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/wdt2_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/wdt2_regs.h new file mode 100644 index 00000000000..6bfd4de1671 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/wdt2_regs.h @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_WDT2_REGS_H_ +#define _MXC_WDT2_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t ctrl; /* 0x0000 Watchdog Timer 2 Control Register */ + __IO uint32_t clear; /* 0x0004 Watchdog Timer 2 Clear Register (Feed Dog) */ + __IO uint32_t flags; /* 0x0008 Watchdog Timer 2 Interrupt and Reset Flags */ + __IO uint32_t enable; /* 0x000C Watchdog Timer 2 Interrupt/Reset Enable/Disable Controls */ + __I uint32_t rsv010; /* 0x0010 */ + __IO uint32_t lock_ctrl; /* 0x0014 Watchdog Timer 2 Register Setting Lock for Control Register */ +} mxc_wdt2_regs_t; + + +/* + Register offsets for module WDT2. +*/ + +#define MXC_R_WDT2_OFFS_CTRL ((uint32_t)0x00000000UL) +#define MXC_R_WDT2_OFFS_CLEAR ((uint32_t)0x00000004UL) +#define MXC_R_WDT2_OFFS_FLAGS ((uint32_t)0x00000008UL) +#define MXC_R_WDT2_OFFS_ENABLE ((uint32_t)0x0000000CUL) +#define MXC_R_WDT2_OFFS_LOCK_CTRL ((uint32_t)0x00000014UL) + + +/* + Field positions and masks for module WDT2. +*/ + +#define MXC_F_WDT2_CTRL_INT_PERIOD_POS 0 +#define MXC_F_WDT2_CTRL_INT_PERIOD ((uint32_t)(0x0000000FUL << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_F_WDT2_CTRL_RST_PERIOD_POS 4 +#define MXC_F_WDT2_CTRL_RST_PERIOD ((uint32_t)(0x0000000FUL << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_F_WDT2_CTRL_EN_TIMER_POS 8 +#define MXC_F_WDT2_CTRL_EN_TIMER ((uint32_t)(0x00000001UL << MXC_F_WDT2_CTRL_EN_TIMER_POS)) +#define MXC_F_WDT2_CTRL_EN_CLOCK_POS 9 +#define MXC_F_WDT2_CTRL_EN_CLOCK ((uint32_t)(0x00000001UL << MXC_F_WDT2_CTRL_EN_CLOCK_POS)) +#define MXC_F_WDT2_CTRL_EN_TIMER_SLP_POS 10 +#define MXC_F_WDT2_CTRL_EN_TIMER_SLP ((uint32_t)(0x00000001UL << MXC_F_WDT2_CTRL_EN_TIMER_SLP_POS)) + +#define MXC_F_WDT2_FLAGS_TIMEOUT_POS 0 +#define MXC_F_WDT2_FLAGS_TIMEOUT ((uint32_t)(0x00000001UL << MXC_F_WDT2_FLAGS_TIMEOUT_POS)) +#define MXC_F_WDT2_FLAGS_RESET_OUT_POS 2 +#define MXC_F_WDT2_FLAGS_RESET_OUT ((uint32_t)(0x00000001UL << MXC_F_WDT2_FLAGS_RESET_OUT_POS)) + +#define MXC_F_WDT2_ENABLE_TIMEOUT_POS 0 +#define MXC_F_WDT2_ENABLE_TIMEOUT ((uint32_t)(0x00000001UL << MXC_F_WDT2_ENABLE_TIMEOUT_POS)) +#define MXC_F_WDT2_ENABLE_RESET_OUT_POS 2 +#define MXC_F_WDT2_ENABLE_RESET_OUT ((uint32_t)(0x00000001UL << MXC_F_WDT2_ENABLE_RESET_OUT_POS)) + +#define MXC_F_WDT2_LOCK_CTRL_WDLOCK_POS 0 +#define MXC_F_WDT2_LOCK_CTRL_WDLOCK ((uint32_t)(0x000000FFUL << MXC_F_WDT2_LOCK_CTRL_WDLOCK_POS)) + + + +/* + Field values and shifted values for module WDT2. +*/ + +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_25_NANO_CLKS ((uint32_t)(0x00000000UL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_24_NANO_CLKS ((uint32_t)(0x00000001UL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_23_NANO_CLKS ((uint32_t)(0x00000002UL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_22_NANO_CLKS ((uint32_t)(0x00000003UL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_21_NANO_CLKS ((uint32_t)(0x00000004UL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_20_NANO_CLKS ((uint32_t)(0x00000005UL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_19_NANO_CLKS ((uint32_t)(0x00000006UL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_18_NANO_CLKS ((uint32_t)(0x00000007UL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_17_NANO_CLKS ((uint32_t)(0x00000008UL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_16_NANO_CLKS ((uint32_t)(0x00000009UL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_15_NANO_CLKS ((uint32_t)(0x0000000AUL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_14_NANO_CLKS ((uint32_t)(0x0000000BUL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_13_NANO_CLKS ((uint32_t)(0x0000000CUL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_12_NANO_CLKS ((uint32_t)(0x0000000DUL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_11_NANO_CLKS ((uint32_t)(0x0000000EUL)) +#define MXC_V_WDT2_CTRL_INT_PERIOD_2_10_NANO_CLKS ((uint32_t)(0x0000000FUL)) + +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_25_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_25_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_24_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_24_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_23_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_23_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_22_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_22_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_21_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_21_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_20_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_20_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_19_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_19_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_18_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_18_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_17_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_17_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_16_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_16_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_15_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_15_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_14_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_14_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_13_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_13_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_12_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_12_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_11_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_11_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_INT_PERIOD_2_10_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_INT_PERIOD_2_10_NANO_CLKS << MXC_F_WDT2_CTRL_INT_PERIOD_POS)) + +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_25_NANO_CLKS ((uint32_t)(0x00000000UL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_24_NANO_CLKS ((uint32_t)(0x00000001UL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_23_NANO_CLKS ((uint32_t)(0x00000002UL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_22_NANO_CLKS ((uint32_t)(0x00000003UL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_21_NANO_CLKS ((uint32_t)(0x00000004UL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_20_NANO_CLKS ((uint32_t)(0x00000005UL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_19_NANO_CLKS ((uint32_t)(0x00000006UL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_18_NANO_CLKS ((uint32_t)(0x00000007UL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_17_NANO_CLKS ((uint32_t)(0x00000008UL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_16_NANO_CLKS ((uint32_t)(0x00000009UL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_15_NANO_CLKS ((uint32_t)(0x0000000AUL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_14_NANO_CLKS ((uint32_t)(0x0000000BUL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_13_NANO_CLKS ((uint32_t)(0x0000000CUL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_12_NANO_CLKS ((uint32_t)(0x0000000DUL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_11_NANO_CLKS ((uint32_t)(0x0000000EUL)) +#define MXC_V_WDT2_CTRL_RST_PERIOD_2_10_NANO_CLKS ((uint32_t)(0x0000000FUL)) + +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_25_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_25_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_24_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_24_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_23_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_23_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_22_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_22_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_21_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_21_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_20_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_20_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_19_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_19_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_18_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_18_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_17_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_17_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_16_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_16_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_15_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_15_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_14_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_14_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_13_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_13_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_12_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_12_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_11_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_11_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT2_CTRL_RST_PERIOD_2_10_NANO_CLKS ((uint32_t)(MXC_V_WDT2_CTRL_RST_PERIOD_2_10_NANO_CLKS << MXC_F_WDT2_CTRL_RST_PERIOD_POS)) + + +#define MXC_V_WDT2_LOCK_KEY 0x24 +#define MXC_V_WDT2_UNLOCK_KEY 0x42 + +#define MXC_V_WDT2_RESET_KEY_0 0xA5 +#define MXC_V_WDT2_RESET_KEY_1 0x5A + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_WDT2_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/wdt_regs.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/wdt_regs.h new file mode 100644 index 00000000000..b793bb0e978 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/wdt_regs.h @@ -0,0 +1,238 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************/ + +#ifndef _MXC_WDT_REGS_H_ +#define _MXC_WDT_REGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mxc_device.h" + +/* + If types are not defined elsewhere (CMSIS) define them here +*/ +#ifndef __IO +#define __IO volatile +#endif +#ifndef __I +#define __I volatile const +#endif +#ifndef __O +#define __O volatile +#endif + + +/* + Typedefed structure(s) for module registers (per instance or section) with direct 32-bit + access to each register in module. +*/ + +/* Offset Register Description + ============= ============================================================================ */ +typedef struct { + __IO uint32_t ctrl; /* 0x0000 Watchdog Timer Control Register */ + __IO uint32_t clear; /* 0x0004 Watchdog Timer Clear Register (Feed Dog) */ + __IO uint32_t flags; /* 0x0008 Watchdog Timer Interrupt and Reset Flags */ + __IO uint32_t enable; /* 0x000C Watchdog Timer Interrupt/Reset Enable/Disable Controls */ + __I uint32_t rsv010; /* 0x0010 */ + __IO uint32_t lock_ctrl; /* 0x0014 Watchdog Timer Register Setting Lock for Control Register */ +} mxc_wdt_regs_t; + + +/* + Register offsets for module WDT. +*/ + +#define MXC_R_WDT_OFFS_CTRL ((uint32_t)0x00000000UL) +#define MXC_R_WDT_OFFS_CLEAR ((uint32_t)0x00000004UL) +#define MXC_R_WDT_OFFS_FLAGS ((uint32_t)0x00000008UL) +#define MXC_R_WDT_OFFS_ENABLE ((uint32_t)0x0000000CUL) +#define MXC_R_WDT_OFFS_LOCK_CTRL ((uint32_t)0x00000014UL) + + +/* + Field positions and masks for module WDT. +*/ + +#define MXC_F_WDT_CTRL_INT_PERIOD_POS 0 +#define MXC_F_WDT_CTRL_INT_PERIOD ((uint32_t)(0x0000000FUL << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_F_WDT_CTRL_RST_PERIOD_POS 4 +#define MXC_F_WDT_CTRL_RST_PERIOD ((uint32_t)(0x0000000FUL << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_F_WDT_CTRL_EN_TIMER_POS 8 +#define MXC_F_WDT_CTRL_EN_TIMER ((uint32_t)(0x00000001UL << MXC_F_WDT_CTRL_EN_TIMER_POS)) +#define MXC_F_WDT_CTRL_EN_CLOCK_POS 9 +#define MXC_F_WDT_CTRL_EN_CLOCK ((uint32_t)(0x00000001UL << MXC_F_WDT_CTRL_EN_CLOCK_POS)) +#define MXC_F_WDT_CTRL_WAIT_PERIOD_POS 12 +#define MXC_F_WDT_CTRL_WAIT_PERIOD ((uint32_t)(0x0000000FUL << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) + +#define MXC_F_WDT_FLAGS_TIMEOUT_POS 0 +#define MXC_F_WDT_FLAGS_TIMEOUT ((uint32_t)(0x00000001UL << MXC_F_WDT_FLAGS_TIMEOUT_POS)) +#define MXC_F_WDT_FLAGS_PRE_WIN_POS 1 +#define MXC_F_WDT_FLAGS_PRE_WIN ((uint32_t)(0x00000001UL << MXC_F_WDT_FLAGS_PRE_WIN_POS)) +#define MXC_F_WDT_FLAGS_RESET_OUT_POS 2 +#define MXC_F_WDT_FLAGS_RESET_OUT ((uint32_t)(0x00000001UL << MXC_F_WDT_FLAGS_RESET_OUT_POS)) + +#define MXC_F_WDT_ENABLE_TIMEOUT_POS 0 +#define MXC_F_WDT_ENABLE_TIMEOUT ((uint32_t)(0x00000001UL << MXC_F_WDT_ENABLE_TIMEOUT_POS)) +#define MXC_F_WDT_ENABLE_PRE_WIN_POS 1 +#define MXC_F_WDT_ENABLE_PRE_WIN ((uint32_t)(0x00000001UL << MXC_F_WDT_ENABLE_PRE_WIN_POS)) +#define MXC_F_WDT_ENABLE_RESET_OUT_POS 2 +#define MXC_F_WDT_ENABLE_RESET_OUT ((uint32_t)(0x00000001UL << MXC_F_WDT_ENABLE_RESET_OUT_POS)) + +#define MXC_F_WDT_LOCK_CTRL_WDLOCK_POS 0 +#define MXC_F_WDT_LOCK_CTRL_WDLOCK ((uint32_t)(0x000000FFUL << MXC_F_WDT_LOCK_CTRL_WDLOCK_POS)) + + + +/* + Field values and shifted values for module WDT. +*/ + +#define MXC_V_WDT_CTRL_INT_PERIOD_2_31_CLKS ((uint32_t)(0x00000000UL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_30_CLKS ((uint32_t)(0x00000001UL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_29_CLKS ((uint32_t)(0x00000002UL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_28_CLKS ((uint32_t)(0x00000003UL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_27_CLKS ((uint32_t)(0x00000004UL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_26_CLKS ((uint32_t)(0x00000005UL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_25_CLKS ((uint32_t)(0x00000006UL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_24_CLKS ((uint32_t)(0x00000007UL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_23_CLKS ((uint32_t)(0x00000008UL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_22_CLKS ((uint32_t)(0x00000009UL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_21_CLKS ((uint32_t)(0x0000000AUL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_20_CLKS ((uint32_t)(0x0000000BUL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_19_CLKS ((uint32_t)(0x0000000CUL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_18_CLKS ((uint32_t)(0x0000000DUL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_17_CLKS ((uint32_t)(0x0000000EUL)) +#define MXC_V_WDT_CTRL_INT_PERIOD_2_16_CLKS ((uint32_t)(0x0000000FUL)) + +#define MXC_S_WDT_CTRL_INT_PERIOD_2_31_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_31_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_30_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_30_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_29_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_29_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_28_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_28_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_27_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_27_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_26_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_26_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_25_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_25_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_24_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_24_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_23_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_23_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_22_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_22_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_21_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_21_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_20_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_20_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_19_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_19_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_18_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_18_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_17_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_17_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_INT_PERIOD_2_16_CLKS ((uint32_t)(MXC_V_WDT_CTRL_INT_PERIOD_2_16_CLKS << MXC_F_WDT_CTRL_INT_PERIOD_POS)) + +#define MXC_V_WDT_CTRL_RST_PERIOD_2_31_CLKS ((uint32_t)(0x00000000UL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_30_CLKS ((uint32_t)(0x00000001UL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_29_CLKS ((uint32_t)(0x00000002UL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_28_CLKS ((uint32_t)(0x00000003UL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_27_CLKS ((uint32_t)(0x00000004UL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_26_CLKS ((uint32_t)(0x00000005UL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_25_CLKS ((uint32_t)(0x00000006UL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_24_CLKS ((uint32_t)(0x00000007UL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_23_CLKS ((uint32_t)(0x00000008UL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_22_CLKS ((uint32_t)(0x00000009UL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_21_CLKS ((uint32_t)(0x0000000AUL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_20_CLKS ((uint32_t)(0x0000000BUL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_19_CLKS ((uint32_t)(0x0000000CUL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_18_CLKS ((uint32_t)(0x0000000DUL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_17_CLKS ((uint32_t)(0x0000000EUL)) +#define MXC_V_WDT_CTRL_RST_PERIOD_2_16_CLKS ((uint32_t)(0x0000000FUL)) + +#define MXC_S_WDT_CTRL_RST_PERIOD_2_31_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_31_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_30_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_30_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_29_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_29_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_28_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_28_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_27_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_27_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_26_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_26_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_25_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_25_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_24_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_24_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_23_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_23_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_22_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_22_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_21_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_21_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_20_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_20_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_19_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_19_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_18_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_18_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_17_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_17_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) +#define MXC_S_WDT_CTRL_RST_PERIOD_2_16_CLKS ((uint32_t)(MXC_V_WDT_CTRL_RST_PERIOD_2_16_CLKS << MXC_F_WDT_CTRL_RST_PERIOD_POS)) + +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_31_CLKS ((uint32_t)(0x00000000UL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_30_CLKS ((uint32_t)(0x00000001UL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_29_CLKS ((uint32_t)(0x00000002UL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_28_CLKS ((uint32_t)(0x00000003UL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_27_CLKS ((uint32_t)(0x00000004UL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_26_CLKS ((uint32_t)(0x00000005UL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_25_CLKS ((uint32_t)(0x00000006UL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_24_CLKS ((uint32_t)(0x00000007UL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_23_CLKS ((uint32_t)(0x00000008UL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_22_CLKS ((uint32_t)(0x00000009UL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_21_CLKS ((uint32_t)(0x0000000AUL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_20_CLKS ((uint32_t)(0x0000000BUL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_19_CLKS ((uint32_t)(0x0000000CUL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_18_CLKS ((uint32_t)(0x0000000DUL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_17_CLKS ((uint32_t)(0x0000000EUL)) +#define MXC_V_WDT_CTRL_WAIT_PERIOD_2_16_CLKS ((uint32_t)(0x0000000FUL)) + +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_31_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_31_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_30_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_30_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_29_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_29_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_28_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_28_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_27_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_27_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_26_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_26_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_25_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_25_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_24_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_24_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_23_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_23_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_22_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_22_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_21_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_21_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_20_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_20_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_19_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_19_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_18_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_18_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_17_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_17_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) +#define MXC_S_WDT_CTRL_WAIT_PERIOD_2_16_CLKS ((uint32_t)(MXC_V_WDT_CTRL_WAIT_PERIOD_2_16_CLKS << MXC_F_WDT_CTRL_WAIT_PERIOD_POS)) + + +#define MXC_V_WDT_LOCK_KEY 0x24 +#define MXC_V_WDT_UNLOCK_KEY 0x42 + +#define MXC_V_WDT_RESET_KEY_0 0xA5 +#define MXC_V_WDT_RESET_KEY_1 0x5A + + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_WDT_REGS_H_ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/gpio_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/gpio_api.c new file mode 100644 index 00000000000..2b5bb5e41b7 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/gpio_api.c @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" +#include "gpio_regs.h" +#include "clkman_regs.h" + +uint32_t gpio_set(PinName name) +{ + MBED_ASSERT(name != (PinName)NC); + pin_function(name, 0); + return 1 << PINNAME_TO_PIN(name); +} + +void gpio_init(gpio_t *obj, PinName name) +{ + obj->name = name; + if (name == (PinName)NC) { + return; + } + + unsigned int port = PINNAME_TO_PORT(name); + unsigned int pin = PINNAME_TO_PIN(name); + + obj->reg_out = (uint32_t*)BITBAND(&MXC_GPIO->out_val[port], pin); + obj->reg_in = (uint32_t*)BITBAND(&MXC_GPIO->in_val[port], pin); + obj->mode = PullDefault; + + /* Ensure that the GPIO clock is enabled */ + MXC_CLKMAN->clk_gate_ctrl1 |= MXC_F_CLKMAN_CLK_GATE_CTRL1_GPIO_CLK_GATER; + + /* Ensure that the GPIO clock is enabled */ + MXC_CLKMAN->sys_clk_ctrl_6_gpio = MXC_S_CLKMAN_CLK_SCALE_DIV_1; +} + +void gpio_mode(gpio_t *obj, PinMode mode) +{ + obj->mode = mode; + pin_mode(obj->name, mode); +} + +void pin_dir_mode(PinName name, PinDirection direction, PinMode mode) +{ + MBED_ASSERT(name != (PinName)NC); + + unsigned int port = PINNAME_TO_PORT(name); + unsigned int pin = PINNAME_TO_PIN(name); + + /* Set function; Firmware Control (GPIO mode) */ + MXC_GPIO->func_sel[port] &= ~(0xF << (4 * pin)); + + /* Normal input is always enabled */ + MXC_GPIO->in_mode[port] &= ~(0xF << (4 * pin)); + + uint32_t new_mode; + if (direction == PIN_OUTPUT) { + // PullUp = not valid, + // PullDown = not valid, + // OpenDrain = MXC_V_GPIO_OUT_MODE_OD, + // PullNone = MXC_V_GPIO_OUT_MODE_NORMAL, + if (mode == OpenDrain) { + new_mode = MXC_V_GPIO_OUT_MODE_OPEN_DRAIN; + } else { + new_mode = MXC_V_GPIO_OUT_MODE_NORMAL; + } + } else { + // PullUp = MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLUP + // PullDown = MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLDOWN + // OpenDrain = MXC_V_GPIO_OUT_MODE_OD + // PullNone = MXC_V_GPIO_OUT_MODE_NORMAL_HIGH_Z + if (mode == PullUp) { + new_mode = MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLUP; + MXC_GPIO->out_val[port] |= 1 << pin; + } else if (mode == PullDown) { + new_mode = MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLDOWN; + MXC_GPIO->out_val[port] &= ~(1 << pin); + } else if (mode == OpenDrain) { + new_mode = MXC_V_GPIO_OUT_MODE_OPEN_DRAIN; + MXC_GPIO->out_val[port] |= 1 << pin; + } else { + new_mode = MXC_V_GPIO_OUT_MODE_NORMAL_HIGH_Z; + MXC_GPIO->out_val[port] &= ~(1 << pin); + } + } + + /* Set new mode */ + uint32_t out_mode = MXC_GPIO->out_mode[port]; + out_mode &= ~(0xF << (pin * 4)); + out_mode |= (new_mode << (pin * 4)); + MXC_GPIO->out_mode[port] = out_mode; +} + +void gpio_dir(gpio_t *obj, PinDirection direction) +{ + pin_dir_mode(obj->name, direction, obj->mode); +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/gpio_irq_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/gpio_irq_api.c new file mode 100644 index 00000000000..ead582a1bb8 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/gpio_irq_api.c @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include +#include "cmsis.h" +#include "gpio_irq_api.h" +#include "mbed_error.h" + +static gpio_irq_t *objs[MXC_GPIO_NUM_PORTS][MXC_GPIO_MAX_PINS_PER_PORT] = {{0}}; +static gpio_irq_handler irq_handler; + +static void handle_irq(unsigned int port) +{ + uint32_t intfl, in_val; + uint32_t mask; + unsigned int pin; + + /* Read pin state */ + in_val = MXC_GPIO->in_val[port]; + + /* Read interrupts */ + intfl = MXC_GPIO->intfl[port] & MXC_GPIO->inten[port]; + + mask = 1; + + for (pin = 0; pin < MXC_GPIO_MAX_PINS_PER_PORT; pin++) { + if (intfl & mask) { + MXC_GPIO->intfl[port] = mask; /* clear interrupt */ + gpio_irq_event event = (in_val & mask) ? IRQ_RISE : IRQ_FALL; + gpio_irq_t *obj = objs[port][pin]; + if (obj && obj->id) { + if ((event == IRQ_RISE) && obj->rise_en) { + irq_handler(obj->id, IRQ_RISE); + } else if ((event == IRQ_FALL) && obj->fall_en) { + irq_handler(obj->id, IRQ_FALL); + } + } + } + mask <<= 1; + } +} + +void gpio_irq_0(void) { handle_irq(0); } +void gpio_irq_1(void) { handle_irq(1); } +void gpio_irq_2(void) { handle_irq(2); } +void gpio_irq_3(void) { handle_irq(3); } +void gpio_irq_4(void) { handle_irq(4); } + +int gpio_irq_init(gpio_irq_t *obj, PinName name, gpio_irq_handler handler, uint32_t id) +{ + if (name == NC) { + return -1; + } + + uint8_t port = PINNAME_TO_PORT(name); + uint8_t pin = PINNAME_TO_PIN(name); + + if ((port > MXC_GPIO_NUM_PORTS) || (pin > MXC_GPIO_MAX_PINS_PER_PORT)) { + return 1; + } + + obj->port = port; + obj->pin = pin; + obj->id = id; + objs[port][pin] = obj; + + /* register handlers */ + irq_handler = handler; + NVIC_SetVector(GPIO_P0_IRQn, (uint32_t)gpio_irq_0); + NVIC_SetVector(GPIO_P1_IRQn, (uint32_t)gpio_irq_1); + NVIC_SetVector(GPIO_P2_IRQn, (uint32_t)gpio_irq_2); + NVIC_SetVector(GPIO_P3_IRQn, (uint32_t)gpio_irq_3); + NVIC_SetVector(GPIO_P4_IRQn, (uint32_t)gpio_irq_4); + + /* disable the interrupt locally */ + MXC_GPIO->int_mode[port] &= ~(0xF << (pin*4)); + + /* clear a pending request */ + MXC_GPIO->intfl[port] = 1 << pin; + + /* enable the requested interrupt */ + MXC_GPIO->inten[port] |= (1 << pin); + NVIC_EnableIRQ((IRQn_Type)((uint32_t)GPIO_P0_IRQn + port)); + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) +{ + /* disable interrupt */ + MXC_GPIO->inten[obj->port] &= ~(1 << obj->pin); + MXC_GPIO->int_mode[obj->port] &= ~(MXC_V_GPIO_INT_MODE_ANY_EDGE << (obj->pin*4)); + objs[obj->port][obj->pin] = NULL; +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) +{ + if (event == IRQ_FALL) { + obj->fall_en = enable; + } else if (event == IRQ_RISE) { + obj->rise_en = enable; + } + + if (obj->fall_en && obj->rise_en) { + MXC_GPIO->int_mode[obj->port] |= (MXC_V_GPIO_INT_MODE_ANY_EDGE << (obj->pin*4)); + } else if (obj->fall_en) { + uint32_t int_mode = MXC_GPIO->int_mode[obj->port]; + int_mode &= ~(MXC_V_GPIO_INT_MODE_ANY_EDGE << (obj->pin*4)); + int_mode |= (MXC_V_GPIO_INT_MODE_FALLING_EDGE << (obj->pin*4)); + MXC_GPIO->int_mode[obj->port] = int_mode; + } else if (obj->rise_en) { + uint32_t int_mode = MXC_GPIO->int_mode[obj->port]; + int_mode &= ~(MXC_V_GPIO_INT_MODE_ANY_EDGE << (obj->pin*4)); + int_mode |= (MXC_V_GPIO_INT_MODE_RISING_EDGE << (obj->pin*4)); + MXC_GPIO->int_mode[obj->port] = int_mode; + } else { + MXC_GPIO->int_mode[obj->port] &= ~(MXC_V_GPIO_INT_MODE_ANY_EDGE << (obj->pin*4)); + } +} + +void gpio_irq_enable(gpio_irq_t *obj) +{ + MXC_GPIO->inten[obj->port] |= (1 << obj->pin); +} + +void gpio_irq_disable(gpio_irq_t *obj) +{ + MXC_GPIO->inten[obj->port] &= ~(1 << obj->pin); +} + +gpio_irq_t *gpio_irq_get_obj(PinName name) +{ + if (name == NC) { + return NULL; + } + + unsigned int port = PINNAME_TO_PORT(name); + unsigned int pin = PINNAME_TO_PIN(name); + + if ((port > MXC_GPIO_NUM_PORTS) || (pin > MXC_GPIO_MAX_PINS_PER_PORT)) { + return NULL; + } + + return objs[port][pin]; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/gpio_object.h b/targets/TARGET_Maxim/TARGET_MAX32625/gpio_object.h new file mode 100644 index 00000000000..63c5be2c37c --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/gpio_object.h @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName name; + __IO uint32_t *reg_out; + __I uint32_t *reg_in; + PinMode mode; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) +{ + MBED_ASSERT(obj->name != (PinName)NC); + *obj->reg_out = !!value; +} + +static inline int gpio_read(gpio_t *obj) +{ + MBED_ASSERT(obj->name != (PinName)NC); + return *obj->reg_in; +} + +void pin_dir_mode(PinName name, PinDirection direction, PinMode mode); + +static inline int gpio_is_connected(const gpio_t *obj) +{ + return obj->name != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/i2c_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/i2c_api.c new file mode 100644 index 00000000000..6886bee048d --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/i2c_api.c @@ -0,0 +1,214 @@ +/******************************************************************************* + * Copyright (c) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "mbed_assert.h" +#include "i2c_api.h" +#include "i2cm_regs.h" +#include "i2cm.h" +#include "pinmap.h" +#include "PeripheralPins.h" + +#ifndef MXC_I2CM_RX_TIMEOUT +#define MXC_I2CM_RX_TIMEOUT 0x5000 +#endif + +#define MBED_NAK 0 +#define MBED_ACK 1 +#define MBED_TIMEOUT 2 + +//****************************************************************************** +void i2c_init(i2c_t *obj, PinName sda, PinName scl) +{ + // SDA and SCL must map to same peripheral instance + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + mxc_i2cm_regs_t *i2c = (mxc_i2cm_regs_t*)pinmap_merge(i2c_sda, i2c_scl); + MBED_ASSERT((int)i2c != NC); + + obj->i2c = i2c; + obj->fifo = MXC_I2CM_GET_FIFO(MXC_I2CM_GET_IDX(i2c)); + obj->start_pending = 0; + + // Merge pin function requests for use with CMSIS init func + ioman_req_t io_req; + pin_function_t *pin_func; + pin_func = (pin_function_t *)pinmap_find_function(sda, PinMap_I2C_SDA); + io_req.value = pin_func->req_val; + pin_func = (pin_function_t *)pinmap_find_function(scl, PinMap_I2C_SCL); + io_req.value |= pin_func->req_val; + + sys_cfg_i2cm_t sys_cfg; + sys_cfg.io_cfg.req_reg = pin_func->reg_req; + sys_cfg.io_cfg.ack_reg = pin_func->reg_ack; + sys_cfg.io_cfg.req_val = io_req; + sys_cfg.clk_scale = CLKMAN_SCALE_DIV_1; + + I2CM_Init(obj->i2c, &sys_cfg, I2CM_SPEED_400KHZ); +} + +//****************************************************************************** +void i2c_frequency(i2c_t *obj, int hz) +{ + I2CM_SetFrequency(obj->i2c, hz); +} + +//****************************************************************************** +int i2c_start(i2c_t *obj) +{ + obj->start_pending = 1; + return 0; +} + +//****************************************************************************** +int i2c_stop(i2c_t *obj) +{ + obj->start_pending = 0; + I2CM_WriteTxFifo(obj->i2c, obj->fifo, MXC_S_I2CM_TRANS_TAG_STOP); + I2CM_TxInProgress(obj->i2c); + return 0; +} + +//****************************************************************************** +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) +{ + MBED_ASSERT(stop != 0); + return I2CM_Read(obj->i2c, address >> 1, NULL, 0, (uint8_t *)data, length); +} + +//****************************************************************************** +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) +{ + mxc_i2cm_regs_t *i2cm = obj->i2c; + mxc_i2cm_fifo_regs_t *fifo = obj->fifo; + + if (stop) { + return I2CM_Write(i2cm, address >> 1, NULL, 0, (uint8_t *)data, length); + } + + i2cm->inten = 0; + i2cm->intfl = i2cm->intfl; + if (I2CM_Tx(i2cm, fifo, address >> 1, (uint8_t *)data, length, 0) == E_NO_ERROR) { + return length; + } else { + return -1; + } +} + +//****************************************************************************** +void i2c_reset(i2c_t *obj) +{ + I2CM_Recover(obj->i2c); +} + +//****************************************************************************** +int i2c_byte_read(i2c_t *obj, int last) +{ + mxc_i2cm_regs_t *i2cm = obj->i2c; + mxc_i2cm_fifo_regs_t *fifo = obj->fifo; + int tmp; + + // Start the transaction if it is not currently ongoing + if (!(i2cm->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) { + i2cm->trans |= MXC_F_I2CM_TRANS_TX_START; + } + + if (last) { + // NACK the last read byte + if (I2CM_WriteTxFifo(i2cm, fifo, MXC_S_I2CM_TRANS_TAG_RXDATA_NACK) != E_NO_ERROR) { + goto byte_write_err; + } + + // Send the stop condition + if (I2CM_WriteTxFifo(i2cm, fifo, MXC_S_I2CM_TRANS_TAG_STOP) != E_NO_ERROR) { + goto byte_write_err; + } + } else { + if (I2CM_WriteTxFifo(i2cm, fifo, MXC_S_I2CM_TRANS_TAG_RXDATA_COUNT) != E_NO_ERROR) { + goto byte_write_err; + } + } + + do { + // Wait for data in RX FIFO + int timeout = MXC_I2CM_RX_TIMEOUT; + while (!(i2cm->intfl & MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY) && + ((i2cm->bb & MXC_F_I2CM_BB_RX_FIFO_CNT) == 0)) { + + if((timeout-- < 0) || (i2cm->trans & MXC_F_I2CM_TRANS_TX_TIMEOUT)) { + goto byte_write_err; + } + + if (i2cm->trans & (MXC_F_I2CM_TRANS_TX_LOST_ARBITR | MXC_F_I2CM_TRANS_TX_NACKED)) { + goto byte_write_err; + } + } + i2cm->intfl = MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY; + + } while ((tmp = fifo->rx) & MXC_S_I2CM_RSTLS_TAG_EMPTY); + + return (uint8_t)tmp; + +byte_write_err: + i2c_reset(obj); + return -1; +} + +//****************************************************************************** +int i2c_byte_write(i2c_t *obj, int data) +{ + mxc_i2cm_regs_t *i2cm = obj->i2c; + mxc_i2cm_fifo_regs_t *fifo = obj->fifo; + int result; + + if (obj->start_pending) { + obj->start_pending = 0; + data |= MXC_S_I2CM_TRANS_TAG_START; + } else { + data |= MXC_S_I2CM_TRANS_TAG_TXDATA_ACK; + } + + if ((result = I2CM_WriteTxFifo(i2cm, fifo, data)) != E_NO_ERROR) { + i2c_reset(obj); + if (result == E_COMM_ERR) { + return MBED_NAK; + } + return MBED_TIMEOUT; + } + + // Start the transaction if it is not currently ongoing + if (!(i2cm->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) { + i2cm->trans |= MXC_F_I2CM_TRANS_TX_START; + } + + return MBED_ACK; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/adc.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/adc.c new file mode 100644 index 00000000000..33ac2914984 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/adc.c @@ -0,0 +1,178 @@ +/** + * @file adc.c + * @brief This file contains the function implementations for the Analog to + * Digital Converter (ADC) peripheral module. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-02 13:32:46 -0500 (Tue, 02 Aug 2016) $ + * $Revision: 23893 $ + * + *************************************************************************** */ + +/** + * @ingroup adc + * @{ + */ + +/* **** Includes **** */ +#include "mxc_config.h" +#include "mxc_assert.h" +#include "mxc_sys.h" +#include "adc.h" + +/* **** Definitions **** */ + +/* **** Globals **** */ + +/* **** Functions **** */ + +/* ************************************************************************* */ +int ADC_Init(void) +{ + int err; + + if ((err = SYS_ADC_Init()) != E_NO_ERROR) { + return err; + } + + /* Wipe previous configuration */ + MXC_ADC->intr = 0; + + /* Clear all ADC interrupt flags (W1C) */ + MXC_ADC->intr = MXC_ADC->intr; + + /* Enable done interrupt */ + MXC_ADC->intr = MXC_F_ADC_INTR_ADC_DONE_IE; + + /* Power up the ADC */ + MXC_ADC->ctrl = (MXC_F_ADC_CTRL_ADC_PU | + MXC_F_ADC_CTRL_ADC_CLK_EN | + MXC_F_ADC_CTRL_BUF_PU | + MXC_F_ADC_CTRL_ADC_REFBUF_PU | + MXC_F_ADC_CTRL_ADC_CHGPUMP_PU); + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +void ADC_StartConvert(mxc_adc_chsel_t channel, unsigned int adc_scale, unsigned int bypass) +{ + uint32_t ctrl_tmp; + + /* Clear the ADC done flag */ + ADC_ClearFlags(MXC_F_ADC_INTR_ADC_DONE_IF); + + /* Insert channel selection */ + ctrl_tmp = MXC_ADC->ctrl; + ctrl_tmp &= ~(MXC_F_ADC_CTRL_ADC_CHSEL); + ctrl_tmp |= ((channel << MXC_F_ADC_CTRL_ADC_CHSEL_POS) & MXC_F_ADC_CTRL_ADC_CHSEL); + + /* Clear channel configuration */ + ctrl_tmp &= ~(MXC_F_ADC_CTRL_ADC_REFSCL | MXC_F_ADC_CTRL_ADC_SCALE | MXC_F_ADC_CTRL_BUF_BYPASS); + + /* ADC reference scaling must be set for all channels but two*/ + if ((channel != ADC_CH_VDD18) && (channel != ADC_CH_VDD12)) { + ctrl_tmp |= MXC_F_ADC_CTRL_ADC_REFSCL; + } + + /* Finalize user-requested channel configuration */ + if (adc_scale || channel > ADC_CH_3) { + ctrl_tmp |= MXC_F_ADC_CTRL_ADC_SCALE; + } + if (bypass) { + ctrl_tmp |= MXC_F_ADC_CTRL_BUF_BYPASS; + } + + /* Write this configuration */ + MXC_ADC->ctrl = ctrl_tmp; + + /* Start conversion */ + MXC_ADC->ctrl |= MXC_F_ADC_CTRL_CPU_ADC_START; + +} + +/* ************************************************************************* */ +int ADC_GetData(uint16_t *outdata) +{ + /* See if a conversion is in process */ + if (MXC_ADC->status & MXC_F_ADC_STATUS_ADC_ACTIVE) { + /* Wait for conversion to complete */ + while ((MXC_ADC->intr & MXC_F_ADC_INTR_ADC_DONE_IF) == 0); + } + + /* Read 32-bit value and truncate to 16-bit for output depending on data align bit*/ + if((MXC_ADC->ctrl & MXC_F_ADC_CTRL_ADC_DATAALIGN) == 0) + *outdata = (uint16_t)(MXC_ADC->data); /* LSB justified */ + else + *outdata = (uint16_t)(MXC_ADC->data >> 6); /* MSB justified */ + + /* Check for overflow */ + if (MXC_ADC->status & MXC_F_ADC_STATUS_ADC_OVERFLOW) { + return E_OVERFLOW; + } + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +int ADC_SetLimit(mxc_adc_limitsel_t unit, mxc_adc_chsel_t channel, + unsigned int low_enable, unsigned int low_limit, + unsigned int high_enable, unsigned int high_limit) +{ + /* Check args */ + if ((unit >= ADC_LIMIT_MAX) || (channel >= ADC_CH_MAX)) + return E_BAD_PARAM; + + /* set channel using the limit */ + MXC_ADC->limit[unit] = ((channel << MXC_F_ADC_LIMIT0_CH_SEL_POS) & MXC_F_ADC_LIMIT0_CH_SEL); + + /* enable/disable the limit*/ + if (low_enable) { + MXC_ADC->limit[unit] |= MXC_F_ADC_LIMIT0_CH_LO_LIMIT_EN | + ((low_limit << MXC_F_ADC_LIMIT0_CH_LO_LIMIT_POS) & MXC_F_ADC_LIMIT0_CH_LO_LIMIT); + } else { + MXC_ADC->limit[unit] &= ~MXC_F_ADC_LIMIT0_CH_LO_LIMIT_EN; + } + + if (high_enable) { + MXC_ADC->limit[unit] |= MXC_F_ADC_LIMIT0_CH_HI_LIMIT_EN | + ((high_limit << MXC_F_ADC_LIMIT0_CH_HI_LIMIT_POS) & MXC_F_ADC_LIMIT0_CH_HI_LIMIT); + } else { + MXC_ADC->limit[unit] &= ~MXC_F_ADC_LIMIT0_CH_HI_LIMIT_EN; + } + + return E_NO_ERROR; +} + +/**@} end of group adc */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/adc.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/adc.h new file mode 100644 index 00000000000..26146f3f36e --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/adc.h @@ -0,0 +1,216 @@ +/** + * @file adc.h + * @brief Analog to Digital Converter function prototypes and data types. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-04 16:21:09 -0500 (Thu, 04 Aug 2016) $ + * $Revision: 23947 $ + * + *************************************************************************** */ + +/* Define to prevent redundant inclusion */ +#ifndef _ADC_H +#define _ADC_H + +/* **** Includes **** */ +#include +#include "adc_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Doxy group definition for this peripheral module */ + +/** + * @defgroup adc Analog to Digital Converter (ADC) + * @ingroup periphlibs + * @{ + */ + +/* **** Definitions **** */ + +/** + * Enumeration type for ADC Channel Selection. See \ref ADC_CHSEL_values "ADC Channel Select Values" for additional information. + */ +typedef enum { + ADC_CH_0 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN0, /**< Channel 0 Select */ + ADC_CH_1 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN1, /**< Channel 1 Select */ + ADC_CH_2 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN2, /**< Channel 2 Select */ + ADC_CH_3 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN3, /**< Channel 3 Select */ + ADC_CH_0_DIV_5 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN0_DIV_5, /**< Channel 0 divided by 5 */ + ADC_CH_1_DIV_5 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN1_DIV_5, /**< Channel 1 divided by 5 */ + ADC_CH_VDDB_DIV_4 = MXC_V_ADC_CTRL_ADC_CHSEL_VDDB_DIV_4, /**< VDDB divided by 4 */ + ADC_CH_VDD18 = MXC_V_ADC_CTRL_ADC_CHSEL_VDD18, /**< VDD18 input select */ + ADC_CH_VDD12 = MXC_V_ADC_CTRL_ADC_CHSEL_VDD12, /**< VDD12 input select */ + ADC_CH_VRTC_DIV_2 = MXC_V_ADC_CTRL_ADC_CHSEL_VRTC_DIV_2, /**< VRTC divided by 2 */ + ADC_CH_TMON = MXC_V_ADC_CTRL_ADC_CHSEL_TMON, /**< TMON input select */ +#if (MXC_ADC_REV > 0) + ADC_CH_VDDIO_DIV_4 = MXC_V_ADC_CTRL_ADC_CHSEL_VDDIO_DIV_4, /**< VDDIO divided by 4 select */ + ADC_CH_VDDIOH_DIV_4 = MXC_V_ADC_CTRL_ADC_CHSEL_VDDIOH_DIV_4, /**< VDDIOH divided by 4 select */ +#endif + ADC_CH_MAX /**< Max enum value for channel selection */ +} mxc_adc_chsel_t; + +/** + * Enumeration type for the ADC limit register to set + */ +typedef enum { + ADC_LIMIT_0 = 0, /**< ADC Limit Register 0 */ + ADC_LIMIT_1 = 1, /**< ADC Limit Register 1 */ + ADC_LIMIT_2 = 2, /**< ADC Limit Register 2 */ + ADC_LIMIT_3 = 3, /**< ADC Limit Register 3 */ + ADC_LIMIT_MAX /**< Number of Limit registers */ +} mxc_adc_limitsel_t; + +///@cond +/** + * Mask for all Interrupt Flag Fields + */ +#define ADC_IF_MASK (0xffffffffUL << MXC_F_ADC_INTR_ADC_DONE_IF_POS) + +/** + * Mask for all Interrupt Enable Fields + */ +#define ADC_IE_MASK (0xffffffffUL >> MXC_F_ADC_INTR_ADC_DONE_IF_POS) +///@endcond + +/* **** Function Prototypes **** */ + +/** + * @brief Initialize the ADC hardware + * + * @return #E_NO_ERROR if successful + */ +int ADC_Init(void); + +/** + * @brief Start ADC conversion on the selected channel + * + * @param channel Channel select from #mxc_adc_chsel_t + * @param adc_scale Enable the ADC input scaling mode if non-zero + * @param bypass Bypass input buffer stage if non-zero + */ +void ADC_StartConvert(mxc_adc_chsel_t channel, unsigned int adc_scale, unsigned int bypass); + +/** + * @brief Gets the result from the previous ADC conversion + * + * @param outdata Pointer to store the ADC data conversion + * result. + * @return #E_OVERFLOW ADC overflow error + * @return #E_NO_ERROR Data returned in outdata parameter + */ +int ADC_GetData(uint16_t *outdata); + +/** + * @brief Set the data limits for an ADC channel monitor + * + * @param unit Which data limit unit to configure + * @param channel Channel select from mxc_adc_chsel_t + * @param low_enable Enable the lower limit on this monitor + * @param low_limit Value for lower limit monitor + * @param high_enable Enable the upper limit on this monitor + * @param high_limit Value for upper limit monitor + * + * @return #E_BAD_PARAM ADC limit or channel greater than supported + * @return #E_NO_ERROR ADC limit set successfully + */ +int ADC_SetLimit(mxc_adc_limitsel_t unit, mxc_adc_chsel_t channel, + unsigned int low_enable, unsigned int low_limit, + unsigned int high_enable, unsigned int high_limit); + +/** + * @brief Get interrupt flags + * + * @return ADC Interrupt flags bit mask. See the @ref ADC_INTR_IF_Register + * "ADC_INTR Register" for the interrupt flag masks. + */ +__STATIC_INLINE uint32_t ADC_GetFlags() +{ + return (MXC_ADC->intr & ADC_IF_MASK); +} + +/** + * @brief Clear interrupt flag(s) using the mask parameter. All bits set in + * the parameter will be cleared. + * + * @param mask Interrupt flags to clear. See the @ref ADC_INTR_IF_Register + * "ADC_INTR Register" for the interrupt flag masks. + */ +__STATIC_INLINE void ADC_ClearFlags(uint32_t mask) +{ + MXC_ADC->intr = ((MXC_ADC->intr & ADC_IF_MASK) | mask); +} + +/** + * @brief Get the Status of the ADC + * + * @return ADC status register. See @ref ADC_STATUS_Register "ADC_STATUS + * Register" for details. + */ +__STATIC_INLINE uint32_t ADC_GetStatus() +{ + return (MXC_ADC->status); +} + +/** + * @brief Enables the ADC interrupts specified by the mask parameter + * + * @param mask ADC interrupts to enable. See @ref ADC_INTR_IE_Register + * "ADC_INTR Register" for the interrupt enable bit masks. + */ +__STATIC_INLINE void ADC_EnableINT(uint32_t mask) +{ + MXC_ADC->intr = ((MXC_ADC->intr & ADC_IE_MASK) | mask); +} + +/** + * @brief Disable ADC interrupts based on mask + * + * @param mask ADC interrupts to disable. See @ref ADC_INTR_IE_Register + * "ADC_INTR Register" for the interrupt enable bit masks. + */ +__STATIC_INLINE void ADC_DisableINT(uint32_t mask) +{ + MXC_ADC->intr = ((MXC_ADC->intr & ADC_IE_MASK) & ~mask); +} + +/**@} end of group adc */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ADC_H */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/aes.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/aes.c new file mode 100644 index 00000000000..02ee5069263 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/aes.c @@ -0,0 +1,213 @@ +/** + * @file aes.c + * @brief This file contains the function implementations for the Advanced + * Encryption Standard (AES) peripheral module. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-02 13:39:05 -0500 (Tue, 02 Aug 2016) $ + * $Revision: 23894 $ + * + *************************************************************************** */ + +/* **** Includes **** */ +#include /* Included for memcpy() & #includes stddef for NULL */ + +#include "mxc_config.h" +#include "aes.h" + +/** + * @ingroup aes + * @{ + */ + +/* **** Definitions **** */ + +/* **** Globals **** */ + +/* **** Local Function Prototypes **** */ +static int aes_memcpy32(uint32_t *out, uint32_t *in, unsigned int count); + +/* **** Functions **** */ + +/* ************************************************************************* */ +int AES_SetKey(const uint8_t *key, mxc_aes_mode_t mode) +{ + unsigned int len; + + /* Erase any existing key */ + MXC_AES_MEM->key[7] = MXC_AES_MEM->key[6] = MXC_AES_MEM->key[5] = MXC_AES_MEM->key[4] \ + = MXC_AES_MEM->key[3] = MXC_AES_MEM->key[2] = MXC_AES_MEM->key[1] = MXC_AES_MEM->key[0] \ + = 0x00000000; + + /* Determine length of key */ + if (mode == MXC_E_AES_MODE_256) { + len = MXC_AES_KEY_256_LEN; + } else if (mode == MXC_E_AES_MODE_192) { + len = MXC_AES_KEY_192_LEN; + } else if (mode == MXC_E_AES_MODE_128) { + len = MXC_AES_KEY_128_LEN; + } else { + return E_BAD_PARAM; + } + + /* Load new key, based on key mode */ + if (aes_memcpy32((uint32_t *)MXC_AES_MEM->key, (uint32_t *)key, len / sizeof(uint32_t)) < 0) { + return E_NULL_PTR; + } + + return E_SUCCESS; +} + +/* ************************************************************************* */ +int AES_ECBOp(const uint8_t *in, uint8_t *out, mxc_aes_mode_t mode, mxc_aes_dir_t dir) +{ + /* Output array can't be a NULL, unless we are in _ASYNC mode */ + if ((out == NULL) + && ((dir != MXC_E_AES_ENCRYPT_ASYNC) && (dir != MXC_E_AES_DECRYPT_ASYNC))) { + return E_NULL_PTR; + } + + /* Another encryption is already in progress */ + if (MXC_AES->ctrl & MXC_F_AES_CTRL_START) { + return E_BUSY; + } + + /* Clear interrupt flag and any existing configuration*/ + MXC_AES->ctrl = MXC_F_AES_CTRL_INTFL; + + /* Select key size & direction + * + * Note: This is done first to detect argument errors, before sensitive data + * is loaded into AES_MEM block + * + */ + switch (mode) { + case MXC_E_AES_MODE_128: + MXC_AES->ctrl |= MXC_S_AES_CTRL_KEY_SIZE_128; + break; + + case MXC_E_AES_MODE_192: + MXC_AES->ctrl |= MXC_S_AES_CTRL_KEY_SIZE_192; + break; + + case MXC_E_AES_MODE_256: + MXC_AES->ctrl |= MXC_S_AES_CTRL_KEY_SIZE_256; + break; + + default: + return E_BAD_PARAM; + } + + switch (dir) { + case MXC_E_AES_ENCRYPT: + case MXC_E_AES_ENCRYPT_ASYNC: + MXC_AES->ctrl |= MXC_S_AES_CTRL_ENCRYPT_MODE; + break; + + case MXC_E_AES_DECRYPT: + case MXC_E_AES_DECRYPT_ASYNC: + MXC_AES->ctrl |= MXC_S_AES_CTRL_DECRYPT_MODE; + break; + + default: + return E_BAD_PARAM; + } + + /* If non-blocking mode has been selected, interrupts are automatically enabled */ + if ((dir == MXC_E_AES_ENCRYPT_ASYNC) || + (dir == MXC_E_AES_DECRYPT_ASYNC)) { + MXC_AES->ctrl |= MXC_F_AES_CTRL_INTEN; + } + + /* Load input into engine */ + if (aes_memcpy32((uint32_t *)MXC_AES_MEM->inp, (uint32_t *)in, MXC_AES_DATA_LEN / sizeof(uint32_t)) < 0) { + return E_NULL_PTR; + } + + /* Start operation */ + MXC_AES->ctrl |= MXC_F_AES_CTRL_START; + + /* Block, waiting on engine to complete, or fall through if non-blocking */ + if ((dir != MXC_E_AES_ENCRYPT_ASYNC) && + (dir != MXC_E_AES_DECRYPT_ASYNC)) { + while (MXC_AES->ctrl & MXC_F_AES_CTRL_START) { + /* Ensure that this wait loop is not optimized out */ + __NOP(); + } + + /* Get output from engine */ + return AES_GetOutput(out); + } + + return E_SUCCESS; +} + +/* ************************************************************************* */ +int AES_GetOutput(uint8_t *out) +{ + /* Don't read it out of the AES memory unless engine is idle */ + if (MXC_AES->ctrl & MXC_F_AES_CTRL_START) { + return E_BUSY; + } + + /* Pull out result */ + if (aes_memcpy32((uint32_t *)out, (uint32_t *)MXC_AES_MEM->out, MXC_AES_DATA_LEN / sizeof(uint32_t)) < 0) { + return E_NULL_PTR; + } + + /* Clear interrupt flag, write 1 to clear */ + MXC_AES->ctrl |= MXC_F_AES_CTRL_INTFL; + + return E_SUCCESS; +} + +/** + * @internal This memory copy is used only by the AES module to avoid data leakage by the standard C library. + * Copy count number of 32-bit locations from in to out + */ +static int aes_memcpy32(uint32_t *out, uint32_t *in, unsigned int count) +{ + if ((out == NULL) || (in == NULL)) { + /* Invalid arguments, but is internal-only so don't use error codes */ + return -1; + } + + while (count--) { + *out++ = *in++; + } + + return 0; +} + +/**@} end of group aes */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/aes.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/aes.h new file mode 100644 index 00000000000..8dc7f6a1a70 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/aes.h @@ -0,0 +1,199 @@ +/** + * @file aes.h + * @brief Advanced Encryption Standard (AES) function prototypes and data types. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-02 13:39:05 -0500 (Tue, 02 Aug 2016) $ + * $Revision: 23894 $ + * + *************************************************************************** */ + +/* Define to prevent redundant inclusion */ +#ifndef _AES_H +#define _AES_H + +#include +#include "aes_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup aes Advanced Encryption Standard (AES) + * @ingroup periphlibs + * @brief High-level API for AES encryption engine + * @{ + */ + +/** + * @page aes_overview Overview and Usage + * @parblock + * #### Key/data format in memory + * + * The API functions require that key and plain/ciphertext will be stored as a + * byte array in LSB .. MSB format. + * + * As an example, given the key @a 0x139a35422f1d61de3c91787fe0507afd, the proper storage order is: + * ~~~~~ + * uint8_t key[16] = { 0xfd, 0x7a, 0x50, 0xe0, + * 0x7f, 0x78, 0x91, 0x3c, + * 0xde, 0x61, 0x1d, 0x2f, + * 0x42, 0x35, 0x9a, 0x13 }; + * ~~~~~ + * This is the same order expected by the underlying hardware. + * @endparblock + */ + +/* **** Definitions **** */ + +#define MXC_AES_DATA_LEN (128 / 8) /**< Number of bytes in an AES plaintext or cyphertext block (always 128-bits) */ + +#define MXC_AES_KEY_128_LEN (128 / 8) /**< Number of bytes in a AES-128 key */ +#define MXC_AES_KEY_192_LEN (192 / 8) /**< Number of bytes in a AES-192 key */ +#define MXC_AES_KEY_256_LEN (256 / 8) /**< Number of bytes in a AES-256 key */ + +/** + * Enumeration type for AES key size selection (bits). + */ +typedef enum { + MXC_E_AES_MODE_128 = MXC_V_AES_CTRL_KEY_SIZE_128, /**< 128-bit key */ + MXC_E_AES_MODE_192 = MXC_V_AES_CTRL_KEY_SIZE_192, /**< 192-bit key */ + MXC_E_AES_MODE_256 = MXC_V_AES_CTRL_KEY_SIZE_256 /**< 256-bit key */ +} mxc_aes_mode_t; + +/** + * Enumeration type for specifying encryption/decrytion and asynchronous or blocking behavior. + */ +typedef enum { + MXC_E_AES_ENCRYPT = 0, /**< Encrypt (blocking) */ + MXC_E_AES_ENCRYPT_ASYNC = 1, /**< Encrypt (interrupt-driven) */ + MXC_E_AES_DECRYPT = 2, /**< Decrypt (blocking) */ + MXC_E_AES_DECRYPT_ASYNC = 3 /**< Decrypt (interrupt-driven) */ +} mxc_aes_dir_t; + +/* **** Function Prototypes **** */ + +/** + * @brief Configure AES block with keying material + * + * @param key 128, 192, or 256 bit keying material + * @param mode Selects key length, valid modes defined in #mxc_aes_mode_t + * + * @return #E_BAD_PARAM Specified @a mode is invalid, see #mxc_aes_mode_t. + * @return #E_NULL_PTR Invalid/Null pointer for parameter @a key. + * @return #E_SUCCESS Key and mode set up correctly. + */ +int AES_SetKey(const uint8_t *key, mxc_aes_mode_t mode); + + +/** + * @brief Encrypt/decrypt an input block with the loaded AES key. + * @note The parameters @a in and @a out should always be 16 bytes + * + * @param in Pointer to input array of 16 bytes. + * @param out Pointer to output array of 16 bytes. + * @param mode AES key size to use for the transaction, see #mxc_aes_mode_t + * @param dir Encrypt/Decrypt and Blocking or Asynchronous operation, see #mxc_aes_dir_t. + * + * @return #E_SUCCESS Operation completed successfully, output data is stored in @a *out. + * @return ErrorCode An @link MXC_Error_Codes Error Code@endlink. + */ +int AES_ECBOp(const uint8_t *in, uint8_t *out, mxc_aes_mode_t mode, mxc_aes_dir_t dir); + +/** + * @brief Read the AES output memory, used for asynchronous encryption, and clears interrupt flag. + * @note The parameter @a out is always 16 bytes + * + * @param out Pointer to output array of 16 bytes + * + * @return #E_SUCCESS Output data was written to the location pointed to by @a *out + * @return Error Code indicating the type of error encountered. See @ref MXC_Error_Codes + * for possible return code values. + */ +int AES_GetOutput(uint8_t *out); + +/** + * @def AES_ECBEncrypt(ptxt, ctxt, mode)s + * @brief Encrypt a block of plaintext with the loaded AES key, blocks until complete + * @hideinitializer + * + * @param ptxt Pointer to plaintext input array (always 16 bytes) + * @param ctxt Pointer to ciphertext output array (always 16 bytes) + * @param mode Selects key length, valid modes found in mxc_aes_mode_t + */ +#define AES_ECBEncrypt(ptxt, ctxt, mode) AES_ECBOp(ptxt, ctxt, mode, MXC_E_AES_ENCRYPT) + + +/** + * @def AES_ECBDecrypt(ctxt, ptxt, mode) + * @hideinitializer + * @brief Decrypt a block of ciphertext with the loaded AES key, blocks until complete + * + * @param ctxt Pointer to ciphertext output array (always 16 bytes) + * @param ptxt Pointer to plaintext input array (always 16 bytes) + * @param mode Selects key length, valid modes found in mxc_aes_mode_t + */ +#define AES_ECBDecrypt(ctxt, ptxt, mode) AES_ECBOp(ctxt, ptxt, mode, MXC_E_AES_DECRYPT) + +/** + * @def AES_ECBEncryptAsync(ptxt, mode) + * @hideinitializer + * @brief Starts encryption of a block, enables interrupt, and returns immediately. + * Use AES_GetOuput() to retrieve result after interrupt fires + * + * + * @param ptxt Pointer to plaintext input array (always 16 bytes) + * @param mode Selects key length, valid modes found in mxc_aes_mode_t + */ +#define AES_ECBEncryptAsync(ptxt, mode) AES_ECBOp(ptxt, NULL, mode, MXC_E_AES_ENCRYPT_ASYNC) + +/** + * @def AES_ECBDecryptAsync(ctxt, mode) + * @hideinitializer + * @brief Starts encryption of a block, enables interrupt, and returns immediately. + * Use AES_GetOuput() to retrieve result after interrupt fires + * + * @param ctxt Pointer to ciphertext output array (always 16 bytes) + * @param mode Selects key length, valid modes found in mxc_aes_mode_t + */ +#define AES_ECBDecryptAsync(ctxt, mode) AES_ECBOp(ctxt, NULL, mode, MXC_E_AES_DECRYPT_ASYNC) + +/**@} end of group aes*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/clkman.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/clkman.c new file mode 100644 index 00000000000..f26bc56cb44 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/clkman.c @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-04-27 09:12:45 -0500 (Wed, 27 Apr 2016) $ + * $Revision: 22531 $ + * + ******************************************************************************/ +#include "mxc_config.h" +#include "mxc_assert.h" +#include "clkman.h" +#include "pwrseq_regs.h" + +/******************************************************************************/ +void CLKMAN_SetSystemClock(clkman_system_source_select_t select, clkman_system_scale_t scale) +{ + MXC_CLKMAN->clk_ctrl = ((MXC_CLKMAN->clk_ctrl & ~MXC_F_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT) | + (MXC_V_CLKMAN_CLK_CTRL_SYSTEM_SOURCE_SELECT_96MHZ_RO)); + + switch(select) { + case CLKMAN_SYSTEM_SOURCE_96MHZ: + default: + // Enable and select the 96MHz oscillator + MXC_PWRSEQ->reg0 |= (MXC_F_PWRSEQ_REG0_PWR_ROEN_RUN); + MXC_PWRSEQ->reg0 &= ~(MXC_F_PWRSEQ_REG0_PWR_OSC_SELECT); + + // Disable the 4MHz oscillator + MXC_PWRSEQ->reg0 &= ~MXC_F_PWRSEQ_REG0_PWR_RCEN_RUN; + + // Divide the system clock by the scale + MXC_PWRSEQ->reg3 = ((MXC_PWRSEQ->reg3 & ~MXC_F_PWRSEQ_REG3_PWR_RO_DIV) | + (scale << MXC_F_PWRSEQ_REG3_PWR_RO_DIV_POS)); + + break; + case CLKMAN_SYSTEM_SOURCE_4MHZ: + // Enable and select the 4MHz oscillator + MXC_PWRSEQ->reg0 |= (MXC_F_PWRSEQ_REG0_PWR_RCEN_RUN); + MXC_PWRSEQ->reg0 |= (MXC_F_PWRSEQ_REG0_PWR_OSC_SELECT); + + // Disable the 96MHz oscillator + MXC_PWRSEQ->reg0 &= ~MXC_F_PWRSEQ_REG0_PWR_ROEN_RUN; + + // 4MHz System source can only be divided down by a maximum factor of 8 + MXC_ASSERT(scale <= CLKMAN_SYSTEM_SCALE_DIV_8); + + // Divide the system clock by the scale + MXC_PWRSEQ->reg3 = ((MXC_PWRSEQ->reg3 & ~MXC_F_PWRSEQ_REG3_PWR_RC_DIV) | + (scale << MXC_F_PWRSEQ_REG3_PWR_RC_DIV_POS)); + break; + } + + SystemCoreClockUpdate(); +} + +/******************************************************************************/ +void CLKMAN_CryptoClockEnable(int enable) +{ + if (enable) { + /* Enable oscillator */ + MXC_CLKMAN->clk_config |= MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_ENABLE; + /* Un-gate clock to TPU modules */ + MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_CRYPTO_CLOCK_ENABLE; + } else { + /* Gate clock off */ + MXC_CLKMAN->clk_ctrl &= ~MXC_F_CLKMAN_CLK_CTRL_CRYPTO_CLOCK_ENABLE; + /* Disable oscillator */ + MXC_CLKMAN->clk_config &= ~MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_ENABLE; + } +} + +/******************************************************************************/ +void CLKMAN_SetClkScale(clkman_clk_t clk, clkman_scale_t scale) +{ + volatile uint32_t *clk_ctrl_reg; + + MXC_ASSERT(clk <= CLKMAN_CLK_MAX); + MXC_ASSERT(scale != CLKMAN_SCALE_AUTO); + + if (clk < CLKMAN_CRYPTO_CLK_AES) { + clk_ctrl_reg = &MXC_CLKMAN->sys_clk_ctrl_0_cm4 + clk; + } else { + clk_ctrl_reg = &MXC_CLKMAN->crypt_clk_ctrl_0_aes + (clk - CLKMAN_CRYPTO_CLK_AES); + } + + *clk_ctrl_reg = scale; +} + +/******************************************************************************/ +clkman_scale_t CLKMAN_GetClkScale(clkman_clk_t clk) +{ + volatile uint32_t *clk_ctrl_reg; + MXC_ASSERT(clk <= CLKMAN_CLK_MAX); + + if (clk < CLKMAN_CRYPTO_CLK_AES) { + clk_ctrl_reg = &MXC_CLKMAN->sys_clk_ctrl_0_cm4 + clk; + } else { + clk_ctrl_reg = &MXC_CLKMAN->crypt_clk_ctrl_0_aes + (clk - CLKMAN_CRYPTO_CLK_AES); + } + + return (clkman_scale_t)*clk_ctrl_reg; +} + +/******************************************************************************/ +void CLKMAN_ClockGate(clkman_enable_clk_t clk, int enable) +{ + if (enable) { + MXC_CLKMAN->clk_ctrl |= clk; + } else { + MXC_CLKMAN->clk_ctrl &= ~clk; + } +} + +/******************************************************************************/ +int CLKMAN_WdtClkSelect(unsigned int idx, clkman_wdt_clk_select_t select) +{ + MXC_ASSERT(idx < MXC_CFG_WDT_INSTANCES); + + if (select == CLKMAN_WDT_SELECT_DISABLED) { + if (idx == 0) { + MXC_CLKMAN->clk_ctrl &= ~MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_ENABLE; + } else if (idx == 1) { + MXC_CLKMAN->clk_ctrl &= ~MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_ENABLE; + } else { + return E_BAD_PARAM; + } + } else { + if (idx == 0) { + MXC_CLKMAN->clk_ctrl = (MXC_CLKMAN->clk_ctrl & ~MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_SELECT) | + MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_ENABLE | + ((select << MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_SELECT_POS) & MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_SELECT); + } else if (idx == 1) { + MXC_CLKMAN->clk_ctrl = (MXC_CLKMAN->clk_ctrl & ~MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_SELECT) | + MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_ENABLE | + ((select << MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_SELECT_POS) & MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_SELECT); + } else { + return E_BAD_PARAM; + } + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +/* NOTE: CLKMAN_TrimRO() is implemented in system_max32XXX.c */ +/******************************************************************************/ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/clkman.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/clkman.h new file mode 100644 index 00000000000..03f734712cd --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/clkman.h @@ -0,0 +1,234 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-04-27 09:12:45 -0500 (Wed, 27 Apr 2016) $ + * $Revision: 22531 $ + * + ******************************************************************************/ + +/** + * @file clkman.h + * @brief Clock management driver header file. + */ + +#ifndef _CLKMAN_H_ +#define _CLKMAN_H_ + +/***** Includes *****/ +#include "mxc_config.h" +#include "clkman_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***** Definitions *****/ + +/** + * @brief Defines clock source selections for the system clock. + */ +typedef enum { + /** Clock select for 96MHz oscillator */ + CLKMAN_SYSTEM_SOURCE_96MHZ, + /** Clock select for 4MHz oscillator */ + CLKMAN_SYSTEM_SOURCE_4MHZ +} +clkman_system_source_select_t; + +/** + * @brief Defines clock scales for the system clock. + * @note 4MHz System source can only be divided down by a maximum factor of 8. + */ +typedef enum { + CLKMAN_SYSTEM_SCALE_DIV_1, /** Clock scale for dividing system by 1 */ + CLKMAN_SYSTEM_SCALE_DIV_2, /** Clock scale for dividing system by 2 */ + CLKMAN_SYSTEM_SCALE_DIV_4, /** Clock scale for dividing system by 4 */ + CLKMAN_SYSTEM_SCALE_DIV_8, /** Clock scale for dividing system by 8 */ + CLKMAN_SYSTEM_SCALE_DIV_16 /** Clock scale for dividing system by 16 */ +} clkman_system_scale_t; + +/** + * @brief Selects an internal module clock for clock scaling configuration. + */ +typedef enum { + CLKMAN_CLK_CPU = 0, /** CPU clock */ + CLKMAN_CLK_SYNC = 1, /** Synchronizer clock */ + CLKMAN_CLK_SPIX = 2, /** SPI XIP module clock */ + CLKMAN_CLK_PRNG = 3, /** PRNG module clock */ + CLKMAN_CLK_WDT0 = 4, /** Watchdog Timer 0 clock */ + CLKMAN_CLK_WDT1 = 5, /** Watchdog Timer 1 clock */ + CLKMAN_CLK_GPIO = 6, /** GPIO module clock */ + CLKMAN_CLK_PT = 7, /** Pulse Train engine clock */ + CLKMAN_CLK_UART = 8, /** UART clock */ + CLKMAN_CLK_I2CM = 9, /** I2C Master module clock (for all instances) */ + CLKMAN_CLK_I2CS = 10, /** I2C Slave module clock */ + CLKMAN_CLK_SPIM0 = 11, /** SPI Master instance 0 module clock */ + CLKMAN_CLK_SPIM1 = 12, /** SPI Master instance 1 module clock */ + CLKMAN_CLK_SPIM2 = 13, /** SPI Master instance 2 module clock */ + CLKMAN_CLK_OWM = 15, /** OWM module clock*/ + CLKMAN_CLK_SPIS = 16, /** SPI Slave module clock*/ + CLKMAN_CRYPTO_CLK_AES = 17, /** AES engine clock */ + CLKMAN_CRYPTO_CLK_MAA = 18, /** Modular Arithmetic Accelerator (MAA) clock */ + CLKMAN_CRYPTO_CLK_PRNG = 19, /** Pseudo-random number Generator (PRNG) clock */ + CLKMAN_CLK_MAX = 19 +} clkman_clk_t; + +/** + * @brief Selects a clock to enable/disable + */ +typedef enum { + CLKMAN_USB_CLOCK = MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_ENABLE, + CLKMAN_CRYPTO_CLOCK = MXC_F_CLKMAN_CLK_CTRL_CRYPTO_CLOCK_ENABLE, + CLKMAN_ADC_CLOCK = MXC_F_CLKMAN_CLK_CTRL_ADC_CLOCK_ENABLE, + CLKMAN_WDT0_CLOCK = MXC_F_CLKMAN_CLK_CTRL_WDT0_CLOCK_ENABLE, + CLKMAN_WDT1_CLOCK = MXC_F_CLKMAN_CLK_CTRL_WDT1_CLOCK_ENABLE, + CLKMAN_RTOS_MODE = MXC_F_CLKMAN_CLK_CTRL_RTOS_MODE, +} clkman_enable_clk_t; + +/** + * @brief Defines clock scales for various clocks. + */ +typedef enum { + CLKMAN_SCALE_DISABLED = MXC_V_CLKMAN_CLK_SCALE_DISABLED, /** Clock disabled */ + CLKMAN_SCALE_DIV_1 = MXC_V_CLKMAN_CLK_SCALE_DIV_1, /** Clock scale for dividing by 1 */ + CLKMAN_SCALE_DIV_2 = MXC_V_CLKMAN_CLK_SCALE_DIV_2, /** Clock scale for dividing by 2 */ + CLKMAN_SCALE_DIV_4 = MXC_V_CLKMAN_CLK_SCALE_DIV_4, /** Clock scale for dividing by 4 */ + CLKMAN_SCALE_DIV_8 = MXC_V_CLKMAN_CLK_SCALE_DIV_8, /** Clock scale for dividing by 8 */ + CLKMAN_SCALE_DIV_16 = MXC_V_CLKMAN_CLK_SCALE_DIV_16, /** Clock scale for dividing by 16 */ + CLKMAN_SCALE_DIV_32 = MXC_V_CLKMAN_CLK_SCALE_DIV_32, /** Clock scale for dividing by 32 */ + CLKMAN_SCALE_DIV_64 = MXC_V_CLKMAN_CLK_SCALE_DIV_64, /** Clock scale for dividing by 64 */ + CLKMAN_SCALE_DIV_128 = MXC_V_CLKMAN_CLK_SCALE_DIV_128, /** Clock scale for dividing by 128 */ + CLKMAN_SCALE_DIV_256 = MXC_V_CLKMAN_CLK_SCALE_DIV_256, /** Clock scale for dividing by 256 */ + CLKMAN_SCALE_AUTO /** Clock scale to auto select divider */ +} clkman_scale_t; + +/** + * @brief Defines clock selections for the watchdog timers. + */ +typedef enum { + CLKMAN_WDT_SELECT_SCALED_SYS_CLK_CTRL = MXC_V_CLKMAN_WDT0_CLOCK_SELECT_SCALED_SYS_CLK_CTRL_4_WDT0, + CLKMAN_WDT_SELECT_32KHZ_RTC_OSCILLATOR = MXC_V_CLKMAN_WDT0_CLOCK_SELECT_32KHZ_RTC_OSCILLATOR, + CLKMAN_WDT_SELECT_96MHZ_OSCILLATOR = MXC_V_CLKMAN_WDT0_CLOCK_SELECT_96MHZ_OSCILLATOR, + CLKMAN_WDT_SELECT_NANO_RING_OSCILLATOR = MXC_V_CLKMAN_WDT0_CLOCK_SELECT_NANO_RING_OSCILLATOR, + CLKMAN_WDT_SELECT_DISABLED +} clkman_wdt_clk_select_t; + + +/***** Function Prototypes *****/ + +/** + * @brief Selects the system clock source. + * @note 4MHz System source can only be divided down by a maximum factor of 8. + * @param select System clock source. + * @param scale System clock scaler. + */ +void CLKMAN_SetSystemClock(clkman_system_source_select_t select, clkman_system_scale_t scale); + +/** + * @brief Enables/disables the Crypto/TPU relaxation oscillator + * @param enable enable (1) or disable (0) + */ +void CLKMAN_CryptoClockEnable(int enable); + +/** + * @brief Enables/Disables the specified clock. + * @param clk clock to enable/disable + * @param enable enable (1) or disable (0) + */ +void CLKMAN_ClockGate(clkman_enable_clk_t clk, int enable); + +/** + * @brief Sets the specified clock scaler value. + * @param clk clock to set scaler value for + * @param scale clock scaler value + */ +void CLKMAN_SetClkScale(clkman_clk_t clk, clkman_scale_t scale); + +/** + * @brief Get the specified clock scaler value + * @param clk clock to get the scaler value for + */ +clkman_scale_t CLKMAN_GetClkScale(clkman_clk_t clk); + +/** + * @brief Selects the clock source for the watchdog timer + * @param idx index of the watchdog timer + * @param select clock to select + * @returns E_NO_ERROR if successful + */ +int CLKMAN_WdtClkSelect(unsigned int idx, clkman_wdt_clk_select_t select); + +/** + * @brief Get the interrupt flags + * @returns mask mask of flags set + */ +__STATIC_INLINE uint32_t CLKMAN_GetFlags(void) +{ + return MXC_CLKMAN->intfl; +} + +/** + * @brief Clear the specified interrupt flags + * @param mask mask of flags to clear + */ +__STATIC_INLINE void CLKMAN_ClrFlags(uint32_t mask) +{ + MXC_CLKMAN->intfl = mask; +} + +/** + * @brief Enable the specified interrupt flags + * @param mask mask of flags to enable + */ +__STATIC_INLINE void CLKMAN_EnableInt(uint32_t mask) +{ + MXC_CLKMAN->inten |= mask; +} + +/** + * @brief Disable the specified interrupt flags + * @param mask mask of flags to disable + */ +__STATIC_INLINE void CLKMAN_DisableInt(uint32_t mask) +{ + MXC_CLKMAN->inten &= ~mask; +} + +/** + * @brief Trim the ring oscillator. + */ +void CLKMAN_TrimRO(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _CLKMAN_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/crc.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/crc.c new file mode 100644 index 00000000000..735cac49682 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/crc.c @@ -0,0 +1,108 @@ +/** + * @file crc.c + * @brief This file contains the function implementations for the Cyclic + * Redundency Check (CRC) peripheral module. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-02 13:45:09 -0500 (Tue, 02 Aug 2016) $ + * $Revision: 23897 $ + * + *************************************************************************** */ + +/* **** Includes **** */ +#include "crc.h" + +/** + * @ingroup crc + * @{ + */ + +/* **** Definitions **** */ + +/* **** Globals **** */ + +/* **** Functions **** */ + +/* ************************************************************************* */ +void CRC16_Init(uint8_t CCITT_TRUE, uint8_t lilEndian) +{ + if(CCITT_TRUE) + MXC_CRC->reseed |= MXC_F_CRC_RESEED_CCITT_MODE; + else + MXC_CRC->reseed &= ~MXC_F_CRC_RESEED_CCITT_MODE; + + if(lilEndian) + MXC_CRC->reseed |= MXC_F_CRC_RESEED_REV_ENDIAN16; + else + MXC_CRC->reseed &= ~MXC_F_CRC_RESEED_REV_ENDIAN16; +} + +/* ************************************************************************* */ +void CRC32_Init(uint8_t lilEndian) +{ + if(lilEndian) + MXC_CRC->reseed |= MXC_F_CRC_RESEED_REV_ENDIAN32; + else + MXC_CRC->reseed &= ~MXC_F_CRC_RESEED_REV_ENDIAN32; +} + +/* ************************************************************************* */ + +void CRC16_Reseed(uint16_t initData) +{ + //set initial value + MXC_CRC->seed16 = initData; + + //reseed the CRC16 generator + MXC_CRC->reseed |= MXC_F_CRC_RESEED_CRC16; + + //wait for reseed to clear itself + while(MXC_CRC->reseed & MXC_F_CRC_RESEED_CRC16); + +} + +/* ************************************************************************* */ +void CRC32_Reseed(uint32_t initData) +{ + //set initial value + MXC_CRC->seed32 = initData; + + //reseed the CRC16 generator + MXC_CRC->reseed |= MXC_F_CRC_RESEED_CRC32; + + //wait for reseed to clear itself + while(MXC_CRC->reseed & MXC_F_CRC_RESEED_CRC32); +} + +/**@} end of group crc */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/crc.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/crc.h new file mode 100644 index 00000000000..646c7165c1a --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/crc.h @@ -0,0 +1,191 @@ +/** + * @file crc.h + * @brief CRC peripheral module function prototypes and data types. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-02 13:45:09 -0500 (Tue, 02 Aug 2016) $ + * $Revision: 23897 $ + * + **************************************************************************** */ + +/* Define to prevent redundant inclusion */ +#ifndef _CRC_H_ +#define _CRC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup crc Cyclic Redundancy Check (CRC) + * @ingroup periphlibs + * @brief High-level API for CRC Peripheral Module + * @{ + */ + +/** + * @page crc_overview Overview and Usage + * @parblock + * - Initialize the CRC for usage by calling either the CRC16_Init() function or the CRC32_Init() funciton + * + For CRC16, CCITT mode is enabled if the parameter is set + * + Select the Endian of the data for calculation + * - passing a 1 sets the module to little endian + * - passing a 0 sets the module to big endian + * - Set the intial CRC seed by calling CRC16_Reseed() or CRC32_Reseed() + * + This is the initial value of the CRC remainder to be used when the data is passed to the module + * - Pass data to the CRC engine using the methods: + * + CRC16_AddData() + * + CRC16_AddDataArray() + * + CRC32_AddData() + * + CRC32_AddDataArray() + * @note any data passed to the add methods of the peripheral is padded with zeros if it is less than + * 32-bits. + * @endparblock +*/ + + +/* **** Includes **** */ +#include "mxc_config.h" +#include +#include "crc_regs.h" + +/* **** Definitions **** */ + +/* **** Globals **** */ + +/* **** Function Prototypes **** */ + +/** + * @brief Initialize CRC clock and select CRC16 mode and byte order. + * + * @param CCITT_TRUE CRC16-CCITT-TRUE = 1, CRC16-CCITT-FALSE = 0 + * @param lilEndian byte order, little endian = 1, big endian = 0 + */ +void CRC16_Init(uint8_t CCITT_TRUE, uint8_t lilEndian); + +/** + * @brief Initialize CRC clock and select byte order for CRC32. + * + * @param lilEndian byte order, little endian = 1, big endian = 0 + */ +void CRC32_Init(uint8_t lilEndian); + +/** + * @brief Initialize CRC16 calculation. + * + * @param initData intial remainder to start the CRC16 calculation with + */ +void CRC16_Reseed(uint16_t initData); + +/** + * @brief Initialize CRC32 calculation. + * + * @param initData intial remainder to start the CRC32 calculation with + */ +void CRC32_Reseed(uint32_t initData); + +/** + * @brief Add data to the CRC16 calculation. + * + * @param data data to add to the CRC16 calculation + * @note data is padded with zeros if less than 32bits. + */ +__STATIC_INLINE void CRC16_AddData(uint32_t data) +{ + MXC_CRC_DATA->value16[0] = data; +} + +/** + * @brief Add data to the CRC32 calculation + * + * @param data data to add to the CRC32 calculation + * @note data is padded with zeros if less than 32bits + */ +__STATIC_INLINE void CRC32_AddData(uint32_t data) +{ + MXC_CRC_DATA->value32[0] = data; +} + +/** + * @brief Add an array of data to the CRC16 calculation + * + * @param data pointer to array of data + * @note data is padded with zeros if less than 32bits + * + * @param arrayLength number of elements in array + */ +__STATIC_INLINE void CRC16_AddDataArray(uint32_t *data, uint32_t arrayLength) +{ + memcpy((void *)(&(MXC_CRC_DATA->value16)), (void *)data, arrayLength * sizeof(data[0])); +} + +/** + * @brief Add an array of data to the CRC32 calculation + * + * @param data pointer to array of data + * @note data is padded with zeros if less than 32bits + * @param arrayLength number of elements in array + */ +__STATIC_INLINE void CRC32_AddDataArray(uint32_t *data, uint32_t arrayLength) +{ + memcpy((void *)(&(MXC_CRC_DATA->value32)), (void *)data, arrayLength * sizeof(data[0])); +} + +/** + * @brief Get the calculated CRC16 value + * + * @return CRC16 value + */ +__STATIC_INLINE uint32_t CRC16_GetCRC() +{ + return MXC_CRC_DATA->value16[0]; +} + +/** + * @brief Get the calculated CRC32 value + * + * @return CRC32 value + */ +__STATIC_INLINE uint32_t CRC32_GetCRC() +{ + return MXC_CRC_DATA->value32[0]; +} + +/**@} end of crc group */ + +#ifdef __cplusplus +} +#endif + +#endif /* _CRC_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/flc.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/flc.c new file mode 100644 index 00000000000..9a02ce6adb0 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/flc.c @@ -0,0 +1,260 @@ +/** + * @file flc.c + * @brief This file contains the function implementations for the Flash + * Controller peripheral module. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-02 13:46:43 -0500 (Tue, 02 Aug 2016) $ + * $Revision: 23898 $ + * + *************************************************************************** */ + +/* **** Includes **** */ +#include "mxc_config.h" +#include "flc.h" + + +/** + * @ingroup flc + * @{ + */ + +/* **** Definitions **** */ + +/* **** Globals **** */ + +/* **** Functions **** */ + +/* ************************************************************************* */ +#if defined ( __GNUC__ ) +#undef IAR_PRAGMAS //Make sure this is not defined for GCC +#endif + +#if IAR_PRAGMAS +// IAR memory section declaration for the in-system flash programming functions to be loaded in RAM. +#pragma section=".flashprog" +#endif +#if defined ( __GNUC__ ) +__attribute__ ((section(".flashprog"))) +#endif +/** + * @brief Return the status of the busy state of the flash controller. + * + * @return 0 Flash Controller is idle. + * @return Non-zero indicates the flash controller is performing an + * erase or write request. + */ +__STATIC_INLINE int FLC_Busy(void) +{ + return (MXC_FLC->ctrl & (MXC_F_FLC_CTRL_WRITE | MXC_F_FLC_CTRL_MASS_ERASE | MXC_F_FLC_CTRL_PAGE_ERASE)); +} + +/* ************************************************************************* */ +#if IAR_PRAGMAS +// IAR memory section declaration for the in-system flash programming functions to be loaded in RAM. +#pragma section=".flashprog" +#endif +#if defined ( __GNUC__ ) +__attribute__ ((section(".flashprog"))) +#endif +int FLC_Init(void) +{ + /* Check if the flash controller is busy */ + if (FLC_Busy()) { + return E_BUSY; + } + + /* Enable automatic calculation of the clock divider to generate a 1MHz clock from the APB clock */ + MXC_FLC->perform |= MXC_F_FLC_PERFORM_AUTO_CLKDIV; + + /* The flash controller will stall any reads while flash operations are in + * progress. Disable the legacy failure detection logic that would flag reads + * during flash operations as errors. + */ + MXC_FLC->perform |= MXC_F_FLC_PERFORM_EN_PREVENT_FAIL; + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +#if IAR_PRAGMAS +// IAR memory section declaration for the in-system flash programming functions to be loaded in RAM. +#pragma section=".flashprog" +#endif +#if defined ( __GNUC__ ) +__attribute__ ((section(".flashprog"))) +#endif +int FLC_PageErase(uint32_t address, uint8_t erase_code, uint8_t unlock_key) +{ + /* Check if the flash controller is busy */ + if (FLC_Busy()) { + return E_BUSY; + } + + /* Clear stale errors. Interrupt flags can only be written to zero, so this is safe */ + MXC_FLC->intr &= ~MXC_F_FLC_INTR_FAILED_IF; + + /* Unlock flash */ + MXC_FLC->ctrl = (MXC_FLC->ctrl & ~MXC_F_FLC_CTRL_FLSH_UNLOCK) | + ((unlock_key << MXC_F_FLC_CTRL_FLSH_UNLOCK_POS) & MXC_F_FLC_CTRL_FLSH_UNLOCK); + + /* Write the Erase Code */ + MXC_FLC->ctrl = (MXC_FLC->ctrl & ~MXC_F_FLC_CTRL_ERASE_CODE) | + ((erase_code << MXC_F_FLC_CTRL_ERASE_CODE_POS) & MXC_F_FLC_CTRL_ERASE_CODE); + + /* Erase the request page */ + MXC_FLC->faddr = address; + MXC_FLC->ctrl |= MXC_F_FLC_CTRL_PAGE_ERASE; + + /* Wait until flash operation is complete */ + while (FLC_Busy()); + + /* Lock flash */ + MXC_FLC->ctrl &= ~(MXC_F_FLC_CTRL_FLSH_UNLOCK | MXC_F_FLC_CTRL_ERASE_CODE); + + /* Check for failures */ + if (MXC_FLC->intr & MXC_F_FLC_INTR_FAILED_IF) { + /* Interrupt flags can only be written to zero, so this is safe */ + MXC_FLC->intr &= ~MXC_F_FLC_INTR_FAILED_IF; + return E_UNKNOWN; + } + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +#if IAR_PRAGMAS +// IAR memory section declaration for the in-system flash programming functions to be loaded in RAM. +#pragma section=".flashprog" +#endif +#if defined ( __GNUC__ ) +__attribute__ ((section(".flashprog"))) +#endif +int FLC_Write(uint32_t address, const void *data, uint32_t length, uint8_t unlock_key) +{ + uint32_t *ptr = (uint32_t*)data; + + /* Can only write in full word units */ + if ((address & 3) || (length & 3)) { + return E_BAD_PARAM; + } + + if (length == 0) { + /* Nothing to do */ + return E_NO_ERROR; + } + + /* Check if the flash controller is busy */ + if (FLC_Busy()) { + return E_BUSY; + } + + /* Clear stale errors. Interrupt flags can only be written to zero, so this is safe */ + MXC_FLC->intr &= ~MXC_F_FLC_INTR_FAILED_IF; + + /* Unlock flash */ + MXC_FLC->ctrl = (MXC_FLC->ctrl & ~MXC_F_FLC_CTRL_FLSH_UNLOCK) | + ((unlock_key << MXC_F_FLC_CTRL_FLSH_UNLOCK_POS) & MXC_F_FLC_CTRL_FLSH_UNLOCK); + + /* Set the address to write and enable auto increment */ + MXC_FLC->faddr = address; + MXC_FLC->ctrl |= MXC_F_FLC_CTRL_AUTO_INCRE_MODE; + uint32_t write_cmd = MXC_FLC->ctrl | MXC_F_FLC_CTRL_WRITE; + + for (; length > 0; length -= 4) { + /* Perform the write */ + MXC_FLC->fdata = *ptr++; + MXC_FLC->ctrl = write_cmd; + while (FLC_Busy()); + } + + /* Lock flash */ + MXC_FLC->ctrl &= ~MXC_F_FLC_CTRL_FLSH_UNLOCK; + + /* Check for failures */ + if (MXC_FLC->intr & MXC_F_FLC_INTR_FAILED_IF) { + /* Interrupt flags can only be written to zero, so this is safe */ + MXC_FLC->intr &= ~MXC_F_FLC_INTR_FAILED_IF; + return E_UNKNOWN; + } + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +#if IAR_PRAGMAS +// IAR memory section declaration for the in-system flash programming functions to be loaded in RAM. +#pragma section=".flashprog" +#endif +#if defined ( __GNUC__ ) +__attribute__ ((section(".flashprog"))) +#endif +int FLC_MassErase(uint8_t erase_code, uint8_t unlock_key) +{ + /* Check if the flash controller is busy */ + if (FLC_Busy()) { + return E_BUSY; + } + + /* Clear stale errors. Interrupt flags can only be written to zero, so this is safe */ + MXC_FLC->intr &= ~MXC_F_FLC_INTR_FAILED_IF; + + /* Unlock flash */ + MXC_FLC->ctrl = (MXC_FLC->ctrl & ~MXC_F_FLC_CTRL_FLSH_UNLOCK) | + ((unlock_key << MXC_F_FLC_CTRL_FLSH_UNLOCK_POS) & MXC_F_FLC_CTRL_FLSH_UNLOCK); + + /* Write the Erase Code */ + MXC_FLC->ctrl = (MXC_FLC->ctrl & ~MXC_F_FLC_CTRL_ERASE_CODE) | + ((erase_code << MXC_F_FLC_CTRL_ERASE_CODE_POS) & MXC_F_FLC_CTRL_ERASE_CODE); + + /* Start the mass erase */ + MXC_FLC->ctrl |= MXC_F_FLC_CTRL_MASS_ERASE; + + /* Wait until flash operation is complete */ + while (FLC_Busy()); + + /* Lock flash */ + MXC_FLC->ctrl &= ~(MXC_F_FLC_CTRL_FLSH_UNLOCK | MXC_F_FLC_CTRL_ERASE_CODE); + + /* Check for failures */ + if (MXC_FLC->intr & MXC_F_FLC_INTR_FAILED_IF) { + /* Interrupt flags can only be written to zero, so this is safe */ + MXC_FLC->intr &= ~MXC_F_FLC_INTR_FAILED_IF; + return E_UNKNOWN; + } + + return E_NO_ERROR; +} + +/**@} end of group flc */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/flc.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/flc.h new file mode 100644 index 00000000000..c4716a493d9 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/flc.h @@ -0,0 +1,117 @@ +/** + * @file flc.h + * @brief Flash Controller function prototypes and data types. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-02 13:46:43 -0500 (Tue, 02 Aug 2016) $ + * $Revision: 23898 $ + * + *************************************************************************** */ + +/* Define to prevent redundant inclusion */ +#ifndef _FLC_H_ +#define _FLC_H_ + +/* **** Includes **** */ +#include "flc_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup flc Flash Controller + * @ingroup sysconfig + * @{ + */ + +/* **** Definitions **** */ + +/* **** Globals **** */ + +/* **** Function Prototypes **** */ + +/** + * @brief Prepares the Flash Controller for in-application flash operations. This function + * only needs to be called one time after a reset event. + * + * @return #E_NO_ERROR if flash controller initialized correctly, error if + * unsuccessful. + */ +int FLC_Init(void); + +/** + * @brief This function will erase a single page of flash. + * + * @param address Address of the page to be erased. + * @param erase_code Flash erase code; defined as + * #MXC_V_FLC_ERASE_CODE_PAGE_ERASE for page erase + * @param unlock_key Unlock key, #MXC_V_FLC_FLSH_UNLOCK_KEY. + * + * @returns #E_NO_ERROR if page erase successful, error if unsuccessful. + */ +int FLC_PageErase(uint32_t address, uint8_t erase_code, uint8_t unlock_key); + +/** + * @brief This function writes data to the flash device through the flash + * controller interface + * + * @param address Start address for desired write. @note This address + * must be 32-bit word aligned + * @param data A pointer to the buffer containing the data to write. + * @param length Size of the data to write in bytes. @note The length + * must be in 32-bit multiples. + * @param unlock_key Unlock key, #MXC_V_FLC_FLSH_UNLOCK_KEY. + * + * @returns #E_NO_ERROR if data written successfully, error if unsuccessful. + */ +int FLC_Write(uint32_t address, const void *data, uint32_t length, uint8_t unlock_key); + +/** + * @brief This function will mass erase the flash. + * + * @param erase_code Flash erase code, #MXC_V_FLC_ERASE_CODE_MASS_ERASE. + * @param unlock_key Unlock key, #MXC_V_FLC_FLSH_UNLOCK_KEY. + * + * @returns #E_NO_ERROR if device mass erase successful, error if unsuccessful. + */ +int FLC_MassErase(uint8_t erase_code, uint8_t unlock_key); + +/**@} end of group flc */ + +#ifdef __cplusplus +} +#endif + +#endif /* _FLC_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/gpio.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/gpio.c new file mode 100644 index 00000000000..2e0f10cca70 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/gpio.c @@ -0,0 +1,186 @@ +/** + * @file gpio.c + * @brief This file contains the function implementations for the + * General-Purpose Input/Output (GPIO) peripheral module. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-15 20:04:11 -0500 (Mon, 15 Aug 2016) $ + * $Revision: 24085 $ + * + *************************************************************************** */ + +/* **** Includes **** */ +#include "mxc_config.h" +#include "mxc_assert.h" +#include "mxc_sys.h" +#include "gpio.h" +#include "clkman_regs.h" + +/** + * @ingroup gpio + * @{ + */ + +/* **** Definitions **** */ + +/* **** Globals **** */ + +/* ************************************************************************* */ +static void (*callbacks[MXC_GPIO_NUM_PORTS][MXC_GPIO_MAX_PINS_PER_PORT])(void *); +static void *cbparam[MXC_GPIO_NUM_PORTS][MXC_GPIO_MAX_PINS_PER_PORT]; + +/* **** Functions **** */ + +/* ************************************************************************* */ +static int PinConfig(unsigned int port, unsigned int pin, gpio_func_t func, gpio_pad_t pad) +{ + /* Check if available */ + if (!(MXC_GPIO->free[port] & (1 << pin))) { + return E_BUSY; + } + + /* Set function */ + uint32_t func_sel = MXC_GPIO->func_sel[port]; + func_sel &= ~(0xF << (4 * pin)); + func_sel |= (func << (4 * pin)); + MXC_GPIO->func_sel[port] = func_sel; + + /* Normal input is always enabled */ + MXC_GPIO->in_mode[port] &= ~(0xF << (4 * pin)); + + /* Set requested output mode */ + uint32_t out_mode = MXC_GPIO->out_mode[port]; + out_mode &= ~(0xF << (4 * pin)); + out_mode |= (pad << (4 * pin)); + MXC_GPIO->out_mode[port] = out_mode; + + /* Enable the pull up/down if necessary */ + if (pad == MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLUP) { + MXC_GPIO->out_val[port] |= (1 << pin); + } else if (pad == MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLDOWN) { + MXC_GPIO->out_val[port] &= ~(1 << pin); + } + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +int GPIO_Config(const gpio_cfg_t *cfg) +{ + unsigned int pin; + int err = E_NO_ERROR; + + MXC_ASSERT(cfg); + MXC_ASSERT(cfg->port < MXC_GPIO_NUM_PORTS); + + // Set system level configurations + if ((err = SYS_GPIO_Init()) != E_NO_ERROR) { + return err; + } + + // Configure each pin in the mask + for (pin = 0; pin < MXC_GPIO_MAX_PINS_PER_PORT; pin++) { + if (cfg->mask & (1 << pin)) { + if (PinConfig(cfg->port, pin, cfg->func, cfg->pad) != E_NO_ERROR) { + err = E_BUSY; + } + } + } + + return err; +} + +/* ************************************************************************* */ +static void IntConfig(unsigned int port, unsigned int pin, gpio_int_mode_t mode) +{ + uint32_t int_mode = MXC_GPIO->int_mode[port]; + int_mode &= ~(0xF << (pin*4)); + int_mode |= (mode << (pin*4)); + MXC_GPIO->int_mode[port] = int_mode; +} + +/* ************************************************************************* */ +void GPIO_IntConfig(const gpio_cfg_t *cfg, gpio_int_mode_t mode) +{ + unsigned int pin; + + MXC_ASSERT(cfg); + MXC_ASSERT(cfg->port < MXC_GPIO_NUM_PORTS); + + // Configure each pin in the mask + for (pin = 0; pin < MXC_GPIO_MAX_PINS_PER_PORT; pin++) { + if (cfg->mask & (1 << pin)) { + IntConfig(cfg->port, pin, mode); + } + } +} + +/* ************************************************************************* */ +void GPIO_RegisterCallback(const gpio_cfg_t *cfg, gpio_callback_fn func, void *cbdata) +{ + unsigned int pin; + + MXC_ASSERT(cfg); + MXC_ASSERT(cfg->port < MXC_GPIO_NUM_PORTS); + + for (pin = 0; pin < MXC_GPIO_MAX_PINS_PER_PORT; pin++) { + if (cfg->mask & (1 << pin)) { + callbacks[cfg->port][pin] = func; + cbparam[cfg->port][pin] = cbdata; + } + } +} + +/* ************************************************************************* */ +void GPIO_Handler(unsigned int port) +{ + uint8_t intfl; + unsigned int pin; + + MXC_ASSERT(port < MXC_GPIO_NUM_PORTS); + + // Read and clear enabled interrupts. + intfl = MXC_GPIO->intfl[port]; + intfl &= MXC_GPIO->inten[port]; + MXC_GPIO->intfl[port] = intfl; + + // Process each pins' interrupt + for (pin = 0; pin < MXC_GPIO_MAX_PINS_PER_PORT; pin++) { + if ((intfl & (1 << pin)) && callbacks[port][pin]) { + callbacks[port][pin](cbparam[port][pin]); + } + } +} + +/**@} end of group gpio */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/gpio.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/gpio.h new file mode 100644 index 00000000000..e9fcfd6d29f --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/gpio.h @@ -0,0 +1,315 @@ +/** + * @file gpio.h + * @brief General-Purpose Input/Output (GPIO) function prototypes and data types. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-15 20:04:11 -0500 (Mon, 15 Aug 2016) $ + * $Revision: 24085 $ + * + *************************************************************************** */ + +/* Define to prevent redundant inclusion */ +#ifndef _GPIO_H_ +#define _GPIO_H_ + +/* **** Includes **** */ +#include "mxc_config.h" +#include "gpio_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Doxy group definition for this peripheral module +/** + * @defgroup gpio General-Purpose Input/Output (GPIO) + * @ingroup periphlibs + * @{ + */ + +/* **** Definitions **** */ +/** + * @defgroup gpio_port_pin Port and Pin Definitions + * @ingroup gpio + * @{ + * @defgroup gpio_port Port Definitions + * @ingroup gpio_port_pin + * @{ + */ +#define PORT_0 (0) /**< Port 0 Define*/ +#define PORT_1 (1) /**< Port 1 Define*/ +#define PORT_2 (2) /**< Port 2 Define*/ +#define PORT_3 (3) /**< Port 3 Define*/ +#define PORT_4 (4) /**< Port 4 Define*/ +#define PORT_5 (5) /**< Port 5 Define*/ +#define PORT_6 (6) /**< Port 6 Define*/ +#define PORT_7 (7) /**< Port 7 Define*/ +#define PORT_8 (8) /**< Port 8 Define*/ +#define PORT_9 (9) /**< Port 9 Define*/ +#define PORT_10 (10) /**< Port 10 Define*/ +#define PORT_11 (11) /**< Port 11 Define*/ +#define PORT_12 (12) /**< Port 12 Define*/ +#define PORT_13 (13) /**< Port 13 Define*/ +#define PORT_14 (14) /**< Port 14 Define*/ +#define PORT_15 (15) /**< Port 15 Define*/ +/**@} end of gpio_port group*/ +/** + * @defgroup gpio_pin Pin Definitions + * @ingroup gpio_port_pin + * @{ + */ +#define PIN_0 (1 << 0) /**< Pin 0 Define */ +#define PIN_1 (1 << 1) /**< Pin 1 Define */ +#define PIN_2 (1 << 2) /**< Pin 2 Define */ +#define PIN_3 (1 << 3) /**< Pin 3 Define */ +#define PIN_4 (1 << 4) /**< Pin 4 Define */ +#define PIN_5 (1 << 5) /**< Pin 5 Define */ +#define PIN_6 (1 << 6) /**< Pin 6 Define */ +#define PIN_7 (1 << 7) /**< Pin 7 Define */ +/**@} end of gpio_pin group */ +/**@} end of gpio_port_pin group */ + +/** + * Enumeration type for the GPIO Function Type + */ +typedef enum { + GPIO_FUNC_GPIO = MXC_V_GPIO_FUNC_SEL_MODE_GPIO, /**< GPIO Function Selection */ + GPIO_FUNC_PT = MXC_V_GPIO_FUNC_SEL_MODE_PT, /**< Pulse Train Function Selection */ + GPIO_FUNC_TMR = MXC_V_GPIO_FUNC_SEL_MODE_TMR /**< Timer Function Selection */ +} +gpio_func_t; + +/** + * Enumeration type for the type of GPIO pad on a given pin. + */ +typedef enum { + GPIO_PAD_INPUT_PULLUP = MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLUP, /**< Set pad to high impedance, weak pull-up */ + GPIO_PAD_OPEN_DRAIN = MXC_V_GPIO_OUT_MODE_OPEN_DRAIN, /**< Set pad to open-drain with high impedance with input buffer */ + GPIO_PAD_OPEN_DRAIN_PULLUP = MXC_V_GPIO_OUT_MODE_OPEN_DRAIN_WEAK_PULLUP, /**< Set pad to open-drain with weak pull-up */ + GPIO_PAD_INPUT = MXC_V_GPIO_OUT_MODE_NORMAL_HIGH_Z, /**< Set pad to high impednace, input buffer enabled */ + GPIO_PAD_NORMAL = MXC_V_GPIO_OUT_MODE_NORMAL, /**< Set pad to normal drive mode for high an low output */ + GPIO_PAD_SLOW = MXC_V_GPIO_OUT_MODE_SLOW_DRIVE, /**< Set pad to slow drive mode, which is normal mode with negative feedback to slow edge transitions */ + GPIO_PAD_FAST = MXC_V_GPIO_OUT_MODE_FAST_DRIVE, /**< Set pad to fash drive mode, which is normal mode with a transistor drive to drive fast high and low */ + GPIO_PAD_INPUT_PULLDOWN = MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLDOWN, /**< Set pad to weak pulldown mode */ + GPIO_PAD_OPEN_SOURCE = MXC_V_GPIO_OUT_MODE_OPEN_SOURCE, /**< Set pad to open source mode, transistor drive to high */ + GPIO_PAD_OPEN_SOURCE_PULLDOWN = MXC_V_GPIO_OUT_MODE_OPEN_SOURCE_WEAK_PULLDOWN /**< Set pad to open source with weak pulldown mode, transistor drive to high, weak pulldown to GND for low */ +} gpio_pad_t; + +/** + * Structure type for configuring a GPIO port. + */ +typedef struct { + uint32_t port; /// Index of GPIO port + uint32_t mask; /// Pin mask. Multiple bits can be set. + gpio_func_t func; /// Function type + gpio_pad_t pad; /// Pad type +} gpio_cfg_t; + +/** + * Enumeration type for the interrupt type on a GPIO port. + */ +typedef enum { + GPIO_INT_DISABLE = MXC_V_GPIO_INT_MODE_DISABLE, /**< Disable interrupts */ + GPIO_INT_FALLING_EDGE = MXC_V_GPIO_INT_MODE_FALLING_EDGE, /**< Interrupt on Falling Edge */ + GPIO_INT_RISING_EDGE = MXC_V_GPIO_INT_MODE_RISING_EDGE, /**< Interrupt on Rising Edge */ + GPIO_INT_ANY_EDGE = MXC_V_GPIO_INT_MODE_ANY_EDGE, /**< Interrupt on Falling or Rising Edge */ + GPIO_INT_LOW_LEVEL = MXC_V_GPIO_INT_MODE_LOW_LVL, /**< Interrupt on a low level input detection */ + GPIO_INT_HIGH_LEVEL = MXC_V_GPIO_INT_MODE_HIGH_LVL /**< Interrupt on a high level input detection */ +} gpio_int_mode_t; + +/* **** Function Prototypes **** */ + +/** + * @brief Configure GPIO pin(s). + * @param cfg Pointer to configuration structure describing the pin. + * + * @return #E_NO_ERROR if everything is successful. + * + */ +int GPIO_Config(const gpio_cfg_t *cfg); + +/** + * @brief Gets the pin(s) input state. + * @param cfg Pointer to configuration structure describing the pin. + * + * @return The requested pin state. + * + */ +__STATIC_INLINE uint32_t GPIO_InGet(const gpio_cfg_t *cfg) +{ + return (MXC_GPIO->in_val[cfg->port] & cfg->mask); +} + +/** + * @brief Sets the pin(s) to a high level output. + * @param cfg Pointer to configuration structure describing the pin. + * + */ +__STATIC_INLINE void GPIO_OutSet(const gpio_cfg_t *cfg) +{ + MXC_GPIO->out_val[cfg->port] |= cfg->mask; +} + +/** + * @brief Clears the pin(s) to a low level output. + * @param cfg Pointer to configuration structure describing the pin. + * + */ +__STATIC_INLINE void GPIO_OutClr(const gpio_cfg_t *cfg) +{ + MXC_GPIO->out_val[cfg->port] &= ~(cfg->mask); +} + +/** + * @brief Gets the pin(s) output state. + * @param cfg Pointer to configuration structure describing the pin. + * + * @return The state of the requested pin. + * + */ +__STATIC_INLINE uint32_t GPIO_OutGet(const gpio_cfg_t *cfg) +{ + return (MXC_GPIO->out_val[cfg->port] & cfg->mask); +} + +/** + * @brief Write the pin(s) to a desired output level. + * @param cfg Pointer to configuration structure describing the pin. + * @param val Desired output level of the pin(s). This will be masked + * with the configuration mask. + * + */ +__STATIC_INLINE void GPIO_OutPut(const gpio_cfg_t *cfg, uint32_t val) +{ + MXC_GPIO->out_val[cfg->port] = (MXC_GPIO->out_val[cfg->port] & ~cfg->mask) | (val & cfg->mask); +} + +/** + * @brief Toggles the the pin(s) output level. + * @param cfg Pointer to configuration structure describing the pin. + * + */ +__STATIC_INLINE void GPIO_OutToggle(const gpio_cfg_t *cfg) +{ + MXC_GPIO->out_val[cfg->port] ^= cfg->mask; +} + +/** + * @brief Configure GPIO interrupt(s) + * @param cfg Pointer to configuration structure describing the pin. + * @param mode Requested interrupt mode. + * + */ +void GPIO_IntConfig(const gpio_cfg_t *cfg, gpio_int_mode_t mode); + +/** + * @brief Enables the specified GPIO interrupt + * @param cfg Pointer to configuration structure describing the pin. + * + */ +__STATIC_INLINE void GPIO_IntEnable(const gpio_cfg_t *cfg) +{ + MXC_GPIO->inten[cfg->port] |= cfg->mask; +} + +/** + * @brief Disables the specified GPIO interrupt. + * @param cfg Pointer to configuration structure describing the pin. + * + */ +__STATIC_INLINE void GPIO_IntDisable(const gpio_cfg_t *cfg) +{ + MXC_GPIO->inten[cfg->port] &= ~cfg->mask; +} + +/** + * @brief Gets the interrupt(s) status on a GPIO pin. + * @param cfg Pointer to configuration structure describing the pin + * for which the status is being requested. + * + * @return The requested interrupt status. + * + */ +__STATIC_INLINE uint32_t GPIO_IntStatus(const gpio_cfg_t *cfg) +{ + return (MXC_GPIO->intfl[cfg->port] & cfg->mask); +} + +/** + * @brief Clears the interrupt(s) status on a GPIO pin. + * @param cfg Pointer to configuration structure describing the pin + * to clear the interrupt state of. + * + */ +__STATIC_INLINE void GPIO_IntClr(const gpio_cfg_t *cfg) +{ + MXC_GPIO->intfl[cfg->port] = cfg->mask; +} + +/** + * @brief Type alias for a GPIO callback function with prototype: + * @code + * void callback_fn(void *cbdata); + * @endcode + * @param cbdata A void pointer to the data type as registered when + * @c GPIO_RegisterCallback() was called. + * + */ +typedef void (*gpio_callback_fn)(void *cbdata); + +/** + * @brief Registers a callback for the interrupt on a given port and pin. + * @param cfg Pointer to configuration structure describing the pin + * @param callback A pointer to a function of type #callback_fn. + * @param cbdata The parameter to be passed to the callback function, #callback_fn, when an interrupt occurs. + * + */ +void GPIO_RegisterCallback(const gpio_cfg_t *cfg, gpio_callback_fn callback, void *cbdata); + +/** + * @brief GPIO IRQ Handler. @note If a callback is registered for a given + * interrupt, the callback function will be called. + * + * @param port number of the port that generated the interrupt service routine. + * + */ +void GPIO_Handler(unsigned int port); + +/**@} end of group gpio */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GPIO_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cm.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cm.c new file mode 100644 index 00000000000..5c1471e44ce --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cm.c @@ -0,0 +1,880 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-06-01 08:51:23 -0500 (Wed, 01 Jun 2016) $ + * $Revision: 23131 $ + * + ******************************************************************************/ + +/** + * @file i2cm.c + * @brief I2C Master driver source. + */ + +/***** Includes *****/ +#include +#include +#include "mxc_assert.h" +#include "mxc_lock.h" +#include "mxc_errors.h" +#include "mxc_sys.h" +#include "i2cm.h" + +/***** Definitions *****/ + +#ifndef MXC_I2CM_TX_TIMEOUT +#define MXC_I2CM_TX_TIMEOUT 0x5000 +#endif + +#ifndef MXC_I2CM_RX_TIMEOUT +#define MXC_I2CM_RX_TIMEOUT 0x5000 +#endif + +#define I2CM_READ_BIT 0x0001 +#define I2CM_FIFO_DEPTH_3Q ((3 * MXC_I2CM_FIFO_DEPTH) / 4) +#define I2CM_FIFO_DEPTH_2Q (MXC_I2CM_FIFO_DEPTH / 2) + +/***** Globals *****/ + +// Saves the state of the non-blocking requests +typedef enum { + I2CM_STATE_READING = 0, + I2CM_STATE_WRITING = 1 +} i2cm_state_t; + +typedef struct { + i2cm_req_t *req; + i2cm_state_t state; +} i2cm_req_state_t; +static i2cm_req_state_t states[MXC_CFG_I2CM_INSTANCES]; + +/***** Functions *****/ + +//static void I2CM_Recover(mxc_i2cm_regs_t *i2cm); +//static int I2CM_WriteTxFifo(mxc_i2cm_regs_t *regs, mxc_i2cm_fifo_regs_t *fifo, const uint16_t data); +//static int I2CM_TxInProgress(mxc_i2cm_regs_t *i2cm); +static void I2CM_FreeCallback(int i2cm_num, int error); +//static int I2CM_Tx(mxc_i2cm_regs_t *i2cm, mxc_i2cm_fifo_regs_t *fifo, uint8_t addr, +// const uint8_t *data, uint32_t len, uint8_t stop); + +//static int I2CM_Rx(mxc_i2cm_regs_t *i2cm, mxc_i2cm_fifo_regs_t *fifo, uint8_t addr, +// uint8_t *data, uint32_t len); + +static int I2CM_CmdHandler(mxc_i2cm_regs_t *i2cm, mxc_i2cm_fifo_regs_t *fifo, i2cm_req_t *req); +static int I2CM_ReadHandler(mxc_i2cm_regs_t *i2cm, i2cm_req_t *req, int i2cm_num); +static int I2CM_WriteHandler(mxc_i2cm_regs_t *i2cm, i2cm_req_t *req, int i2cm_num); + +/******************************************************************************/ +int I2CM_Init(mxc_i2cm_regs_t *i2cm, const sys_cfg_i2cm_t *sys_cfg, i2cm_speed_t speed) +{ + int err; + + // Check the base pointer + MXC_ASSERT(MXC_I2CM_GET_IDX(i2cm) >= 0); + + // Set system level configurations + if ((err = SYS_I2CM_Init(i2cm, sys_cfg)) != E_NO_ERROR) { + return err; + } + + I2CM_SetFrequency(i2cm,speed); + + // Reset module + i2cm->ctrl = MXC_F_I2CM_CTRL_MSTR_RESET_EN; + i2cm->ctrl = 0; + + // Set timeout to 255 ms and turn on the auto-stop option + i2cm->timeout = (MXC_F_I2CM_TIMEOUT_TX_TIMEOUT | MXC_F_I2CM_TIMEOUT_AUTO_STOP_EN); + + // Enable tx_fifo and rx_fifo + i2cm->ctrl |= (MXC_F_I2CM_CTRL_TX_FIFO_EN | MXC_F_I2CM_CTRL_RX_FIFO_EN); + + return E_NO_ERROR; +} + +/******************************************************************************/ +int I2CM_Shutdown(mxc_i2cm_regs_t *i2cm) +{ + int i2cm_num, err; + + // Check the base pointer + i2cm_num = MXC_I2CM_GET_IDX(i2cm); + MXC_ASSERT(i2cm_num >= 0); + + // Disable and clear interrupts + i2cm->inten = 0; + i2cm->intfl = i2cm->intfl; + + // Call all of the pending callbacks for this I2CM + if(states[i2cm_num].req != NULL) { + I2CM_Recover(i2cm); + I2CM_FreeCallback(i2cm_num, E_SHUTDOWN); + } + + // Clears system level configurations + if ((err = SYS_I2CM_Shutdown(i2cm)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + + +/******************************************************************************/ +int I2CM_Read(mxc_i2cm_regs_t *i2cm, uint8_t addr, const uint8_t *cmd_data, + uint32_t cmd_len, uint8_t* data, uint32_t len) +{ + int i2cm_num; + int error = E_NO_ERROR; + int retval = E_NO_ERROR; + mxc_i2cm_fifo_regs_t *fifo; + + if(data == NULL) { + return E_NULL_PTR; + } + + // Make sure the I2CM has been initialized + if(i2cm->ctrl == 0) { + return E_UNINITIALIZED; + } + + if(!(len > 0)) { + return E_NO_ERROR; + } + + // Lock this I2CM + i2cm_num = MXC_I2CM_GET_IDX(i2cm); + while(mxc_get_lock((uint32_t*)&states[i2cm_num].req,1) != E_NO_ERROR) {} + + // Get the FIFO pointer for this I2CM + fifo = MXC_I2CM_GET_FIFO(i2cm_num); + + // Disable and clear the interrupts + i2cm->inten = 0; + i2cm->intfl = i2cm->intfl; + + // Transmit the command if there is command data and length + if((cmd_data != NULL) && (cmd_len > 0)) { + retval = I2CM_Tx(i2cm, fifo, addr, cmd_data, cmd_len, 0); + } + + // Read data from the slave if we don't have any errors + if(retval == E_NO_ERROR) { + retval = I2CM_Rx(i2cm, fifo, addr, data, len); + } + + // Wait for the transaction to complete + if((error = I2CM_TxInProgress(i2cm)) != E_NO_ERROR) { + retval = error; + } + + // Unlock this I2CM + mxc_free_lock((uint32_t*)&states[i2cm_num].req); + + if(retval != E_NO_ERROR) { + return retval; + } + + return len; +} + +/******************************************************************************/ +int I2CM_Write(mxc_i2cm_regs_t *i2cm, uint8_t addr, const uint8_t *cmd_data, + uint32_t cmd_len, uint8_t* data, uint32_t len) +{ + int i2cm_num; + int error = E_NO_ERROR; + int retval = E_NO_ERROR; + mxc_i2cm_fifo_regs_t *fifo; + + if(data == NULL) { + return E_NULL_PTR; + } + + // Make sure the I2CM has been initialized + if(i2cm->ctrl == 0) { + return E_UNINITIALIZED; + } + + if(!(len > 0)) { + return E_NO_ERROR; + } + + // Lock this I2CM + i2cm_num = MXC_I2CM_GET_IDX(i2cm); + while(mxc_get_lock((uint32_t*)&states[i2cm_num].req,1) != E_NO_ERROR) {} + + // Get the FIFO pointer for this I2CM + fifo = MXC_I2CM_GET_FIFO(i2cm_num); + + // Disable and clear the interrupts + i2cm->inten = 0; + i2cm->intfl = i2cm->intfl; + + // Transmit the command if there is command data and length, don't send stop bit + if((cmd_data != NULL) && (cmd_len > 0)) { + retval = I2CM_Tx(i2cm, fifo, addr, cmd_data, cmd_len, 0); + } + + // Write data to the slave, send the stop bit + if(retval == E_NO_ERROR) { + retval = I2CM_Tx(i2cm, fifo, addr, data, len, 1); + } + + // Wait for the transaction to complete + if((error = I2CM_TxInProgress(i2cm)) != E_NO_ERROR) { + retval = error; + } + + // Unlock this I2CM + mxc_free_lock((uint32_t*)&states[i2cm_num].req); + + if(retval != E_NO_ERROR) { + return retval; + } + + return len; +} + +/******************************************************************************/ +int I2CM_ReadAsync(mxc_i2cm_regs_t *i2cm, i2cm_req_t *req) +{ + int i2cm_num, error; + + if(req->data == NULL) { + return E_NULL_PTR; + } + + // Make sure the I2CM has been initialized + if(i2cm->ctrl == 0) { + return E_UNINITIALIZED; + } + + if(!(req->data_len > 0)) { + return E_NO_ERROR; + } + + i2cm_num = MXC_I2CM_GET_IDX(i2cm); + + // Attempt to register this request + if(mxc_get_lock((uint32_t*)&states[i2cm_num].req, (uint32_t)req) != E_NO_ERROR) { + return E_BUSY; + } + + states[i2cm_num].state = I2CM_STATE_READING; + + // Clear the number of bytes counter + req->cmd_num = 0; + req->data_num = 0; + + // Disable and clear the interrupts + i2cm->inten = 0; + i2cm->intfl = i2cm->intfl; + + // Start the read + if((error = I2CM_ReadHandler(i2cm, req, i2cm_num)) != E_NO_ERROR) { + I2CM_Recover(i2cm); + I2CM_FreeCallback(i2cm_num, error); + return error; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int I2CM_WriteAsync(mxc_i2cm_regs_t *i2cm, i2cm_req_t *req) +{ + int i2cm_num, error; + + if(req->data == NULL) { + return E_NULL_PTR; + } + + // Make sure the I2CM has been initialized + if(i2cm->ctrl == 0) { + return E_UNINITIALIZED; + } + + if(!(req->data_len > 0)) { + return E_NO_ERROR; + } + + i2cm_num = MXC_I2CM_GET_IDX(i2cm); + + // Attempt to register this request + if(mxc_get_lock((uint32_t*)&states[i2cm_num].req, (uint32_t)req) != E_NO_ERROR) { + return E_BUSY; + } + + states[i2cm_num].state = I2CM_STATE_WRITING; + + // Clear the number of bytes counter + req->cmd_num = 0; + req->data_num = 0; + + // Disable and clear the interrupts + i2cm->inten = 0; + i2cm->intfl = i2cm->intfl; + + // Start the Write + if((error = I2CM_WriteHandler(i2cm, req, i2cm_num)) != E_NO_ERROR) { + I2CM_Recover(i2cm); + I2CM_FreeCallback(i2cm_num, error); + return error; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int I2CM_AbortAsync(i2cm_req_t *req) +{ + int i2cm_num; + mxc_i2cm_regs_t *i2cm; + + // Find the request, set to NULL + for(i2cm_num = 0; i2cm_num < MXC_CFG_I2CM_INSTANCES; i2cm_num++) { + if(req == states[i2cm_num].req) { + + i2cm = MXC_I2CM_GET_I2CM(i2cm_num); + I2CM_Recover(i2cm); + I2CM_FreeCallback(i2cm_num, E_ABORT); + + return E_NO_ERROR; + } + } + + return E_BAD_PARAM; +} + +/******************************************************************************/ +void I2CM_Handler(mxc_i2cm_regs_t *i2cm) +{ + uint32_t intfl; + int i2cm_num, error; + + // Save and clear the interrupts + intfl = i2cm->intfl; + i2cm->intfl = intfl; + + // Mask the disabled interrupts + intfl &= i2cm->inten; + + i2cm_num = MXC_I2CM_GET_IDX(i2cm); + + // Check for errors + if ((intfl & MXC_F_I2CM_INTFL_TX_NACKED) || (intfl & MXC_F_I2CM_INTFL_TX_LOST_ARBITR)) { + I2CM_Recover(i2cm); + I2CM_FreeCallback(i2cm_num, E_COMM_ERR); + return; + } + + if(intfl & MXC_F_I2CM_INTFL_TX_TIMEOUT) { + I2CM_Recover(i2cm); + I2CM_FreeCallback(i2cm_num, E_TIME_OUT); + return; + } + + // Read or write + if(states[i2cm_num].state == I2CM_STATE_READING) { + if((error = I2CM_ReadHandler(i2cm, states[i2cm_num].req, i2cm_num)) != E_NO_ERROR) { + I2CM_Recover(i2cm); + I2CM_FreeCallback(i2cm_num, error); + return; + } + + } else if(states[i2cm_num].state == I2CM_STATE_WRITING) { + if((error = I2CM_WriteHandler(i2cm, states[i2cm_num].req, i2cm_num)) != E_NO_ERROR) { + I2CM_Recover(i2cm); + I2CM_FreeCallback(i2cm_num, error); + return; + } + } + + // Done with the transaction + if(intfl & MXC_F_I2CM_INTFL_TX_DONE) { + I2CM_Recover(i2cm); + I2CM_FreeCallback(i2cm_num, E_NO_ERROR); + } + +} + +/******************************************************************************/ +int I2CM_Busy(mxc_i2cm_regs_t *i2cm) +{ + // Check to see if there are any ongoing transactions + if((states[MXC_I2CM_GET_IDX(i2cm)].req == NULL) && + !(i2cm->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) { + + return E_NO_ERROR; + } + + return E_BUSY; +} + +/******************************************************************************/ +int I2CM_PrepForSleep(mxc_i2cm_regs_t *i2cm) +{ + if(I2CM_Busy(i2cm) != E_NO_ERROR) { + return E_BUSY; + } + + // Disable interrupts + i2cm->inten = 0; + return E_NO_ERROR; +} + +/******************************************************************************/ +int I2CM_BusCheck(mxc_i2cm_regs_t *i2cm) +{ + // If SCL is low, we don't have the bus + if(!(i2cm->bb & MXC_F_I2CM_BB_BB_SCL_IN_VAL)) { + return E_BUSY; + } + + // If SDA is low, we don't have the bus + if(!(i2cm->bb & MXC_F_I2CM_BB_BB_SDA_IN_VAL)) { + return E_BUSY; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +static void I2CM_FreeCallback(int i2cm_num, int error) +{ + // Save the request + i2cm_req_t *temp_req = states[i2cm_num].req; + + // Unlock this UART to write + mxc_free_lock((uint32_t*)&states[i2cm_num].req); + + // Callback if not NULL + if(temp_req->callback != NULL) { + temp_req->callback(temp_req, error); + } +} + +/******************************************************************************/ +void I2CM_Recover(mxc_i2cm_regs_t *i2cm) +{ + // Disable and clear interrupts + i2cm->inten = 0; + i2cm->intfl = i2cm->intfl; + i2cm->ctrl = MXC_F_I2CM_CTRL_MSTR_RESET_EN; + i2cm->ctrl = MXC_F_I2CM_CTRL_TX_FIFO_EN | MXC_F_I2CM_CTRL_RX_FIFO_EN; +} + +/******************************************************************************/ +int I2CM_WriteTxFifo(mxc_i2cm_regs_t *i2cm, mxc_i2cm_fifo_regs_t *fifo, const uint16_t data) +{ + int32_t timeout = MXC_I2CM_TX_TIMEOUT; + + // Read the TX FIFO to determine if it's full + do { + + // Wait for the TX FIFO to have room and check for errors + if (i2cm->intfl & (MXC_F_I2CM_INTFL_TX_NACKED | + MXC_F_I2CM_INTFL_TX_LOST_ARBITR)) { + + return E_COMM_ERR; + } + + if((i2cm->intfl & MXC_F_I2CM_INTFL_TX_TIMEOUT) || !timeout--) { + return E_TIME_OUT; + } + + } while (fifo->tx); + + fifo->tx = data; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int I2CM_TxInProgress(mxc_i2cm_regs_t *i2cm) +{ + int32_t timeout = MXC_I2CM_TX_TIMEOUT; + + while ((i2cm->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS) && --timeout); + + if (i2cm->intfl & (MXC_F_I2CM_INTFL_TX_NACKED | + MXC_F_I2CM_INTFL_TX_LOST_ARBITR)) { + + I2CM_Recover(i2cm); + return E_COMM_ERR; + } + + if((i2cm->intfl & MXC_F_I2CM_INTFL_TX_TIMEOUT) && !timeout--) { + I2CM_Recover(i2cm); + return E_TIME_OUT; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int I2CM_Tx(mxc_i2cm_regs_t *i2cm, mxc_i2cm_fifo_regs_t *fifo, uint8_t addr, + const uint8_t *data, uint32_t len, uint8_t stop) +{ + uint32_t i; + int error; + + // Write the address to the TXFIFO + if((error = I2CM_WriteTxFifo(i2cm, fifo, (MXC_S_I2CM_TRANS_TAG_START | (addr << 1)))) != E_NO_ERROR) { + return error; + } + + // Start the transaction if it is not currently ongoing + if (!(i2cm->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) { + i2cm->trans |= MXC_F_I2CM_TRANS_TX_START; + } + + // Fill the FIFO + for (i = 0; i < len; i++) { + if((error = I2CM_WriteTxFifo(i2cm, fifo, (MXC_S_I2CM_TRANS_TAG_TXDATA_ACK | data[i]))) != E_NO_ERROR) { + return error; + } + } + + // Send the stop condition + if(stop) { + if ((error = I2CM_WriteTxFifo(i2cm, fifo, MXC_S_I2CM_TRANS_TAG_STOP)) != E_NO_ERROR) { + return error; + } + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int I2CM_Rx(mxc_i2cm_regs_t *i2cm, mxc_i2cm_fifo_regs_t *fifo, uint8_t addr, + uint8_t *data, uint32_t len) +{ + uint32_t i = len; + int32_t timeout; + uint16_t temp; + int error; + + // Write the address to the TXFIFO + if((error = I2CM_WriteTxFifo(i2cm, fifo, (MXC_S_I2CM_TRANS_TAG_START | + (addr << 1) | I2CM_READ_BIT))) != E_NO_ERROR) { + + return error; + } + + // Write to the TXFIFO the number of bytes we want to read + while(i > 256) { + if((error = I2CM_WriteTxFifo(i2cm, fifo, (MXC_S_I2CM_TRANS_TAG_RXDATA_COUNT | 255))) != E_NO_ERROR) { + return error; + } + + i -= 256; + } + + if(i > 1) { + if((error = I2CM_WriteTxFifo(i2cm, fifo, (MXC_S_I2CM_TRANS_TAG_RXDATA_COUNT | (i-2)))) != E_NO_ERROR) { + return error; + } + } + + // Start the transaction if it is not currently ongoing + if (!(i2cm->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) { + i2cm->trans |= MXC_F_I2CM_TRANS_TX_START; + } + + + // NACK the last read byte + if((error = I2CM_WriteTxFifo(i2cm, fifo, (MXC_S_I2CM_TRANS_TAG_RXDATA_NACK))) != E_NO_ERROR) { + return error; + } + + // Send the stop condition + if ((error = I2CM_WriteTxFifo(i2cm, fifo, MXC_S_I2CM_TRANS_TAG_STOP)) != E_NO_ERROR) { + return error; + } + + // Get the data from the RX FIFO + i = 0; + while (i < len) { + + // Wait for there to be data in the RX FIFO + timeout = MXC_I2CM_RX_TIMEOUT; + while (!(i2cm->intfl & MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY) && + ((i2cm->bb & MXC_F_I2CM_BB_RX_FIFO_CNT) == 0)) { + + if((timeout-- < 0) || (i2cm->trans & MXC_F_I2CM_TRANS_TX_TIMEOUT)) { + return E_TIME_OUT; + } + + if (i2cm->trans & (MXC_F_I2CM_TRANS_TX_LOST_ARBITR | MXC_F_I2CM_TRANS_TX_NACKED)) { + return E_COMM_ERR; + } + } + i2cm->intfl = MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY; + + // Save the data from the RX FIFO + temp = fifo->rx; + if (temp & MXC_S_I2CM_RSTLS_TAG_EMPTY) { + continue; + } + data[i++] = (uint8_t)temp; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +static int I2CM_CmdHandler(mxc_i2cm_regs_t *i2cm, mxc_i2cm_fifo_regs_t *fifo, i2cm_req_t *req) +{ + int error; + + // Start of the command + if(req->cmd_num == 0) { + + // Write the address to the TXFIFO + if((error = I2CM_WriteTxFifo(i2cm, fifo, (MXC_S_I2CM_TRANS_TAG_START | (req->addr << 1)))) != E_NO_ERROR) { + return error; + } + + // Start the transaction if it is not currently ongoing + if (!(i2cm->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) { + i2cm->trans |= MXC_F_I2CM_TRANS_TX_START; + } + } + + // Write to the FIFO until it is full or we run out of command bytes + while((req->cmd_num < req->cmd_len) && (!fifo->tx)) { + fifo->tx = MXC_S_I2CM_TRANS_TAG_TXDATA_ACK | req->cmd_data[req->cmd_num++]; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +static int I2CM_ReadHandler(mxc_i2cm_regs_t *i2cm, i2cm_req_t *req, int i2cm_num) +{ + int error, cmd_remain, data_remain; + uint16_t data; + uint32_t temp_len, inten; + mxc_i2cm_fifo_regs_t *fifo; + + // Get the FIFO pointer for this I2CM + fifo = MXC_I2CM_GET_FIFO(i2cm_num); + + cmd_remain = req->cmd_len - req->cmd_num; + data_remain = req->data_len - req->data_num; + + // Process the command portion + if((cmd_remain) && (req->cmd_data != NULL)) { + if((error = I2CM_CmdHandler(i2cm, fifo, req)) != E_NO_ERROR) { + return error; + } + + cmd_remain = req->cmd_len - req->cmd_num; + } + + // Process the data portion + if((cmd_remain == 0) && (data_remain)) { + + // Save the data from the RXFIFO + data = fifo->rx; + while((req->data_num < req->data_len) && !(data & MXC_S_I2CM_RSTLS_TAG_EMPTY)) { + req->data[req->data_num++] = data; + data = fifo->rx; + } + + // Start of the data portion + if(req->data_num == 0) { + + temp_len = req->data_len; + + // Write the address to the TXFIFO + if((error = I2CM_WriteTxFifo(i2cm, fifo, (MXC_S_I2CM_TRANS_TAG_START | + (req->addr << 1) | I2CM_READ_BIT))) != E_NO_ERROR) { + + return error; + } + + // Write to the TXFIFO the number of bytes we want to read + while(temp_len > 256) { + if((error = I2CM_WriteTxFifo(i2cm, fifo, (MXC_S_I2CM_TRANS_TAG_RXDATA_COUNT | 255))) != E_NO_ERROR) { + return error; + } + + temp_len -= 256; + } + + if(temp_len > 1) { + if((error = I2CM_WriteTxFifo(i2cm, fifo, (MXC_S_I2CM_TRANS_TAG_RXDATA_COUNT | (temp_len-2)))) != E_NO_ERROR) { + return error; + } + } + + // Start the transaction if it is not currently ongoing + if (!(i2cm->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) { + i2cm->trans |= MXC_F_I2CM_TRANS_TX_START; + } + + // NACK the last read byte + if((error = I2CM_WriteTxFifo(i2cm, fifo, (MXC_S_I2CM_TRANS_TAG_RXDATA_NACK))) != E_NO_ERROR) { + return error; + } + + // Send the stop condition + if ((error = I2CM_WriteTxFifo(i2cm, fifo, MXC_S_I2CM_TRANS_TAG_STOP)) != E_NO_ERROR) { + return error; + } + } + } + + // Enable the required interrupts + inten = MXC_F_I2CM_INTEN_TX_DONE | MXC_F_I2CM_INTEN_TX_NACKED | + MXC_F_I2CM_INTEN_TX_LOST_ARBITR | MXC_F_I2CM_INTEN_TX_TIMEOUT; + + if (cmd_remain) { + inten |= (MXC_F_I2CM_INTEN_TX_FIFO_EMPTY | MXC_F_I2CM_INTEN_TX_FIFO_3Q_EMPTY); + } + + data_remain = req->data_len - req->data_num; + if (data_remain > I2CM_FIFO_DEPTH_3Q) { + inten |= MXC_F_I2CM_INTEN_RX_FIFO_3Q_FULL; + + } else if (data_remain > I2CM_FIFO_DEPTH_2Q) { + inten |= MXC_F_I2CM_INTEN_RX_FIFO_2Q_FULL; + + } else if (data_remain > 0) { + inten |= MXC_F_I2CM_INTEN_RX_FIFO_NOT_EMPTY; + } + + i2cm->inten = inten; + + return E_NO_ERROR; +} + +/******************************************************************************/ +static int I2CM_WriteHandler(mxc_i2cm_regs_t *i2cm, i2cm_req_t *req, int i2cm_num) +{ + int error, cmd_remain, data_remain; + uint32_t inten; + mxc_i2cm_fifo_regs_t *fifo; + + // Get the FIFO pointer for this I2CM + fifo = MXC_I2CM_GET_FIFO(i2cm_num); + + cmd_remain = req->cmd_len - req->cmd_num; + data_remain = req->data_len - req->data_num; + + // Process the command portion + if((cmd_remain) && (req->cmd_data != NULL)) { + if((error = I2CM_CmdHandler(i2cm, fifo, req)) != E_NO_ERROR) { + return error; + } + + cmd_remain = req->cmd_len - req->cmd_num; + } + + // Process the data portion + if((cmd_remain == 0) && (data_remain)) { + + // Start of the data portion + if(req->data_num == 0) { + + // Write the address to the TXFIFO + if((error = I2CM_WriteTxFifo(i2cm, fifo, (MXC_S_I2CM_TRANS_TAG_START | + (req->addr << 1)))) != E_NO_ERROR) { + + return error; + } + + // Start the transaction if it is not currently ongoing + if (!(i2cm->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) { + i2cm->trans |= MXC_F_I2CM_TRANS_TX_START; + } + } + + // Write bytes to the FIFO until it's full or we run out of bytes + while(req->data_num < req->data_len) { + fifo->tx = MXC_S_I2CM_TRANS_TAG_TXDATA_ACK | req->data[req->data_num++]; + } + + // Send the stop condition + if ((error = I2CM_WriteTxFifo(i2cm, fifo, MXC_S_I2CM_TRANS_TAG_STOP)) != E_NO_ERROR) { + return error; + } + } + + // Enable the required interrupts + data_remain = req->data_len - req->data_num; + inten = MXC_F_I2CM_INTEN_TX_DONE | MXC_F_I2CM_INTEN_TX_NACKED | + MXC_F_I2CM_INTEN_TX_LOST_ARBITR | MXC_F_I2CM_INTEN_TX_TIMEOUT; + + if(data_remain || cmd_remain) { + inten |= (MXC_F_I2CM_INTEN_TX_FIFO_EMPTY | MXC_F_I2CM_INTEN_TX_FIFO_3Q_EMPTY); + } + i2cm->inten = inten; + + return E_NO_ERROR; +} + +int I2CM_SetFrequency(mxc_i2cm_regs_t *i2cm, int speed) +{ + // Speed converted into Khz + float i2cSpeed = speed / 1000.0f; + //get clk speed into MHz + int sClk = SYS_I2CM_GetFreq(i2cm) / 1000000; + // duty cycle of .67 + float dc = 2.0f / 3.0f; + //Hold Time + float hold = (100.0f / i2cSpeed); + int riseTime; + //max rise time based on speed according to the I2C specs + if (i2cSpeed <= 100) { + riseTime = 1000; + } else if (i2cSpeed <= 400) { + riseTime = 300; + } else if (i2cSpeed <= 1000) { + riseTime = 120; + } else { + return E_NOT_SUPPORTED; + } + // Clock cycles to delay + int latency = 4; + int filtDev, sclHi, sclLow; + filtDev = (hold * sClk) / 2; + sclHi = (((dc * sClk * 1000.0f / i2cSpeed) - (((2.5f * filtDev) + (riseTime / 1000.0f * sClk) + latency) * (1.0f + dc))) / (1.0f + dc)); + sclLow = ((sClk * 1000.0f / i2cSpeed) - (2.5f * filtDev) - (riseTime / 1000.0f * sClk) - latency - sclHi); + + i2cm->fs_clk_div = ((filtDev << MXC_F_I2CM_FS_CLK_DIV_FS_FILTER_CLK_DIV_POS) | + (sclHi << MXC_F_I2CM_FS_CLK_DIV_FS_SCL_HI_CNT_POS) | + (sclLow << MXC_F_I2CM_FS_CLK_DIV_FS_SCL_LO_CNT_POS)); + return E_NO_ERROR; +} \ No newline at end of file diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cm.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cm.h new file mode 100644 index 00000000000..b938ad312d9 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cm.h @@ -0,0 +1,257 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-04-27 11:55:43 -0500 (Wed, 27 Apr 2016) $ + * $Revision: 22541 $ + * + ******************************************************************************/ + +/** + * @file i2cm.h + * @brief I2C Master driver header file. + */ + +#ifndef _I2CM_H_ +#define _I2CM_H_ + +/***** Includes *****/ +#include "mxc_config.h" +#include "mxc_sys.h" +#include "i2cm_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***** Definitions *****/ + +/// @brief I2CM frequencies. +typedef enum { + I2CM_SPEED_100KHZ = 100000, + I2CM_SPEED_400KHZ = 400000 +} i2cm_speed_t; + +/// @brief I2CM Transaction request. +typedef struct i2cm_req i2cm_req_t; +struct i2cm_req { + + /** + * @details Only supports 7-bit addressing. Driver will shift the address and + * add the read bit when necessary. + */ + uint8_t addr; + const uint8_t *cmd_data; ///< Optional command data to write before reading. + uint32_t cmd_len; ///< Number of bytes in command. + uint8_t *data; ///< Data to write or read. + uint32_t data_len; ///< Length of data. + uint32_t cmd_num; ///< Number of command bytes sent + uint32_t data_num; ///< Number of data bytes sent + + /** + * @brief Callback for asynchronous request. + * @param i2cm_req_t* Pointer to the transaction request. + * @param int Error code. + */ + void (*callback)(i2cm_req_t*, int); +}; + +/***** Globals *****/ + +/***** Function Prototypes *****/ + +/** + * @brief Initialize I2CM module. + * @param i2cm Pointer to I2CM regs. + * @param cfg Pointer to I2CM configuration. + * @param speed I2CM frequency. + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int I2CM_Init(mxc_i2cm_regs_t *i2cm, const sys_cfg_i2cm_t *sys_cfg, i2cm_speed_t speed); + +/** + * @brief Shutdown I2CM module. + * @param i2cm Pointer to I2CM regs. + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int I2CM_Shutdown(mxc_i2cm_regs_t *i2cm); + +/** + * @brief Read I2CM data. Will block until transaction is complete. + * @param i2cm Pointer to I2CM regs. + * @param addr I2C address of the slave. + * @param cmd_data Data to write before reading. + * @param cmd_len Number of bytes to write before reading. + * @param data Where to store read data. + * @param len Number of bytes to read. + * @details Command is an optional feature where the master will write the cmd_data + * before reading from the slave. If command is undesired, leave the pointer + * NULL and cmd_len 0. If there is a command, the master will send a + repeated start before reading. Will block until transaction has completed. + * @returns Bytes transacted if everything is successful, error if unsuccessful. + */ +int I2CM_Read(mxc_i2cm_regs_t *i2cm, uint8_t addr, const uint8_t *cmd_data, + uint32_t cmd_len, uint8_t* data, uint32_t len); + +/** + * @brief Write I2CM data. Will block until transaction is complete. + * @param i2cm Pointer to I2CM regs. + * @param addr I2C address of the slave. + * @param cmd_data Data to write before writing data. + * @param cmd_len Number of bytes to write before writing data. + * @param data Data to be written. + * @param len Number of bytes to Write. + * @details Command is an optional feature where the master will write the cmd_data + * before writing to the slave. If command is undesired, leave the pointer + * NULL and cmd_len 0. If there is a command, the master will send a + repeated start before writing again. Will block until transaction has completed. + * @returns Bytes transacted if everything is successful, error if unsuccessful. + */ +int I2CM_Write(mxc_i2cm_regs_t *i2cm, uint8_t addr, const uint8_t *cmd_data, + uint32_t cmd_len, uint8_t* data, uint32_t len); + +/** + * @brief Asynchronously read I2CM data. + * @param i2cm Pointer to I2CM regs. + * @param req Request for an I2CM transaction. + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int I2CM_ReadAsync(mxc_i2cm_regs_t *i2cm, i2cm_req_t *req); + +/** + * @brief Asynchronously write I2CM data. + * @param i2cm Pointer to I2CM regs. + * @param req Request for an I2CM transaction. + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int I2CM_WriteAsync(mxc_i2cm_regs_t *i2cm, i2cm_req_t *req); + +/** + * @brief Abort asynchronous request. + * @param req Pointer to request for a I2CM transaction. + * @note Will call the callback for the request. + * @returns #E_NO_ERROR if request aborted, error if unsuccessful. + */ +int I2CM_AbortAsync(i2cm_req_t *req); + +/** + * @brief I2CM interrupt handler. + * @details This function should be called by the application from the interrupt + * handler if I2CM interrupts are enabled. Alternately, this function + * can be periodically called by the application if I2CM interrupts are + * disabled. + * @param i2cm Base address of the I2CM module. + */ +void I2CM_Handler(mxc_i2cm_regs_t *i2cm); + +/** + * @brief Checks to see if the I2CM is busy. + * @param i2cm Pointer to I2CM regs. + * @returns #E_NO_ERROR if idle, #E_BUSY if in use. + */ +int I2CM_Busy(mxc_i2cm_regs_t *i2cm); + +/** + * @brief Attempt to prepare the I2CM for sleep. + * @param i2cm Pointer to I2CM regs. + * @details Checks for any ongoing transactions. Disables interrupts if the I2CM + is idle. + * @returns #E_NO_ERROR if ready to sleep, #E_BUSY if not ready for sleep. + */ +int I2CM_PrepForSleep(mxc_i2cm_regs_t *i2cm); + +/** + * @brief Check the I2C bus. + * @param i2cm Pointer to I2CM regs. + * @details Checks the I2CM bus to determine if there is any other master using + * the bus. + * @returns #E_NO_ERROR if SCL and SDA are high, #E_BUSY otherwise. + */ +int I2CM_BusCheck(mxc_i2cm_regs_t *i2cm); + +/** + * @brief Drain all of the data in the RXFIFO. + * @param i2cm Pointer to UART regs. + */ +__STATIC_INLINE void I2CM_DrainRX(mxc_i2cm_regs_t *i2cm) +{ + i2cm->ctrl &= ~(MXC_F_I2CM_CTRL_RX_FIFO_EN); + i2cm->ctrl |= MXC_F_I2CM_CTRL_RX_FIFO_EN; +} + +/** + * @brief Drain all of the data in the TXFIFO. + * @param i2cm Pointer to UART regs. + */ +__STATIC_INLINE void I2CM_DrainTX(mxc_i2cm_regs_t *i2cm) +{ + i2cm->ctrl &= ~(MXC_F_I2CM_CTRL_TX_FIFO_EN); + i2cm->ctrl |= MXC_F_I2CM_CTRL_TX_FIFO_EN; +} + +/** + * @brief Clear interrupt flags. + * @param i2cm Pointer to I2CM regs. + * @param mask Mask of interrupts to clear. + */ +__STATIC_INLINE void I2CM_ClearFlags(mxc_i2cm_regs_t *i2cm, uint32_t mask) +{ + i2cm->intfl = mask; +} + +/** + * @brief Get interrupt flags. + * @param i2cm Pointer to I2CM regs. + * @returns Mask of active flags. + */ +__STATIC_INLINE unsigned I2CM_GetFlags(mxc_i2cm_regs_t *i2cm) +{ + return(i2cm->intfl); +} +/** + * @brief Set the I2C Frequency + * @param i2cm Pointer to I2CM regs. + * @param speed speed in Hz + * @details sets the registers for the proper frequency + * @returns #E_NO_ERROR if Frequency is supported, #E_NOT_Supported otherwise. + */ +int I2CM_SetFrequency(mxc_i2cm_regs_t *i2cm, int speed); + +void I2CM_Recover(mxc_i2cm_regs_t *i2cm); +int I2CM_WriteTxFifo(mxc_i2cm_regs_t *regs, mxc_i2cm_fifo_regs_t *fifo, const uint16_t data); +int I2CM_TxInProgress(mxc_i2cm_regs_t *i2cm); +int I2CM_Tx(mxc_i2cm_regs_t *i2cm, mxc_i2cm_fifo_regs_t *fifo, uint8_t addr, const uint8_t *data, uint32_t len, uint8_t stop); +int I2CM_Rx(mxc_i2cm_regs_t *i2cm, mxc_i2cm_fifo_regs_t *fifo, uint8_t addr, uint8_t *data, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* _I2CM_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cs.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cs.c new file mode 100644 index 00000000000..06ee8bf20fe --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cs.c @@ -0,0 +1,209 @@ +/** + * @file i2cs.c + * @brief This file contains the function implementations for the I2CS + * (Inter-Integrated Circuit Slave) peripheral module. + */ +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-15 20:05:48 -0500 (Mon, 15 Aug 2016) $ + * $Revision: 24086 $ + * + *************************************************************************** */ + +/* **** Includes **** */ +#include +#include "mxc_assert.h" +#include "mxc_errors.h" +#include "mxc_sys.h" +#include "i2cs.h" + +/** + * @ingroup i2cs + * @{ + */ +/* **** Definitions **** */ + +/* **** Globals ***** */ + + +// No Doxygen documentation for the items between here and endcond. +/* Clock divider lookup table */ +static const uint32_t clk_div_table[2][8] = { + /* I2CS_SPEED_100KHZ */ + { + // 12000000 + (6 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS), + // 24000000 + (12 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS), + // 36000000 NOT SUPPORTED + 0, + // 48000000 + (24 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS), + // 60000000 NOT SUPPORTED + 0, + // 72000000 NOT SUPPORTED + 0, + // 84000000 NOT SUPPORTED + 0, + // 96000000 + (48 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS) + }, + /* I2CS_SPEED_400KHZ */ + { + // 12000000 + (2 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS), + // 24000000 + (3 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS), + // 36000000 NOT SUPPORTED + 0, + // 48000000 + (6 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS), + // 60000000 NOT SUPPORTED + 0, + // 72000000 NOT SUPPORTED + 0, + // 84000000 NOT SUPPORTED + 0, + // 96000000 + (12 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS) + }, +}; + + +static void (*callbacks[MXC_CFG_I2CS_INSTANCES][MXC_CFG_I2CS_BUFFER_SIZE])(uint8_t); + +/* **** Functions **** */ + +/* ************************************************************************* */ +int I2CS_Init(mxc_i2cs_regs_t *i2cs, const sys_cfg_i2cs_t *sys_cfg, i2cs_speed_t speed, + uint16_t address, i2cs_addr_t addr_len) +{ + int err, i, i2cs_index; + + i2cs_index = MXC_I2CS_GET_IDX(i2cs); + MXC_ASSERT(i2cs_index >= 0); + + // Set system level configurations + if ((err = SYS_I2CS_Init(i2cs, sys_cfg)) != E_NO_ERROR) { + return err; + } + + // Compute clock array index + int clki = ((SYS_I2CS_GetFreq(i2cs) / 12000000) - 1); + + // Get clock divider settings from lookup table + if ((speed == I2CS_SPEED_100KHZ) && (clk_div_table[I2CS_SPEED_100KHZ][clki] > 0)) { + i2cs->clk_div = clk_div_table[I2CS_SPEED_100KHZ][clki]; + } else if ((speed == I2CS_SPEED_400KHZ) && (clk_div_table[I2CS_SPEED_400KHZ][clki] > 0)) { + i2cs->clk_div = clk_div_table[I2CS_SPEED_400KHZ][clki]; + } else { + MXC_ASSERT_FAIL(); + } + + // Clear the interrupt callbacks + for(i = 0; i < MXC_CFG_I2CS_BUFFER_SIZE; i++) { + callbacks[i2cs_index][i] = NULL; + } + + // Reset module + i2cs->dev_id = MXC_F_I2CS_DEV_ID_SLAVE_RESET; + i2cs->dev_id = ((((address >> 0) << MXC_F_I2CS_DEV_ID_SLAVE_DEV_ID_POS) + & MXC_F_I2CS_DEV_ID_SLAVE_DEV_ID) | addr_len); + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +int I2CS_Shutdown(mxc_i2cs_regs_t *i2cs) +{ + int err; + + // Disable and clear interrupts + i2cs->inten = 0; + i2cs->intfl = i2cs->intfl; + + // clears system level configurations + if ((err = SYS_I2CS_Shutdown(i2cs)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +void I2CS_Handler(mxc_i2cs_regs_t *i2cs) +{ + uint32_t intfl; + uint8_t i; + int i2cs_index = MXC_I2CS_GET_IDX(i2cs); + + // Save and clear the interrupt flags + intfl = i2cs->intfl; + i2cs->intfl = intfl; + + // Process each interrupt + for(i = 0; i < 32; i++) { + if(intfl & (0x1 << i)) { + if(callbacks[i2cs_index][i] != NULL) { + callbacks[i2cs_index][i](i); + } + } + } + +} + +/* ************************************************************************* */ +void I2CS_RegisterCallback(mxc_i2cs_regs_t *i2cs, uint8_t addr, i2cs_callback_fn callback) +{ + int i2cs_index = MXC_I2CS_GET_IDX(i2cs); + + // Make sure we don't overflow + MXC_ASSERT(addr < MXC_CFG_I2CS_BUFFER_SIZE); + + if(callback != NULL) { + // Save the callback address + callbacks[i2cs_index][addr] = callback; + + // Clear and Enable the interrupt for the given byte + i2cs->intfl = (0x1 << addr); + i2cs->inten |= (0x1 << addr); + } else { + // Disable and clear the interrupt + i2cs->inten &= ~(0x1 << addr); + i2cs->intfl = (0x1 << addr); + + // Clear the callback address + callbacks[i2cs_index][addr] = NULL; + } +} + +/**@} end of group i2cs*/ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cs.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cs.h new file mode 100644 index 00000000000..5cc6bc395f4 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/i2cs.h @@ -0,0 +1,215 @@ +/** + * @file i2cs.h + * @brief I2CS (Inter-Integrated Circuit Slave) function prototypes and data types. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-15 20:05:48 -0500 (Mon, 15 Aug 2016) $ + * $Revision: 24086 $ + * + *************************************************************************** */ + +/* Define to prevent redundant inclusion */ +#ifndef _I2CS_H_ +#define _I2CS_H_ + +/* **** Includes **** */ +#include "mxc_config.h" +#include "mxc_sys.h" +#include "mxc_assert.h" +#include "i2cs_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup i2cs I2C Slave + * @ingroup i2c_master_slave + * @brief I2C Slave (I2CS) API + * @{ + */ + +/* **** Definitions **** */ +/** + * Internal buffer size for storing I2C Slave Messages + */ +#define I2CS_BUFFER_SIZE 32 + +/** + * Enumeration type to select supported I2CS frequencies. + */ +typedef enum { + I2CS_SPEED_100KHZ = 0, /**< Use to select a bus communication speed of 100 kHz. */ + I2CS_SPEED_400KHZ = 1 /**< Use to select a bus communication speed of 400 kHz. */ +} i2cs_speed_t; + +/** + * Enumeration type to select the I2CS addressing mode. + */ +typedef enum { + I2CS_ADDR_8 = 0, /**< Sets the slave address mode to 8-bits (7-bits address plus read/write bit). */ + I2CS_ADDR_10 = MXC_F_I2CS_DEV_ID_TEN_BIT_ID_MODE /**< Sets the slave address mode to 10-bits. */ +} i2cs_addr_t; + +/** + * Type alias for an I2CS callback function that will be called when a given byte is updated by the Master, see I2CS_RegisterCallback(mxc_i2cs_regs_t *i2cs, uint8_t addr, i2cs_callback_fn callback). + * @details The function prototype for implementing callback_fn is: + * @code + * void func(uint8_t addr); + * @endcode + */ +typedef void (*i2cs_callback_fn)(uint8_t error_code); +/* **** Globals **** */ + +/* **** Function Prototypes **** */ + +/** + * @brief Initialize I2CS module. + * @param i2cs Pointer to I2CS regs. + * @param sys_cfg Pointer to I2CS system configuration, see + * #sys_cfg_i2cs_t. + * @param speed I2CS frequency. + * @param address I2CS address. + * @param addr_len I2CS address length. + * @return #E_NO_ERROR if everything is successful or an + * @ref MXC_Error_Codes "error code" if unsuccessful. + * + */ +int I2CS_Init(mxc_i2cs_regs_t *i2cs, const sys_cfg_i2cs_t *sys_cfg, i2cs_speed_t speed, uint16_t address, i2cs_addr_t addr_len); + +/** + * @brief Shutdown I2CS module. + * @param i2cs Pointer to I2CS regs. + * @return #E_NO_ERROR if everything is successful or an + * @ref MXC_Error_Codes "error code" if unsuccessful. + */ +int I2CS_Shutdown(mxc_i2cs_regs_t *i2cs); + +/** + * @brief I2CS interrupt handler. + * @details This function should be called by the application from the + * interrupt handler if I2CS interrupts are enabled. Alternately, + * this function can be periodically called by the application if + * I2CS interrupts are disabled. + * + * @param i2cs Pointer to I2CS regs. + */ +void I2CS_Handler(mxc_i2cs_regs_t *i2cs); + +/** + * @brief Register a callback that is triggered by an update of a specified + * byte. + * @details Registering a callback causes the slave to interrupt when the + * master has updated a specified byte. + * + * @param i2cs Pointer to the I2CS register structure, see + * #mxc_i2cs_regs_t. + * @param addr Index to trigger a call to the #i2cs_callback_fn. + * @param callback callback function of type #i2cs_callback_fn to be called + * when the addr being written by the master matches \c addr. + */ +void I2CS_RegisterCallback(mxc_i2cs_regs_t *i2cs, uint8_t addr, i2cs_callback_fn callback); + +/** + * @brief Write I2CS data to a given byte. + * @details The slave has a buffer of registers that the external master can + * read. Use this function to write data into a specified + * address/index. + * + * @param i2cs Pointer to I2CS regs. + * @param addr Address/Index to write. + * @param data Data to be written. + */ +__STATIC_INLINE void I2CS_Write(mxc_i2cs_regs_t *i2cs, uint8_t addr, uint8_t data) +{ + // Make sure we don't overflow + MXC_ASSERT(addr < MXC_CFG_I2CS_BUFFER_SIZE); + i2cs->data_byte[addr] = ((i2cs->data_byte[addr] & ~MXC_F_I2CS_DATA_BYTE_DATA_FIELD) | + (data << MXC_F_I2CS_DATA_BYTE_DATA_FIELD_POS)); +} + +/** + * @brief Read I2CS data from a given address . + * @details The slave has a buffer of registers that the external master can + * read. Use this function to read the data from the registers. + * + * @param i2cs Pointer to I2CS regs. + * @param addr Address/Index to read from. + * + * @return Data contained in requested @c addr register. + */ +__STATIC_INLINE uint8_t I2CS_Read(mxc_i2cs_regs_t *i2cs, uint8_t addr) +{ + // Make sure we don't overflow + MXC_ASSERT(addr < MXC_CFG_I2CS_BUFFER_SIZE); + return ((i2cs->data_byte[addr] & MXC_F_I2CS_DATA_BYTE_DATA_FIELD) >> + MXC_F_I2CS_DATA_BYTE_DATA_FIELD_POS); +} + +/** + * @brief Set the given index to read only (RO). + * @details This index will be flagged as read only. The slave will NACK the + * master if it attempts to write this location. Multiple calls with + * different index/address values will yield multiple read-only + * locations within the slave register set. + * + * @param i2cs Pointer to I2CS regs. + * @param addr Address/Index of the byte to set to RO. + */ +__STATIC_INLINE void I2CS_SetRO(mxc_i2cs_regs_t *i2cs, uint8_t addr) +{ + // Make sure we don't overflow + MXC_ASSERT(addr < MXC_CFG_I2CS_BUFFER_SIZE); + i2cs->data_byte[addr] |= MXC_F_I2CS_DATA_BYTE_READ_ONLY_FL; +} + +/** + * @brief Sets the given address to R/W. + * @param i2cs Pointer to I2CS regs. + * @param addr Index to start clearing RO flag. + */ +__STATIC_INLINE void I2CS_ClearRO(mxc_i2cs_regs_t *i2cs, uint8_t addr) +{ + // Make sure we don't overflow + MXC_ASSERT(addr < MXC_CFG_I2CS_BUFFER_SIZE); + i2cs->data_byte[addr] &= ~MXC_F_I2CS_DATA_BYTE_READ_ONLY_FL; +} + +/**@} end of group i2cs */ + +#ifdef __cplusplus +} +#endif + +#endif /* _I2CS_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/icc.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/icc.c new file mode 100644 index 00000000000..1e048ba9a85 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/icc.c @@ -0,0 +1,77 @@ +/** + * @file icc.c + * @brief This file contains the function implementations for the + * Instruction Cache Controller. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-15 11:26:49 -0500 (Mon, 15 Aug 2016) $ + * $Revision: 24063 $ + * + *************************************************************************** */ + + +/* **** Includes **** */ +#include "mxc_config.h" +#include "icc.h" +/** + * @ingroup icc + * @{ + */ + +/* **** Definitions **** */ + +/* **** Globals **** */ + +/* **** Functions **** */ + +/* ************************************************************************* */ +void ICC_Enable(void) +{ + /* Invalidate cache and wait until ready */ + MXC_ICC->invdt_all = 1; + while (!(MXC_ICC->ctrl_stat & MXC_F_ICC_CTRL_STAT_READY)); + + /* Enable cache */ + MXC_ICC->ctrl_stat |= MXC_F_ICC_CTRL_STAT_ENABLE; + + /* Must invalidate a second time for proper use */ + MXC_ICC->invdt_all = 1; +} + +/* ************************************************************************* */ +void ICC_Disable(void) +{ + MXC_ICC->ctrl_stat &= ~MXC_F_ICC_CTRL_STAT_ENABLE; +} +/**@} end of group icc */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/icc.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/icc.h new file mode 100644 index 00000000000..7510eb21726 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/icc.h @@ -0,0 +1,83 @@ +/** + * @file icc.h + * @brief Instruction Cache Controller function prototypes and data types. + */ + +/* **************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-15 11:26:49 -0500 (Mon, 15 Aug 2016) $ + * $Revision: 24063 $ + * + *************************************************************************** */ + +/* Define to prevent redundant inclusion */ +#ifndef _ICC_H_ +#define _ICC_H_ + +/* **** Includes **** */ +#include "icc_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Doxy group definition for this peripheral module */ + +/** + * @defgroup icc Instruction Cache Controller (ICC) + * @ingroup sysconfig + * @{ + */ +/** + * @brief Enable and flush the instruction cache controller. + */ +void ICC_Enable(void); + +/** + * @brief Disable the instruction cache controller. + */ +void ICC_Disable(void); + +/** + * @brief Flush the instruction cache controller. + */ +__STATIC_INLINE void ICC_Flush() +{ + ICC_Disable(); + ICC_Enable(); +} +/**@} end of group icc */ +#ifdef __cplusplus +} +#endif + +#endif /* _ICC_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/ioman.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/ioman.c new file mode 100644 index 00000000000..16c4b32117d --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/ioman.c @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-04-27 09:05:41 -0500 (Wed, 27 Apr 2016) $ + * $Revision: 22529 $ + * + ******************************************************************************/ + +#include +#include "mxc_config.h" +#include "ioman.h" + +/******************************************************************************/ +int IOMAN_Config(const ioman_cfg_t *cfg) +{ + + if(cfg == NULL) { + return E_NULL_PTR; + } + + if ((cfg->req_reg == &MXC_IOMAN->i2cm0_req) || (cfg->req_reg == &MXC_IOMAN->i2cm1_req)) { + /* Request pin mapping */ + *cfg->req_reg = cfg->req_val.value; + + /* Check for acknowledgment */ + /* Mask the I2CM SCL push/pull bit because it does not have an ack bit*/ + if (*cfg->ack_reg != (cfg->req_val.value & ~(MXC_F_IOMAN_I2CM0_REQ_SCL_PUSH_PULL))) { + return E_BUSY; + } + } else { + if (*cfg->ack_reg != cfg->req_val.value) { + /* Request pin mapping */ + *cfg->req_reg = cfg->req_val.value; + + /* Check for acknowledgment */ + if (*cfg->ack_reg != cfg->req_val.value) { + return E_BUSY; + } + } + } + + return E_NO_ERROR; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/ioman.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/ioman.h new file mode 100644 index 00000000000..e005786d29c --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/ioman.h @@ -0,0 +1,288 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-06-14 15:52:19 -0500 (Tue, 14 Jun 2016) $ + * $Revision: 23326 $ + * + ******************************************************************************/ + +/** + * @file ioman.h + * @brief IOMAN provides IO Management to the device. The functions in this + * API enable requesting port pin assignment and release for all peripherals + * with external I/O. Port pin mapping support is included for peripherals + * that can support more than one pin mapping in a package. + */ + +#ifndef _IOMAN_H_ +#define _IOMAN_H_ + +#include "mxc_config.h" +#include "ioman_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***** Definitions *****/ + +/** @brief Aliases for IOMAN package mapping field values. Refer to the + * User's Guide for pinouts for each mapping. + */ +typedef enum { + IOMAN_MAP_UNUSED = 0, /**< Pin is not used */ + IOMAN_MAP_A = 0, /**< Pin Mapping A */ + IOMAN_MAP_B = 1, /**< Pin Mapping B */ +} +ioman_map_t; + +/** @brief Typing of IOMAN Req and Ack register fields */ +typedef union { + uint32_t value; + mxc_ioman_spix_req_t spix; /**< SPIX IOMAN configuration struct */ + mxc_ioman_uart0_req_t uart; /**< UART IOMAN configuration struct, see mxc_ioman_uart0_req_t */ + mxc_ioman_i2cm0_req_t i2cm; /**< I2C Master 0 IOMAN configuration struct, see mxc_ioman_i2cm0_req_t */ + mxc_ioman_i2cs_req_t i2cs; /**< I2C Slave IOMAN configuration struct, see mxc_ioman_i2cs_req_t */ + mxc_ioman_spim0_req_t spim0; /**< SPI Master 0 IOMAN configuration struct, see mxc_ioman_spim0_req_t */ + mxc_ioman_spim1_req_t spim1; /**< SPI Master 1 IOMAN configuration struct, see mxc_ioman_spim1_req_t */ + mxc_ioman_spim2_req_t spim2; /**< SPI Master 2 IOMAN configuration struct, see mxc_ioman_spim1_req_t */ + mxc_ioman_spis_req_t spis; /**< SPI Slave IOMAN configuration struct, see mxc_ioman_spis_req_t */ + mxc_ioman_owm_req_t owm; /**< 1-Wire Master IOMAN configuration struct, see mxc_ioman_owm_req_t */ +} ioman_req_t; + +/** @brief IOMAN configuration object */ +typedef struct { + volatile uint32_t *req_reg; /** Pointer to an IOMAN request register */ + volatile uint32_t *ack_reg; /** Pointer to an IOMAN acknowledge register */ + ioman_req_t req_val; /** IOMAN request register value, see ioman_req_t */ +} ioman_cfg_t; + + +/***** Function Prototypes *****/ + +/** + * @brief Configure the IO Manager using the specified configuration object. + * @param cfg IOMAN configuration object + * @returns E_NO_ERROR Configuration successful + */ +int IOMAN_Config(const ioman_cfg_t *cfg); + +/** + * @brief Create an IOMAN configuration object for the SPI XIP module. Call IOMAN_Config with this object. + * @param core Request (1) or release (0) SPIX core external pins + * @param ss0 Request (1) or release (0) slave select 0 active out + * @param ss1 Request (1) or release (0) slave select 1 active out + * @param ss2 Request (1) or release (0) slave select 2 active out + * @param quad Request (1) or release (0) quad IO + * @param fast Request (1) or release (0) fast mode + * @returns io_man_cfg_t IOMAN configuration object for the SPI XIP module. + */ +ioman_cfg_t IOMAN_SPIX(int core, int ss0, int ss1, int ss2, int quad, int fast); + +/** + * @brief Create an IOMAN configuration object for a UART module. Call IOMAN_Config with this object. + * @param idx Index of the UART module + * @param io_map Set the pin mapping for RX/TX pins, see ioman_map_t + * @param cts_map Set the pin mapping for CTS pin, see ioman_map_t + * @param rts_map Set the pin mapping for RTS pin, see ioman_map_t + * @param io_en Request (1) or release (0) RX and TX pins + * @param cts_en Request (1) or release (0) CTS pin + * @param rts_en Request (1) or release (0) RTS pin + * @returns ioman_cfg_t IOMAN configuration object for the UART module + */ +ioman_cfg_t IOMAN_UART(int idx, ioman_map_t io_map, ioman_map_t cts_map, ioman_map_t rts_map, int io_en, int cts_en, int rts_en); + +/** + * @brief Create an IOMAN configuration object for the I2CM module. Call IOMAN_Config with this object. + * @param idx Index of the I2CM module + * @param io_en Request (1) or release (0) the I/O for the I2CM0 module + * @param scl_mode Set SCL in Push/Pull mode (1) or open-drain (0). + * @returns ioman_cfg_t IOMAN configuration object for the I2CM0 module. + */ +ioman_cfg_t IOMAN_I2CM(int idx, int io_en, int scl_mode); + +/** + * @brief Create an IOMAN configuration object for an I2C slave module. Call IOMAN_Config with this object. + * @param map Select the pin mapping for all configured pins, see ioman_map_t + * @param io_en Request (1) or release (0) the I/O for this module + * @returns ioman_cfg_t IOMAN configuration object for the I2CS module + */ +ioman_cfg_t IOMAN_I2CS(ioman_map_t map, int io_en); + +/** + * @brief Create an IOMAN configuration object for a SPI Master (SPIM) module. Call IOMAN_Config with this object. + * @param io_en Request (1) or release (0) the core IO for the module + * @param ss0 Request (1) or release (0) slave select 0 + * @param ss1 Request (1) or release (0) slave select 1 + * @param ss2 Request (1) or release (0) slave select 2 + * @param ss3 Request (1) or release (0) slave select 3 + * @param ss4 Request (1) or release (0) slave select 4 + * @param quad Request (1) or release (0) quad IO + * @param fast Request (1) or release (0) fast mode + * @returns ioman_cfg_t IOMAN configuration object for an SPIM0 module + */ +ioman_cfg_t IOMAN_SPIM0(int io_en, int ss0, int ss1, int ss2, int ss3, int ss4, int quad, int fast); + +/** + * @brief Create an IOMAN configuration object for a SPIM module. Call IOMAN_Config with this object. + * @param io_en Request (1) or release (0) the core IO for the module + * @param ss0 Request (1) or release (0) slave select 0 + * @param ss1 Request (1) or release (0) slave select 1 + * @param ss2 Request (1) or release (0) slave select 2 + * @param quad Request (1) or release (0) quad IO + * @param fast Request (1) or release (0) fast mode + * @returns ioman_cfg_t IOMAN configuration object for the SPIM1 module. + */ +ioman_cfg_t IOMAN_SPIM1(int io_en, int ss0, int ss1, int ss2, int quad, int fast); + +/** + * @brief Create an IOMAN configuration object for a SPI module. Call IOMAN_Config with this object. + * @param io_en Request (1) or release (0) the core IO for the module + * @param ss0 Request (1) or release (0) slave select 0 + * @param ss1 Request (1) or release (0) slave select 1 + * @param ss2 Request (1) or release (0) slave select 2 + * @param sr0 Request (1) or release (0) slave ready 0 + * @param sr1 Request (1) or release (0) slave ready 1 + * @param fast Request (1) or release (0) fast mode + * @returns ioman_cfg_t IOMAN configuration object for the SPIM2 module + */ +ioman_cfg_t IOMAN_SPIM2(int io_en, int ss0, int ss1, int ss2, int sr0, int sr1, int quad, int fast); + +/** + * @brief Create an IOMAN configuration object for a SPI module. Call IOMAN_Config with this object. + * @param io_en Request (1) or release (0) the core IO for the module + * @param quad Request (1) or release (0) quad IO + * @param fast Request (1) or release (0) fast mode + * @returns ioman_cfg_t IOMAN configuration object for the SPIM2 module + */ +ioman_cfg_t IOMAN_SPIS(int io_en, int quad, int fast); + +/** + * @brief Create an IOMAN configuration object for the 1-Wire Master module. Call IOMAN_Config with this object. + * @param io_en Request (1) or release (0) the core IO for the module + * @param epu Request (1) or release (0) external pullup + * @returns ioman_cfg_t IOMAN configuration object for the OWM module + */ +ioman_cfg_t IOMAN_OWM(int io_en, int epu); + +/** + * @} + */ + +/******************************************************************************/ +/* All the function prototypes above are implemented as macros below. The + * above prototypes are for simplicity in doxygen. + */ +#define IOMAN_SPIX(c, ss0, ss1, ss2, q, f) { \ + .req_reg = &MXC_IOMAN->spix_req, \ + .ack_reg = &MXC_IOMAN->spix_ack, \ + .req_val.spix = { .core_io_req = c, \ + .ss0_io_req = ss0, \ + .ss1_io_req = ss1, \ + .ss2_io_req = ss2, \ + .quad_io_req = q, \ + .fast_mode = f } } + +#define IOMAN_UART(i, im, cm, rm, ien, cen, ren) { \ + .req_reg = (uint32_t*)((unsigned int)(&MXC_IOMAN->uart0_req) + (i * 2*sizeof(uint32_t))), \ + .ack_reg = (uint32_t*)((unsigned int)(&MXC_IOMAN->uart0_ack) + (i * 2*sizeof(uint32_t))), \ + .req_val.uart = { .io_map = im, \ + .cts_map = cm, \ + .rts_map = rm, \ + .io_req = ien, \ + .cts_io_req = cen, \ + .rts_io_req = ren } } + +#define IOMAN_I2CM(i, ien, scl_mode) { \ + .req_reg = (uint32_t*)((unsigned int)(&MXC_IOMAN->i2cm0_req) + (i * 2*sizeof(uint32_t))), \ + .ack_reg = (uint32_t*)((unsigned int)(&MXC_IOMAN->i2cm0_ack) + (i * 2*sizeof(uint32_t))), \ + .req_val.i2cm = { .mapping_req = ien, \ + .scl_push_pull = scl_mode } } + +#define IOMAN_I2CS(m, ien) { \ + .req_reg = &MXC_IOMAN->i2cs_req, \ + .ack_reg = &MXC_IOMAN->i2cs_ack, \ + .req_val.i2cs = { .io_sel = m, \ + .mapping_req = ien } } + +#define IOMAN_SPIM0(io, ss0, ss1, ss2, ss3, ss4, q, f) { \ + .req_reg = &MXC_IOMAN->spim0_req, \ + .ack_reg = &MXC_IOMAN->spim0_ack, \ + .req_val.spim0 = { .core_io_req = io, \ + .ss0_io_req = ss0, \ + .ss1_io_req = ss1, \ + .ss2_io_req = ss2, \ + .ss3_io_req = ss3, \ + .ss4_io_req = ss4, \ + .quad_io_req = q, \ + .fast_mode = f } } + +#define IOMAN_SPIM1(io, ss0, ss1, ss2, q, f) { \ + .req_reg = &MXC_IOMAN->spim1_req, \ + .ack_reg = &MXC_IOMAN->spim1_ack, \ + .req_val.spim1 = { .core_io_req = io, \ + .ss0_io_req = ss0, \ + .ss1_io_req = ss1, \ + .ss2_io_req = ss2, \ + .quad_io_req = q, \ + .fast_mode = f } } + +#define IOMAN_SPIM2(io, ss0, ss1, ss2, sr0, sr1, q, f) { \ + .req_reg = &MXC_IOMAN->spim2_req, \ + .ack_reg = &MXC_IOMAN->spim2_ack, \ + .req_val.spim2 = { .mapping_req = 0, \ + .core_io_req = io, \ + .ss0_io_req = ss0, \ + .ss1_io_req = ss1, \ + .ss2_io_req = ss2, \ + .sr0_io_req = sr0, \ + .sr1_io_req = sr1, \ + .quad_io_req = q, \ + .fast_mode = f } } + +#define IOMAN_SPIS(io, q, f) { \ + .req_reg = &MXC_IOMAN->spis_req, \ + .ack_reg = &MXC_IOMAN->spis_ack, \ + .req_val.spis = { .core_io_req = io, \ + .quad_io_req = q, \ + .fast_mode = f } } + +#define IOMAN_OWM(io, p) { \ + .req_reg = &MXC_IOMAN->owm_req, \ + .ack_reg = &MXC_IOMAN->owm_ack, \ + .req_val.owm = { .mapping_req = io, \ + .epu_io_req = p } } + +#ifdef __cplusplus +} +#endif + +#endif /* _IOMAN_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.c new file mode 100644 index 00000000000..fd1a0889e31 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.c @@ -0,0 +1,413 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-05-06 14:27:28 -0500 (Fri, 06 May 2016) $ + * $Revision: 22742 $ + * ******************************************************************************/ + +/***** Includes *****/ +#include "mxc_config.h" +#include "mxc_assert.h" +#include "lp.h" +#include "ioman_regs.h" + +/***** Definitions *****/ + +#ifndef LP0_PRE_HOOK +#define LP0_PRE_HOOK +#endif +#ifndef LP1_PRE_HOOK +#define LP1_PRE_HOOK +#endif +#ifndef LP1_POST_HOOK +#define LP1_POST_HOOK +#endif + +/***** Globals *****/ + +/***** Functions *****/ + +/* Clear all wake-up configuration */ +void LP_ClearWakeUpConfig(void) +{ + /* Clear GPIO WUD event and configuration registers, globally */ + MXC_PWRSEQ->reg1 |= (MXC_F_PWRSEQ_REG1_PWR_CLR_IO_EVENT_LATCH | + MXC_F_PWRSEQ_REG1_PWR_CLR_IO_CFG_LATCH); + MXC_PWRSEQ->reg1 &= ~(MXC_F_PWRSEQ_REG1_PWR_CLR_IO_EVENT_LATCH | + MXC_F_PWRSEQ_REG1_PWR_CLR_IO_CFG_LATCH); + + /* Mask off all wake-up sources */ + MXC_PWRSEQ->msk_flags &= ~(MXC_F_PWRSEQ_MSK_FLAGS_PWR_IOWAKEUP | + MXC_F_PWRSEQ_MSK_FLAGS_PWR_USB_PLUG_WAKEUP | + MXC_F_PWRSEQ_MSK_FLAGS_PWR_USB_REMOVE_WAKEUP | + MXC_F_PWRSEQ_MSK_FLAGS_RTC_CMPR0 | + MXC_F_PWRSEQ_MSK_FLAGS_RTC_CMPR1 | + MXC_F_PWRSEQ_MSK_FLAGS_RTC_PRESCALE_CMP | + MXC_F_PWRSEQ_MSK_FLAGS_RTC_ROLLOVER); +} + +/* Clear wake-up flags */ +unsigned int LP_ClearWakeUpFlags(void) +{ + unsigned int flags_tmp; + + /* Get flags */ + flags_tmp = MXC_PWRSEQ->flags; + + /* Clear GPIO WUD event registers, globally */ + MXC_PWRSEQ->reg1 |= (MXC_F_PWRSEQ_REG1_PWR_CLR_IO_EVENT_LATCH); + MXC_PWRSEQ->reg1 &= ~(MXC_F_PWRSEQ_REG1_PWR_CLR_IO_EVENT_LATCH); + + /* Clear power sequencer event flags (write-1-to-clear) */ + MXC_PWRSEQ->flags = flags_tmp; + + return flags_tmp; +} + +/* Configure the selected pin for wake-up detect */ +int LP_ConfigGPIOWakeUpDetect(const gpio_cfg_t *gpio, unsigned int act_high, lp_pu_pd_select_t wk_pu_pd) +{ + int result = E_NO_ERROR; + unsigned int pin; + + /* Check that port and pin are within range */ + MXC_ASSERT(gpio->port < MXC_GPIO_NUM_PORTS); + MXC_ASSERT(gpio->mask > 0); + + /* Ports 0-3 are controlled by wud_req0, while 4-7 are controlled by wud_req1 */ + if (gpio->port < 4) { + MXC_IOMAN->wud_req0 |= (gpio->mask << (gpio->port << 3)); + if (MXC_IOMAN->wud_ack0 != MXC_IOMAN->wud_req0) { /* Order of volatile access does not matter here */ + result = E_BUSY; + } + } else if (gpio->port < 8) { + MXC_IOMAN->wud_req1 |= (gpio->mask << ((gpio->port - 4) << 3)); + if (MXC_IOMAN->wud_ack1 != MXC_IOMAN->wud_req1) { /* Order of volatile access does not matter here */ + result = E_BUSY; + } + } else { + return E_NOT_SUPPORTED; + } + + if (result == E_NO_ERROR) { + + for (pin = 0; pin < MXC_GPIO_MAX_PINS_PER_PORT; pin++) { + + if (gpio->mask & (1 << pin)) { + + /* Enable modifications to WUD configuration */ + MXC_PWRMAN->wud_ctrl = MXC_F_PWRMAN_WUD_CTRL_CTRL_ENABLE; + + /* Select pad in WUD control */ + /* Note: Pads are numbered from 0-48; {0-7} => {P0.0-P0.7}, {8-15} => {P1.0-P1.7}, etc. */ + MXC_PWRMAN->wud_ctrl |= (gpio->port * 8) + pin; + + /* Configure sense level on this pad */ + MXC_PWRMAN->wud_ctrl |= (MXC_E_PWRMAN_PAD_MODE_ACT_HI_LO << MXC_F_PWRMAN_WUD_CTRL_PAD_MODE_POS); + + if (act_high) { + /* Select active high with PULSE0 (backwards from what you'd expect) */ + MXC_PWRMAN->wud_pulse0 = 1; + } else { + /* Select active low with PULSE1 (backwards from what you'd expect) */ + MXC_PWRMAN->wud_pulse1 = 1; + } + + /* Clear out the pad mode */ + MXC_PWRMAN->wud_ctrl &= ~(MXC_F_PWRMAN_WUD_CTRL_PAD_MODE); + + /* Select this pad to have the wake-up function enabled */ + MXC_PWRMAN->wud_ctrl |= (MXC_E_PWRMAN_PAD_MODE_CLEAR_SET << MXC_F_PWRMAN_WUD_CTRL_PAD_MODE_POS); + + /* Activate with PULSE1 */ + MXC_PWRMAN->wud_pulse1 = 1; + + if (wk_pu_pd != LP_NO_PULL) { + /* Select weak pull-up/pull-down on this pad while in LP1 */ + MXC_PWRMAN->wud_ctrl |= (MXC_E_PWRMAN_PAD_MODE_WEAK_HI_LO << MXC_F_PWRMAN_WUD_CTRL_PAD_MODE_POS); + + /* Again, logic is opposite of what you'd expect */ + if (wk_pu_pd == LP_WEAK_PULL_UP) { + MXC_PWRMAN->wud_pulse0 = 1; + } else { + MXC_PWRMAN->wud_pulse1 = 1; + } + } + + /* Disable configuration each time, required by hardware */ + MXC_PWRMAN->wud_ctrl = 0; + } + } + } + + /* Disable configuration */ + MXC_IOMAN->wud_req0 = 0; + MXC_IOMAN->wud_req1 = 0; + + /* Enable IOWakeup, as there is at least 1 GPIO pin configured as a wake source */ + MXC_PWRSEQ->msk_flags |= MXC_F_PWRSEQ_MSK_FLAGS_PWR_IOWAKEUP; + + return result; +} + +uint8_t LP_IsGPIOWakeUpSource(const gpio_cfg_t *gpio) +{ + uint8_t gpioWokeUp = 0; + + /* Check that port and pin are within range */ + MXC_ASSERT(gpio->port < MXC_GPIO_NUM_PORTS); + MXC_ASSERT(gpio->mask > 0); + + /* Ports 0-3 are wud_seen0, while 4-7 are wud_seen1*/ + if (gpio->port < 4) { + gpioWokeUp = (MXC_PWRMAN->wud_seen0 >> (gpio->port << 3)) & gpio->mask; + } else if (gpio->port < 8) { + gpioWokeUp = (MXC_PWRMAN->wud_seen1 >> ((gpio->port - 4) << 3)) & gpio->mask; + } else { + return E_NOT_SUPPORTED; + } + + return gpioWokeUp; +} + +int LP_ClearGPIOWakeUpDetect(const gpio_cfg_t *gpio) +{ + int result = E_NO_ERROR; + unsigned int pin; + + /* Check that port and pin are within range */ + MXC_ASSERT(gpio->port < MXC_GPIO_NUM_PORTS); + MXC_ASSERT(gpio->mask > 0); + + /* Ports 0-3 are controlled by wud_req0, while 4-7 are controlled by wud_req1*/ + if (gpio->port < 4) { + MXC_IOMAN->wud_req0 |= (gpio->mask << (gpio->port << 3)); + if (MXC_IOMAN->wud_ack0 != MXC_IOMAN->wud_req0) { /* Order of volatile access does not matter here */ + result = E_BUSY; + } + } else if (gpio->port < 8) { + MXC_IOMAN->wud_req1 |= (gpio->mask << ((gpio->port - 4) << 3)); + if (MXC_IOMAN->wud_ack1 != MXC_IOMAN->wud_req1) { /* Order of volatile access does not matter here */ + result = E_BUSY; + } + } else { + return E_NOT_SUPPORTED; + } + + if (result == E_NO_ERROR) { + for (pin = 0; pin < MXC_GPIO_MAX_PINS_PER_PORT; pin++) { + if (gpio->mask & (1 << pin)) { + + /* Enable modifications to WUD configuration */ + MXC_PWRMAN->wud_ctrl = MXC_F_PWRMAN_WUD_CTRL_CTRL_ENABLE; + + /* Select pad in WUD control */ + /* Note: Pads are numbered from 0-48; {0-7} => {P0.0-P0.7}, {8-15} => {P1.0-P1.7}, etc. */ + MXC_PWRMAN->wud_ctrl |= (gpio->port * 8) + pin; + + /* Clear out the pad mode */ + MXC_PWRMAN->wud_ctrl &= ~(MXC_F_PWRMAN_WUD_CTRL_PAD_MODE); + + /* Select the wake up function on this pad */ + MXC_PWRMAN->wud_ctrl |= (MXC_E_PWRMAN_PAD_MODE_CLEAR_SET << MXC_F_PWRMAN_WUD_CTRL_PAD_MODE_POS); + + /* disable wake up with PULSE0 */ + MXC_PWRMAN->wud_pulse0 = 1; + + /* Disable configuration each time, required by hardware */ + MXC_PWRMAN->wud_ctrl = 0; + } + } + } + + /* Disable configuration */ + MXC_IOMAN->wud_req0 = 0; + MXC_IOMAN->wud_req1 = 0; + + return result; +} + +int LP_ConfigUSBWakeUp(unsigned int plug_en, unsigned int unplug_en) +{ + /* Enable or disable wake on USB plug-in */ + if (plug_en) { + MXC_PWRSEQ->msk_flags |= MXC_F_PWRSEQ_MSK_FLAGS_PWR_USB_PLUG_WAKEUP; + } else { + MXC_PWRSEQ->msk_flags &= ~(MXC_F_PWRSEQ_MSK_FLAGS_PWR_USB_PLUG_WAKEUP); + } + + /* Enable or disable wake on USB unplug */ + if (unplug_en) { + MXC_PWRSEQ->msk_flags |= MXC_F_PWRSEQ_MSK_FLAGS_PWR_USB_REMOVE_WAKEUP; + } else { + MXC_PWRSEQ->msk_flags &= ~(MXC_F_PWRSEQ_MSK_FLAGS_PWR_USB_REMOVE_WAKEUP); + } + + return E_NO_ERROR; +} + +int LP_ConfigRTCWakeUp(unsigned int comp0_en, unsigned int comp1_en, + unsigned int prescale_cmp_en, unsigned int rollover_en) +{ + /* Note: MXC_PWRSEQ.pwr_misc[0] should be set to have the mask be active low */ + + /* Enable or disable wake on RTC Compare 0 */ + if (comp0_en) { + MXC_PWRSEQ->msk_flags |= MXC_F_PWRSEQ_FLAGS_RTC_CMPR0; + + } else { + MXC_PWRSEQ->msk_flags &= ~(MXC_F_PWRSEQ_FLAGS_RTC_CMPR0); + } + + /* Enable or disable wake on RTC Compare 1 */ + if (comp1_en) { + MXC_PWRSEQ->msk_flags |= MXC_F_PWRSEQ_FLAGS_RTC_CMPR1; + + } else { + MXC_PWRSEQ->msk_flags &= ~(MXC_F_PWRSEQ_FLAGS_RTC_CMPR1); + } + + /* Enable or disable wake on RTC Prescaler */ + if (prescale_cmp_en) { + MXC_PWRSEQ->msk_flags |= MXC_F_PWRSEQ_FLAGS_RTC_PRESCALE_CMP; + + } else { + MXC_PWRSEQ->msk_flags &= ~(MXC_F_PWRSEQ_FLAGS_RTC_PRESCALE_CMP); + } + + /* Enable or disable wake on RTC Rollover */ + if (rollover_en) { + MXC_PWRSEQ->msk_flags |= MXC_F_PWRSEQ_FLAGS_RTC_ROLLOVER; + + } else { + MXC_PWRSEQ->msk_flags &= ~(MXC_F_PWRSEQ_FLAGS_RTC_ROLLOVER); + } + + return E_NO_ERROR; +} + + +int LP_EnterLP2(void) +{ + /* Clear SLEEPDEEP bit to avoid LP1/LP0 entry*/ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + /* Go into LP2 mode and wait for an interrupt to wake the processor */ + __WFI(); + + return E_NO_ERROR; +} + +int LP_EnterLP1(void) +{ + /* Turn on retention controller */ + MXC_PWRSEQ->retn_ctrl0 |= MXC_F_PWRSEQ_RETN_CTRL0_RETN_CTRL_EN; + + /* Clear the firstboot bit, which is generated by a POR event and locks out LPx modes */ + MXC_PWRSEQ->reg0 &= ~(MXC_F_PWRSEQ_REG0_PWR_FIRST_BOOT); + + /* Set the LP1 select bit so CPU goes to LP1 during SLEEPDEEP */ + MXC_PWRSEQ->reg0 |= MXC_F_PWRSEQ_REG0_PWR_LP1; + + /* The SLEEPDEEP bit will cause a WFE() to trigger LP0/LP1 (depending on ..._REG0_PWR_LP1 state) */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* Performance-measurement hook, may be defined as nothing */ + LP1_PRE_HOOK; + + /* Dummy read to make sure SSB writes are complete */ + MXC_PWRSEQ->reg0; + + /* Enter LP1 -- sequence is per instructions from ARM, Ltd. */ + __SEV(); + __WFE(); + __WFE(); + + /* Performance-measurement hook, may be defined as nothing */ + LP1_POST_HOOK; + + /* Clear SLEEPDEEP bit */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + /* No error */ + return E_NO_ERROR; +} + +void LP_EnterLP0(void) +{ + /* Turn off Auto GPIO Freeze/UnFreeze in sleep modes */ + MXC_PWRSEQ->reg1 &= ~MXC_F_PWRSEQ_REG1_PWR_AUTO_MBUS_GATE; + + /* Disable interrupts, ok not to save state as exit LP0 is a reset */ + __disable_irq(); + + /* Clear the firstboot bit, which is generated by a POR event and locks out LPx modes */ + MXC_PWRSEQ->reg0 &= ~(MXC_F_PWRSEQ_REG0_PWR_FIRST_BOOT); + + /* Turn off retention controller */ + MXC_PWRSEQ->retn_ctrl0 &= ~(MXC_F_PWRSEQ_RETN_CTRL0_RETN_CTRL_EN); + + /* Turn off retention regulator */ + MXC_PWRSEQ->reg0 &= ~(MXC_F_PWRSEQ_REG0_PWR_RETREGEN_RUN | MXC_F_PWRSEQ_REG0_PWR_RETREGEN_SLP); + + /* LP0 ONLY to eliminate ~50nA of leakage on VDD12 */ + MXC_PWRSEQ->reg1 |= MXC_F_PWRSEQ_REG1_PWR_SRAM_NWELL_SW; + + /* Clear the LP1 select bit so CPU goes to LP0 during SLEEPDEEP */ + MXC_PWRSEQ->reg0 &= ~(MXC_F_PWRSEQ_REG0_PWR_LP1); + + /* The SLEEPDEEP bit will cause a WFE() to trigger LP0/LP1 (depending on ..._REG0_PWR_LP1 state) */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* Performance-measurement hook, may be defined as nothing */ + LP0_PRE_HOOK; + + /* Freeze GPIO using MBUS so that it doesn't change while digital core is alseep */ + MXC_PWRSEQ->reg1 |= MXC_F_PWRSEQ_REG1_PWR_MBUS_GATE; + + /* Dummy read to make sure SSB writes are complete */ + MXC_PWRSEQ->reg0; + + /* Go into LP0 -- sequence is per instructions from ARM, Ltd. */ + __SEV(); + __WFE(); + __WFE(); + + /* Catch the case where this code does not properly sleep */ + /* Unfreeze the GPIO by clearing MBUS_GATE (always safe to do) */ + MXC_PWRSEQ->reg1 &= ~(MXC_F_PWRSEQ_REG1_PWR_MBUS_GATE); + MXC_ASSERT_FAIL(); + while (1) { + __NOP(); + } + + /* Does not actually return */ +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.h new file mode 100644 index 00000000000..1c1e73846e1 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.h @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-23 10:22:39 -0500 (Wed, 23 Mar 2016) $ + * $Revision: 22053 $ + * + ******************************************************************************/ + +/** + * @file lp.h + * @brief This is the high level API for the Lower Power + */ + +#ifndef _LP_H_ +#define _LP_H_ + +#include "gpio.h" +#include "pwrman_regs.h" +#include "pwrseq_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***** Definitions *****/ +/** + * @brief Enumerations for pull-up and pull-downs + * + */ +typedef enum { + LP_WEAK_PULL_DOWN = -1, + LP_NO_PULL = 0, + LP_WEAK_PULL_UP = 1 +} +lp_pu_pd_select_t; + +/***** Function Prototypes *****/ + +/** + * @brief Gets the first boot flag + * + * @returns 0 if FIRST_BOOT was not set, or 1 if FIRST_BOOT was set + */ +__STATIC_INLINE unsigned int LP_IsFirstBoot() +{ + return ((MXC_PWRSEQ->reg0 & MXC_F_PWRSEQ_REG0_PWR_FIRST_BOOT) >> MXC_F_PWRSEQ_REG0_PWR_FIRST_BOOT_POS); +} + +/** + * @brief Clears the first boot flag + * + */ +__STATIC_INLINE void LP_ClearFirstBoot() +{ + MXC_PWRSEQ->reg0 &= ~MXC_F_PWRSEQ_REG0_PWR_FIRST_BOOT; +} + +/** + * @brief Determines of program woke up from LP0 + * + * @returns 0 if not woken up from LP0, or 1 if woken from LP0 + */ +__STATIC_INLINE unsigned int LP_IsLP0WakeUp() +{ + //POR should be set and first boot clear + if((MXC_PWRMAN->pwr_rst_ctrl & MXC_F_PWRMAN_PWR_RST_CTRL_POR) && + ((MXC_PWRSEQ->reg0 & MXC_F_PWRSEQ_REG0_PWR_FIRST_BOOT) == 0)) + return 1; + else + return 0; + +} + +__STATIC_INLINE unsigned int LP_GetWakeUpFlags(void) +{ + return MXC_PWRSEQ->flags; +} +/** + * @brief Clear ALL wake-up configuration on all pins. Disables wake-up entirely. + */ +void LP_ClearWakeUpConfig(void); + +/** + * @brief Read wake-up flags, clear flags, and return to caller. + * @returns Wake-up flags from Power Sequencer + */ +unsigned int LP_ClearWakeUpFlags(void); + +/** + * @brief This function configures one GPIO pin to wake the processor from LP0 or LP1. + * It is not used for LP2 wake-up, as normal GPIO interrupt processing is active in that mode. + * @param gpio GPIO pointer describing the port and pin for selected wake-up source + * @param act_high If non-zero, the signal is configured for active high wake-up. Otherwise, active low. + * @param wk_pu_pd Selection for the 1 Meg ohm pull-up or pull-down on this pin, see #lp_pu_pd_select_t + * @returns #E_NO_ERROR on success, error if unsuccessful. + */ +int LP_ConfigGPIOWakeUpDetect(const gpio_cfg_t *gpio, unsigned int act_high, lp_pu_pd_select_t wk_pu_pd); + +/** + * @brief Clear the wake-up configuration on one specific GPIO pin + * @param gpio GPIO pointer describing the port and pin for selected wake-up source + * @returns #E_NO_ERROR on success, error if unsuccessful. + */ +int LP_ClearGPIOWakeUpDetect(const gpio_cfg_t *gpio); + +/** + * @brief Check if a specific gpio triggered the wake up + * @param gpio GPIO pointer describing the port and pin(s) + * @returns 0 = gpio passed in did not trigger a wake up + * nonzero = at least one of the gpio passed in triggered a wake up + * the bit set represents which pin is the wake up source + */ +uint8_t LP_IsGPIOWakeUpSource(const gpio_cfg_t *gpio); + +/** + * @brief Wake on USB plug or unplug + * @param plug_en set to 1 to enable wake-up when USB VBUS is detected + * @param unplug_en set to 1 to enable wake-up when USB VBUS disappears + * @returns #E_NO_ERROR on success, error if unsuccessful. + */ +int LP_ConfigUSBWakeUp(unsigned int plug_en, unsigned int unplug_en); + +/** + * @brief Wake on any enabled event signal from RTC + * @param comp0_en set to 1 to enable wake-up when RTC Comparison 0 is set + * @param comp1_en set to 1 to enable wake-up when RTC Comparison 1 is set + * @param prescale_cmp_en set to 1 to enable wake-up when RTC Prescaler Compare is set + * @param rollover_en set to 1 to enable wake-up when RTC Roll-over is set + * @returns #E_NO_ERROR on success, error if unsuccessful. + */ +int LP_ConfigRTCWakeUp(unsigned int comp0_en, unsigned int comp1_en, unsigned int prescale_cmp_en, unsigned int rollover_en); + +/** + * @brief Enter LP2 power-saving mode + * @returns #E_NO_ERROR on success, error if unsuccessful. + */ +int LP_EnterLP2(void); + +/** + * @brief Enter LP1 mode, which saves CPU state and SRAM. Execution resumes after this call. + * @note Interrupts should be globally disabled before calling this function. + * @returns #E_NO_ERROR on success, error if unsuccessful. + */ +int LP_EnterLP1(void); + +/** + * @brief Enter the lowest-possible power mode, known as LP0. SRAM contents are lost. + * Waking up from LP0 is like a system reset. This function does not return. + * @note Interrupts are globally disabled upon entering this function. + */ +void LP_EnterLP0(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _LP_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/maa.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/maa.c new file mode 100644 index 00000000000..efa64e64c69 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/maa.c @@ -0,0 +1,236 @@ +/** + * @file maa.c + * @brief Modular Arithmetic Accelerator (MAA) API Function Implementations. + */ +/* ***************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + **************************************************************************** */ + +/* **** Includes **** */ +#include +#include "mxc_assert.h" +#include "mxc_lock.h" +#include "mxc_sys.h" +#include "maa.h" + +/** + * @ingroup maa + * @{ + */ + +///@cond +#define maa_is_running() (MXC_MAA->ctrl & MXC_F_MAA_CTRL_START ? 1 : 0) + +/** + * Macro that translates from #mxc_maa_reg_select_t to a pointer for MAA memory operations. + */ +#define UMAA_REGFILE_TO_ADDR(base, x) ((base + (MXC_MAA_HALF_SIZE * x))) + +/** + * Macro that adjusts the pointer so that it is pointing to the last 32-bit word in the maa (sub-)segment + */ +#define UMAA_ADDR_INDEX_LAST_32BIT(x) ((uint8_t *)x + (MXC_MAA_HALF_SIZE-4)) +///@endcond + + +/* ************************************************************************* */ +mxc_maa_ret_t MAA_Init(void) +{ + SYS_MAA_Init(); + + return MXC_E_MAA_OK; +} + +/* ************************************************************************* */ +mxc_maa_ret_t MAA_WipeRAM(void) +{ + /* Check for running MAA */ + if (maa_is_running()) { + return MXC_E_MAA_ERR; + } + + /* Clear register files */ + memset((void *)MXC_MAA_MEM->seg0, 0, sizeof(MXC_MAA_MEM->seg0)); + memset((void *)MXC_MAA_MEM->seg1, 0, sizeof(MXC_MAA_MEM->seg1)); + memset((void *)MXC_MAA_MEM->seg2, 0, sizeof(MXC_MAA_MEM->seg2)); + memset((void *)MXC_MAA_MEM->seg3, 0, sizeof(MXC_MAA_MEM->seg3)); + memset((void *)MXC_MAA_MEM->seg4, 0, sizeof(MXC_MAA_MEM->seg4)); + memset((void *)MXC_MAA_MEM->seg5, 0, sizeof(MXC_MAA_MEM->seg5)); + + return MXC_E_MAA_OK; +} + +/* ************************************************************************* */ +mxc_maa_ret_t MAA_Load(mxc_maa_reg_select_t regfile, const uint8_t *data, unsigned int size, mxc_maa_endian_select_t flag) +{ + uint32_t *maaptr; + uint32_t fill; + unsigned int zerotmp; + + if ((regfile > MXC_E_REG_51) || (size > MXC_MAA_REG_SIZE)) { + /* Out of range */ + return MXC_E_MAA_ERR; + } + + if (flag == MXC_MAA_F_MEM_REVERSE) { + /* This is not currently implemented */ + return MXC_E_MAA_ERR; + } + + maaptr = (uint32_t *)UMAA_REGFILE_TO_ADDR(MXC_BASE_MAA_MEM, regfile); + + /* + * MAA (sub-)segments must be loaded with zero pad to a 64-bit boundary, or the "garbage bits" + * will case erroneous results. + */ + /* Find the ceiling for the closest 64-bit boundary based on the selected MAWS */ + zerotmp = (((MXC_MAA->maws & MXC_F_MAA_MAWS_MODLEN) >> MXC_F_MAA_MAWS_MODLEN_POS) + 63) & 0xfc0; + /* Convert to bytes */ + zerotmp /= 8; + + /* Fill uMAA memory in long word sized chunks */ + while (size > 3) { + *maaptr++ = (data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0]; + data += 4; + size -= 4; + zerotmp = (zerotmp > 4) ? (zerotmp - 4) : 0; + } + + /* Remainder */ + if (size) { + fill = data[0]; + fill |= ((size > 1) ? (data[1] << 8) : 0); + fill |= ((size > 2) ? (data[2] << 16) : 0); + *maaptr++ = fill; + + /* We just filled 4 bytes in this section */ + zerotmp = (zerotmp > 4) ? (zerotmp - 4) : 0; + } + + /* Wipe the remaining "garbage bits" */ + while (zerotmp) { + *maaptr++ = 0; + zerotmp = (zerotmp > 4) ? (zerotmp - 4) : 0; + } + + return MXC_E_MAA_OK; +} + +/* ************************************************************************* */ +mxc_maa_ret_t MAA_Unload(mxc_maa_reg_select_t regfile, uint8_t *data, unsigned int size, mxc_maa_endian_select_t flag) +{ + uint32_t *maaptr; + uint32_t fill; + + if ((regfile > MXC_E_REG_51) || (size > MXC_MAA_REG_SIZE)) { + /* Out of range */ + return MXC_E_MAA_ERR; + } + + if (flag == MXC_MAA_F_MEM_REVERSE) { + /* This is not currently implemented */ + return MXC_E_MAA_ERR; + } + + maaptr = (uint32_t *)UMAA_REGFILE_TO_ADDR(MXC_BASE_MAA_MEM, regfile); + + /* Unload uMAA memory in long word sized chunks */ + while (size > 3) { + fill = *maaptr++; + data[0] = fill & 0xff; + data[1] = (fill >> 8) & 0xff; + data[2] = (fill >> 16) & 0xff; + data[3] = (fill >> 24) & 0xff; + data += 4; + size -= 4; + } + + /* Remainder */ + if (size) { + fill = *maaptr; + data[0] = fill & 0xff; + if (size > 1) { + data[1] = (fill >> 8) & 0xff; + } + if (size > 2) { + data[2] = (fill >> 16) & 0xff; + } + } + + return MXC_E_MAA_OK; +} + +/* ************************************************************************* */ +mxc_maa_ret_t MAA_Run(mxc_maa_operation_t op, + mxc_maa_reg_select_t al, mxc_maa_reg_select_t bl, + mxc_maa_reg_select_t rl, mxc_maa_reg_select_t tl) +{ + if (maa_is_running()) { + /* Attempt to start the MAA while already running */ + return MXC_E_MAA_ERR; + } + + /* Clear out any previous flags */ + MXC_MAA->ctrl = 0x00000020; + + /* Construct memory segment selections, select operation, and start the uMAA */ + MXC_MAA->ctrl = (((al << MXC_F_MAA_CTRL_SEG_A_POS) & MXC_F_MAA_CTRL_SEG_A) | + ((bl << MXC_F_MAA_CTRL_SEG_B_POS) & MXC_F_MAA_CTRL_SEG_B) | + ((rl << MXC_F_MAA_CTRL_SEG_RES_POS) & MXC_F_MAA_CTRL_SEG_RES) | + ((tl << MXC_F_MAA_CTRL_SEG_TMP_POS) & MXC_F_MAA_CTRL_SEG_TMP) | + ((op << MXC_F_MAA_CTRL_OPSEL_POS) & MXC_F_MAA_CTRL_OPSEL) | + MXC_F_MAA_CTRL_START); + + /* Blocking wait for uMAA to complete. */ + while ((MXC_MAA->ctrl & MXC_F_MAA_CTRL_IF_DONE) == 0); + + if (MXC_MAA->ctrl & MXC_F_MAA_CTRL_IF_ERROR) { + /* MAA signaled error */ + return MXC_E_MAA_ERR; + } + + return MXC_E_MAA_OK; +} + +/* ************************************************************************* */ +mxc_maa_ret_t MAA_SetWordSize(unsigned int len) +{ + if ((len > MXC_MAA_REG_SIZE_BITS) || maa_is_running()) { + return MXC_E_MAA_ERR; + } + + /* Set bit length for calculation, and disable endian swap */ + MXC_MAA->maws = ((len << MXC_F_MAA_MAWS_MODLEN_POS) & MXC_F_MAA_MAWS_MODLEN); + + return MXC_E_MAA_OK; +} +/**@} end of ingroup maa */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/maa.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/maa.h new file mode 100644 index 00000000000..03c7d95cc14 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/maa.h @@ -0,0 +1,220 @@ +/** + * @file maa.h + * @brief Registers, Bit Masks and Bit Positions for the Modular Math + * Accelerator (MAA) module. + */ +/* ***************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-15 11:28:30 -0500 (Mon, 15 Aug 2016) $ + * $Revision: 24064 $ + * + **************************************************************************** */ + +/* Define to prevent redundant inclusion */ +#ifndef _MAA_H +#define _MAA_H + +/* **** Includes **** */ +#include + +#include "maa_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup maa MAA + * @ingroup periphlibs + * @details The API only supports synchronous operations due to the sensitive + * nature of the input and output data. + * @{ + */ + +/* **** Definitions **** */ + +/** + * Definition for the maximum MAA register size on this device in bytes, 128. + */ +#define MXC_MAA_REG_SIZE 0x80 +/** + * Definition for the maximum MAA register size on this device in bits, 1024. + */ +#define MXC_MAA_REG_SIZE_BITS (MXC_MAA_REG_SIZE << 3) + +/** + * @define Sub-register ("half size"), allowing 2x more operands in MAA at a time when MAWS <= MAX_SIZE/2 + */ +#define MXC_MAA_HALF_SIZE (MXC_MAA_REG_SIZE/2) + +/** Flags for MAA_Load() and MAA_Unload() */ +#define MXC_MAA_F_MEM_VERBATIM 0 +/** Flags for MAA_Load() and MAA_Unload() */ +#define MXC_MAA_F_MEM_REVERSE 1 + +/** + * Enumeration type for Segment and Sub-segment selection + */ +/* Warning: Do not change the assigned numbers/ordering without associated changes to UMAA_REGFILE_TO_ADDR(x) */ +typedef enum { + /* Register names when MAWS > 512 */ + MXC_E_REG_0 = 0, /**< Register name if MAA_MAWS > 512 */ + MXC_E_REG_1 = 2, /**< Register name if MAA_MAWS > 512 */ + MXC_E_REG_2 = 4, /**< Register name if MAA_MAWS > 512 */ + MXC_E_REG_3 = 6, /**< Register name if MAA_MAWS > 512 */ + MXC_E_REG_4 = 8, /**< Register name if MAA_MAWS > 512 */ + MXC_E_REG_5 = 10, /**< Register name if MAA_MAWS > 512 */ + /* Register names when MAWS < 512 */ + MXC_E_REG_00 = 0, /**< Register name if MAA_MAWS < 512 */ + MXC_E_REG_01 = 1, /**< Register name if MAA_MAWS < 512 */ + MXC_E_REG_10 = 2, /**< Register name if MAA_MAWS < 512 */ + MXC_E_REG_11 = 3, /**< Register name if MAA_MAWS < 512 */ + MXC_E_REG_20 = 4, /**< Register name if MAA_MAWS < 512 */ + MXC_E_REG_21 = 5, /**< Register name if MAA_MAWS < 512 */ + MXC_E_REG_30 = 6, /**< Register name if MAA_MAWS < 512 */ + MXC_E_REG_31 = 7, /**< Register name if MAA_MAWS < 512 */ + MXC_E_REG_40 = 8, /**< Register name if MAA_MAWS < 512 */ + MXC_E_REG_41 = 9, /**< Register name if MAA_MAWS < 512 */ + MXC_E_REG_50 = 10, /**< Register name if MAA_MAWS < 512 */ + MXC_E_REG_51 = 11 /**< Register name if MAA_MAWS < 512 */ +} mxc_maa_reg_select_t; + +/** + * Enumeration type for MAA operation select. + */ +typedef enum { + MXC_E_MAA_EXP = 0, /**< Exponentiate */ + MXC_E_MAA_SQR = 1, /**< Square */ + MXC_E_MAA_MUL = 2, /**< Multiply */ + MXC_E_MAA_SQRMUL = 3, /**< Square followed by Multiply */ + MXC_E_MAA_ADD = 4, /**< Addition */ + MXC_E_MAA_SUB = 5 /**< Subtraction */ +} mxc_maa_operation_t; + +/** + * Enumeration type to set special flags for loading & unloading data. + */ +typedef enum { + + MXC_E_MAA_VERBATIM = 0, /**< Copy bytes without reversal and right-justification */ + MXC_E_MAA_REVERSE /**< Reverse bytes and right-justify (bytes are loaded at the highest address, then descending) */ +} mxc_maa_endian_select_t; + +/** + * Enumeration type for MAA module specific return codes. + */ +typedef enum { + MXC_E_MAA_ERR = -1, /**< Error */ + MXC_E_MAA_OK = 0, /**< No Error */ + MXC_E_MAA_BUSY /**< MAA engine busy, try again later */ +} mxc_maa_ret_t; + +/** + * @brief Initialize the required clocks and enable the MAA peripheral + * module. + */ +mxc_maa_ret_t MAA_Init(void); + +/** + * @brief Erase all MAA register RAM + */ +mxc_maa_ret_t MAA_WipeRAM(void); + + +/** + * @brief Load the selected MAA register. + * + * @param regfile Selects the register to load. + * @param data Pointer to a data buffer to load into the register. + * @param size Size of the data to load. + * @param flag Reverse the data so that it will unload properly on + * little endian machines, see #mxc_maa_endian_select_t. + * + * @return #MXC_E_MAA_ERR if any parameter out of range. + * @return #MXC_E_MAA_BUSY if MAA registers are not currently accessible. + * @return #MXC_E_MAA_OK if the selected register is loaded correctly. + */ +mxc_maa_ret_t MAA_Load(mxc_maa_reg_select_t regfile, const uint8_t *data, unsigned int size, mxc_maa_endian_select_t flag); + +/** + * @brief Unload (copy from) the selected MAA register + * + * @param regfile Selects the register to unload. + * @param data Pointer to a buffer to store the unloaded data. + * @param size Maximum size of the data to unload. + * @param flag Reverse the data so that it will unload properly on + * little endian machines, see #mxc_maa_endian_select_t. + * @return #MXC_E_MAA_ERR if any parameter out of range. + * @return #MXC_E_MAA_BUSY if MAA registers are not currently accessible. + * @return #MXC_E_MAA_OK if the requested register data is copied correctly + * to @p data. + */ +mxc_maa_ret_t MAA_Unload(mxc_maa_reg_select_t regfile, uint8_t *data, unsigned int size, mxc_maa_endian_select_t flag); + +/** + * @brief Execute an MAA operation specified. + * + * @param op Operation to perform, see #mxc_maa_operation_t. + * @param al Segment to use for operand A, see #mxc_maa_reg_select_t. + * @param bl Segment to use for operand B. + * @param rl Segment which will hold result R after the operation is + * complete. + * @param tl Segment to use for temporary storage T. + * + * @return #MXC_E_MAA_ERR if any parameter out of range. + * @return #MXC_E_MAA_BUSY if MAA registers are not currently accessible. + * @return #MXC_E_MAA_OK if the operation completed. + */ +mxc_maa_ret_t MAA_Run(mxc_maa_operation_t op, \ + mxc_maa_reg_select_t al, mxc_maa_reg_select_t bl, \ + mxc_maa_reg_select_t rl, mxc_maa_reg_select_t tl); + +/** + * @brief Set the bit length of the modulus. + * + * @param len Modulus size in bits (ie. \f$ ln_2(modulus) \f$ ) + * + * @return #MXC_E_MAA_ERR if any parameter out of range. + * @return #MXC_E_MAA_BUSY if MAA registers are not currently accessible. + * @return #MXC_E_MAA_OK if the length is set as requested. + */ +mxc_maa_ret_t MAA_SetWordSize(unsigned int len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_assert.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_assert.c new file mode 100644 index 00000000000..8070c350881 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_assert.c @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-11 11:46:37 -0600 (Fri, 11 Mar 2016) $ + * $Revision: 21839 $ + * + ******************************************************************************/ + +/** + * @file mxc_assert.c + * @brief Source for assertion failure. + */ + +#include "mxc_config.h" + +/***** Includes *****/ + +/***** Definitions *****/ + +/***** Globals *****/ + +/***** Functions *****/ + +/******************************************************************************/ +__weak void mxc_assert(const char *expr, const char *file, int line) +{ + while(1) {} +} + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_assert.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_assert.h new file mode 100644 index 00000000000..a2720ace008 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_assert.h @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-11 11:46:37 -0600 (Fri, 11 Mar 2016) $ + * $Revision: 21839 $ + * + ******************************************************************************/ + +/** + * @file mxc_assert.h + * @brief Assertion checks for debugging. + */ + +#ifndef _MXC_ASSERT_H_ +#define _MXC_ASSERT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/***** Includes *****/ + +/***** Definitions *****/ + +#ifdef MXC_ASSERT_ENABLE +/* Use this to check that expr is true (non-zero) */ +#define MXC_ASSERT(expr) \ +if (!(expr)) \ +{ \ + mxc_assert(#expr, __FILE__, __LINE__); \ +} +/* Use this to fail without any expression checking */ +#define MXC_ASSERT_FAIL() mxc_assert("FAIL", __FILE__, __LINE__); +#else +#define MXC_ASSERT(expr) +#define MXC_ASSERT_FAIL() +#endif + +/***** Globals *****/ + +/***** Function Prototypes *****/ + +/** + * @brief Assert an error when the given expression fails during debugging. + * @param expr String with the expression that failed the assertion. + * @param req File containing the failed assertion. + * @param line Line number for the failed assertion. + * @note This is defined as a weak function. Can be overridden at the + * application layer to print the debugging information. + * printf("%s, file: %s, line %d \n", expr, file, line); + */ +void mxc_assert(const char *expr, const char *file, int line); + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_ASSERT_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_config.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_config.h new file mode 100644 index 00000000000..368abaf8546 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_config.h @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-11 12:50:27 -0600 (Fri, 11 Mar 2016) $ + * $Revision: 21840 $ + * + ******************************************************************************/ + +#ifndef _MXC_CONFIG_H +#define _MXC_CONFIG_H + +#include "mxc_device.h" +#include "mxc_errors.h" + +#endif /* _MXC_CONFIG_H */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_errors.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_errors.h new file mode 100644 index 00000000000..868dcdd119c --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_errors.h @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-05-18 13:19:43 -0500 (Wed, 18 May 2016) $ + * $Revision: 22894 $ + * + ******************************************************************************/ + +/** +* @file mxc_errors.h +* @brief List of Common Errors +* @note A Negative Error Convention is used to avoid conflict with positive +* Non-Error returns. +* +*/ + +#ifndef _ERRORS_H_ +#define _ERRORS_H_ + +/** No Error */ +#define E_NO_ERROR 0 +/** No Error, success */ +#define E_SUCCESS 0 +/** Pointer is NULL */ +#define E_NULL_PTR -1 +/** No such device */ +#define E_NO_DEVICE -2 +/** Parameter not acceptable */ +#define E_BAD_PARAM -3 +/** Value not valid or allowed */ +#define E_INVALID -4 +/** Module not initialized */ +#define E_UNINITIALIZED -5 +/** Busy now, try again later */ +#define E_BUSY -6 +/** Operation not allowed in current state */ +#define E_BAD_STATE -7 +/** Generic error */ +#define E_UNKNOWN -8 +/** General communications error */ +#define E_COMM_ERR -9 +/** Operation timed out */ +#define E_TIME_OUT -10 +/** Expected response did not occur */ +#define E_NO_RESPONSE -11 +/** Operations resulted in unexpected overflow */ +#define E_OVERFLOW -12 +/** Operations resulted in unexpected underflow */ +#define E_UNDERFLOW -13 +/** Data or resource not available at this time */ +#define E_NONE_AVAIL -14 +/** Event was shutdown */ +#define E_SHUTDOWN -15 +/** Event was aborted */ +#define E_ABORT -16 +/** The requested operation is not supported */ +#define E_NOT_SUPPORTED -17 + +#endif /* _ERRORS_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_lock.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_lock.h new file mode 100644 index 00000000000..28bb062f6ec --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_lock.h @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-11 11:46:37 -0600 (Fri, 11 Mar 2016) $ + * $Revision: 21839 $ + * + ******************************************************************************/ + +/** + * @file mxc_lock.h + * @brief Used to create exclusion for critical sections. + */ + +#ifndef _MXC_LOCK_H_ +#define _MXC_LOCK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/***** Includes *****/ +#include "mxc_config.h" + +/***** Definitions *****/ + +/***** Globals *****/ + +/***** Function Prototypes *****/ + +/** + * @brief Attempts to acquire the lock. + * @param lock Pointer to variable used for the lock. + * @param value Value to be place in the lock. Can not be 0. + * @details This in an interrupt safe function that can be used as a mutex. + The lock variable must remain in scope until the lock is released. + Will not block if another thread has acquired the lock. + * @returns E_NO_ERROR if everything successful, E_BUSY if lock is taken. + */ +__STATIC_INLINE int mxc_get_lock(uint32_t *lock, uint32_t value) +{ + do { + + // Return if the lock is taken by a different thread + if(__LDREXW((volatile unsigned long *)lock) != 0) { + return E_BUSY; + } + + // Attempt to take the lock + } while(__STREXW(value, (volatile unsigned long *)lock) != 0); + + // Do not start any other memory access until memory barrier is complete + __DMB(); + + return E_NO_ERROR; +} + +/** + * @brief Free the given lock. + * @param lock Pointer to variable used for the lock. + */ +__STATIC_INLINE void mxc_free_lock(uint32_t *lock) +{ + // Ensure memory operations complete before releasing lock + __DMB(); + *lock = 0; +} + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_LOCK_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_sys.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_sys.c new file mode 100644 index 00000000000..49bd5428e7b --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_sys.c @@ -0,0 +1,845 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-06-17 13:05:03 -0500 (Fri, 17 Jun 2016) $ + * $Revision: 23367 $ + * + ******************************************************************************/ + +#include +#include "mxc_config.h" +#include "mxc_assert.h" +#include "mxc_sys.h" +#include "ioman.h" +#include "clkman.h" +#include "pwrseq_regs.h" +#include "pwrman_regs.h" +#include "spix_regs.h" +#include "trim_regs.h" + +/***** Definitions *****/ +#define SYS_RTC_CLK 32768UL + +/******************************************************************************/ +uint32_t SYS_GetFreq(uint32_t clk_scale) +{ + uint32_t freq; + unsigned int clkdiv; + + if (clk_scale == MXC_V_CLKMAN_CLK_SCALE_DISABLED) { + freq = 0; + } else { + clkdiv = 1 << (clk_scale - 1); + freq = SystemCoreClock / clkdiv; + } + + return freq; +} + +/******************************************************************************/ +uint32_t SYS_CPU_GetFreq(void) +{ + return SYS_GetFreq(CLKMAN_GetClkScale(CLKMAN_CLK_CPU)); +} + +/******************************************************************************/ +int SYS_ADC_Init(void) +{ + /* Power up the ADC AFE, enable clocks */ + MXC_PWRMAN->pwr_rst_ctrl |= MXC_F_PWRMAN_PWR_RST_CTRL_AFE_POWERED; + MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_ADC_CLOCK_ENABLE; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SYS_AES_Init(void) +{ + /* Set up clocks for AES block */ + /* Enable crypto ring oscillator, which is used by all TPU components (AES, uMAA, etc.) */ + CLKMAN_CryptoClockEnable(1); + + /* Change prescaler to /1 */ + CLKMAN_SetClkScale(CLKMAN_CRYPTO_CLK_AES, CLKMAN_SCALE_DIV_1); + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SYS_GPIO_Init(void) +{ + if (CLKMAN_GetClkScale(CLKMAN_CLK_GPIO) == CLKMAN_SCALE_DISABLED) { + CLKMAN_SetClkScale(CLKMAN_CLK_GPIO, CLKMAN_SCALE_DIV_1); + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SYS_UART_Init(mxc_uart_regs_t *uart, const uart_cfg_t *uart_cfg, const sys_cfg_uart_t *sys_cfg) +{ + static int subsequent_call = 0; + int err, idx; + clkman_scale_t clk_scale; + uint32_t min_baud; + + if(sys_cfg == NULL) + return E_NULL_PTR; + + if (sys_cfg->clk_scale != CLKMAN_SCALE_AUTO) { + CLKMAN_SetClkScale(CLKMAN_CLK_UART, sys_cfg->clk_scale); + } else if (!subsequent_call) { + /* This clock divider is shared amongst all UARTs. Only change it if it + * hasn't already been configured. UART_Init() will check for validity + * for this baudrate. + */ + subsequent_call = 1; + + /* Setup the clock divider for the given baud rate */ + clk_scale = CLKMAN_SCALE_DISABLED; + do { + min_baud = ((SystemCoreClock >> clk_scale++) / (16 * (MXC_F_UART_BAUD_BAUD_DIVISOR >> MXC_F_UART_BAUD_BAUD_DIVISOR_POS))); + } while (uart_cfg->baud < min_baud && clk_scale < CLKMAN_SCALE_AUTO); + + /* check if baud rate cannot be reached */ + if(uart_cfg->baud < min_baud) + return E_BAD_STATE; + + CLKMAN_SetClkScale(CLKMAN_CLK_UART, clk_scale); + } + + if ((err = IOMAN_Config(&sys_cfg->io_cfg)) != E_NO_ERROR) { + return err; + } + + /* Reset the peripheral */ + idx = MXC_UART_GET_IDX(uart); + MXC_PWRMAN->peripheral_reset |= (MXC_F_PWRMAN_PERIPHERAL_RESET_UART0 << idx); + MXC_PWRMAN->peripheral_reset &= ~((MXC_F_PWRMAN_PERIPHERAL_RESET_UART0 << idx)); + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SYS_UART_Shutdown(mxc_uart_regs_t *uart) +{ + int err; + int idx = MXC_UART_GET_IDX(uart); + ioman_cfg_t io_cfg = (ioman_cfg_t)IOMAN_UART(idx, 0, 0, 0, 0, 0, 0); + + if ((err = IOMAN_Config(&io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +uint32_t SYS_UART_GetFreq(mxc_uart_regs_t *uart) +{ + return SYS_GetFreq(CLKMAN_GetClkScale(CLKMAN_CLK_UART)); +} + +/******************************************************************************/ +int SYS_I2CM_Init(mxc_i2cm_regs_t *i2cm, const sys_cfg_i2cm_t *cfg) +{ + int err; + + if(cfg == NULL) + return E_NULL_PTR; + + CLKMAN_SetClkScale(CLKMAN_CLK_I2CM, cfg->clk_scale); + MXC_CLKMAN->i2c_timer_ctrl = 1; + + if ((err = IOMAN_Config(&cfg->io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SYS_I2CM_Shutdown(mxc_i2cm_regs_t *i2cm) +{ + int err; + int idx = MXC_I2CM_GET_IDX(i2cm); + ioman_cfg_t io_cfg = (ioman_cfg_t)IOMAN_I2CM(idx, 0, 0); + + if ((err = IOMAN_Config(&io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +uint32_t SYS_I2CM_GetFreq(mxc_i2cm_regs_t *i2cm) +{ + return SYS_GetFreq(CLKMAN_GetClkScale(CLKMAN_CLK_I2CM)); +} + +/******************************************************************************/ +int SYS_I2CS_Init(mxc_i2cs_regs_t *i2cs, const sys_cfg_i2cs_t *cfg) +{ + int err; + + if(cfg == NULL) + return E_NULL_PTR; + + CLKMAN_SetClkScale(CLKMAN_CLK_I2CS, cfg->clk_scale); + MXC_CLKMAN->i2c_timer_ctrl = 1; + + if ((err = IOMAN_Config(&cfg->io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SYS_I2CS_Shutdown(mxc_i2cs_regs_t *i2cs) +{ + int err; + ioman_cfg_t io_cfg = (ioman_cfg_t)IOMAN_I2CS(0, 0); + + if ((err = IOMAN_Config(&io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +uint32_t SYS_I2CS_GetFreq(mxc_i2cs_regs_t *i2cs) +{ + uint32_t freq, clkdiv; + + if (CLKMAN_GetClkScale(CLKMAN_CLK_I2CS) == MXC_V_CLKMAN_CLK_SCALE_DISABLED) { + freq = 0; + } else { + clkdiv = 1 << (CLKMAN_GetClkScale(CLKMAN_CLK_I2CS) - 1); + freq = (SystemCoreClock / clkdiv); + } + + return freq; +} + +/******************************************************************************/ +int SYS_SPIM_Init(mxc_spim_regs_t *spim, const spim_cfg_t *spim_cfg, const sys_cfg_spim_t *sys_cfg) +{ + int err, idx; + clkman_scale_t clk_scale; + uint32_t max_baud; + + if(sys_cfg == NULL) + return E_NULL_PTR; + + idx = MXC_SPIM_GET_IDX(spim); + + if (sys_cfg->clk_scale != CLKMAN_SCALE_AUTO) { + if(spim_cfg->baud > ((SystemCoreClock >> (sys_cfg->clk_scale - 1))/2)) { + return E_BAD_PARAM; + } + CLKMAN_SetClkScale((clkman_clk_t)(CLKMAN_CLK_SPIM0 + idx), sys_cfg->clk_scale); + } else { + + if(spim_cfg->baud > (SystemCoreClock/2)) { + return E_BAD_PARAM; + } + + /* Setup the clock divider for the given baud rate */ + clk_scale = CLKMAN_SCALE_DISABLED; + do { + max_baud = ((SystemCoreClock >> clk_scale++) / 2); + } while (spim_cfg->baud < max_baud && clk_scale < CLKMAN_SCALE_AUTO); + + if(clk_scale == CLKMAN_SCALE_AUTO) { + clk_scale--; + } + + CLKMAN_SetClkScale((clkman_clk_t)(CLKMAN_CLK_SPIM0 + idx), clk_scale); + } + + if ((err = IOMAN_Config(&sys_cfg->io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SYS_SPIM_Shutdown(mxc_spim_regs_t *spim) +{ + int err; + int idx = MXC_SPIM_GET_IDX(spim); + ioman_cfg_t io_cfg; + + switch(idx) { + case 0: + io_cfg = (ioman_cfg_t)IOMAN_SPIM0(0, 0, 0, 0, 0, 0, 0, 0); + break; + case 1: + io_cfg = (ioman_cfg_t)IOMAN_SPIM1(0, 0, 0, 0, 0, 0); + break; + case 2: + io_cfg = (ioman_cfg_t)IOMAN_SPIM2(0, 0, 0, 0, 0, 0, 0, 0); + break; + default: + return E_BAD_PARAM; + } + + if ((err = IOMAN_Config(&io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +uint32_t SYS_SPIM_GetFreq(mxc_spim_regs_t *spim) +{ + int idx = MXC_SPIM_GET_IDX(spim); + return SYS_GetFreq(CLKMAN_GetClkScale((clkman_clk_t)(CLKMAN_CLK_SPIM0 + idx))); +} + +/******************************************************************************/ +int SYS_SPIX_Init(const sys_cfg_spix_t *sys_cfg, uint32_t baud) +{ + int err; + clkman_scale_t clk_scale; + uint32_t min_baud; + + if (sys_cfg->clk_scale != CLKMAN_SCALE_AUTO) { + CLKMAN_SetClkScale((clkman_clk_t)(CLKMAN_CLK_SPIX), sys_cfg->clk_scale); + } else { + /* Setup the clock divider for the given baud rate */ + clk_scale = CLKMAN_SCALE_DISABLED; + do { + min_baud = ((SystemCoreClock >> clk_scale++) / (2 * + (MXC_F_SPIX_MASTER_CFG_SCK_HI_CLK >> MXC_F_SPIX_MASTER_CFG_SCK_HI_CLK_POS))); + } while (baud < min_baud && clk_scale < CLKMAN_SCALE_AUTO); + + /* check if baud rate cannot be reached */ + if(baud < min_baud) + return E_BAD_STATE; + + CLKMAN_SetClkScale((clkman_clk_t)(CLKMAN_CLK_SPIX), clk_scale); + } + + if ((err = IOMAN_Config(&sys_cfg->io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SYS_SPIX_Shutdown(void) +{ + int err; + ioman_cfg_t io_cfg = IOMAN_SPIX(0, 0, 0, 0, 0, 0); + + if ((err = IOMAN_Config(&io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +uint32_t SYS_SPIX_GetFreq(void) +{ + return SYS_GetFreq(CLKMAN_GetClkScale((clkman_clk_t)(CLKMAN_CLK_SPIX))); +} + +/******************************************************************************/ +int SYS_SPIS_Init(const sys_cfg_spis_t *sys_cfg) +{ + int err; + + if (sys_cfg->clk_scale != CLKMAN_SCALE_AUTO) { + CLKMAN_SetClkScale((clkman_clk_t)(CLKMAN_CLK_SPIS), sys_cfg->clk_scale); + } else { + CLKMAN_SetClkScale((clkman_clk_t)(CLKMAN_CLK_SPIS), CLKMAN_SCALE_DIV_1); + } + + if ((err = IOMAN_Config(&sys_cfg->io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SYS_SPIS_Shutdown(mxc_spis_regs_t *spis) +{ + int err; + ioman_cfg_t io_cfg = IOMAN_SPIS(0, 0, 0); + + if ((err = IOMAN_Config(&io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +uint32_t SYS_SPIS_GetFreq(mxc_spis_regs_t *spis) +{ + return SYS_GetFreq(CLKMAN_GetClkScale((clkman_clk_t)(CLKMAN_CLK_SPIS))); +} + +/******************************************************************************/ +int SYS_OWM_Init(mxc_owm_regs_t *owm, const sys_cfg_owm_t *sys_cfg) +{ + int err; + + if(sys_cfg == NULL) + return E_NULL_PTR; + + if (sys_cfg->clk_scale != CLKMAN_SCALE_AUTO) { + CLKMAN_SetClkScale(CLKMAN_CLK_OWM, sys_cfg->clk_scale); + } else { + CLKMAN_SetClkScale(CLKMAN_CLK_OWM, CLKMAN_SCALE_DIV_1); + } + + if ((err = IOMAN_Config(&sys_cfg->io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SYS_OWM_Shutdown(mxc_owm_regs_t *owm) +{ + int err; + + ioman_cfg_t io_cfg = IOMAN_OWM(0, 0); + + if ((err = IOMAN_Config(&io_cfg)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +uint32_t SYS_OWM_GetFreq(mxc_owm_regs_t *owm) +{ + return SYS_GetFreq(CLKMAN_GetClkScale(CLKMAN_CLK_OWM)); +} + +/******************************************************************************/ +uint32_t SYS_TMR_GetFreq(mxc_tmr_regs_t *tmr) +{ + return SystemCoreClock; +} + +/******************************************************************************/ +int SYS_TMR_Init(mxc_tmr_regs_t *tmr, const sys_cfg_tmr_t *cfg) +{ + int pin, gpio_index, tmr_index; + + if (cfg != NULL) { + /* Make sure the given GPIO mapps to the given TMR */ + for (pin = 0; pin < MXC_GPIO_MAX_PINS_PER_PORT; pin++) { + if(cfg->mask & (1 << pin)) { + gpio_index = (MXC_GPIO_MAX_PINS_PER_PORT * cfg->port) + pin; + tmr_index = gpio_index % MXC_CFG_TMR_INSTANCES; + + if(tmr_index == MXC_TMR_GET_IDX(tmr)) + return GPIO_Config(cfg); + else + return E_BAD_PARAM; + } + } + + return E_BAD_PARAM; + + } else { + return E_NO_ERROR; + } +} + +/******************************************************************************/ +uint32_t SYS_SysTick_GetFreq(void) +{ + /* Determine is using internal (SystemCoreClock) or external (32768) clock */ + if ( (SysTick->CTRL & SysTick_CTRL_CLKSOURCE_Msk) || !(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk)) { + return SystemCoreClock; + } else { + return SYS_RTC_CLK; + } +} + +/******************************************************************************/ +uint32_t SYS_PT_GetFreq(void) +{ + return SYS_GetFreq(CLKMAN_GetClkScale(CLKMAN_CLK_PT)); +} + +/******************************************************************************/ +void SYS_PT_Init(sys_pt_clk_scale clk_scale) +{ + /* setup clock divider for pulse train clock */ + CLKMAN_SetClkScale(CLKMAN_CLK_PT, clk_scale); +} + +/******************************************************************************/ +int SYS_PT_Config(mxc_pt_regs_t *pt, const sys_cfg_pt_t *cfg) +{ + int pt_index; + + /* Make sure the given GPIO mapps to the given PT */ + pt_index = MXC_PT_GET_IDX(pt); + if(pt_index < 0) { + return E_NOT_SUPPORTED; + } + + /* Even number port */ + if(cfg->port%2 == 0) { + /* Pin number should match PT number */ + if(!(cfg->mask & (0x1 << pt_index))) { + return E_NOT_SUPPORTED; + } + } else { + /* Pin number+8 should match PT */ + if(!((cfg->mask << 8) & (0x1 << pt_index))) { + return E_NOT_SUPPORTED; + } + } + + return GPIO_Config(cfg); +} + +/******************************************************************************/ +void SYS_USB_Enable(uint8_t enable) +{ + /* Enable USB clock */ + CLKMAN_ClockGate(CLKMAN_USB_CLOCK, enable); + + if(enable) { + /* Enable USB Power */ + MXC_PWRMAN->pwr_rst_ctrl |= MXC_F_PWRMAN_PWR_RST_CTRL_USB_POWERED; + } else { + /* Disable USB Power */ + MXC_PWRMAN->pwr_rst_ctrl &= ~MXC_F_PWRMAN_PWR_RST_CTRL_USB_POWERED; + } +} + +/******************************************************************************/ +int SYS_SysTick_Config(uint32_t ticks, int clk_src) +{ + + if(ticks == 0) + return E_BAD_PARAM; + + /* If SystemClock, call default CMSIS config and return */ + if (clk_src) { + return SysTick_Config(ticks); + } else { + /* External clock source requested + enable RTC clock in run mode*/ + MXC_PWRSEQ->reg0 |= (MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN); + + /* Disable SysTick Timer */ + SysTick->CTRL = 0; + /* Check reload value for valid */ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) { + /* Reload value impossible */ + return E_BAD_PARAM; + } + /* set reload register */ + SysTick->LOAD = ticks - 1; + + /* set Priority for Systick Interrupt */ + NVIC_SetPriority(SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); + + /* Load the SysTick Counter Value */ + SysTick->VAL = 0; + + /* Enable SysTick IRQ and SysTick Timer leaving clock source as external */ + SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; + + /* Function successful */ + return E_NO_ERROR; + } +} + +/******************************************************************************/ +int SYS_SysTick_Delay(uint32_t ticks) +{ + uint32_t cur_ticks, num_full, num_remain, previous_ticks, num_subtract, i; + uint32_t reload, value, ctrl; /* save/restore variables */ + + if(ticks == 0) + return E_BAD_PARAM; + + /* If SysTick is not enabled we can take it for our delay */ + if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk)) { + + /* Save current state in case it's disabled but already configured, restore at return.*/ + reload = SysTick->LOAD; + value = SysTick->VAL; + ctrl = SysTick->CTRL; + + /* get the number of ticks less than max RELOAD. */ + num_remain = ticks % SysTick_LOAD_RELOAD_Msk; + + /* if ticks is < Max SysTick Reload num_full will be 0, otherwise it will + give us the number of max SysTicks cycles required */ + num_full = (ticks - 1) / SysTick_LOAD_RELOAD_Msk; + + /* Do the required full systick countdowns */ + if (num_full) { + /* load the max count value into systick */ + SysTick->LOAD = SysTick_LOAD_RELOAD_Msk; + /* load the starting value */ + SysTick->VAL = 0; + /*enable SysTick counter with SystemClock source internal, immediately forces LOAD register into VAL register */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; + /* CountFlag will get set when VAL reaches zero */ + for (i = num_full; i > 0; i--) { + do { + cur_ticks = SysTick->CTRL; + } while (!(cur_ticks & SysTick_CTRL_COUNTFLAG_Msk)); + } + /* Disable systick */ + SysTick->CTRL = 0; + } + /* Now handle the remainder of ticks */ + if (num_remain) { + SysTick->LOAD = num_remain; + SysTick->VAL = 0; + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; + /* wait for countflag to get set */ + do { + cur_ticks = SysTick->CTRL; + } while (!(cur_ticks & SysTick_CTRL_COUNTFLAG_Msk)); + /* Disable systick */ + SysTick->CTRL = 0; + } + + /* restore original state of SysTick and return */ + SysTick->LOAD = reload; + SysTick->VAL = value; + SysTick->CTRL = ctrl; + + return E_NO_ERROR; + + } else { + /* SysTick is enabled + When SysTick is enabled count flag can not be used + and the reload can not be changed. + Do not read the CTRL register -> clears count flag */ + + /* Get the reload value for wrap/reload case */ + reload = SysTick->LOAD; + + /* Read the starting systick value */ + previous_ticks = SysTick->VAL; + + do { + /* get current SysTick value */ + cur_ticks = SysTick->VAL; + /* Check for wrap/reload of timer countval */ + if (cur_ticks > previous_ticks) { + /* subtract count to 0 (previous_ticks) and wrap (reload value - cur_ticks) */ + num_subtract = (previous_ticks + (reload - cur_ticks)); + } else { + /* standard case (no wrap) + subtract off the number of ticks since last pass */ + num_subtract = (previous_ticks - cur_ticks); + } + /* check to see if we are done. */ + if (num_subtract >= ticks) + return E_NO_ERROR; + else + ticks -= num_subtract; + /* cur_ticks becomes previous_ticks for next timer read. */ + previous_ticks = cur_ticks; + } while (ticks > 0); + /* Should not ever be reached */ + return E_NO_ERROR; + } +} + +/******************************************************************************/ +int SYS_RTC_Init(void) +{ + /* Enable power for RTC for all LPx states */ + MXC_PWRSEQ->reg0 |= (MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN | + MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP); + + /* Enable clock to synchronizers */ + CLKMAN_SetClkScale(CLKMAN_CLK_SYNC, CLKMAN_SCALE_DIV_1); + + return E_NO_ERROR; +} + +/******************************************************************************/ +void SYS_IOMAN_UseVDDIO(const gpio_cfg_t *cfg) +{ + unsigned int startbit = (cfg->port * 8); + volatile uint32_t *use_vddioh_reg = &MXC_IOMAN->use_vddioh_0 + (startbit / 32); + *use_vddioh_reg &= ~cfg->mask << (startbit % 32); +} + +/******************************************************************************/ +void SYS_IOMAN_UseVDDIOH(const gpio_cfg_t *cfg) +{ + unsigned int startbit = (cfg->port * 8); + volatile uint32_t *use_vddioh_reg = &MXC_IOMAN->use_vddioh_0 + (startbit / 32); + *use_vddioh_reg |= cfg->mask << (startbit % 32); +} + +/******************************************************************************/ +void SYS_WDT_Init(mxc_wdt_regs_t *wdt, const sys_cfg_wdt_t *cfg) +{ + + if(cfg->clk == CLKMAN_WDT_SELECT_NANO_RING_OSCILLATOR) { + /*enable nanoring in run mode */ + MXC_PWRSEQ->reg0 |= (MXC_F_PWRSEQ_REG0_PWR_NREN_RUN); + } else if(cfg->clk == CLKMAN_WDT_SELECT_32KHZ_RTC_OSCILLATOR) { + /*enabled RTC in run mode */ + MXC_PWRSEQ->reg0 |= (MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN); + } + + if(wdt == MXC_WDT0) { + /*select clock source */ + CLKMAN_WdtClkSelect(0, cfg->clk); + + /*Set scale of clock (only used for system clock as source) */ + CLKMAN_SetClkScale(CLKMAN_CLK_WDT0, cfg->clk_scale); + + /*Enable clock */ + CLKMAN_ClockGate(CLKMAN_WDT0_CLOCK, 1); + } else if (wdt == MXC_WDT1) { + /*select clock source */ + CLKMAN_WdtClkSelect(1, cfg->clk); + + /*Set scale of clock (only used for system clock as source) */ + CLKMAN_SetClkScale(CLKMAN_CLK_WDT1, cfg->clk_scale); + + /*Enable clock */ + CLKMAN_ClockGate(CLKMAN_WDT1_CLOCK, 1); + } +} + +/******************************************************************************/ +void SYS_PRNG_Init(void) +{ + /* Start crypto ring, unconditionally */ + CLKMAN_CryptoClockEnable(1); + + /* If we find the dividers in anything other than off, don't touch them */ + if (CLKMAN_GetClkScale(CLKMAN_CRYPTO_CLK_PRNG) == CLKMAN_SCALE_DISABLED) { + /* Div 1 mode */ + CLKMAN_SetClkScale(CLKMAN_CRYPTO_CLK_PRNG, CLKMAN_SCALE_DIV_1); + } + + if (CLKMAN_GetClkScale(CLKMAN_CLK_PRNG) == CLKMAN_SCALE_DISABLED) { + /* Div 1 mode */ + CLKMAN_SetClkScale(CLKMAN_CLK_PRNG, CLKMAN_SCALE_DIV_1); + } +} + +/******************************************************************************/ +void SYS_MAA_Init(void) +{ + /* Start crypto ring, unconditionally */ + CLKMAN_CryptoClockEnable(1); + + /* If we find the dividers in anything other than off, don't touch them */ + if (CLKMAN_GetClkScale(CLKMAN_CRYPTO_CLK_MAA) == CLKMAN_SCALE_DISABLED) { + /* Div 1 mode */ + CLKMAN_SetClkScale(CLKMAN_CRYPTO_CLK_MAA, CLKMAN_SCALE_DIV_1); + } +} + +/******************************************************************************/ +uint32_t SYS_SRAM_GetSize(void) +{ + uint32_t memSize; + + /* Read TRIM value*/ + int SRAMtrim = (MXC_TRIM->reg10_mem_size & MXC_F_TRIM_REG10_MEM_SIZE_SRAM) >> MXC_F_TRIM_REG10_MEM_SIZE_SRAM_POS; + + /* Decode trim value into memory size in bytes */ + switch(SRAMtrim) { + case MXC_V_TRIM_REG10_MEM_SRAM_THREE_FOURTHS_SIZE: + memSize = (MXC_SRAM_FULL_MEM_SIZE >> 2) * 3; + break; + + case MXC_V_TRIM_REG10_MEM_SRAM_HALF_SIZE: + memSize = MXC_SRAM_FULL_MEM_SIZE >> 1; + break; + + default: /* other values are FULL size */ + memSize = MXC_SRAM_FULL_MEM_SIZE; + break; + } + + /* Returns size in bytes */ + return memSize; +} + +/******************************************************************************/ +uint32_t SYS_FLASH_GetSize(void) +{ + uint32_t memSize; + + /* Read TRIM value */ + int FLASHtrim = (MXC_TRIM->reg10_mem_size & MXC_F_TRIM_REG10_MEM_SIZE_FLASH) >> MXC_F_TRIM_REG10_MEM_SIZE_FLASH_POS; + + /* Decode trim value into memory size in bytes*/ + switch(FLASHtrim) { + case MXC_V_TRIM_REG10_MEM_FLASH_THREE_FOURTHS_SIZE: + memSize = (MXC_FLASH_FULL_MEM_SIZE >> 2) * 3; + break; + case MXC_V_TRIM_REG10_MEM_FLASH_HALF_SIZE: + memSize = (MXC_FLASH_FULL_MEM_SIZE >> 1); + break; + case MXC_V_TRIM_REG10_MEM_FLASH_THREE_EIGHTHS_SIZE: + memSize = (MXC_FLASH_FULL_MEM_SIZE >> 3) * 3; + break; + case MXC_V_TRIM_REG10_MEM_FLASH_FOURTH_SIZE: + memSize = (MXC_FLASH_FULL_MEM_SIZE >> 2); + break; + default: /* other values are FULL size */ + memSize = MXC_FLASH_FULL_MEM_SIZE; + break; + } + + /* Returns size in bytes */ + return memSize; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_sys.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_sys.h new file mode 100644 index 00000000000..0a16ea1a385 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_sys.h @@ -0,0 +1,445 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-05-18 16:40:40 -0500 (Wed, 18 May 2016) $ + * $Revision: 22910 $ + * + ******************************************************************************/ + +/** + * @file mxc_sys.h + * @brief System level header file. + */ + +#ifndef _MXC_SYS_H_ +#define _MXC_SYS_H_ + +#include "mxc_config.h" +#include "clkman.h" +#include "ioman.h" +#include "gpio.h" +#include "i2cm_regs.h" +#include "i2cs_regs.h" +#include "tmr_regs.h" +#include "pt_regs.h" +#include "wdt_regs.h" +#include "owm_regs.h" +#include "spis_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***** Definitions *****/ + +/** @brief System Configuration Object */ +typedef struct { + clkman_scale_t clk_scale; /** desired clock scale value for the peripheral */ + ioman_cfg_t io_cfg; /** IOMAN configuration object */ +} sys_cfg_t; + +/** @brief Watchdog System Configuration Object */ +typedef struct { + clkman_wdt_clk_select_t clk; /** select the clock source for the watchdog */ + clkman_scale_t clk_scale; /** desired clock scale value for the peripheral */ + /** clk_scale is only applied if the system clock is used as the clk */ +} sys_cfg_wdt_t; + +/** @brief UART System Configuration Object */ +typedef sys_cfg_t sys_cfg_uart_t; + +/** @brief I2CM System Configuration Object */ +typedef sys_cfg_t sys_cfg_i2cm_t; + +/** @brief I2CS System Configuration Object */ +typedef sys_cfg_t sys_cfg_i2cs_t; + +/** @brief SPIM System Configuration Object */ +typedef sys_cfg_t sys_cfg_spim_t; + +/** @brief SPIX System Configuration Object */ +typedef sys_cfg_t sys_cfg_spix_t; + +/** @brief SPIS System Configuration Object */ +typedef sys_cfg_t sys_cfg_spis_t; + +/** @brief OWM System Configuration Object */ +typedef sys_cfg_t sys_cfg_owm_t; + +/** @brief Timer System Configuration Object */ +typedef gpio_cfg_t sys_cfg_tmr_t; + +/** @brief Pulse Train System Configuration Object */ +typedef gpio_cfg_t sys_cfg_pt_t; +typedef clkman_scale_t sys_pt_clk_scale; + +/***** Include Files *****/ +/* These includes require the above types to be defined first */ +#include "uart.h" +#include "spim.h" + +/***** Function Prototypes *****/ + +/** + * @brief Get the frequency of a clock scaler + * @param clk_scale value of clk_scale field from clk_ctrl register + * @returns frequency in Hz + */ +uint32_t SYS_GetFreq(uint32_t clk_scale); + +/** + * @brief Get the frequency of the CPU + * @returns frequency in Hz + */ +uint32_t SYS_CPU_GetFreq(void); + +/** + * @brief System level initialization for ADC module. + * @returns E_NO_ERROR if everything is successful + */ +int SYS_ADC_Init(void); + +/** + * @brief System level initialization for AES module. + * @returns E_NO_ERROR if everything is successful + */ +int SYS_AES_Init(void); + +/** + * @brief System level initialization for GPIO module. + * @returns E_NO_ERROR if everything is successful + */ +int SYS_GPIO_Init(void); + +/** + * @brief System level initialization for UART module. + * @param uart Pointer to UART module registers + * @param uart_cfg UART configuration object + * @param sys_cfg System configuration object + * @returns E_NO_ERROR if everything is successful + */ +int SYS_UART_Init(mxc_uart_regs_t *uart, const uart_cfg_t *uart_cfg, const sys_cfg_uart_t *sys_cfg); + +/** + * @brief System level shutdown for UART module + * @param uart Pointer to UART module registers + * @returns E_NO_ERROR if everything is successful + */ +int SYS_UART_Shutdown(mxc_uart_regs_t *uart); + +/** + * @brief Get the frequency of the UART module source clock + * @param uart Pointer to UART module registers + * @returns frequency in Hz + */ +uint32_t SYS_UART_GetFreq(mxc_uart_regs_t *uart); + +/** + * @brief System level initialization for I2CM module. + * @param i2cm Pointer to I2CM module registers + * @param cfg System configuration object + * @returns E_NO_ERROR if everything is successful + */ +int SYS_I2CM_Init(mxc_i2cm_regs_t *i2cm, const sys_cfg_i2cm_t *cfg); + +/** + * @brief System level shutdown for I2CM module + * @param i2cm Pointer to I2CM module registers + * @returns E_NO_ERROR if everything is successful + */ +int SYS_I2CM_Shutdown(mxc_i2cm_regs_t *i2cm); + +/** + * @brief Get the frequency of the I2CM module source clock + * @param i2cm Pointer to I2CM module registers + * @returns frequency in Hz + */ +uint32_t SYS_I2CM_GetFreq(mxc_i2cm_regs_t *i2cm); + +/** + * @brief System level initialization for I2CS module. + * @param i2cs Pointer to I2CS module registers + * @param cfg System configuration object + * @returns E_NO_ERROR if everything is successful + */ +int SYS_I2CS_Init(mxc_i2cs_regs_t *i2cs, const sys_cfg_i2cs_t *cfg); + +/** + * @brief System level shutdown for I2CS module + * @param i2cs Pointer to I2CS module registers + * @returns E_NO_ERROR if everything is successful + */ +int SYS_I2CS_Shutdown(mxc_i2cs_regs_t *i2cs); + +/** + * @brief Get the frequency of the I2CS module source clock + * @param i2cs Pointer to I2CS module registers + * @returns frequency in Hz + */ +uint32_t SYS_I2CS_GetFreq(mxc_i2cs_regs_t *i2cs); + +/** + * @brief System level initialization for SPIM module. + * @param spim Pointer to SPIM module registers + * @param spim_cfg SPIM configuration object + * @param sys_cfg System configuration object + * @returns E_NO_ERROR if everything is successful + */ +int SYS_SPIM_Init(mxc_spim_regs_t *spim, const spim_cfg_t *spim_cfg, const sys_cfg_spim_t *sys_cfg); + +/** + * @brief System level shutdown for SPIM module + * @param spim Pointer to SPIM module registers + * @returns E_NO_ERROR if everything is successful + */ +int SYS_SPIM_Shutdown(mxc_spim_regs_t *spim); + +/** + * @brief Get the frequency of the SPIM module source clock + * @param spim Pointer to SPIM module registers + * @returns frequency in Hz + */ +uint32_t SYS_SPIM_GetFreq(mxc_spim_regs_t *spim); + +/** + * @brief System level initialization for SPIX module. + * @param sys_cfg System configuration object + * @param baud Baud rate for clock divider configuration + * @returns E_NO_ERROR if everything is successful + */ +int SYS_SPIX_Init(const sys_cfg_spix_t *sys_cfg, uint32_t baud); + +/** + * @brief System level shutdown for SPIX module + * @returns E_NO_ERROR if everything is successful + */ +int SYS_SPIX_Shutdown(void); + +/** + * @brief Get the frequency of the SPIX module source clock + * @returns frequency in Hz + */ +uint32_t SYS_SPIX_GetFreq(void); + +/** + * @brief System level initialization for SPIS module. + * @param sys_cfg System configuration object. + * @returns E_NO_ERROR if everything is successful. + */ +int SYS_SPIS_Init(const sys_cfg_spix_t *sys_cfg); + +/** + * @brief System level shutdown for SPIS module + * @returns E_NO_ERROR if everything is successful + */ +int SYS_SPIS_Shutdown(mxc_spis_regs_t *spis); + +/** + * @brief Get the frequency of the SPIS module source clock + * @returns frequency in Hz + */ +uint32_t SYS_SPIS_GetFreq(mxc_spis_regs_t *spis); + +/** + * @brief System level initialization for OWM module. + * @param owm Pointer to OWM module registers + * @param owm_cfg OWM configuration object + * @param sys_cfg System configuration object + * @returns E_NO_ERROR if everything is successful + */ +int SYS_OWM_Init(mxc_owm_regs_t *owm, const sys_cfg_owm_t *sys_cfg); + +/** + * @brief System level shutdown for OWM module + * @param owm Pointer to OWM module registers + * @returns E_NO_ERROR if everything is successful + */ +int SYS_OWM_Shutdown(mxc_owm_regs_t *owm); + +/** + * @brief Get the frequency of the OWM module source clock + * @param owm Pointer to OWM module registers + * @returns frequency in Hz + */ +uint32_t SYS_OWM_GetFreq(mxc_owm_regs_t *owm); + +/** + * @brief System level initialization for TMR module. + * @param tmr Pointer to TMR module registers + * @param cfg System configuration object + * @returns E_NO_ERROR if everything is successful + */ +int SYS_TMR_Init(mxc_tmr_regs_t *tmr, const sys_cfg_tmr_t *cfg); + +/** + * @brief Get the frequency of the TMR module source clock + * @param spim Pointer to TMR module registers + * @returns frequency in Hz + */ +uint32_t SYS_TMR_GetFreq(mxc_tmr_regs_t *tmr); + +/** + * @brief Get the frequency of the Pulse Train module source clock + * @returns frequency in Hz + */ +uint32_t SYS_PT_GetFreq(void); + +/** + * @brief Initialize the global pulse train clock scale + * @param clk_scale scale the system clock for the PT clock + */ +void SYS_PT_Init(sys_pt_clk_scale clk_scale); + +/** + * @brief System level initialization for Pulse Train module. + * @param pt Pointer to PT module registers + * @param cfg System configuration object + * @returns E_NO_ERROR if everything is successful + */ +int SYS_PT_Config(mxc_pt_regs_t *pt, const sys_cfg_pt_t *cfg); + +/** + * @brief System level initialization for USB device. + * @param enable 1 to enable the peripheral, 0 to disable. + */ +void SYS_USB_Enable(uint8_t enable); + +/** + * @brief System Tick Configuration Helper + * + * The function enables selection of the external clock source for the + * System Tick Timer. It initializes the System Timer and its interrupt, + * and starts the System Tick Timer. Counter is in free running mode to generate + * periodic interrupts. + + * @param ticks Number of ticks between two interrupts. + * @param clk_src Selects between default SystemClock or External Clock. + * - 0 Use external clock source + * - 1 SystemClock + * @return E_NO_ERROR Function succeeded. + * @return E_INVALID Invalid reload value requested. + * + * @see CLKMAN_SetRTOSMode(uint8_t enable) if using the external clock source to drive the System Tick Timer + * + */ +int SYS_SysTick_Config(uint32_t ticks, int clk_src); + +/** + * @brief Disable System Tick timer + * + * + */ +__STATIC_INLINE void SYS_SysTick_Disable(void) +{ + SysTick->CTRL = 0; +} + +/** + * @brief Delay a requested number of SysTick Timer Ticks. + * @param ticks Number of System Ticks to delay. + * @note This delay function is based on the clock used for the SysTick timer + * if the SysTick timer is enabled. If the SysTick timer is + * not enabled, the current SysTick registers are saved and the + * timer will use the SystemClock as the source for the delay. + * The delay is measured in clock ticks and is not based on the + * SysTick interval. + * @returns E_NO_ERROR if everything is successful + */ +int SYS_SysTick_Delay(uint32_t ticks); + +/** + * @brief Get the frequency of the SysTick Timer + * @returns frequency in Hz + */ +uint32_t SYS_SysTick_GetFreq(void); + +/** + * @brief Delay a requested number of microseconds. + * @param us Number of microseconds to delay. + * @note Calls SYS_SysTick_Delay. + */ +__STATIC_INLINE void SYS_SysTick_DelayUs(uint32_t us) +{ + SYS_SysTick_Delay((uint32_t)(((uint64_t)SYS_SysTick_GetFreq() * us) / 1000000)); +} + +/** + * @brief System level initialization for RTC module. + * @returns E_NO_ERROR if everything is successful + */ +int SYS_RTC_Init(void); + +/** + * @brief Select VDDIO for the specified GPIO pin. + */ +void SYS_IOMAN_UseVDDIO(const gpio_cfg_t *cfg); + +/** + * @brief Select VDDIOH for the specified GPIO pin. + */ +void SYS_IOMAN_UseVDDIOH(const gpio_cfg_t *cfg); + +/** + * @brief System level initialization for Watchdog module. + * @param wdt Pointer to Watchdog module registers + * @param cfg Watchdog System configuration object + */ +void SYS_WDT_Init(mxc_wdt_regs_t *wdt, const sys_cfg_wdt_t *cfg); + +/** + * @brief System level initialization for PRNG module. + * Enable crypto clock and set divisors to 1 if disabled + */ +void SYS_PRNG_Init(void); + +/** + * @brief System level initialization for MAA module. + * Enable crypto clock and set divisors to 1 if disabled + */ +void SYS_MAA_Init(void); + +/* + * @brief Gets the size of the SRAM + * @returns size of SRAM in bytes + */ +uint32_t SYS_SRAM_GetSize(void); + +/* + * @brief Gets the size of the Flash + * @returns size of Flash in bytes + */ +uint32_t SYS_FLASH_GetSize(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _MXC_SYS_H_*/ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/owm.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/owm.c new file mode 100644 index 00000000000..7647ec71cab --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/owm.c @@ -0,0 +1,591 @@ +/** + * @file owm.c + * @brief 1-Wire Master (OWM) API Function Implementations. + */ +/* ***************************************************************************** + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-14 10:08:53 -0500 (Mon, 14 Mar 2016) $ + * $Revision: 21855 $ + * + **************************************************************************** */ + +/* **** Includes **** */ +#include +#include "mxc_assert.h" +#include "mxc_sys.h" +#include "owm.h" + +/** + * @ingroup owm + * @{ + */ +///@cond +/* **** Definitions **** */ +#define OWM_CLK_FREQ 1000000 //1-Wire requires 1MHz clock + +/* **** Globals **** */ +int LastDiscrepancy; +int LastDeviceFlag; + +/* **** Functions **** */ +static uint8_t CalculateCRC8(uint8_t* data, int len); +static uint8_t update_crc8(uint8_t crc, uint8_t value); +///@endcond + + +/* ************************************************************************* */ +int OWM_Init(mxc_owm_regs_t *owm, const owm_cfg_t *cfg, const sys_cfg_owm_t *sys_cfg) +{ + int err = 0; + uint32_t owm_clk, clk_div = 0; + uint32_t ext_pu_mode = 0; + uint32_t ext_pu_polarity = 0; + + // Check the OWM register pointer is valid + MXC_ASSERT(MXC_OWM_GET_IDX(owm) >= 0); + + if(cfg == NULL) { + return E_NULL_PTR; + } + + // Set system level configurations + if ((err = SYS_OWM_Init(owm, sys_cfg)) != E_NO_ERROR) { + return err; + } + + // Configure clk divisor to get 1MHz OWM clk + owm_clk = SYS_OWM_GetFreq(owm); + + if(owm_clk == 0) { + return E_UNINITIALIZED; + } + + // Return error if clk doesn't divide evenly to 1MHz + if(owm_clk % OWM_CLK_FREQ) { + return E_NOT_SUPPORTED; + } + + clk_div = (owm_clk / (OWM_CLK_FREQ)); + + // Can not support lower frequencies + if(clk_div == 0) { + return E_NOT_SUPPORTED; + } + + // Select the PU mode and polarity based on cfg input + switch(cfg->ext_pu_mode) { + case OWM_EXT_PU_ACT_HIGH: + ext_pu_mode = MXC_V_OWM_CFG_EXT_PULLUP_MODE_USED; + ext_pu_polarity = MXC_V_OWM_CTRL_STAT_EXT_PULLUP_POL_ACT_HIGH; + break; + case OWM_EXT_PU_ACT_LOW: + ext_pu_mode = MXC_V_OWM_CFG_EXT_PULLUP_MODE_USED; + ext_pu_polarity = MXC_V_OWM_CTRL_STAT_EXT_PULLUP_POL_ACT_LOW; + break; + case OWM_EXT_PU_UNUSED: + ext_pu_mode = MXC_V_OWM_CFG_EXT_PULLUP_MODE_UNUSED; + ext_pu_polarity = MXC_V_OWM_CTRL_STAT_EXT_PULLUP_POL_ACT_HIGH; + break; + default: + return E_BAD_PARAM; + } + + // Set clk divisor + owm->clk_div_1us = (clk_div << MXC_F_OWM_CLK_DIV_1US_DIVISOR_POS) & MXC_F_OWM_CLK_DIV_1US_DIVISOR; + + // Set configuration + owm->cfg = (((cfg->int_pu_en << MXC_F_OWM_CFG_INT_PULLUP_ENABLE_POS) & MXC_F_OWM_CFG_INT_PULLUP_ENABLE) | + ((ext_pu_mode << MXC_F_OWM_CFG_EXT_PULLUP_MODE_POS) & MXC_F_OWM_CFG_EXT_PULLUP_MODE) | + ((cfg->long_line_mode << MXC_F_OWM_CFG_LONG_LINE_MODE) & MXC_F_OWM_CFG_LONG_LINE_MODE_POS)); + + owm->ctrl_stat = (((ext_pu_polarity << MXC_F_OWM_CTRL_STAT_EXT_PULLUP_POL_POS) & MXC_F_OWM_CTRL_STAT_EXT_PULLUP_POL) | + ((cfg->overdrive_spec << MXC_F_OWM_CTRL_STAT_OD_SPEC_MODE_POS) & MXC_F_OWM_CTRL_STAT_OD_SPEC_MODE)); + + // Clear all interrupt flags + owm->intfl = owm->intfl; + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +int OWM_Shutdown(mxc_owm_regs_t *owm) +{ + int err; + + // Disable and clear interrupts + owm->inten = 0; + owm->intfl = owm->intfl; + + // Release IO pins and disable clk + if ((err = SYS_OWM_Shutdown(owm)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +int OWM_Reset(mxc_owm_regs_t *owm) +{ + owm->intfl = MXC_F_OWM_INTFL_OW_RESET_DONE; // Clear the reset flag + owm->ctrl_stat |= MXC_F_OWM_CTRL_STAT_START_OW_RESET; // Generate a reset pulse + while((owm->intfl & MXC_F_OWM_INTFL_OW_RESET_DONE) == 0); // Wait for reset time slot to complete + + return (!!(owm->ctrl_stat & MXC_F_OWM_CTRL_STAT_PRESENCE_DETECT)); // Return presence pulse detect status +} + +/* ************************************************************************* */ +int OWM_TouchByte(mxc_owm_regs_t *owm, uint8_t data) +{ + owm->cfg &= ~MXC_F_OWM_CFG_SINGLE_BIT_MODE; // Set to 8 bit mode + owm->intfl = (MXC_F_OWM_INTFL_TX_DATA_EMPTY | MXC_F_OWM_INTFL_RX_DATA_READY); // Clear the flags + owm->data = (data << MXC_F_OWM_DATA_TX_RX_POS) & MXC_F_OWM_DATA_TX_RX; // Write data + while((owm->intfl & MXC_F_OWM_INTFL_TX_DATA_EMPTY) == 0); // Wait for data to be sent + while((owm->intfl & MXC_F_OWM_INTFL_RX_DATA_READY) == 0); // Wait for data to be read + + return (owm->data >> MXC_F_OWM_DATA_TX_RX_POS) & 0xFF; // Return the data read +} + +/* ************************************************************************* */ +int OWM_WriteByte(mxc_owm_regs_t *owm, uint8_t data) +{ + // Send one byte of data and verify the data sent = data parameter + return (OWM_TouchByte(owm, data) == data) ? E_NO_ERROR : E_COMM_ERR; +} + +/* ************************************************************************* */ +int OWM_ReadByte(mxc_owm_regs_t *owm) +{ + // Read one byte of data + return OWM_TouchByte(owm, 0xFF); +} + +/* ************************************************************************* */ +int OWM_TouchBit(mxc_owm_regs_t *owm, uint8_t bit) +{ + MXC_OWM->cfg |= MXC_F_OWM_CFG_SINGLE_BIT_MODE; // Set to 1 bit mode + owm->intfl = (MXC_F_OWM_INTFL_TX_DATA_EMPTY | MXC_F_OWM_INTFL_RX_DATA_READY); // Clear the flags + owm->data = (bit << MXC_F_OWM_DATA_TX_RX_POS) & MXC_F_OWM_DATA_TX_RX; // Write data + while((owm->intfl & MXC_F_OWM_INTFL_TX_DATA_EMPTY) == 0); // Wait for data to be sent + while((owm->intfl & MXC_F_OWM_INTFL_RX_DATA_READY) == 0); // Wait for data to be read + + return (owm->data >> MXC_F_OWM_DATA_TX_RX_POS) & 0x1; // Return the bit read +} + +/* ************************************************************************* */ +int OWM_WriteBit(mxc_owm_regs_t *owm, uint8_t bit) +{ + // Send a bit and verify the bit sent = bit parameter + return (OWM_TouchBit(owm, bit) == bit) ? E_NO_ERROR : E_COMM_ERR; +} + +/* ************************************************************************* */ +int OWM_ReadBit(mxc_owm_regs_t *owm) +{ + // Read a bit + return OWM_TouchBit(owm, 1); +} + +/* ************************************************************************* */ +int OWM_Write(mxc_owm_regs_t *owm, uint8_t* data, int len) +{ + int num = 0; + + owm->cfg &= ~MXC_F_OWM_CFG_SINGLE_BIT_MODE; // Set to 8 bit mode + + while(num < len) { // Loop for number of bytes to write + owm->intfl = (MXC_F_OWM_INTFL_TX_DATA_EMPTY | MXC_F_OWM_INTFL_RX_DATA_READY | MXC_F_OWM_INTEN_LINE_SHORT); // Clear the flags + owm->data = (data[num] << MXC_F_OWM_DATA_TX_RX_POS) & MXC_F_OWM_DATA_TX_RX; // Write data + while((owm->intfl & MXC_F_OWM_INTFL_TX_DATA_EMPTY) == 0); // Wait for data to be sent + while((owm->intfl & MXC_F_OWM_INTFL_RX_DATA_READY) == 0); // Wait for data to be read + + // Verify data sent is correct + if(owm->data != data[num]) { + return E_COMM_ERR; + } + + // Check error flag + if(owm->intfl & MXC_F_OWM_INTEN_LINE_SHORT) { + return E_COMM_ERR; // Wire was low before transaction + } + + num++; // Keep track of how many bytes written + } + + return num; // Return number of bytes written +} + +/* ************************************************************************* */ +int OWM_Read(mxc_owm_regs_t *owm, uint8_t* data, int len) +{ + int num = 0; + + owm->cfg &= ~MXC_F_OWM_CFG_SINGLE_BIT_MODE; // Set to 8 bit mode + + while(num < len) { // Loop for number of bytes to read + owm->intfl = (MXC_F_OWM_INTFL_TX_DATA_EMPTY | MXC_F_OWM_INTFL_RX_DATA_READY | MXC_F_OWM_INTEN_LINE_SHORT); // Clear the flags + owm->data = 0xFF; // Write 0xFF for a read + while((owm->intfl & MXC_F_OWM_INTFL_TX_DATA_EMPTY) == 0); // Wait for data to be sent + while((owm->intfl & MXC_F_OWM_INTFL_RX_DATA_READY) == 0); // Wait for data to be read + + // Check error flag + if(owm->intfl & MXC_F_OWM_INTEN_LINE_SHORT) { + return E_COMM_ERR; // Wire was low before transaction + } + + // Store read data into buffer + data[num] = (owm->data >> MXC_F_OWM_DATA_TX_RX_POS) & MXC_F_OWM_DATA_TX_RX; + + num++; // Keep track of how many bytes read + } + + return num; // Return number of bytes read +} + +/* ************************************************************************* */ +int OWM_ReadROM(mxc_owm_regs_t *owm, uint8_t* ROMCode) +{ + int num_read = 0; + + // Send reset and wait for presence pulse + if(OWM_Reset(owm)) { + // Send Read ROM command code + if(OWM_WriteByte(owm, READ_ROM_COMMAND) == E_NO_ERROR) { + // Read 8 bytes and store in buffer + num_read = OWM_Read(owm, ROMCode, 8); + + // Check the number of bytes read + if(num_read != 8) { + return E_COMM_ERR; + } + } else { + // Write failed + return E_COMM_ERR; + } + } else { + // No presence pulse + return E_COMM_ERR; + } + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +int OWM_MatchROM(mxc_owm_regs_t *owm, uint8_t* ROMCode) +{ + int num_wrote = 0; + + // Send reset and wait for presence pulse + if(OWM_Reset(owm)) { + // Send match ROM command code + if(OWM_WriteByte(owm, MATCH_ROM_COMMAND) == E_NO_ERROR) { + // Write 8 bytes in ROMCode buffer + num_wrote = OWM_Write(owm, ROMCode, 8); + + // Check the number of bytes written + if(num_wrote != 8) { + return E_COMM_ERR; + } + } else { + // Write failed + return E_COMM_ERR; + } + } else { + // No presence pulse + return E_COMM_ERR; + } + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +int OWM_ODMatchROM(mxc_owm_regs_t *owm, uint8_t* ROMCode) +{ + int num_wrote = 0; + + // Set to standard speed + owm->cfg &= ~(MXC_F_OWM_CFG_OVERDRIVE); + + // Send reset and wait for presence pulse + if(OWM_Reset(owm)) { + // Send Overdrive match ROM command code + if(OWM_WriteByte(owm, OD_MATCH_ROM_COMMAND) == E_NO_ERROR) { + // Set overdrive + owm->cfg |= MXC_F_OWM_CFG_OVERDRIVE; + + // Write 8 bytes in ROMCode buffer + num_wrote = OWM_Write(owm, ROMCode, 8); + + // Check the number of bytes written + if(num_wrote != 8) { + return E_COMM_ERR; + } + } else { + // Write failed + return E_COMM_ERR; + } + } else { + // No presence pulse + return E_COMM_ERR; + } + + return E_NO_ERROR; +} + +/* ************************************************************************* */ +int OWM_SkipROM(mxc_owm_regs_t *owm) +{ + // Send reset and wait for presence pulse + if(OWM_Reset(owm)) { + // Send skip ROM command code + return OWM_WriteByte(owm, SKIP_ROM_COMMAND); + } else { + // No presence pulse + return E_COMM_ERR; + } +} + +/* ************************************************************************* */ +int OWM_ODSkipROM(mxc_owm_regs_t *owm) +{ + // Set to standard speed + owm->cfg &= ~(MXC_F_OWM_CFG_OVERDRIVE); + + // Send reset and wait for presence pulse + if(OWM_Reset(owm)) { + // Send Overdrive skip ROM command code + if(OWM_WriteByte(owm, OD_SKIP_ROM_COMMAND) == E_NO_ERROR) { + // Set overdrive speed + owm->cfg |= MXC_F_OWM_CFG_OVERDRIVE; + + return E_NO_ERROR; + } else { + // Write failed + return E_COMM_ERR; + } + } else { + // No presence pulse + return E_COMM_ERR; + } +} + +/* ************************************************************************* */ +int OWM_Resume(mxc_owm_regs_t *owm) +{ + // Send reset and wait for presence pulse + if(OWM_Reset(owm)) { + // Send resume command code + return OWM_WriteByte(owm, RESUME_COMMAND); + } else { + // No presence pulse + return E_COMM_ERR; + } +} + +/* ************************************************************************* */ +int OWM_SearchROM(mxc_owm_regs_t *owm, int newSearch, uint8_t* ROMCode) +{ + int nibble_start_bit = 1; + int rom_byte_number = 0; + uint8_t rom_nibble_mask = 0x0F; + uint8_t search_direction = 0; + int readValue = 0; + int sentBits = 0; + int discrepancy = 0; + int bit_position = 0; + int discrepancy_mask = 0; + int last_zero = 0; + uint8_t crc8 = 0; + int search_result = 0; + + // Clear ROM array + memset(ROMCode, 0x0, 8); + + if(newSearch) { + // Reset all global variables to start search from begining + LastDiscrepancy = 0; + LastDeviceFlag = 0; + } + + // Check if the last call was the last device + if(LastDeviceFlag) { + // Reset the search + LastDiscrepancy = 0; + LastDeviceFlag = 0; + return 0; + } + + // Send reset and wait for presence pulse + if (OWM_Reset(owm)) { + // Send the search command + OWM_WriteByte(owm, SEARCH_ROM_COMMAND); + + // Set search ROM accelerator bit + owm->ctrl_stat |= MXC_F_OWM_CTRL_STAT_SRA_MODE; + + // Loop until through all ROM bytes 0-7 (this loops 2 times per byte) + while(rom_byte_number < 8) { + // Each loop finds the discrepancy bits and finds 4 bits (nibble) of the ROM + + // Set the search direction the same as last time for the nibble masked + search_direction = ROMCode[rom_byte_number] & rom_nibble_mask; + + // If the upper nibble is the mask then shift bits to lower nibble + if(rom_nibble_mask > 0x0F) { + search_direction = search_direction >> 4; + } + + // Get the last discrepancy bit position relative to the nibble start bit + bit_position = LastDiscrepancy - nibble_start_bit; + + // Check if last discrepancy is witin this nibble + if( (bit_position >= 0) && (bit_position < 4) ) { + // Last discrepancy is within this nibble + // Set the bit of the last discrepancy bit + search_direction |= (1 << (bit_position)); + } + + // Performs two read bits and a write bit for 4 bits of the ROM + readValue = OWM_TouchByte(owm, search_direction); + // Get discrepancy flags + discrepancy = readValue & 0xF; + // Get the 4 bits sent to select the ROM + sentBits = (readValue >> 4) & 0xF; + + // Store the bit location of the MSB discrepancy with sentbit = 0 + if(discrepancy) { + // Initialize bit_position to MSB of nibble + bit_position = 3; + + while(bit_position >= 0) { + // Get discrepancy flag of the current bit position + discrepancy_mask = discrepancy & (1 << bit_position); + + // If there is a discrepancy and the sent bit is 0 save this bit position + if( (discrepancy_mask) && !(sentBits & discrepancy_mask)) { + last_zero = nibble_start_bit + bit_position; + break; + } + + bit_position--; + } + } + + // Clear the nibble + ROMCode[rom_byte_number] &= ~rom_nibble_mask; + + // Store the sentBits in the ROMCode + if(rom_nibble_mask > 0x0F) { + ROMCode[rom_byte_number] |= (sentBits << 4); + } else { + ROMCode[rom_byte_number] |= sentBits; + } + + // Increment the nibble start bit and shift mask + nibble_start_bit += 4; + rom_nibble_mask <<= 4; + + // If the mask is 0 then go to new ROM byte rom_byte_number and reset mask + if (rom_nibble_mask == 0) { + rom_byte_number++; + rom_nibble_mask = 0x0F; + } + + } // End while(rom_byte_number < 8) + + // Clear search ROM accelerator + owm->ctrl_stat &= ~(MXC_F_OWM_CTRL_STAT_SRA_MODE); + + // Calculate CRC to verify ROM code is correct + crc8 = CalculateCRC8(ROMCode, 7); + + // If the search was successful then + if ((nibble_start_bit >= 65) && (crc8 == ROMCode[7])) { + // Search successful so set LastDiscrepancy,LastDeviceFlag,search_result + LastDiscrepancy = last_zero; + + // Check for last device + if (LastDiscrepancy == 0) { + LastDeviceFlag = 1; + } + + search_result = 1; + } + } // End if (OWM_Reset) + + // If no device found then reset counters so next 'search' will be like a first + if (!search_result || !ROMCode[0]) { + LastDiscrepancy = 0; + LastDeviceFlag = 0; + search_result = 0; + } + + return search_result; +} + +/* + * Calcualate CRC8 of the buffer of data provided + */ +uint8_t CalculateCRC8(uint8_t* data, int len) +{ + int i; + uint8_t crc = 0; + + for(i = 0; i < len; i++) { + crc = update_crc8(crc, data[i]); + } + + return crc; +} + +/* + * Calculate the CRC8 of the byte value provided with the current crc value + * provided Returns updated crc value + */ +uint8_t update_crc8(uint8_t crc, uint8_t val) +{ + uint8_t inc, tmp; + + for (inc = 0; inc < 8; inc++) { + tmp = (uint8_t)(crc << 7); // Save X7 bit value + crc >>= 1; // Shift crc + if (((tmp >> 7) ^ (val & 0x01)) == 1) { // If X7 xor X8 (input data) + crc ^= 0x8c; // XOR crc with X4 and X5, X1 = X7^X8 + crc |= 0x80; // Carry + } + val >>= 1; + } + + return crc; +} + +/**@} end of group owm */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/owm.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/owm.h new file mode 100644 index 00000000000..ea40b53d37e --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/owm.h @@ -0,0 +1,320 @@ +/** + * @file owm.h + * @brief Registers, Bit Masks and Bit Positions for the 1-Wire Master + * peripheral module. + */ +/* **************************************************************************** +* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +* +* $Date: 2016-03-14 10:08:53 -0500 (Mon, 14 Mar 2016) $ +* $Revision: 21855 $ +* +**************************************************************************** */ + +/* Define to prevent redundant inclusion */ +#ifndef _OWM_H_ +#define _OWM_H_ + +/* **** Includes **** */ +#include "mxc_config.h" +#include "mxc_sys.h" +#include "owm_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup owm 1-Wire Master (OWM) + * @ingroup periphlibs + * @{ + */ + +/* **** Definitions **** */ + +/** + * Enumeration type for 1-Wire Overdrive Speed Options. + */ +typedef enum { + OWM_OVERDRIVE_UNUSED = MXC_V_OWM_CTRL_STAT_OD_SPEC_MODE_12US, /**< 12us Overdrive Speed Select. */ + OWM_OVERDRIVE_12US = MXC_V_OWM_CTRL_STAT_OD_SPEC_MODE_12US, /**< 12us Overdrive Speed Select. */ + OWM_OVERDRIVE_10US = MXC_V_OWM_CTRL_STAT_OD_SPEC_MODE_10US /**< 10us Overdrive Speed Select. */ +} owm_overdrive_t; + +/** + * Enumeration type for specifying options for 1-Wire external pullup mode. + */ +typedef enum { + OWM_EXT_PU_ACT_HIGH = 0, /**< Pullup pin is active high when enabled. */ + OWM_EXT_PU_ACT_LOW = 1, /**< Pullup pin is active low when enabled. */ + OWM_EXT_PU_UNUSED = 2, /**< Pullup pin is not used for an external pullup. */ +} owm_ext_pu_t; + +/** + * Structure type for 1-Wire Master configuration. + */ +typedef struct { + uint8_t int_pu_en; /**< 1 = internal pullup on. */ + owm_ext_pu_t ext_pu_mode; /**< See #owm_ext_pu_t. */ + uint8_t long_line_mode; /**< 1 = long line mode enable. */ + owm_overdrive_t overdrive_spec; /**< 0 = timeslot is 12us, 1 = timeslot is 10us. */ +} owm_cfg_t; + + +#define READ_ROM_COMMAND 0x33 /**< Read ROM Command */ +#define MATCH_ROM_COMMAND 0x55 /**< Match ROM Command */ +#define SEARCH_ROM_COMMAND 0xF0 /**< Search ROM Command */ +#define SKIP_ROM_COMMAND 0xCC /**< Skip ROM Command */ +#define OD_SKIP_ROM_COMMAND 0x3C /**< Overdrive Skip ROM Command */ +#define OD_MATCH_ROM_COMMAND 0x69 /**< Overdrive Match ROM Command */ +#define RESUME_COMMAND 0xA5 /**< Resume Command */ + +/* **** Globals **** */ + +/* **** Function Prototypes **** */ + +/** + * @brief Initialize and enable OWM module. + * @param owm Pointer to OWM regs. + * @param cfg Pointer to OWM configuration. + * @param sys_cfg Pointer to system configuration object + * + * @retval #E_NO_ERROR if everything is successful + * @retval #E_NULL_PTR if parameter is a null pointer + * @retval #E_BUSY if IOMAN was not configured correctly + * @retval #E_UNINITIALIZED if OWM CLK disabled + * @retval #E_NOT_SUPPORTED if 1MHz CLK cannot be created with given system and owm CLK + * @retval #E_BAD_PARAM if bad cfg parameter passed in + */ +int OWM_Init(mxc_owm_regs_t *owm, const owm_cfg_t *cfg, const sys_cfg_owm_t *sys_cfg); + +/** + * @brief Shutdown OWM module. + * @param owm Pointer to OWM regs. + * @retval #E_NO_ERROR if everything is successful + * @retval #E_BUSY if IOMAN was not released + */ +int OWM_Shutdown(mxc_owm_regs_t *owm); + +/** + * @brief Send 1-Wire reset pulse. Will block until transaction is complete. + * @param owm Pointer to OWM regs. + * @retval (0) = no presence pulse detected, (1) = presence pulse detected + */ +int OWM_Reset(mxc_owm_regs_t *owm); + +/** + * @brief Send and receive one byte of data. Will block until transaction is complete. + * @param owm Pointer to OWM regs. + * @param data data to send + * @retval data read (1 byte) + */ +int OWM_TouchByte(mxc_owm_regs_t *owm, uint8_t data); + +/** + * @brief Write one byte of data. Will block until transaction is complete. + * @param owm Pointer to OWM regs. + * @param data data to send + * @retval #E_NO_ERROR if everything is successful + * @retval #E_COMM_ERR if data written != data parameter + */ +int OWM_WriteByte(mxc_owm_regs_t *owm, uint8_t data); + +/** + * @brief Read one byte of data. Will block until transaction is complete. + * @param owm Pointer to OWM regs. + * @retval data read (1 byte) + */ +int OWM_ReadByte(mxc_owm_regs_t *owm); + +/** + * @brief Send and receive one bit of data. Will block until transaction is complete. + * @param owm Pointer to OWM regs. + * @param bit bit to send + * @retval bit read + */ +int OWM_TouchBit(mxc_owm_regs_t *owm, uint8_t bit); + +/** + * @brief Write one bit of data. Will block until transaction is complete. + * @param owm Pointer to OWM regs. + * @param bit bit to send + * @retval #E_NO_ERROR if everything is successful + * @retval #E_COMM_ERR if bit written != bit parameter + */ +int OWM_WriteBit(mxc_owm_regs_t *owm, uint8_t bit); + +/** + * @brief Read one bit of data. Will block until transaction is complete. + * @param owm Pointer to OWM regs. + * @retval bit read + */ +int OWM_ReadBit(mxc_owm_regs_t *owm); + +/** + * @brief Write multiple bytes of data. Will block until transaction is complete. + * @param owm Pointer to OWM regs. + * @param data Pointer to buffer for write data. + * @param len Number of bytes to write. + * + * @retval Number of bytes written if successful + * @retval #E_COMM_ERR if line short detected before transaction + */ +int OWM_Write(mxc_owm_regs_t *owm, uint8_t* data, int len); + +/** + * @brief Read multiple bytes of data. Will block until transaction is complete. + * @param owm Pointer to OWM regs. + * @param data Pointer to buffer for read data. + * @param len Number of bytes to read. + * + * @retval Number of bytes read if successful + * @retval #E_COMM_ERR if line short detected before transaction + */ +int OWM_Read(mxc_owm_regs_t *owm, uint8_t* data, int len); + +/** + * @brief Starts 1-Wire communication with Read ROM command + * @note Only use the Read ROM command with one slave on the bus + * @param owm Pointer to OWM regs. + * @param ROMCode Pointer to buffer for ROM code read + * @retval #E_NO_ERROR if everything is successful + * @retval #E_COMM_ERR if reset, read or write fails + */ +int OWM_ReadROM(mxc_owm_regs_t *owm, uint8_t* ROMCode); + +/** + * @brief Starts 1-Wire communication with Match ROM command + * @param owm Pointer to OWM regs. + * @param ROMCode Pointer to buffer with ROM code to match + * @retval #E_NO_ERROR if everything is successful + * @retval #E_COMM_ERR if reset or write fails + */ +int OWM_MatchROM(mxc_owm_regs_t *owm, uint8_t* ROMCode); + +/** + * @brief Starts 1-Wire communication with Overdrive Match ROM command + * @note After Overdrive Match ROM command is sent, the OWM is set to + * overdrive speed. To set back to standard speed use OWM_SetOverdrive. + * @param owm Pointer to OWM regs. + * @param ROMCode Pointer to buffer with ROM code to match + * @retval #E_NO_ERROR if everything is successful + * @retval #E_COMM_ERR if reset or write fails + */ +int OWM_ODMatchROM(mxc_owm_regs_t *owm, uint8_t* ROMCode); + +/** + * @brief Starts 1-Wire communication with Skip ROM command + * @param owm Pointer to OWM regs. + * @retval #E_NO_ERROR if everything is successful + * @retval #E_COMM_ERR if reset or write fails + */ +int OWM_SkipROM(mxc_owm_regs_t *owm); + +/** + * @brief Starts 1-Wire communication with Overdrive Skip ROM command + * @note After Overdrive Skip ROM command is sent, the OWM is set to + * overdrive speed. To set back to standard speed use OWM_SetOverdrive + * @param owm Pointer to OWM regs. + * @retval #E_NO_ERROR if everything is successful + * @retval #E_COMM_ERR if reset or write fails + */ +int OWM_ODSkipROM(mxc_owm_regs_t *owm); + +/** + * @brief Starts 1-Wire communication with Resume command + * @param owm Pointer to OWM regs. + * @retval #E_NO_ERROR if everything is successful + * @retval #E_COMM_ERR if reset or write fails + */ +int OWM_Resume(mxc_owm_regs_t *owm); + +/** + * @brief Starts 1-Wire communication with Search ROM command + * @param owm Pointer to OWM regs. + * @param newSearch (1) = start new search, (0) = continue search for next ROM + * @param ROMCode Pointer to buffer with ROM code found + * @retval (1) = ROM found, (0) = no new ROM found, end of search + */ +int OWM_SearchROM(mxc_owm_regs_t *owm, int newSearch, uint8_t* ROMCode); + +/** + * @brief Clear interrupt flags. + * @param owm Pointer to OWM regs. + * @param mask Mask of interrupts to clear. + */ +__STATIC_INLINE void OWM_ClearFlags(mxc_owm_regs_t *owm, uint32_t mask) +{ + owm->intfl = mask; +} + +/** + * @brief Get interrupt flags. + * @param owm Pointer to OWM regs. + * @retval Mask of active flags. + */ +__STATIC_INLINE unsigned OWM_GetFlags(mxc_owm_regs_t *owm) +{ + return (owm->intfl); +} + +/** + * @brief Enables/Disables the External pullup + * @param owm Pointer to OWM regs. + * @param enable (1) = enable, (0) = disable + */ +__STATIC_INLINE void OWM_SetExtPullup(mxc_owm_regs_t *owm, int enable) +{ + if(enable) + owm->cfg |= MXC_F_OWM_CFG_EXT_PULLUP_ENABLE; + else + owm->cfg &= ~(MXC_F_OWM_CFG_EXT_PULLUP_ENABLE); +} + +/** + * @brief Enables/Disables Overdrive speed + * @param owm Pointer to OWM regs. + * @param enable (1) = overdrive, (0) = standard + */ +__STATIC_INLINE void OWM_SetOverdrive(mxc_owm_regs_t *owm, int enable) +{ + if(enable) + owm->cfg |= MXC_F_OWM_CFG_OVERDRIVE; + else + owm->cfg &= ~(MXC_F_OWM_CFG_OVERDRIVE); +} + +/**@} end of group owm */ +#ifdef __cplusplus +} +#endif + +#endif /* _OWM_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/pmu.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/pmu.c new file mode 100644 index 00000000000..8dbd616c471 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/pmu.c @@ -0,0 +1,236 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-06-21 16:19:28 -0500 (Tue, 21 Jun 2016) $ + * $Revision: 23450 $ + * + ******************************************************************************/ + +#include +#include +#include "mxc_config.h" +#include "mxc_assert.h" +#include "pmu.h" + +#if (MXC_PMU_REV == 0) +/* MAX32630 A1 & A2 Erratum #6: PMU only supports channels 0-4 -- workaround */ +#include "clkman_regs.h" +/* Channel 5 infinite loop program */ +static const uint32_t pmu_0[] = { + PMU_JUMP(0, 0, (uint32_t)pmu_0) +}; +#endif + +static void (*callbacks[MXC_CFG_PMU_CHANNELS])(int); + + +/******************************************************************************/ +void PMU_Handler(void) +{ + int channel; + uint32_t cfg1, cfg2; + mxc_pmu_regs_t *MXC_PMUn; + + for (channel = 0; channel < MXC_CFG_PMU_CHANNELS; channel++) { + MXC_PMUn = &MXC_PMU0[channel]; + + if (MXC_PMUn->cfg & MXC_F_PMU_CFG_INTERRUPT) { + cfg1 = MXC_PMUn->cfg; + /* Since any set flags will be cleared by the write-back below, mask them off */ + cfg2 = cfg1 & ~(MXC_F_PMU_CFG_LL_STOPPED | MXC_F_PMU_CFG_BUS_ERROR | MXC_F_PMU_CFG_TO_STAT); + + /* Clear the interrupt flag */ + MXC_PMUn->cfg = cfg2 | MXC_F_PMU_CFG_INTERRUPT; + + if (callbacks[channel]) { + callbacks[channel](cfg1); + } + } + } +} + +/******************************************************************************/ +int PMU_Start(unsigned int channel, const void *program_address, pmu_callback callback) +{ + if(channel >= MXC_CFG_PMU_CHANNELS) + return E_BAD_PARAM; + + mxc_pmu_regs_t *MXC_PMUn = &MXC_PMU0[channel]; + uint32_t cfg = MXC_PMUn->cfg; + + /* is this channel already running? */ + if (cfg & MXC_F_PMU_CFG_ENABLE) { + return E_BUSY; + } + +#if (MXC_PMU_REV == 0) + /* MAX32630 A1 & A2 Erratum #6: PMU only supports channels 0-4 */ + if (channel == 5) { + /* Channel 5 is used for the work-around */ + return E_BUSY; + } + /* Select always-ON clock for PMU */ + MXC_CLKMAN->clk_gate_ctrl0 |= MXC_F_CLKMAN_CLK_GATE_CTRL0_PMU_CLK_GATER; + /* Start channel 5 with infinite-loop program */ + MXC_PMU5->cfg &= ~MXC_F_PMU_CFG_ENABLE; /* Clear enable and wipe W1C flags */ + MXC_PMU5->dscadr = (uint32_t)pmu_0; + MXC_PMU5->cfg = MXC_F_PMU_CFG_ENABLE | (0x1c << MXC_F_PMU_CFG_BURST_SIZE_POS); +#endif + /* Set callback */ + callbacks[channel] = callback; + + /* Set start op-code */ + MXC_PMUn->dscadr = (uint32_t)program_address; + + /* Configure the channel */ + cfg = (cfg & ~(MXC_F_PMU_CFG_MANUAL | MXC_F_PMU_CFG_BURST_SIZE)) | (0x1c << MXC_F_PMU_CFG_BURST_SIZE_POS); + + /* Enable if necessary */ + if (callback) { + cfg |= MXC_F_PMU_CFG_INT_EN; + } else { + cfg &= ~MXC_F_PMU_CFG_INT_EN; + } + + /* Start the channel */ + cfg |= MXC_F_PMU_CFG_ENABLE; + + /*If any W1C flags are set, this write will clear them */ + MXC_PMUn->cfg = cfg; + + return E_NO_ERROR; +} + +/******************************************************************************/ +void PMU_Stop(unsigned int channel) +{ + mxc_pmu_regs_t *MXC_PMUn = &MXC_PMU0[channel]; + uint32_t cfg = MXC_PMUn->cfg; + + /* Since any set flags will be cleared by the write-back below, mask them off */ + cfg &= ~(MXC_F_PMU_CFG_LL_STOPPED | MXC_F_PMU_CFG_BUS_ERROR | MXC_F_PMU_CFG_TO_STAT | MXC_F_PMU_CFG_INTERRUPT); + + /* Clear the enable bit to stop the channel */ + cfg &= ~MXC_F_PMU_CFG_ENABLE; + + MXC_PMUn->cfg = cfg; + + /* Remove callback */ + callbacks[channel] = NULL; + +#if (MXC_PMU_REV == 0) + /* MAX32630 A1 & A2 Erratum #6: PMU only supports channels 0-4 */ + /* Check channels 0-4 for any running channels. If none found, stop channel 5 */ + if ((MXC_PMU0->cfg & MXC_F_PMU_CFG_ENABLE) == 0 && + (MXC_PMU1->cfg & MXC_F_PMU_CFG_ENABLE) == 0 && + (MXC_PMU2->cfg & MXC_F_PMU_CFG_ENABLE) == 0 && + (MXC_PMU3->cfg & MXC_F_PMU_CFG_ENABLE) == 0 && + (MXC_PMU4->cfg & MXC_F_PMU_CFG_ENABLE) == 0) { + + MXC_PMU5->cfg &= ~MXC_F_PMU_CFG_ENABLE; + } +#endif + +} + +/******************************************************************************/ +int PMU_SetCounter(unsigned int channel, unsigned int counter, uint16_t value) +{ + if((channel >= MXC_CFG_PMU_CHANNELS) || counter > 1) + return E_BAD_PARAM; + + mxc_pmu_regs_t *MXC_PMUn = &MXC_PMU0[channel]; + + if (counter == 0) { + MXC_PMUn->loop = (MXC_PMUn->loop & ~MXC_F_PMU_LOOP_COUNTER_0) | (value << MXC_F_PMU_LOOP_COUNTER_0_POS); + } else { + MXC_PMUn->loop = (MXC_PMUn->loop & ~MXC_F_PMU_LOOP_COUNTER_1) | (value << MXC_F_PMU_LOOP_COUNTER_1_POS); + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int PMU_SetTimeout(unsigned int channel, pmu_ps_sel_t timeoutClkScale, pmu_to_sel_t timeoutTicks) +{ + if(channel >= MXC_CFG_PMU_CHANNELS) + return E_BAD_PARAM; + + mxc_pmu_regs_t *MXC_PMUn = &MXC_PMU0[channel]; + uint32_t cfg = MXC_PMUn->cfg; + + /* Since any set flags will be cleared by the write-back below, mask them off */ + cfg &= ~(MXC_F_PMU_CFG_LL_STOPPED | MXC_F_PMU_CFG_BUS_ERROR | MXC_F_PMU_CFG_TO_STAT | MXC_F_PMU_CFG_INTERRUPT); + + /* Adjust timeout settings */ + cfg &= ~(MXC_F_PMU_CFG_TO_SEL | MXC_F_PMU_CFG_PS_SEL); + cfg |= ((timeoutClkScale << MXC_F_PMU_CFG_PS_SEL_POS) & MXC_F_PMU_CFG_PS_SEL) | + ((timeoutTicks << MXC_F_PMU_CFG_TO_SEL_POS) & MXC_F_PMU_CFG_TO_SEL); + + MXC_PMUn->cfg = cfg; + + return E_NO_ERROR; +} + +/******************************************************************************/ +uint32_t PMU_GetFlags(unsigned int channel) +{ + mxc_pmu_regs_t *MXC_PMUn = &MXC_PMU0[channel]; + uint32_t cfg = MXC_PMUn->cfg; + + /* Mask off configuration bits leaving only flag bits */ + cfg &= ~(MXC_F_PMU_CFG_ENABLE | MXC_F_PMU_CFG_MANUAL | MXC_F_PMU_CFG_TO_SEL | MXC_F_PMU_CFG_PS_SEL | + MXC_F_PMU_CFG_INT_EN | MXC_F_PMU_CFG_BURST_SIZE); + + return cfg; +} + +/******************************************************************************/ +void PMU_ClearFlags(unsigned int channel, unsigned int mask) +{ + mxc_pmu_regs_t *MXC_PMUn = &MXC_PMU0[channel]; + uint32_t cfg = MXC_PMUn->cfg; + + /* Since any set flags will be cleared by the write-back below, mask them off */ + cfg &= ~(MXC_F_PMU_CFG_LL_STOPPED | MXC_F_PMU_CFG_BUS_ERROR | MXC_F_PMU_CFG_TO_STAT | MXC_F_PMU_CFG_INTERRUPT); + + /* Now, apply the caller-supplied bits to clear */ + cfg |= mask; + + MXC_PMUn->cfg = cfg; +} + +/******************************************************************************/ +uint32_t PMU_IsActive(unsigned int channel) +{ + mxc_pmu_regs_t *MXC_PMUn = &MXC_PMU0[channel]; + return (MXC_PMUn->cfg & MXC_F_PMU_CFG_ENABLE); +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/pmu.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/pmu.h new file mode 100644 index 00000000000..41ac34b6c3f --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/pmu.h @@ -0,0 +1,286 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-06-21 16:14:41 -0500 (Tue, 21 Jun 2016) $ + * $Revision: 23446 $ + * + ******************************************************************************/ + +/** + * @file pmu.h + * @addtogroup pmu Peripheral Management Unit + * @{ + * @brief This is the API for the peripheral management unit. + */ + +#ifndef _PMU_H_ +#define _PMU_H_ + +#include "pmu_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @brief Defines Clock scale used for Timeout +typedef enum { + PMU_PS_SEL_DISABLE = MXC_V_PMU_CFG_PS_SEL_DISABLE, // Timeout disabled + PMU_PS_SEL_DIV_2_8 = MXC_V_PMU_CFG_PS_SEL_DIV_2_8, // Timeout clk = PMU clock / 2^8 = 256 + PMU_PS_SEL_DIV_2_16 = MXC_V_PMU_CFG_PS_SEL_DIV_2_16, // Timeout clk = PMU clock / 2^16 = 65536 + PMU_PS_SEL_DIV_2_24 = MXC_V_PMU_CFG_PS_SEL_DIV_2_24 // Timeout clk = PMU clock / 2^24 = 16777216 +}pmu_ps_sel_t; + +/// @brief Defines the number of clk ticks for timeout duration +typedef enum { + PMU_TO_SEL_TICKS_4 = MXC_V_PMU_CFG_TO_SEL_TICKS_4, //timeout = 4 * Timeout clk period + PMU_TO_SEL_TICKS_8 = MXC_V_PMU_CFG_TO_SEL_TICKS_8, //timeout = 8 * Timeout clk period + PMU_TO_SEL_TICKS_16 = MXC_V_PMU_CFG_TO_SEL_TICKS_16, //timeout = 16 * Timeout clk period + PMU_TO_SEL_TICKS_32 = MXC_V_PMU_CFG_TO_SEL_TICKS_32, //timeout = 32 * Timeout clk period + PMU_TO_SEL_TICKS_64 = MXC_V_PMU_CFG_TO_SEL_TICKS_64, //timeout = 64 * Timeout clk period + PMU_TO_SEL_TICKS_128 = MXC_V_PMU_CFG_TO_SEL_TICKS_128, //timeout = 128 * Timeout clk period + PMU_TO_SEL_TICKS_256 = MXC_V_PMU_CFG_TO_SEL_TICKS_256, //timeout = 256 * Timeout clk period + PMU_TO_SEL_TICKS_512 = MXC_V_PMU_CFG_TO_SEL_TICKS_512 //timeout = 512 * Timeout clk period +}pmu_to_sel_t; + + +/* The macros like the one below are designed to help build static PMU programs + * as arrays of 32bit words. + */ +#define PMU_IS(interrupt, stop) ((!!interrupt) << PMU_INT_POS) | ((!!stop) << PMU_STOP_POS) + +typedef struct pmu_move_des_t { + uint32_t op_code : 3; /* 0x0 */ + uint32_t interrupt : 1; + uint32_t stop : 1; + uint32_t read_size : 2; + uint32_t read_inc : 1; + uint32_t write_size : 2; + uint32_t write_inc : 1; + uint32_t cont : 1; + uint32_t length : 20; + + uint32_t write_address; + uint32_t read_address; +} pmu_move_des_t; +#define PMU_MOVE(i, s, rs, ri, ws, wi, c, length, wa, ra) \ + (PMU_MOVE_OP | PMU_IS(i,s) | ((rs & 3) << PMU_MOVE_READS_POS) | ((!!ri) << PMU_MOVE_READI_POS) | \ + ((ws & 3) << PMU_MOVE_WRITES_POS) | ((!!wi) << PMU_MOVE_WRITEI_POS) | ((!!c) << PMU_MOVE_CONT_POS) | ((length & 0xFFFFF) << PMU_MOVE_LEN_POS)), wa, ra + +/* new_value = value | (old_value & ~ mask) */ +typedef struct pmu_write_des_t { + uint32_t op_code : 3; /* 0x1 */ + uint32_t interrupt : 1; + uint32_t stop : 1; + uint32_t : 3; + uint32_t write_method : 4; + uint32_t : 20; + + uint32_t write_address; + uint32_t value; + uint32_t mask; +} pmu_write_des_t; +#define PMU_WRITE(i, s, wm, a, v, m) (PMU_WRITE_OP | PMU_IS(i,s) | ((wm & 0xF) << PMU_WRITE_METHOD_POS)), a, v, m + +typedef struct pmu_wait_des_t { + uint32_t op_code : 3; /* 0x2 */ + uint32_t interrupt : 1; + uint32_t stop : 1; + uint32_t wait : 1; + uint32_t sel : 1; + uint32_t : 25; + + uint32_t mask1; + uint32_t mask2; + uint32_t wait_count; +} pmu_wait_des_t; +#define PMU_WAIT(i, s, sel, m1, m2, cnt) (PMU_WAIT_OP | PMU_IS(i,s) | ((cnt>0)?(1<user_entropy & MXC_F_PRNG_USER_ENTROPY_RND_NUM_READY); +} + +/** + * @brief Retrieve a seed value from the PRNG + * @note The PRNG hardware does not produce true random numbers. The output + * should be used as a seed to an approved random-number algorithm, per + * a certifying authority such as NIST or PCI. The approved algorithm + * will output random numbers which are cerfitied for use in encryption + * and authentication algorithms. + * + * @return This function returns a 16-bit seed value + */ +__STATIC_INLINE uint16_t PRNG_GetSeed(void) +{ + return MXC_PRNG->rnd_num; +} + +/** + * @brief Add user entropy to the PRNG entropy source + * + * @param entropy This value will be mixed into the PRNG entropy source + */ +__STATIC_INLINE void PRNG_AddUserEntropy(uint8_t entropy) +{ + MXC_PRNG->user_entropy = (uint32_t)entropy; +} + +#ifdef __cplusplus +} +#endif + +#endif /* _PRNG_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/pt.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/pt.c new file mode 100644 index 00000000000..66c6a3adf4c --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/pt.c @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-11 11:46:37 -0600 (Fri, 11 Mar 2016) $ + * $Revision: 21839 $ + * + ******************************************************************************/ + +#include +#include "pt.h" + +/******************************************************************************/ +void PT_Init(sys_pt_clk_scale clk_scale) +{ + //disable all pulse trains + MXC_PTG->enable = 0; + + //clear all interrupts + MXC_PTG->intfl = MXC_PTG->intfl; + + SYS_PT_Init(clk_scale); +} + +/******************************************************************************/ +int PT_PTConfig(mxc_pt_regs_t *pt, pt_pt_cfg_t *cfg, const sys_cfg_pt_t *sysCfg) +{ + int err; + uint32_t ptClock; + uint32_t rate; + + //check for valid base pointer + MXC_ASSERT(MXC_PT_GET_IDX(pt) >= 0); + + if(cfg == NULL) + return E_NULL_PTR; + + if(cfg->bps == 0) + return E_BAD_PARAM; + + //disable pulse train + PT_Stop(pt); + + //setup system GPIO configuration + if((err = SYS_PT_Config(pt, sysCfg)) != E_NO_ERROR) + return err; + + //get PT clock frequency from SYS level + ptClock = SYS_PT_GetFreq(); + + if(ptClock == 0) + return E_UNINITIALIZED; + + if(ptClock < (cfg->bps)) + return E_BAD_STATE; + + rate = (ptClock / (cfg->bps)); + + pt->rate_length = ((rate << MXC_F_PT_RATE_LENGTH_RATE_CONTROL_POS) + & MXC_F_PT_RATE_LENGTH_RATE_CONTROL) | + ((cfg->ptLength << MXC_F_PT_RATE_LENGTH_MODE_POS) + & MXC_F_PT_RATE_LENGTH_MODE); + + pt->train = cfg->pattern; + pt->loop = ((cfg->loop << MXC_F_PT_LOOP_COUNT_POS) & MXC_F_PT_LOOP_COUNT) | + ((cfg->loopDelay << MXC_F_PT_LOOP_DELAY_POS) & MXC_F_PT_LOOP_DELAY); + + return E_NO_ERROR; +} + +/******************************************************************************/ +int PT_SqrWaveConfig(mxc_pt_regs_t *pt, uint32_t freq, const sys_cfg_pt_t *sysCfg) +{ + int err; + uint32_t ptClock; + uint32_t rate; + + //check for valid base pointer + MXC_ASSERT(MXC_PT_GET_IDX(pt) >= 0); + + if(freq == 0) + return E_BAD_PARAM; + + //disable pulse train + PT_Stop(pt); + + //setup system GPIO configuration + if((err = SYS_PT_Config(pt, sysCfg)) != E_NO_ERROR) + return err; + + //get PT clock frequency from SYS level + ptClock = SYS_PT_GetFreq(); + + if(ptClock == 0) + return E_UNINITIALIZED; + + if(ptClock < (2*freq)) + return E_BAD_STATE; + + rate = (ptClock / (2*freq)) + 1; + + pt->rate_length = ((rate << MXC_F_PT_RATE_LENGTH_RATE_CONTROL_POS) + & MXC_F_PT_RATE_LENGTH_RATE_CONTROL) | + (MXC_V_PT_RATE_LENGTH_MODE_SQUARE_WAVE << MXC_F_PT_RATE_LENGTH_MODE_POS); + + return E_NO_ERROR; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/pt.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/pt.h new file mode 100644 index 00000000000..a39d0184d3f --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/pt.h @@ -0,0 +1,313 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-21 14:44:55 -0500 (Mon, 21 Mar 2016) $ + * $Revision: 22017 $ + * + ******************************************************************************/ + +/** + * @file pt.h + * @addtogroup pt Pulse Train + * @brief This is the high level API for the pulse train module + * @{ + * + */ + +#ifndef _PT_H +#define _PT_H + +#include "mxc_config.h" +#include "pt_regs.h" +#include "mxc_assert.h" +#include "mxc_sys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @struct pt_pt_cfg_t +/// Pulse train mode configuration structure. @note Do not use for square wave +typedef struct { + uint32_t bps; ///< pulse train bit rate + uint32_t pattern; ///< Output pattern to shift out, starts at LSB + uint8_t ptLength; ///< Number of bits in pulse train, 0 = 32bits, 1 = non valid , 2 = 2 bits, ... + uint16_t loop; ///< Number of times to repeat the train, 0 = continuous + uint16_t loopDelay; ///< Delay between loops specified in bits Example: loopDelay = 4, delays time = time it takes to shift out 4 bits +} pt_pt_cfg_t; + +/** + * @brief This function initializes pulse train modules to a known stopped state + * and sets the global PT clock scale + * @param clk_scale scale the system clock for the global PT clock + */ +void PT_Init(sys_pt_clk_scale clk_scale); + +/** + * @brief Configures the pulse train in the specified mode. + * @details The parameters in config structure must be set before calling this function. + * This function should be used for configuring pulse train mode only. + * @note The pulse train cannot be running when this function is called + * + * @param pt pulse train to operate on + * @param cfg pointer to pulse train configuration + * @param sysCfg pointer to pulse train system GPIO configuration + * + * @returns E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int PT_PTConfig(mxc_pt_regs_t *pt, pt_pt_cfg_t *cfg, const sys_cfg_pt_t *sysCfg); + +/** + * @brief Configures the pulse train in the square wave mode. + * @details This function should be used for configuring square wave mode only. + * @note The pulse train cannot be running when this function is called + * + * @param pt pulse train to operate on + * @param freq square wave output frequency in Hz + * @param sysCfg pointer to pulse train system GPIO configuration + * + * @returns E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int PT_SqrWaveConfig(mxc_pt_regs_t *pt, uint32_t freq, const sys_cfg_pt_t *sysCfg); + +/** + * @brief Starts the pulse train specified + * + * @param pt pulse train to operate on + */ +__STATIC_INLINE void PT_Start(mxc_pt_regs_t *pt) +{ + int ptIndex = MXC_PT_GET_IDX(pt); + + MXC_PTG->enable |= (1 << ptIndex); + + //wait for PT to start + while( (MXC_PTG->enable & (1 << ptIndex)) == 0 ); +} + +/** + * @brief Start multiple pulse train modules together. + * + * @param pts set the bits of pulse trains to start + * Bit0-\>pt0, Bit1-\>pt1... etc. + */ +__STATIC_INLINE void PT_StartMulti(uint32_t pts) +{ + MXC_PTG->enable |= pts; + + //wait for PTs to start + while( (MXC_PTG->enable & pts) != pts ); +} + +/** + * @brief Stops a pulse train + * + * @param pt pulse train to operate on + */ +__STATIC_INLINE void PT_Stop(mxc_pt_regs_t *pt) +{ + int ptIndex = MXC_PT_GET_IDX(pt); + + MXC_PTG->enable &= ~(1 << ptIndex); +} + +/** + * @brief Stop multiple pulse trains together + * + * @param pts set the bits of pulse trains to stop + * Bit0-\>pt0, Bit1-\>pt1... etc. + */ +__STATIC_INLINE void PT_StopMulti(uint32_t pts) +{ + MXC_PTG->enable &= ~(pts); +} + +/** + * @brief Determines if the pulse train is running + * + * @param pt pulse train to operate on + * + * @return 0 = pulse train is off, non-zero = pulse train is on + */ +__STATIC_INLINE uint32_t PT_IsActive(mxc_pt_regs_t *pt) +{ + int ptIndex = MXC_PT_GET_IDX(pt); + + return (!!(MXC_PTG->enable & (1 << ptIndex))); +} + +/** + * @brief Determines if the pulse trains selected are running + * + * @param pts set the bits of pulse trains to check + * Bit0-\>pt0, Bit1-\>pt1... etc. + * + * @return 0 = all pulse trains are off, non-zero = at least one pulse train is on + */ +__STATIC_INLINE uint32_t PT_IsActiveMulti(uint32_t pts) +{ + return (MXC_PTG->enable & pts); +} + +/** + * @brief Sets the pattern of the pulse train + * + * @param pt Pointer to pulse train to operate on + * @param pattern output pattern + * + */ +__STATIC_INLINE void PT_SetPattern(mxc_pt_regs_t *pt, uint32_t pattern) +{ + pt->train = pattern; +} + +/** + * @brief Enable pulse train interrupt + * + * @param pts Pointer to pulse train to operate on + */ +__STATIC_INLINE void PT_EnableINT(mxc_pt_regs_t *pt) +{ + int ptIndex = MXC_PT_GET_IDX(pt); + + MXC_PTG->inten |= (1 << ptIndex); +} + +/** + * @brief Enable interrupts for the pulse trains selected + * + * @param pts set the bits of pulse trains to enable + * Bit0-\>pt0, Bit1-\>pt1... etc. + */ +__STATIC_INLINE void PT_EnableINTMulti(uint32_t pts) +{ + MXC_PTG->inten |= pts; +} + +/** + * @brief Disable pulse train interrupt + * + * @param pts pulse train to operate on + */ +__STATIC_INLINE void PT_DisableINT(mxc_pt_regs_t *pt) +{ + int ptIndex = MXC_PT_GET_IDX(pt); + + MXC_PTG->inten &= ~(1 << ptIndex); +} + +/** + * @brief Disable interrupts for the pulse trains selected + * + * @param pts set the bits of pulse trains to enable + * Bit0-\>pt0, Bit1-\>pt1... etc. + */ +__STATIC_INLINE void PT_DisableINTMulti(uint32_t pts) +{ + MXC_PTG->inten &= ~pts; +} +/** + * @brief Gets the pulse trains's interrupt flags + * + * @return The Pulse Train Flags, bits that are 1 are set. + */ +__STATIC_INLINE uint32_t PT_GetFlags(void) +{ + return MXC_PTG->intfl; +} + +/** + * @brief Clears the pulse train's interrupt flag + * + * @param mask bits to clear + * + */ +__STATIC_INLINE void PT_ClearFlags(uint32_t mask) +{ + MXC_PTG->intfl = mask; +} + +/** + * @brief Setup and enables a pulse train to restart after another pulse train has exited its loop. + * Each pulse train can have up to two restart triggers. + * + * @param ptToRestart pulse train to restart after \a ptStop ends + * @param ptStop pulse train that stops and triggers \a ptToRestart to begin + * @param restartIndex selects which restart trigger to set (0 or 1) + */ +__STATIC_INLINE void PT_SetRestart(mxc_pt_regs_t *ptToRestart, mxc_pt_regs_t *ptStop, uint8_t restartIndex) +{ + int ptStopIndex = MXC_PT_GET_IDX(ptStop); + + MXC_ASSERT(ptStopIndex >= 0); + + if(restartIndex) { + ptToRestart->restart |= (ptStopIndex << MXC_F_PT_RESTART_PT_Y_SELECT_POS) | + MXC_F_PT_RESTART_ON_PT_Y_LOOP_EXIT; + } else { + ptToRestart->restart |= (ptStopIndex << MXC_F_PT_RESTART_PT_X_SELECT_POS) | + MXC_F_PT_RESTART_ON_PT_X_LOOP_EXIT; + } +} + +/** + * @brief Disable the restart for the specified pulse train + * + * @param ptToRestart pulse train to disable the restart + * @param restartIndex selects which restart trigger to disable (0 or 1) + */ +__STATIC_INLINE void PT_RestartDisable(mxc_pt_regs_t *ptToRestart, uint8_t restartIndex) +{ + if(restartIndex) + ptToRestart->restart &= ~MXC_F_PT_RESTART_ON_PT_Y_LOOP_EXIT; + else + ptToRestart->restart &= ~MXC_F_PT_RESTART_ON_PT_X_LOOP_EXIT; +} + +/** + * @brief Resynchronize individual pulse trains together. + * Resync will stop those resync_pts; others will be still running + * + * @param resyncPts pulse train modules that need to be re-synced by bit number. + * Bit0-\>pt0, Bit1-\>pt1... etc. + */ +__STATIC_INLINE void PT_Resync(uint32_t resyncPts) +{ + MXC_PTG->resync = resyncPts; + while(MXC_PTG->resync); +} + +/**@}*/ +#ifdef __cplusplus +} +#endif + +#endif /* _PT_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/rtc.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/rtc.c new file mode 100644 index 00000000000..1b283b8d632 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/rtc.c @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-22 12:05:05 -0500 (Tue, 22 Mar 2016) $ + * $Revision: 22032 $ + * + ******************************************************************************/ +/** + * @file rtc.c + * @addtogroup rtc Real-time Clock + * @{ + * @brief This is the high level API for the real-time clock module + */ + +#include "rtc.h" +#include "mxc_assert.h" +#include "mxc_sys.h" +#include + +/******************************************************************************/ +int RTC_Init(const rtc_cfg_t *cfg) +{ + int err; + int i = 0; + + //init function -> validate configuration pointer is not NULL + if (cfg == NULL) + return E_NULL_PTR; + //check to make sure that the passed in parameters, prescaler mask and snooze, are valid + if ((cfg->prescalerMask > ((rtc_prescale_t)cfg->prescaler)) || (cfg->snoozeCount > MXC_F_RTC_SNZ_VAL_VALUE)) + return E_INVALID; + + // Set system level configurations + if ((err = SYS_RTC_Init()) != E_NO_ERROR) { + return err; + } + + //disable rtc + MXC_RTCTMR->ctrl &= ~(MXC_F_RTC_CTRL_ENABLE); + + //disable all interrupts + MXC_RTCTMR->inten = 0; + + //clear all interrupts + MXC_RTCTMR->flags = RTC_FLAGS_CLEAR_ALL; + + //reset starting count + MXC_RTCTMR->timer = 0; + + //set the compare registers to the values passed in + for(i = 0; i < RTC_NUM_COMPARE; i++) + MXC_RTCTMR->comp[i] = cfg->compareCount[i]; + + // set the prescaler + MXC_RTCTMR->prescale = cfg->prescaler; + // set the prescale mask, checked it for validity on entry + MXC_RTCTMR->prescale_mask = cfg->prescalerMask; + + //set snooze mode (rtc_snooze_t) + MXC_RTCTMR->ctrl &= (~MXC_F_RTC_CTRL_SNOOZE_ENABLE); + MXC_RTCTMR->ctrl |= (cfg->snoozeMode << MXC_F_RTC_CTRL_SNOOZE_ENABLE_POS); + + //set the snooze count. Checked for validity on entry. + MXC_RTCTMR->snz_val = (cfg->snoozeCount << MXC_F_RTC_SNZ_VAL_VALUE_POS) & MXC_F_RTC_SNZ_VAL_VALUE; + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); + + //reset trim to defaults, trim disabled, trim faster override disabled + MXC_RTCTMR->trim_ctrl &= ~(MXC_F_RTC_TRIM_CTRL_TRIM_ENABLE_R | MXC_F_RTC_TRIM_CTRL_TRIM_FASTER_OVR_R); + + //set trim slower control bit to 0, which is trim faster by default + MXC_RTCTMR->trim_value &= ~(MXC_F_RTC_TRIM_VALUE_TRIM_SLOWER_CONTROL); + + return E_NO_ERROR; +} + +/******************************************************************************/ +int RTC_SetCompare(uint8_t compareIndex, uint32_t counts) +{ + //check for invalid index + if (compareIndex >= RTC_NUM_COMPARE) + return E_INVALID; + + MXC_RTCTMR->comp[compareIndex] = counts; + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); + + return E_NO_ERROR; +} + +/******************************************************************************/ +uint32_t RTC_GetCompare(uint8_t compareIndex) +{ + //Debug Assert for Invalid Index + MXC_ASSERT(compareIndex < RTC_NUM_COMPARE); + //check for invalid index + if (compareIndex >= RTC_NUM_COMPARE) + return (uint32_t)(E_BAD_PARAM); /* Unsigned int, so if out of bounds we return 0xFFFFFFFD (-3) */ + + return MXC_RTCTMR->comp[compareIndex]; +} + +/******************************************************************************/ +int RTC_SetTrim(uint32_t trim, uint8_t trimSlow) +{ + // make sure rtc is disabled + if(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_ENABLE) + return E_BAD_STATE; // RTC is active, bad state + + // Can check against this because it starts at bit 0 in the register + // Need to check because too large of a value messes with the upper bits in + // the trim register. + if (trim > MXC_F_RTC_TRIM_VALUE_TRIM_VALUE) + return E_INVALID; + + // write the trim to the hardware trim_value register + MXC_RTCTMR->trim_value = (trim << MXC_F_RTC_TRIM_VALUE_TRIM_VALUE_POS) & MXC_F_RTC_TRIM_VALUE_TRIM_VALUE; + + if(trimSlow) + MXC_RTCTMR->trim_value |= MXC_F_RTC_TRIM_VALUE_TRIM_SLOWER_CONTROL; + else + MXC_RTCTMR->trim_value &= ~MXC_F_RTC_TRIM_VALUE_TRIM_SLOWER_CONTROL; + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); + + return E_NO_ERROR; +} + +/******************************************************************************/ +uint32_t RTC_GetTrim() +{ + return MXC_RTCTMR->trim_value; // return the register value for trim +} + +/******************************************************************************/ +int RTC_TrimEnable(void) +{ + // make sure rtc is disabled + if(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_ENABLE) + return E_BAD_STATE; // RTC is active, bad state + + MXC_RTCTMR->trim_ctrl = MXC_F_RTC_TRIM_CTRL_TRIM_ENABLE_R; + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); + + return E_NO_ERROR; +} + +/******************************************************************************/ +void RTC_TrimDisable(void) +{ + // clear the trim enable bit + MXC_RTCTMR->trim_ctrl &= ~MXC_F_RTC_TRIM_CTRL_TRIM_ENABLE_R; + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); + + return; +} + +/** + * @} + */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/rtc.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/rtc.h new file mode 100644 index 00000000000..d61e4086529 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/rtc.h @@ -0,0 +1,446 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-21 10:05:23 -0500 (Mon, 21 Mar 2016) $ + * $Revision: 22008 $ + * + ******************************************************************************/ + +/** + * @file rtc.h + * @addtogroup rtc Real-time Clock + * @{ + * @brief This is the high level API for the real-time clock module + */ + +#ifndef _RTC_H +#define _RTC_H + +#include "mxc_config.h" +#include "rtc_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @enum rtc_prescale_t Defines clock divider for 4096Hz input clock. +typedef enum { + RTC_PRESCALE_DIV_2_0 = MXC_V_RTC_PRESCALE_DIV_2_0, ///< (4.096kHz) divide input clock by \f$ 2^{0} = 1 \f$ (0x001) + RTC_PRESCALE_DIV_2_1 = MXC_V_RTC_PRESCALE_DIV_2_1, ///< (2.048kHz) divide input clock by \f$ 2^{1} = 2 \f$ (0x002) + RTC_PRESCALE_DIV_2_2 = MXC_V_RTC_PRESCALE_DIV_2_2, ///< (1.024kHz) divide input clock by \f$ 2^{2} = 4 \f$ + RTC_PRESCALE_DIV_2_3 = MXC_V_RTC_PRESCALE_DIV_2_3, ///< (512Hz) divide input clock by \f$ 2^{3} = 8 \f$ + RTC_PRESCALE_DIV_2_4 = MXC_V_RTC_PRESCALE_DIV_2_4, ///< (256Hz) divide input clock by \f$ 2^{4} = 16 \f$ + RTC_PRESCALE_DIV_2_5 = MXC_V_RTC_PRESCALE_DIV_2_5, ///< (128Hz) divide input clock by \f$ 2^{5} = 32 \f$ + RTC_PRESCALE_DIV_2_6 = MXC_V_RTC_PRESCALE_DIV_2_6, ///< (64Hz) divide input clock by \f$ 2^{6} = 64 \f$ + RTC_PRESCALE_DIV_2_7 = MXC_V_RTC_PRESCALE_DIV_2_7, ///< (32Hz) divide input clock by \f$ 2^{7} = 128 \f$ + RTC_PRESCALE_DIV_2_8 = MXC_V_RTC_PRESCALE_DIV_2_8, ///< (16Hz) divide input clock by \f$ 2^{8} = 256 \f$ + RTC_PRESCALE_DIV_2_9 = MXC_V_RTC_PRESCALE_DIV_2_9, ///< (8Hz) divide input clock by \f$ 2^{9} = 512 \f$ + RTC_PRESCALE_DIV_2_10 = MXC_V_RTC_PRESCALE_DIV_2_10, ///< (4Hz) divide input clock by \f$ 2^{10} = 1024 \f$ + RTC_PRESCALE_DIV_2_11 = MXC_V_RTC_PRESCALE_DIV_2_11, ///< (2Hz) divide input clock by \f$ 2^{11} = 2048 \f$ (0x07FF) + RTC_PRESCALE_DIV_2_12 = MXC_V_RTC_PRESCALE_DIV_2_12, ///< (1Hz) divide input clock by \f$ 2^{12} = 4096 \f$ (0x0FFF) +} rtc_prescale_t; + +/// @def RTC_CTRL_ACTIVE_TRANS Active Transaction Flags for the RTC +#define RTC_CTRL_ACTIVE_TRANS (MXC_F_RTC_CTRL_RTC_ENABLE_ACTIVE | \ + MXC_F_RTC_CTRL_OSC_GOTO_LOW_ACTIVE | \ + MXC_F_RTC_CTRL_OSC_FRCE_SM_EN_ACTIVE | \ + MXC_F_RTC_CTRL_OSC_FRCE_ST_ACTIVE | \ + MXC_F_RTC_CTRL_RTC_SET_ACTIVE | \ + MXC_F_RTC_CTRL_RTC_CLR_ACTIVE | \ + MXC_F_RTC_CTRL_ROLLOVER_CLR_ACTIVE | \ + MXC_F_RTC_CTRL_PRESCALE_CMPR0_ACTIVE | \ + MXC_F_RTC_CTRL_PRESCALE_UPDATE_ACTIVE | \ + MXC_F_RTC_CTRL_CMPR1_CLR_ACTIVE | \ + MXC_F_RTC_CTRL_CMPR0_CLR_ACTIVE | \ + MXC_F_RTC_CTRL_TRIM_ENABLE_ACTIVE | \ + MXC_F_RTC_CTRL_TRIM_SLOWER_ACTIVE | \ + MXC_F_RTC_CTRL_TRIM_CLR_ACTIVE | \ + MXC_F_RTC_CTRL_ACTIVE_TRANS_0) + +/// @def RTC_FLAGS_CLEAR_ALL Number of RTC compare registers +#define RTC_FLAGS_CLEAR_ALL (MXC_F_RTC_FLAGS_COMP0 | \ + MXC_F_RTC_FLAGS_COMP1| \ + MXC_F_RTC_FLAGS_PRESCALE_COMP | \ + MXC_F_RTC_FLAGS_OVERFLOW | \ + MXC_F_RTC_FLAGS_TRIM) +/// @enum rtc_snooze_t Defines the snooze modes +typedef enum { + RTC_SNOOZE_DISABLE = MXC_V_RTC_CTRL_SNOOZE_DISABLE, ///< Snooze Mode Disabled + RTC_SNOOZE_MODE_A = MXC_V_RTC_CTRL_SNOOZE_MODE_A, ///< COMP1 = COMP1 + RTC_SNZ_VALUE when snooze flag is set + RTC_SNOOZE_MODE_B = MXC_V_RTC_CTRL_SNOOZE_MODE_B, ///< COMP1 = RTC_TIMER + RTC_SNZ_VALUE when snooze flag is set +} rtc_snooze_t; /// Defines the snooze modes + +/// @def RTC_NUM_COMPARE Number of RTC compare registers +#define RTC_NUM_COMPARE 2 + +/// @brief A structure that represents the configuration of the RTC peripheral +typedef struct { + rtc_prescale_t prescaler; /// prescale value rtc_prescale_t + rtc_prescale_t prescalerMask; /// Mask value used to compare to the rtc prescale value, when the \f$ \big((Count_{prescaler}\,\&\,Prescale\,Mask) == 0\big) \f$, the prescale compare flag will be set. + uint32_t compareCount[RTC_NUM_COMPARE]; /// Values used for the RTC alarms. See RTC_SetCompare() and RTC_GetCompare() + uint32_t snoozeCount; /// The number of RTC ticks to snooze if enabled. + rtc_snooze_t snoozeMode; /// The desired snooze mode +} rtc_cfg_t; + +/** + * @brief Initializes the RTC + * @note Must setup clocking and power prior to this function. + * + * @param cfg configuration + * + * @retval E_NO_ERROR if everything is successful + * @retval E_NULL_PTR if cfg pointer is NULL + * @retval E_INVALID if comparison index, prescaler mask or snooze mask are + * out of bounds + */ +int RTC_Init(const rtc_cfg_t *cfg); + +/** + * @brief Enable and start the real-time clock continuing from its current value + */ +__STATIC_INLINE void RTC_Start(void) +{ + MXC_RTCTMR->ctrl |= MXC_F_RTC_CTRL_ENABLE; + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); +} + +/** + * @brief Disable and stop the real-time clock + */ +__STATIC_INLINE void RTC_Stop(void) +{ + MXC_RTCTMR->ctrl &= ~(MXC_F_RTC_CTRL_ENABLE); + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); +} + +/** + * @brief Determines if the RTC is running or not. + * + * @retval 0 if Disabled, Non-zero if Active + */ +__STATIC_INLINE uint32_t RTC_IsActive(void) +{ + return (MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_ENABLE); +} + +/** + * @brief Set the current count of the RTC + * + * @param count count value to set current real-time count. + */ +__STATIC_INLINE void RTC_SetCount(uint32_t count) +{ + MXC_RTCTMR->timer = count; + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); +} + +/** + * @brief Get the current timer value of the RTC. + * + * @retval The value of the RTC counter. + */ +__STATIC_INLINE uint32_t RTC_GetCount(void) +{ + return (MXC_RTCTMR->timer); +} + +/** + * @brief Set the comparator value + * + * @param compareIndex Index of comparator to set, see RTC_NUM_COMPARE + * for the total number of compare registers available. + * @param counts Unsigned 32-bit compare value to set. + * @retval E_NO_ERROR Compare count register set successfully for requested + * comparator. + * @retval E_INVALID compareIndex is \>= RTC_NUM_COMPARE. + */ +int RTC_SetCompare(uint8_t compareIndex, uint32_t counts); + +/** + * @brief Get the comparator value + * + * @param compareIndex Index of the comparator to get. See RTC_NUM_COMPARE + * for the total number of compare registers available. + * + * @retval uint32_t The current value of the specified compare register for the RTC + */ +uint32_t RTC_GetCompare(uint8_t compareIndex); + +/** + * @brief Set the prescale reload value for the real-time clock. + * @details The prescale reload value determines the number of 4kHz ticks + * occur before the timer is incremented. See @ref prescaler_val "Table" + * for accepted values and corresponding timer resolution. + * + * + * + *
Prescaler Settings and Corresponding RTC Resolutions
PRESCALE Prescale Reload 4kHz ticks in LSB Min Timer Value (sec) Max Timer Value (sec) Max Timer Value (Days) Max Timer Value (Years) + *
0h RTC_PRESCALE_DIV_2_0 1 0.00024 1048576 12 0.0 + *
1h RTC_PRESCALE_DIV_2_1 2 0.00049 2097152 24 0.1 + *
2h RTC_PRESCALE_DIV_2_2 4 0.00098 4194304 49 0.1 + *
3h RTC_PRESCALE_DIV_2_3 8 0.00195 8388608 97 0.3 + *
4h RTC_PRESCALE_DIV_2_4 16 0.00391 16777216 194 0.5 + *
5h RTC_PRESCALE_DIV_2_5 32 0.00781 33554432 388 1.1 + *
6h RTC_PRESCALE_DIV_2_6 64 0.01563 67108864 777 2.2 + *
7h RTC_PRESCALE_DIV_2_7 128 0.03125 134217728 1553 4.4 + *
8h RTC_PRESCALE_DIV_2_8 256 0.06250 268435456 3107 8.7 + *
9h RTC_PRESCALE_DIV_2_9 512 0.12500 536870912 6214 17.5 + *
Ah RTC_PRESCALE_DIV_2_10 1024 0.25000 1073741824 12428 34.9 + *
Bh RTC_PRESCALE_DIV_2_11 2048 0.50000 2147483648 24855 69.8 + *
Ch RTC_PRESCALE_DIV_2_12 4096 1.00000 4294967296 49710 139.6 + *
+ * + * @param prescaler Prescale value to set, see rtc_prescale_t. + */ +__STATIC_INLINE void RTC_SetPrescaler(rtc_prescale_t prescaler) +{ + MXC_RTCTMR->prescale = prescaler; + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); +} + +/** + * @brief Get the current value of the real-time clock prescaler. + * + * @retval rtc_prescale_t Returns the current RTC prescaler setting, + * See rtc_prescale_t for values of the prescaler. + */ +__STATIC_INLINE rtc_prescale_t RTC_GetPrescaler(void) +{ + return (rtc_prescale_t)(MXC_RTCTMR->prescale); +} + +/** + * @brief Set the prescaler mask, which is used to set the RTC prescale counter + * compare flag when the prescaler timer matches the bits indicated + * by the mask. + * @param mask A bit mask that is used to set the prescale compare flag if the + * prescale timer has the corresponding bits set. @note This mask must + * be less than or equal to the prescaler reload value. + * See RTC_SetPrescaler() + * @details When \f$ \big((Count_{prescaler}\,\&\,Prescale\,Mask) == 0\big) \f$, the prescale compare flag is set + * @retval int Returns E_NO_ERROR if prescale value is valid and is set. + * @retval int Returns E_INVALID if mask is \> than prescaler value + */ +__STATIC_INLINE int RTC_SetPrescalerMask(rtc_prescale_t mask) +{ + if (mask > ((rtc_prescale_t)(MXC_RTCTMR->prescale))) { + return E_INVALID; + } + MXC_RTCTMR->prescale_mask = mask; + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); + return E_NO_ERROR; +} + +/** + * @brief Set the number of ticks for snooze mode. See RTC_Snooze(). + * @param count Sets the count used for snoozing when snooze mode is enabled and + * the snooze flag is set. + * @retval E_NO_ERROR If snooze value is set correctly and value is valid. + * @retval E_INVALID If SnoozeCount exceeds maximum supported, see MXC_F_RTC_SNZ_VAL_VALUE + * + */ +__STATIC_INLINE int RTC_SetSnoozeCount(uint32_t count) +{ + // Check to make sure max value is not being exceeded + if (count > MXC_F_RTC_SNZ_VAL_VALUE) + return E_INVALID; + + MXC_RTCTMR->snz_val = count; + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); + return E_NO_ERROR; +} + +/** + * @brief Gets the Snooze Count that is currently loaded in the RTC timer + * @details Returns the current value for the Snooze. This value is used as + * part of the snooze calculation depending on the snooze mode. @see RTC_SetSnoozeMode + * @retval uint32_t value of the snooze register + * + */ +__STATIC_INLINE uint32_t RTC_GetSnoozeCount(void) +{ + return MXC_RTCTMR->snz_val; +} + +/** + * @brief Set the flags to activate the snooze + * @details Begins a snooze of the RTC. When this function is called + * the snooze count is determined based on the snooze mode. + * See RTC_GetCount() and RTC_SetSnoozeMode() + */ +__STATIC_INLINE void RTC_Snooze(void) +{ + MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_SNOOZE_A | MXC_F_RTC_FLAGS_SNOOZE_B; + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); +} + +/** + * @brief Sets the Snooze Mode. + * @details + * + *
Snooze Modes
ModeSnooze Time Calculation + *
RTC_SNOOZE_DISABLESnooze Disabled + *
RTC_SNOOZE_MODE_A\f$ compare1 = compare1 + snoozeCount \f$ + *
RTC_SNOOZE_MODE_B\f$ compare1 = count + snoozeCount \f$ + *
+ * \a count is the value of the RTC counter when RTC_Snooze() is called to begin snooze + */ +__STATIC_INLINE void RTC_SetSnoozeMode(rtc_snooze_t mode) +{ + uint32_t ctrl; + // Get the control register and mask off the non-snooze bits + ctrl = (MXC_RTCTMR->ctrl & ~(MXC_F_RTC_CTRL_SNOOZE_ENABLE)); + // set the requested snooze mode bits and save the settings + MXC_RTCTMR->ctrl = (ctrl | (mode << MXC_F_RTC_CTRL_SNOOZE_ENABLE_POS)); + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); +} + +/** + * @brief Enables the interrupts defined by the mask for the RTC. + * @details + * + *
RTC Interrupts
InterruptMask + *
Compare 0MXC_F_RTC_INTEN_COMP0 + *
Compare 1 \\ SnoozeMXC_F_RTC_INTEN_COMP1 + *
Prescale CompMXC_F_RTC_FLAGS_INTEN_COMP + *
RTC Count OverflowMXC_F_RTC_INTEN_OVERFLOW + *
TrimMXC_F_RTC_INTEN_TRIM + *
+ * @param mask set the bits of the interrupts to enable + */ +__STATIC_INLINE void RTC_EnableINT(uint32_t mask) +{ + MXC_RTCTMR->inten |= mask; +} + +/** + * @brief Disable RTC interrupts based on the mask, See @ref RTC_interrupts + * + * @param mask set the bits of the interrupts to disable + */ +__STATIC_INLINE void RTC_DisableINT(uint32_t mask) +{ + MXC_RTCTMR->inten &= ~mask; +} + +/** + * @brief Gets the RTC's interrupt flags + * + * @retval uint32_t interrupt flags + */ +__STATIC_INLINE uint32_t RTC_GetFlags(void) +{ + return (MXC_RTCTMR->flags); +} + +/** + * @brief Clears the RTC's interrupt flags based on the mask provided + * + * @param mask masked used to clear individual interrupt flags + */ +__STATIC_INLINE void RTC_ClearFlags(uint32_t mask) +{ + MXC_RTCTMR->flags = mask; + + //wait for pending actions to complete + while(MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); +} + +/** + * @brief Gets the active transaction flags + * + * @retval 0 = no active transactions , nonzero = active transactions bits + */ +__STATIC_INLINE uint32_t RTC_GetActiveTrans(void) +{ + return (MXC_RTCTMR->ctrl & RTC_CTRL_ACTIVE_TRANS); +} + +/** + * @brief Sets the trim value and trim slow/fast option + * @note Ensure RTC is disabled prior to calling this function + * + * @param trim trim value - maximum trim value setting of 0x03FFFF + * @param trimSlow 1 = trim slow, 0 = trim fast + * + * @retval E_NO_ERROR Trim value is valid and set. + * @retval E_INVALID Trim value exceeds max trim. + * @retval E_BAD_STATE RTC is not disabled. + * + */ +int RTC_SetTrim(uint32_t trim, uint8_t trimSlow); + +/** + * @brief Gets the trim value currently set + * @note Ensure RTC is disabled prior to calling this function + * + * @retval uint32_t Current trim value of RTC. + */ +uint32_t RTC_GetTrim(void); + +/** + * @brief Enabled the trim. + * @note Ensure RTC is disabled prior to calling this function + * @retval E_NO_ERROR Trim enabled + * @retval E_INVALID + */ +int RTC_TrimEnable(void); + +/** + * @brief Disable the trim. + */ +void RTC_TrimDisable(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTC_H */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spim.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spim.c new file mode 100644 index 00000000000..a132752b883 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spim.c @@ -0,0 +1,720 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-07-26 08:41:27 -0500 (Tue, 26 Jul 2016) $ + * $Revision: 23789 $ + * + ******************************************************************************/ + +/** + * @file spim.c + * @brief SPI Master driver source. + */ + +/***** Includes *****/ +#include +#include +#include "mxc_config.h" +#include "mxc_assert.h" +#include "mxc_lock.h" +#include "spim.h" + +/***** Definitions *****/ +#define SPIM_MAX_BYTE_LEN 32 +#define SPIM_MAX_PAGE_LEN 32 + +/***** Globals *****/ + +// Saves the state of the non-blocking requests +typedef struct { + spim_req_t *req; + unsigned head_rem; +} spim_req_head_t; + +static spim_req_head_t states[MXC_CFG_SPIM_INSTANCES]; + +/***** Functions *****/ + +static unsigned SPIM_ReadRXFIFO(mxc_spim_regs_t *spim, mxc_spim_fifo_regs_t *fifo, + uint8_t *data, unsigned len); + +static uint32_t SPIM_TransHandler(mxc_spim_regs_t *spim, spim_req_t *req, int spim_num); + +/******************************************************************************/ +int SPIM_Init(mxc_spim_regs_t *spim, const spim_cfg_t *cfg, const sys_cfg_spim_t *sys_cfg) +{ + int err, spim_num; + uint32_t spim_clk, clocks; + + spim_num = MXC_SPIM_GET_IDX(spim); + MXC_ASSERT(spim_num >= 0); + + // Check the input parameters + if(cfg == NULL) + return E_NULL_PTR; + + if(cfg->baud == 0) + return E_BAD_PARAM; + + // Set system level configurations + if ((err = SYS_SPIM_Init(spim, cfg, sys_cfg)) != E_NO_ERROR) { + return err; + } + + /* Configure the baud, make sure the SPIM clk is enabled and the baud + is less than the maximum */ + spim_clk = SYS_SPIM_GetFreq(spim); + if((spim_clk == 0) || ((spim_clk == SystemCoreClock) && ((spim_clk/2) < cfg->baud))) { + return E_BAD_PARAM; + } + + // Initialize state pointers + states[spim_num].req = NULL; + states[spim_num].head_rem = 0; + + // Drain the FIFOs, enable SPIM, enable SCK Feedback + spim->gen_ctrl = 0; + spim->gen_ctrl = (MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN | MXC_F_SPIM_GEN_CTRL_TX_FIFO_EN | + MXC_F_SPIM_GEN_CTRL_RX_FIFO_EN | MXC_F_SPIM_GEN_CTRL_ENABLE_SCK_FB_MODE); + + // Set mode and page size + spim->mstr_cfg = (((cfg->mode << MXC_F_SPIM_MSTR_CFG_SPI_MODE_POS) & MXC_F_SPIM_MSTR_CFG_SPI_MODE) | + MXC_S_SPIM_MSTR_CFG_PAGE_32B | (0x2 << MXC_F_SPIM_MSTR_CFG_ACT_DELAY_POS)); + + // Configure the SSEL polarity + spim->ss_sr_polarity = ((cfg->ssel_pol << MXC_F_SPIM_SS_SR_POLARITY_SS_POLARITY_POS) & + MXC_F_SPIM_SS_SR_POLARITY_SS_POLARITY); + +#if(MXC_SPIM_REV == 0) + // Disable the feedback clock in modes 1 and 2 + if((cfg->mode == 1) || (cfg->mode == 2)) { + spim->gen_ctrl &= ~MXC_F_SPIM_GEN_CTRL_ENABLE_SCK_FB_MODE; + spim->mstr_cfg |= (0x1 << MXC_F_SPIM_MSTR_CFG_SDIO_SAMPLE_POINT_POS); + } +#else + // Increase the RX FIFO margin + MXC_SPIM1->spcl_ctrl = ((MXC_SPIM1->spcl_ctrl & ~(MXC_F_SPIM_SPCL_CTRL_RX_FIFO_MARGIN)) | + (0x3 << MXC_F_SPIM_SPCL_CTRL_RX_FIFO_MARGIN_POS)); +#endif + + // Calculate the hi/lo clock setting + if(spim_clk/2 > cfg->baud) { + + /* Disable the feedback mode and use the sample mode with an appropriate hi/lo clk + to achieve the lower baud rate */ + spim->gen_ctrl &= ~MXC_F_SPIM_GEN_CTRL_ENABLE_SCK_FB_MODE; + + clocks = (spim_clk / (2*cfg->baud)); + + if(clocks == 0 || clocks > 0x10) { + return E_BAD_PARAM; + } + + // 0 => 16 in the 4 bit field for HI_CLK and LO_CLK + if(clocks == 0x10) { + clocks = 0; + } + + } else { + // Continue to use feedback mode and set hi/lo clk to 1 + clocks = 1; + } + + spim->mstr_cfg |= (((clocks << MXC_F_SPIM_MSTR_CFG_SCK_HI_CLK_POS) & MXC_F_SPIM_MSTR_CFG_SCK_HI_CLK) | + ((clocks << MXC_F_SPIM_MSTR_CFG_SCK_LO_CLK_POS) & MXC_F_SPIM_MSTR_CFG_SCK_LO_CLK)); + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SPIM_Shutdown(mxc_spim_regs_t *spim) +{ + int spim_num, err; + spim_req_t *temp_req; + + // Disable and clear interrupts + spim->inten = 0; + spim->intfl = spim->intfl; + + // Disable SPIM and FIFOS + spim->gen_ctrl &= ~(MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN | MXC_F_SPIM_GEN_CTRL_TX_FIFO_EN | + MXC_F_SPIM_GEN_CTRL_RX_FIFO_EN); + + // Call all of the pending callbacks for this SPIM + spim_num = MXC_SPIM_GET_IDX(spim); + if(states[spim_num].req != NULL) { + + // Save the request + temp_req = states[spim_num].req; + + // Unlock this SPIM + mxc_free_lock((uint32_t*)&states[spim_num].req); + + // Callback if not NULL + if(temp_req->callback != NULL) { + temp_req->callback(temp_req, E_SHUTDOWN); + } + } + + // Clear system level configurations + if ((err = SYS_SPIM_Shutdown(spim)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SPIM_Clocks(mxc_spim_regs_t *spim, uint32_t len, uint8_t ssel, uint8_t deass) +{ + int spim_num; + mxc_spim_fifo_regs_t *fifo; + uint16_t header = 0x1; + uint32_t num = len; + + // Make sure the SPIM has been initialized + if((spim->gen_ctrl & MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN) == 0) + return E_UNINITIALIZED; + + if(!(len > 0)) { + return E_NO_ERROR; + } + + // Check the previous transaction if we're switching the slave select + if((ssel != ((spim->mstr_cfg & MXC_F_SPIM_MSTR_CFG_SLAVE_SEL) >> + MXC_F_SPIM_MSTR_CFG_SLAVE_SEL_POS)) && (spim->gen_ctrl & MXC_F_SPIM_GEN_CTRL_BB_SS_IN_OUT)) { + + // Return E_BUSY if the slave select is still asserted + return E_BUSY; + } + + // Attempt to lock this SPIM + spim_num = MXC_SPIM_GET_IDX(spim); + if(mxc_get_lock((uint32_t*)&states[spim_num].req, 1) != E_NO_ERROR) { + return E_BUSY; + } + + // Set which slave select we are using + spim->mstr_cfg = ((spim->mstr_cfg & ~MXC_F_SPIM_MSTR_CFG_SLAVE_SEL) | + ((ssel << MXC_F_SPIM_MSTR_CFG_SLAVE_SEL_POS) & MXC_F_SPIM_MSTR_CFG_SLAVE_SEL)); + + //force deass to a 1 or 0 + deass = !!deass; + +#if(MXC_SPIM_REV == 0) + // Wait for all of the data to transmit + while(spim->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_TX_FIFO_USED) {} + + // Disable the feedback clock, save state + uint32_t gen_ctrl = spim->gen_ctrl; + spim->gen_ctrl &= ~MXC_F_SPIM_GEN_CTRL_ENABLE_SCK_FB_MODE; +#endif + + // Get the TX and RX FIFO for this SPIM + fifo = MXC_SPIM_GET_SPIM_FIFO(spim_num); + + // Send the headers to transmit the clocks + while(len > 32) { + fifo->trans_16[0] = header; + fifo->trans_16[0] = 0xF000; + fifo->trans_16[0] = 0xF000; + len -= 32; + } + + if(len) { + if(len < 32) { + header |= (len << 4); + } + header |= (deass << 13); + + fifo->trans_16[0] = header; + + if(len > 16) { + fifo->trans_16[0] = 0xF000; + } + fifo->trans_16[0] = 0xF000; + } + +#if(MXC_SPIM_REV == 0) + // Wait for all of the data to transmit + while(spim->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_TX_FIFO_USED) {} + + // Restore feedback clock setting + spim->gen_ctrl |= (gen_ctrl & MXC_F_SPIM_GEN_CTRL_ENABLE_SCK_FB_MODE); +#endif + + // Unlock this SPIM + mxc_free_lock((uint32_t*)&states[spim_num].req); + + return num; +} + + +/******************************************************************************/ +int SPIM_Trans(mxc_spim_regs_t *spim, spim_req_t *req) +{ + int spim_num; + + // Make sure the SPIM has been initialized + if((spim->gen_ctrl & MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN) == 0) + return E_UNINITIALIZED; + + // Check the input parameters + if(req == NULL) + return E_NULL_PTR; + + if((req->rx_data == NULL) && (req->tx_data == NULL)) + return E_NULL_PTR; + + if(!(req->len > 0)) { + return E_NO_ERROR; + } + + // Check the previous transaction if we're switching the slave select + if((req->ssel != ((spim->mstr_cfg & MXC_F_SPIM_MSTR_CFG_SLAVE_SEL) >> + MXC_F_SPIM_MSTR_CFG_SLAVE_SEL_POS)) && (spim->gen_ctrl & MXC_F_SPIM_GEN_CTRL_BB_SS_IN_OUT)) { + + // Return E_BUSY if the slave select is still asserted + return E_BUSY; + } + + // Attempt to register this write request + spim_num = MXC_SPIM_GET_IDX(spim); + if(mxc_get_lock((uint32_t*)&states[spim_num].req, (uint32_t)req) != E_NO_ERROR) { + return E_BUSY; + } + + // Set which slave select we are using + spim->mstr_cfg = ((spim->mstr_cfg & ~MXC_F_SPIM_MSTR_CFG_SLAVE_SEL) | + ((req->ssel << MXC_F_SPIM_MSTR_CFG_SLAVE_SEL_POS) & MXC_F_SPIM_MSTR_CFG_SLAVE_SEL)); + + //force deass to a 1 or 0 + req->deass = !!req->deass; + + // Clear the number of bytes counter + req->read_num = 0; + req->write_num = 0; + req->callback = NULL; + states[spim_num].head_rem = 0; + + // Start the transaction, keep calling the handler until complete + while(SPIM_TransHandler(spim, req, spim_num) != 0); + + if(req->tx_data == NULL) { + return req->read_num; + } + return req->write_num; +} + +/******************************************************************************/ +int SPIM_TransAsync(mxc_spim_regs_t *spim, spim_req_t *req) +{ + int spim_num; + + // Make sure the SPIM has been initialized + if((spim->gen_ctrl & MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN) == 0) + return E_UNINITIALIZED; + + // Check the input parameters + if(req == NULL) + return E_NULL_PTR; + + if((req->rx_data == NULL) && (req->tx_data == NULL)) + return E_NULL_PTR; + + if(!(req->len > 0)) { + return E_NO_ERROR; + } + + + // Check the previous transaction if we're switching the slave select + if((req->ssel != ((spim->mstr_cfg & MXC_F_SPIM_MSTR_CFG_SLAVE_SEL) >> + MXC_F_SPIM_MSTR_CFG_SLAVE_SEL_POS)) && (spim->gen_ctrl & MXC_F_SPIM_GEN_CTRL_BB_SS_IN_OUT)) { + + // Return E_BUSY if the slave select is still asserted + return E_BUSY; + } + + // Attempt to register this write request + spim_num = MXC_SPIM_GET_IDX(spim); + if(mxc_get_lock((uint32_t*)&states[spim_num].req, (uint32_t)req) != E_NO_ERROR) { + return E_BUSY; + } + + // Set which slave select we are using + spim->mstr_cfg = ((spim->mstr_cfg & ~MXC_F_SPIM_MSTR_CFG_SLAVE_SEL) | + ((req->ssel << MXC_F_SPIM_MSTR_CFG_SLAVE_SEL_POS) & MXC_F_SPIM_MSTR_CFG_SLAVE_SEL)); + + //force deass to a 1 or 0 + req->deass = !!req->deass; + + // Clear the number of bytes counter + req->read_num = 0; + req->write_num = 0; + states[spim_num].head_rem = 0; + + // Start the transaction, enable the interrupts + spim->inten = SPIM_TransHandler(spim, req, spim_num); + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SPIM_AbortAsync(spim_req_t *req) +{ + int spim_num; + mxc_spim_regs_t *spim; + + // Check the input parameters + if(req == NULL) { + return E_BAD_PARAM; + } + + // Find the request, set to NULL + for(spim_num = 0; spim_num < MXC_CFG_SPIM_INSTANCES; spim_num++) { + if(req == states[spim_num].req) { + + spim = MXC_SPIM_GET_SPIM(spim_num); + + // Disable interrupts, clear the flags + spim->inten = 0; + spim->intfl = spim->intfl; + + // Reset the SPIM to cancel the on ongoing transaction + spim->gen_ctrl &= ~(MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN); + spim->gen_ctrl |= (MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN); + + // Unlock this SPIM + mxc_free_lock((uint32_t*)&states[spim_num].req); + + // Callback if not NULL + if(req->callback != NULL) { + req->callback(req, E_ABORT); + } + + return E_NO_ERROR; + } + } + + return E_BAD_PARAM; +} + +/******************************************************************************/ +void SPIM_Handler(mxc_spim_regs_t *spim) +{ + int spim_num; + uint32_t flags; + + // Clear the interrupt flags + spim->inten = 0; + flags = spim->intfl; + spim->intfl = flags; + + spim_num = MXC_SPIM_GET_IDX(spim); + + // Figure out if this SPIM has an active request + if((states[spim_num].req != NULL) && (flags)) { + spim->inten = SPIM_TransHandler(spim, states[spim_num].req, spim_num); + } +} + +/******************************************************************************/ +int SPIM_Busy(mxc_spim_regs_t *spim) +{ + // Check to see if there are any ongoing transactions + if((states[MXC_SPIM_GET_IDX(spim)].req == NULL) && + !(spim->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_TX_FIFO_USED)) { + + return E_NO_ERROR; + } + + return E_BUSY; +} + +/******************************************************************************/ +int SPIM_PrepForSleep(mxc_spim_regs_t *spim) +{ + if(SPIM_Busy(spim) != E_NO_ERROR) { + return E_BUSY; + } + + // Disable interrupts + spim->inten = 0; + return E_NO_ERROR; +} + +/******************************************************************************/ +static unsigned SPIM_ReadRXFIFO(mxc_spim_regs_t *spim, mxc_spim_fifo_regs_t *fifo, + uint8_t *data, unsigned len) +{ + unsigned num = 0; + unsigned avail = ((spim->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED) >> + MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED_POS); + + // Get data from the RXFIFO + while(avail && (len - num)) { + + if((avail >= 4) && ((len-num) >= 4)) { + // Save data from the RXFIFO + uint32_t temp = fifo->rslts_32[0]; + data[num+0] = ((temp & 0x000000FF) >> 0); + data[num+1] = ((temp & 0x0000FF00) >> 8); + data[num+2] = ((temp & 0x00FF0000) >> 16); + data[num+3] = ((temp & 0xFF000000) >> 24); + num+=4; + avail-=4; + } else if ((avail >= 2) && ((len-num) >= 2)) { + // Save data from the RXFIFO + uint16_t temp = fifo->rslts_16[0]; + data[num+0] = ((temp & 0x00FF) >> 0); + data[num+1] = ((temp & 0xFF00) >> 8); + num+=2; + avail-=2; + } else { + // Save data from the RXFIFO + data[num] = fifo->rslts_8[0]; + num+=1; + avail-=1; + } + + // Check to see if there is more data in the FIFO + if(avail == 0) { + avail = ((spim->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED) >> + MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED_POS); + } + } + + return num; +} + +uint16_t header_save; + + +/******************************************************************************/ +static uint32_t SPIM_TransHandler(mxc_spim_regs_t *spim, spim_req_t *req, int spim_num) +{ + uint8_t read, write; + uint16_t header; + uint32_t pages, bytes, inten; + unsigned remain, bytes_read, head_rem_temp, avail; + mxc_spim_fifo_regs_t *fifo; + + inten = 0; + + // Get the FIFOS for this UART + fifo = MXC_SPIM_GET_SPIM_FIFO(spim_num); + + // Figure out if we're reading + if(req->rx_data != NULL) { + read = 1; + } else { + read = 0; + } + + // Figure out if we're writing + if(req->tx_data != NULL) { + write = 1; + } else { + write = 0; + } + + // Read byte from the FIFO if we are reading + if(read) { + + // Read all of the data in the RXFIFO, or until we don't need anymore + bytes_read = SPIM_ReadRXFIFO(spim, fifo, &req->rx_data[req->read_num], + (req->len - req->read_num)); + + req->read_num += bytes_read; + + // Adjust head_rem if we are only reading + if(!write && (states[spim_num].head_rem > 0)) { + states[spim_num].head_rem -= bytes_read; + } + + // Figure out how many byte we have left to read + if(states[spim_num].head_rem > 0) { + remain = states[spim_num].head_rem; + } else { + remain = req->len - req->read_num; + } + + if(remain) { + + // Set the RX interrupts + if (remain > MXC_CFG_SPIM_FIFO_DEPTH) { + spim->fifo_ctrl = ((spim->fifo_ctrl & ~MXC_F_SPIM_FIFO_CTRL_RX_FIFO_AF_LVL) | + ((MXC_CFG_SPIM_FIFO_DEPTH - 2) << + MXC_F_SPIM_FIFO_CTRL_RX_FIFO_AF_LVL_POS)); + + } else { + spim->fifo_ctrl = ((spim->fifo_ctrl & ~MXC_F_SPIM_FIFO_CTRL_RX_FIFO_AF_LVL) | + ((remain - 1) << MXC_F_SPIM_FIFO_CTRL_RX_FIFO_AF_LVL_POS)); + } + + inten |= MXC_F_SPIM_INTEN_RX_FIFO_AF; + } + } + + // Figure out how many bytes we have left to send headers for + if(write) { + remain = req->len - req->write_num; + } else { + remain = req->len - req->read_num; + } + + // See if we need to send a new header + if(states[spim_num].head_rem <= 0 && remain) { + + // Set the transaction configuration in the header + header = ((write << 0) | (read << 1) | (req->width << 9)); + + if(remain >= SPIM_MAX_BYTE_LEN) { + + // Send a 32 byte header + if(remain == SPIM_MAX_BYTE_LEN) { + + header |= ((0x1 << 2) | (req->deass << 13)); + + // Save the number of bytes we need to write to the FIFO + bytes = SPIM_MAX_BYTE_LEN; + + } else { + // Send in increments of 32 byte pages + header |= (0x2 << 2); + pages = remain / SPIM_MAX_PAGE_LEN; + + if(pages >= 32) { + // 0 maps to 32 in the header + bytes = 32 * SPIM_MAX_PAGE_LEN; + } else { + header |= (pages << 4); + bytes = pages * SPIM_MAX_PAGE_LEN; + } + + // Check if this is the last header we will send + if((remain - bytes) == 0) { + header |= (req->deass << 13); + } + } + + header_save = header; + fifo->trans_16[0] = header; + + // Save the number of bytes we need to write to the FIFO + states[spim_num].head_rem = bytes; + + } else { + + // Send final header with the number of bytes remaining and if + // we want to de-assert the SS at the end of the transaction + header |= ((0x1 << 2) | (remain << 4) | (req->deass << 13)); + fifo->trans_16[0] = header; + states[spim_num].head_rem = remain; + } + } + + // Put data into the FIFO if we are writing + remain = req->len - req->write_num; + head_rem_temp = states[spim_num].head_rem; + if(write && head_rem_temp) { + + // Fill the FIFO + avail = (MXC_CFG_SPIM_FIFO_DEPTH - ((spim->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_TX_FIFO_USED) >> + MXC_F_SPIM_FIFO_CTRL_TX_FIFO_USED_POS)); + + // Use memcpy for everything except the last byte in odd length transactions + while((avail >= 2) && (head_rem_temp >= 2)) { + + unsigned length; + if(head_rem_temp < avail) { + length = head_rem_temp; + } else { + length = avail; + } + + // Only memcpy even numbers + length = ((length / 2) * 2); + + memcpy((void*)fifo->trans_32, &(req->tx_data[req->write_num]), length); + + head_rem_temp -= length; + req->write_num += length; + + avail = (MXC_CFG_SPIM_FIFO_DEPTH - ((spim->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_TX_FIFO_USED) >> + MXC_F_SPIM_FIFO_CTRL_TX_FIFO_USED_POS)); + } + + // Copy the last byte and pad with 0xF0 to not get confused as header + if((avail >= 1) && (head_rem_temp == 1)) { + + // Write the last byte + fifo->trans_16[0] = (0xF000 | req->tx_data[req->write_num]); + + avail -= 1; + req->write_num += 1; + head_rem_temp -= 1; + } + + states[spim_num].head_rem = head_rem_temp; + remain = req->len - req->write_num; + + // Set the TX interrupts + if(remain) { + + // Set the TX FIFO almost empty interrupt if we have to refill + spim->fifo_ctrl = ((spim->fifo_ctrl & ~MXC_F_SPIM_FIFO_CTRL_TX_FIFO_AE_LVL) | + ((MXC_CFG_SPIM_FIFO_DEPTH - 2) << MXC_F_SPIM_FIFO_CTRL_TX_FIFO_AE_LVL_POS)); + + inten |= MXC_F_SPIM_INTEN_TX_FIFO_AE; + + } + } + + // Check to see if we've finished reading and writing + if(((read && (req->read_num == req->len)) || !read) && + ((req->write_num == req->len) || !write)) { + + // Disable interrupts + spim->inten = 0; + + // Unlock this SPIM + mxc_free_lock((uint32_t*)&states[spim_num].req); + + // Callback if not NULL + if(req->callback != NULL) { + req->callback(req, E_NO_ERROR); + } + } + + // Enable the SPIM interrupts + return inten; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spim.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spim.h new file mode 100644 index 00000000000..f9ed9b8c037 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spim.h @@ -0,0 +1,263 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-04-27 11:55:43 -0500 (Wed, 27 Apr 2016) $ + * $Revision: 22541 $ + * + ******************************************************************************/ + +/** + * @file spim.h + * @brief SPI Master driver header file. + */ + +#include "mxc_config.h" +#include "mxc_sys.h" +#include "spim_regs.h" + +#ifndef _SPIM_H_ +#define _SPIM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/***** Definitions *****/ + +/// @brief Active levels for slave select lines. +typedef enum { + SPIM_SSEL0_HIGH = (0x1 << 0), + SPIM_SSEL0_LOW = 0, + SPIM_SSEL1_HIGH = (0x1 << 1), + SPIM_SSEL1_LOW = 0, + SPIM_SSEL2_HIGH = (0x1 << 2), + SPIM_SSEL2_LOW = 0, + SPIM_SSEL3_HIGH = (0x1 << 3), + SPIM_SSEL3_LOW = 0, + SPIM_SSEL4_HIGH = (0x1 << 4), + SPIM_SSEL4_LOW = 0 +} +spim_ssel_t; + +/// @brief Number of data lines to use. +typedef enum { + SPIM_WIDTH_1 = 0, + SPIM_WIDTH_2 = 1, + SPIM_WIDTH_4 = 2 +} spim_width_t; + +/// @brief SPIM configuration type. +typedef struct { + uint8_t mode; ///< SPIM mode to use, 0-3. + uint32_t ssel_pol; ///< Mask of active levels for slave select signals, use spim_ssel_t. + uint32_t baud; ///< Baud rate in Hz. +} spim_cfg_t; + +/// @brief SPIM Transaction request. +typedef struct spim_req spim_req_t; +struct spim_req { + uint8_t ssel; ///< Slave select number. + uint8_t deass; ///< De-assert slave select at the end of the transaction. + const uint8_t *tx_data; ///< TX buffer. + uint8_t *rx_data; ///< RX buffer. + spim_width_t width; ///< Number of data lines to use + unsigned len; ///< Number of bytes to send. + unsigned read_num; ///< Number of bytes read. + unsigned write_num; ///< Number of bytes written. + + /** + * @brief Callback for asynchronous request. + * @param spim_req_t* Pointer to the transaction request. + * @param int Error code. + */ + void (*callback)(spim_req_t*, int); +}; + +/***** Globals *****/ + +/***** Function Prototypes *****/ + +/** + * @brief Initialize SPIM module. + * @param spim Pointer to SPIM regs. + * @param cfg Pointer to SPIM configuration. + * @param sys_cfg Pointer to system configuration object + * @returns #E_NO_ERROR if everything is successful + */ +int SPIM_Init(mxc_spim_regs_t *spim, const spim_cfg_t *cfg, const sys_cfg_spim_t *sys_cfg); + +/** + * @brief Shutdown SPIM module. + * @param spim Pointer to SPIM regs. + * @returns #E_NO_ERROR if everything is successful + */ +int SPIM_Shutdown(mxc_spim_regs_t *spim); + +/** + * @brief Send Clock cycles on SCK without reading or writing. + * @param spim Pointer to SPIM regs. + * @param len Number of clock cycles to send. + * @param ssel Slave select number. + * @param deass De-assert slave select at the end of the transaction. + * @returns Cycles transacted if everything is successful, error if unsuccessful. + */ +int SPIM_Clocks(mxc_spim_regs_t *spim, uint32_t len, uint8_t ssel, uint8_t deass); + +/** + * @brief Read/write SPIM data. Will block until transaction is complete. + * @param spim Pointer to SPIM regs. + * @param req Request for a SPIM transaction. + * @note Callback is ignored. + * @returns Bytes transacted if everything is successful, error if unsuccessful. + */ +int SPIM_Trans(mxc_spim_regs_t *spim, spim_req_t *req); + +/** + * @brief Asynchronously read/write SPIM data. + * @param spim Pointer to SPIM regs. + * @param req Request for a SPIM transaction. + * @note Request struct must remain allocated until callback. + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int SPIM_TransAsync(mxc_spim_regs_t *spim, spim_req_t *req); + +/** + * @brief Abort asynchronous request. + * @param req Pointer to request for a SPIM transaction. + * @returns #E_NO_ERROR if request aborted, error if unsuccessful. + */ +int SPIM_AbortAsync(spim_req_t *req); + +/** + * @brief SPIM interrupt handler. + * @details This function should be called by the application from the interrupt + * handler if SPIM interrupts are enabled. Alternately, this function + * can be periodically called by the application if SPIM interrupts are + * disabled. + * @param spim Base address of the SPIM module. + */ +void SPIM_Handler(mxc_spim_regs_t *spim); + +/** + * @brief Check the SPIM to see if it's busy. + * @param spim Pointer to SPIM regs. + * @returns #E_NO_ERROR if idle, #E_BUSY if in use. + */ +int SPIM_Busy(mxc_spim_regs_t *spim); + +/** + * @brief Attempt to prepare the SPIM for sleep. + * @param spim Pointer to SPIM regs. +* @details Checks for any ongoing transactions. Disables interrupts if the SPIM + is idle. + * @returns #E_NO_ERROR if ready to sleep, #E_BUSY if not ready for sleep. + */ +int SPIM_PrepForSleep(mxc_spim_regs_t *spim); + +/** + * @brief Enables the SPIM without overwriting existing configuration. + * @param spim Pointer to SPIM regs. + */ +__STATIC_INLINE void SPIM_Enable(mxc_spim_regs_t *spim) +{ + spim->gen_ctrl |= (MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN | + MXC_F_SPIM_GEN_CTRL_TX_FIFO_EN | MXC_F_SPIM_GEN_CTRL_RX_FIFO_EN); +} + +/** + * @brief Drain all of the data in the RXFIFO. + * @param spim Pointer to UART regs. + */ +__STATIC_INLINE void SPIM_DrainRX(mxc_spim_regs_t *spim) +{ + uint32_t ctrl_save = spim->gen_ctrl; + spim->gen_ctrl = (ctrl_save & ~MXC_F_SPIM_GEN_CTRL_RX_FIFO_EN); + spim->gen_ctrl = ctrl_save; +} + +/** + * @brief Drain all of the data in the TXFIFO. + * @param spim Pointer to UART regs. + */ +__STATIC_INLINE void SPIM_DrainTX(mxc_spim_regs_t *spim) +{ + uint32_t ctrl_save = spim->gen_ctrl; + spim->gen_ctrl = (ctrl_save & ~MXC_F_SPIM_GEN_CTRL_TX_FIFO_EN); + spim->gen_ctrl = ctrl_save; +} + +/** + * @brief TX FIFO availability. + * @param spim Pointer to UART regs. + * @returns Number of empty bytes available in write FIFO. + */ +__STATIC_INLINE unsigned SPIM_NumWriteAvail(mxc_spim_regs_t *spim) +{ + return (MXC_CFG_SPIM_FIFO_DEPTH - ((spim->fifo_ctrl & + MXC_F_SPIM_FIFO_CTRL_TX_FIFO_USED) >> MXC_F_SPIM_FIFO_CTRL_TX_FIFO_USED_POS)); +} + +/** + * @brief RX FIFO availability. + * @param spim Pointer to UART regs. + * @returns Number of bytes in read FIFO. + */ +__STATIC_INLINE unsigned SPIM_NumReadAvail(mxc_spim_regs_t *spim) +{ + return ((spim->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED) >> + MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED_POS); +} + +/** + * @brief Clear interrupt flags. + * @param spim Pointer to SPIM regs. + * @param mask Mask of interrupts to clear. + */ +__STATIC_INLINE void SPIM_ClearFlags(mxc_spim_regs_t *spim, uint32_t mask) +{ + spim->intfl = mask; +} + +/** + * @brief Get interrupt flags. + * @param spim Pointer to SPIM regs. + * @returns Mask of active flags. + */ +__STATIC_INLINE unsigned SPIM_GetFlags(mxc_spim_regs_t *spim) +{ + return (spim->intfl); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _SPIM_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spis.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spis.c new file mode 100644 index 00000000000..503987d7b43 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spis.c @@ -0,0 +1,457 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-08-03 16:00:49 -0500 (Wed, 03 Aug 2016) $ + * $Revision: 23914 $ + * + ******************************************************************************/ + +/** + * @file spis.c + * @brief SPI Slave driver source. + */ + +/***** Includes *****/ +#include +#include +#include "mxc_config.h" +#include "mxc_assert.h" +#include "mxc_lock.h" +#include "spis.h" + +/***** Definitions *****/ +#define SPIS_FIFO_BUFFER 6 + +/***** Globals *****/ + +static spis_req_t *states[MXC_CFG_SPIS_INSTANCES]; + +/***** Functions *****/ + +static uint32_t SPIS_TransHandler(mxc_spis_regs_t *spis, spis_req_t *req, int spis_num); + +/******************************************************************************/ +int SPIS_Init(mxc_spis_regs_t *spis, uint8_t mode, const sys_cfg_spis_t *sys_cfg) +{ + int err, spis_num; + + spis_num = MXC_SPIS_GET_IDX(spis); + MXC_ASSERT(spis_num >= 0); + + // Set system level configurations + if ((err = SYS_SPIS_Init(sys_cfg)) != E_NO_ERROR) { + return err; + } + + // Initialize state pointers + states[spis_num] = NULL; + + // Drain the FIFOs, enable SPIS + spis->gen_ctrl = 0; + spis->gen_ctrl = (MXC_F_SPIS_GEN_CTRL_SPI_SLAVE_EN | MXC_F_SPIS_GEN_CTRL_TX_FIFO_EN | + MXC_F_SPIS_GEN_CTRL_RX_FIFO_EN); + + // Set the TX FIFO almost empty level + spis->fifo_ctrl = ((spis->fifo_ctrl & ~MXC_F_SPIS_FIFO_CTRL_TX_FIFO_AE_LVL) | + ((MXC_CFG_SPIS_FIFO_DEPTH - SPIS_FIFO_BUFFER) << MXC_F_SPIS_FIFO_CTRL_TX_FIFO_AE_LVL_POS)); + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SPIS_Shutdown(mxc_spis_regs_t *spis) +{ + int spis_num, err; + spis_req_t *temp_req; + + // Disable and clear interrupts + spis->inten = 0; + spis->intfl = spis->intfl; + + // Disable SPIS and FIFOS + spis->gen_ctrl &= ~(MXC_F_SPIS_GEN_CTRL_SPI_SLAVE_EN | MXC_F_SPIS_GEN_CTRL_TX_FIFO_EN | + MXC_F_SPIS_GEN_CTRL_RX_FIFO_EN); + + // Call all of the pending callbacks for this SPIS + spis_num = MXC_SPIS_GET_IDX(spis); + if(states[spis_num] != NULL) { + + // Save the request + temp_req = states[spis_num]; + + // Unlock this SPIS + mxc_free_lock((uint32_t*)&states[spis_num]); + + // Callback if not NULL + if(temp_req->callback != NULL) { + temp_req->callback(temp_req, E_SHUTDOWN); + } + } + + // Clear system level configurations + if ((err = SYS_SPIS_Shutdown(spis)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SPIS_Trans(mxc_spis_regs_t *spis, spis_req_t *req) +{ + int spis_num; + + // Make sure the SPIS has been initialized + if((spis->gen_ctrl & MXC_F_SPIS_GEN_CTRL_SPI_SLAVE_EN) == 0) + return E_UNINITIALIZED; + + // Check the input parameters + if(req == NULL) + return E_NULL_PTR; + + if((req->rx_data == NULL) && (req->tx_data == NULL)) + return E_NULL_PTR; + + if(!(req->len > 0)) { + return E_NO_ERROR; + } + + // Attempt to register this write request + spis_num = MXC_SPIS_GET_IDX(spis); + if(mxc_get_lock((uint32_t*)&states[spis_num], (uint32_t)req) != E_NO_ERROR) { + return E_BUSY; + } + + //force deass to a 1 or 0 + req->deass = !!req->deass; + + // Clear the number of bytes counter + req->read_num = 0; + req->write_num = 0; + req->callback = NULL; + + // Start the transaction, keep calling the handler until complete + spis->intfl = (MXC_F_SPIS_INTFL_SS_DEASSERTED | MXC_F_SPIS_INTFL_TX_UNDERFLOW); + while(SPIS_TransHandler(spis, req, spis_num) & (MXC_F_SPIS_INTEN_RX_FIFO_AF | + MXC_F_SPIS_INTEN_TX_FIFO_AE)) { + + if((req->tx_data != NULL) && (spis->intfl & MXC_F_SPIS_INTFL_TX_UNDERFLOW)) { + return E_UNDERFLOW; + } + + if((req->rx_data != NULL) && (spis->intfl & MXC_F_SPIS_INTFL_RX_LOST_DATA)) { + return E_OVERFLOW; + } + + if((req->deass) && (spis->intfl & MXC_F_SPIS_INTFL_SS_DEASSERTED)) { + if(((req->rx_data != NULL) && ((req->read_num + SPIS_NumReadAvail(spis)) < req->len)) || + ((req->tx_data != NULL) && (req->write_num < req->len))) { + + return E_COMM_ERR; + } + } + } + + if(req->tx_data == NULL) { + return req->read_num; + } + return req->write_num; +} + +/******************************************************************************/ +int SPIS_TransAsync(mxc_spis_regs_t *spis, spis_req_t *req) +{ + int spis_num; + + // Make sure the SPIS has been initialized + if((spis->gen_ctrl & MXC_F_SPIS_GEN_CTRL_SPI_SLAVE_EN) == 0) + return E_UNINITIALIZED; + + // Check the input parameters + if(req == NULL) + return E_NULL_PTR; + + if((req->rx_data == NULL) && (req->tx_data == NULL)) + return E_NULL_PTR; + + if(!(req->len > 0)) { + return E_NO_ERROR; + } + + // Attempt to register this write request + spis_num = MXC_SPIS_GET_IDX(spis); + if(mxc_get_lock((uint32_t*)&states[spis_num], (uint32_t)req) != E_NO_ERROR) { + return E_BUSY; + } + + //force deass to a 1 or 0 + req->deass = !!req->deass; + + // Clear the number of bytes counter + req->read_num = 0; + req->write_num = 0; + + // Start the transaction, enable the interrupts + spis->intfl = MXC_F_SPIS_INTFL_SS_DEASSERTED; + spis->inten = SPIS_TransHandler(spis, req, spis_num); + + if(spis->intfl & MXC_F_SPIS_INTFL_SS_DEASSERTED) { + return E_COMM_ERR; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int SPIS_AbortAsync(spis_req_t *req) +{ + int spis_num; + + // Check the input parameters + if(req == NULL) { + return E_BAD_PARAM; + } + + // Find the request, set to NULL + for(spis_num = 0; spis_num < MXC_CFG_SPIS_INSTANCES; spis_num++) { + if(req == states[spis_num]) { + + // Disable interrupts, clear the flags + MXC_SPIS_GET_SPIS(spis_num)->inten = 0; + MXC_SPIS_GET_SPIS(spis_num)->intfl = MXC_SPIS_GET_SPIS(spis_num)->intfl; + + // Unlock this SPIS + mxc_free_lock((uint32_t*)&states[spis_num]); + + // Callback if not NULL + if(req->callback != NULL) { + req->callback(req, E_ABORT); + } + + return E_NO_ERROR; + } + } + + return E_BAD_PARAM; +} + +/******************************************************************************/ +void SPIS_Handler(mxc_spis_regs_t *spis) +{ + int spis_num; + uint32_t flags; + spis_req_t *req; + + // Clear the interrupt flags + spis->inten = 0; + flags = spis->intfl; + spis->intfl = flags; + + spis_num = MXC_SPIS_GET_IDX(spis); + req = states[spis_num]; + + // Check for errors + if((flags & MXC_F_SPIS_INTFL_TX_UNDERFLOW) && (req->tx_data != NULL)) { + // Unlock this SPIS + mxc_free_lock((uint32_t*)&states[spis_num]); + + // Callback if not NULL + if(req->callback != NULL) { + req->callback(req, E_UNDERFLOW); + } + return; + } + if((flags & MXC_F_SPIS_INTFL_RX_LOST_DATA) && (req->rx_data != NULL)) { + // Unlock this SPIS + mxc_free_lock((uint32_t*)&states[spis_num]); + + // Callback if not NULL + if(req->callback != NULL) { + req->callback(req, E_OVERFLOW); + } + return; + } + + // Check for deassert + if((flags & MXC_F_SPIS_INTFL_SS_DEASSERTED) && (req != NULL) && + (req->deass)) { + + if(((req->rx_data != NULL) && ((req->read_num + SPIS_NumReadAvail(spis)) < req->len)) || + ((req->tx_data != NULL) && (req->write_num < req->len))) { + + // Unlock this SPIS + mxc_free_lock((uint32_t*)&states[spis_num]); + + // Callback if not NULL + if(req->callback != NULL) { + req->callback(states[spis_num], E_COMM_ERR); + } + + return; + } + } + + // Figure out if this SPIS has an active request + if(flags && (req != NULL)) { + + spis->inten = SPIS_TransHandler(spis, req, spis_num); + } +} + +/******************************************************************************/ +int SPIS_Busy(mxc_spis_regs_t *spis) +{ + // Check to see if there are any ongoing transactions + if(states[MXC_SPIS_GET_IDX(spis)] == NULL) { + return E_NO_ERROR; + } + + return E_BUSY; +} + +/******************************************************************************/ +int SPIS_PrepForSleep(mxc_spis_regs_t *spis) +{ + if(SPIS_Busy(spis) != E_NO_ERROR) { + return E_BUSY; + } + + // Disable interrupts + spis->inten = 0; + return E_NO_ERROR; +} + +/******************************************************************************/ +static uint32_t SPIS_TransHandler(mxc_spis_regs_t *spis, spis_req_t *req, int spis_num) +{ + uint8_t read, write; + uint32_t inten; + unsigned remain, avail, temp_len; + mxc_spis_fifo_regs_t *fifo; + + inten = 0; + + // Get the FIFOS for this UART + fifo = MXC_SPIS_GET_SPIS_FIFO(spis_num); + + // Figure out if we're reading + if(req->rx_data != NULL) { + read = 1; + } else { + read = 0; + } + + // Figure out if we're writing + if(req->tx_data != NULL) { + write = 1; + } else { + write = 0; + } + + // Put data into the FIFO if we are writing + if(write) { + + avail = SPIS_NumWriteAvail(spis); + remain = req->len - req->write_num; + + if(remain > avail) { + temp_len = avail; + } else { + temp_len = remain; + } + + memcpy((void*)fifo->tx_32, &(req->tx_data[req->write_num]), temp_len); + spis->intfl = MXC_F_SPIS_INTFL_TX_FIFO_AE; + req->write_num += temp_len; + remain = req->len - req->write_num; + + // Set the TX interrupts + if(remain) { + inten |= (MXC_F_SPIS_INTEN_TX_FIFO_AE | MXC_F_SPIS_INTFL_TX_UNDERFLOW); + } + } + + // Read from the FIFO if we are reading + if(read) { + + avail = SPIS_NumReadAvail(MXC_SPIS); + remain = req->len - req->read_num; + + if(remain > avail) { + temp_len = avail; + } else { + temp_len = remain; + } + + memcpy((void*)&req->rx_data[req->read_num], (void*)&(fifo->rx_8[0]), temp_len); + spis->intfl = MXC_F_SPIS_INTFL_RX_FIFO_AF; + req->read_num += temp_len; + remain = req->len - req->read_num; + + // Set the RX interrupts + if(remain) { + + // Adjust the almost full threshold + if (remain > (MXC_CFG_SPIS_FIFO_DEPTH - SPIS_FIFO_BUFFER)) { + spis->fifo_ctrl = ((spis->fifo_ctrl & ~MXC_F_SPIS_FIFO_CTRL_RX_FIFO_AF_LVL) | + ((MXC_CFG_SPIS_FIFO_DEPTH - SPIS_FIFO_BUFFER) << MXC_F_SPIS_FIFO_CTRL_RX_FIFO_AF_LVL_POS)); + + } else { + spis->fifo_ctrl = ((spis->fifo_ctrl & ~MXC_F_SPIS_FIFO_CTRL_RX_FIFO_AF_LVL) | + ((remain-1) << MXC_F_SPIS_FIFO_CTRL_RX_FIFO_AF_LVL_POS)); + } + + inten |= (MXC_F_SPIS_INTEN_RX_FIFO_AF | MXC_F_SPIS_INTFL_RX_LOST_DATA); + } + } + + // Check to see if we've finished reading and writing + if(((read && (req->read_num == req->len)) || !read) && + ((req->write_num == req->len) || !write)) { + + // Unlock this SPIS + mxc_free_lock((uint32_t*)&states[spis_num]); + + // Callback if not NULL + if(req->callback != NULL) { + req->callback(req, E_NO_ERROR); + } + + return 0; + } + + // Enable deassert interrupt + if(req->deass) { + inten |= MXC_F_SPIS_INTEN_SS_DEASSERTED; + } + + return inten; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spis.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spis.h new file mode 100644 index 00000000000..8858976b47e --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spis.h @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-05-18 16:27:43 -0500 (Wed, 18 May 2016) $ + * $Revision: 22908 $ + * + ******************************************************************************/ + +/** + * @file spis.s + * @brief SPI Slave driver header file. + */ + +#include "mxc_config.h" +#include "mxc_sys.h" +#include "spis_regs.h" + +#ifndef _SPIS_H_ +#define _SPIS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/***** Definitions *****/ + +/// @brief Number of data lines to use. +typedef enum { + SPIS_WIDTH_1 = 0, + SPIS_WIDTH_2 = 1, + SPIS_WIDTH_4 = 2 +} spis_width_t; + +/// @brief SPIS Transaction request. +typedef struct spis_req spis_req_t; +struct spis_req { + uint8_t deass; ///< End the transaction when SS is deasserted. + const uint8_t *tx_data; ///< TX buffer. + uint8_t *rx_data; ///< RX buffer. + spis_width_t width; ///< Number of data lines to use. + unsigned len; ///< Number of bytes to send. + unsigned read_num; ///< Number of bytes transacted. + unsigned write_num; ///< Number of bytes transacted. + + /** + * @brief Callback for asynchronous request. + * @param spis_req_t* Pointer to the transaction request. + * @param int Error code. + */ + void (*callback)(spis_req_t*, int); +}; + +/***** Globals *****/ + +/***** Function Prototypes *****/ + +/** + * @brief Initialize SPIS module. + * @param spis Pointer to SPIS regs. + * @param cfg Pointer to SPIS configuration. + * @param mode SPI Mode to configure the slave. + * @param sys_cfg Pointer to system configuration object. + * @returns #E_NO_ERROR if everything is successful. + */ +int SPIS_Init(mxc_spis_regs_t *spis, uint8_t mode, const sys_cfg_spis_t *sys_cfg); + + +/** + * @brief Shutdown SPIS module. + * @param spis Pointer to SPIS regs. + * @returns #E_NO_ERROR if everything is successful + */ +int SPIS_Shutdown(mxc_spis_regs_t *spis); + +/** + * @brief Read/write SPIS data. Will block until transaction is complete. + * @param spis Pointer to SPIS regs. + * @param req Request for a SPIS transaction. + * @note Callback is ignored. + * @returns Bytes transacted if everything is successful, error if unsuccessful. + */ +int SPIS_Trans(mxc_spis_regs_t *spis, spis_req_t *req); + +/** + * @brief Asynchronously read/write SPIS data. + * @param spis Pointer to SPIS regs. + * @param req Request for a SPIS transaction. + * @note Request struct must remain allocated until callback. + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int SPIS_TransAsync(mxc_spis_regs_t *spis, spis_req_t *req); + +/** + * @brief Abort asynchronous request. + * @param req Pointer to request for a SPIS transaction. + * @returns #E_NO_ERROR if request aborted, error if unsuccessful. + */ +int SPIS_AbortAsync(spis_req_t *req); + +/** + * @brief SPIS interrupt handler. + * @details This function should be called by the application from the interrupt + * handler if SPIS interrupts are enabled. Alternately, this function + * can be periodically called by the application if SPIS interrupts are + * disabled. + * @param spis Base address of the SPIS module. + */ +void SPIS_Handler(mxc_spis_regs_t *spis); + +/** + * @brief Check the SPIS to see if it's busy. + * @param spis Pointer to SPIS regs. + * @returns #E_NO_ERROR if idle, #E_BUSY if in use. + */ +int SPIS_Busy(mxc_spis_regs_t *spis); + +/** + * @brief Attempt to prepare the SPIS for sleep. + * @param spis Pointer to SPIS regs. +* @details Checks for any ongoing transactions. Disables interrupts if the SPIS + is idle. + * @returns #E_NO_ERROR if ready to sleep, #E_BUSY if not ready for sleep. + */ +int SPIS_PrepForSleep(mxc_spis_regs_t *spis); + +/** + * @brief Enables the SPIS without overwriting existing configuration. + * @param spis Pointer to SPIS regs. + */ +__STATIC_INLINE void SPIS_Enable(mxc_spis_regs_t *spis) +{ + spis->gen_ctrl |= (MXC_F_SPIS_GEN_CTRL_SPI_SLAVE_EN | + MXC_F_SPIS_GEN_CTRL_TX_FIFO_EN | MXC_F_SPIS_GEN_CTRL_RX_FIFO_EN); +} + +/** + * @brief Drain all of the data in the RXFIFO. + * @param spis Pointer to UART regs. + */ +__STATIC_INLINE void SPIS_DrainRX(mxc_spis_regs_t *spis) +{ + uint32_t ctrl_save = spis->gen_ctrl; + spis->gen_ctrl = (ctrl_save & ~MXC_F_SPIS_GEN_CTRL_RX_FIFO_EN); + spis->gen_ctrl = ctrl_save; +} + +/** + * @brief Drain all of the data in the TXFIFO. + * @param spis Pointer to UART regs. + */ +__STATIC_INLINE void SPIS_DrainTX(mxc_spis_regs_t *spis) +{ + uint32_t ctrl_save = spis->gen_ctrl; + spis->gen_ctrl = (ctrl_save & ~MXC_F_SPIS_GEN_CTRL_TX_FIFO_EN); + spis->gen_ctrl = ctrl_save; +} + +/** + * @brief TX FIFO availability. + * @param spis Pointer to UART regs. + * @returns Number of empty bytes available in write FIFO. + */ +__STATIC_INLINE unsigned SPIS_NumWriteAvail(mxc_spis_regs_t *spis) +{ + return (MXC_CFG_SPIS_FIFO_DEPTH - ((spis->fifo_stat & + MXC_F_SPIS_FIFO_STAT_TX_FIFO_USED) >> MXC_F_SPIS_FIFO_STAT_TX_FIFO_USED_POS)); +} + +/** + * @brief RX FIFO availability. + * @param spis Pointer to UART regs. + * @returns Number of bytes in read FIFO. + */ +__STATIC_INLINE unsigned SPIS_NumReadAvail(mxc_spis_regs_t *spis) +{ + return ((spis->fifo_stat & MXC_F_SPIS_FIFO_STAT_RX_FIFO_USED) >> + MXC_F_SPIS_FIFO_STAT_RX_FIFO_USED_POS); +} + +/** + * @brief Clear interrupt flags. + * @param spis Pointer to SPIS regs. + * @param mask Mask of interrupts to clear. + */ +__STATIC_INLINE void SPIS_ClearFlags(mxc_spis_regs_t *spis, uint32_t mask) +{ + spis->intfl = mask; +} + +/** + * @brief Get interrupt flags. + * @param spis Pointer to SPIS regs. + * @returns Mask of active flags. + */ +__STATIC_INLINE unsigned SPIS_GetFlags(mxc_spis_regs_t *spis) +{ + return (spis->intfl); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _SPIS_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spix.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spix.c new file mode 100644 index 00000000000..590e4d70d98 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spix.c @@ -0,0 +1,292 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-05-31 17:30:09 -0500 (Tue, 31 May 2016) $ + * $Revision: 23119 $ + * + ******************************************************************************/ +/** + * @file spix.c + * @brief SPI execute in place driver. + */ + +/***** Includes *****/ +#include +#include "mxc_config.h" +#include "mxc_assert.h" +#include "spix.h" +#include "spix_regs.h" + +/***** Definitions *****/ +#define CMD_CLOCKS 8 +#define ADDR_3BYTE_CLOCKS 24 +#define ADDR_4BYTE_CLOCKS 32 + +/***** Globals *****/ + +/***** Functions *****/ + +/******************************************************************************/ +#if defined ( __GNUC__) +#undef IAR_SPIX_PRAGMA //Make sure this is not defined for GCC +#endif + +#if IAR_SPIX_PRAGMA +// IAR memory section declaration for the SPIX functions to be loaded in RAM. +#pragma section=".spix_config" +#endif + +#if(MXC_SPIX_REV == 0) + +#if defined ( __GNUC__ ) +__attribute__ ((section(".spix_config"), noinline)) +#endif /* __GNUC */ + +#if IAR_SPIX_PRAGMA +#pragma location=".spix_config" // IAR locate function in RAM section .spix_config +#pragma optimize=no_inline // IAR no inline optimization on this function +#endif /* IAR_PRAGMA */ + +static void SPIX_UpdateFBIgnore() +{ + // Update the feedback ignore clocks + uint8_t clocks = 0; + uint8_t no_cmd_clocks = 0; + + // Adjust the clocks for the command + if((MXC_SPIX->fetch_ctrl & MXC_F_SPIX_FETCH_CTRL_CMD_WIDTH) == + MXC_S_SPIX_FETCH_CTRL_CMD_WIDTH_QUAD_IO) { + + clocks += CMD_CLOCKS/4; + } else if((MXC_SPIX->fetch_ctrl & MXC_F_SPIX_FETCH_CTRL_CMD_WIDTH) == + MXC_S_SPIX_FETCH_CTRL_CMD_WIDTH_DUAL_IO) { + + clocks += CMD_CLOCKS/2; + } else { + + clocks += CMD_CLOCKS; + } + + // Adjust the clocks for the address + if((MXC_SPIX->fetch_ctrl & MXC_F_SPIX_FETCH_CTRL_ADDR_WIDTH) == + MXC_S_SPIX_FETCH_CTRL_ADDR_WIDTH_QUAD_IO) { + + if(MXC_SPIX->fetch_ctrl & MXC_F_SPIX_FETCH_CTRL_FOUR_BYTE_ADDR) { + clocks += ADDR_4BYTE_CLOCKS/4; + no_cmd_clocks += ADDR_4BYTE_CLOCKS/4; + } else { + clocks += ADDR_3BYTE_CLOCKS/4; + no_cmd_clocks += ADDR_3BYTE_CLOCKS/4; + } + + } else if((MXC_SPIX->fetch_ctrl & MXC_F_SPIX_FETCH_CTRL_ADDR_WIDTH) == + MXC_S_SPIX_FETCH_CTRL_ADDR_WIDTH_DUAL_IO) { + + if(MXC_SPIX->fetch_ctrl & MXC_F_SPIX_FETCH_CTRL_FOUR_BYTE_ADDR) { + clocks += ADDR_4BYTE_CLOCKS/2; + no_cmd_clocks += ADDR_4BYTE_CLOCKS/2; + } else { + clocks += ADDR_3BYTE_CLOCKS/2; + no_cmd_clocks += ADDR_3BYTE_CLOCKS/2; + } + } else { + + if(MXC_SPIX->fetch_ctrl & MXC_F_SPIX_FETCH_CTRL_FOUR_BYTE_ADDR) { + clocks += ADDR_4BYTE_CLOCKS; + no_cmd_clocks += ADDR_4BYTE_CLOCKS; + } else { + clocks += ADDR_3BYTE_CLOCKS; + no_cmd_clocks += ADDR_3BYTE_CLOCKS; + } + } + + // Adjust for the mode clocks + clocks += ((MXC_SPIX->mode_ctrl & MXC_F_SPIX_MODE_CTRL_MODE_CLOCKS) >> + MXC_F_SPIX_MODE_CTRL_MODE_CLOCKS_POS); + + // Set the FB Ignore clocks + MXC_SPIX->sck_fb_ctrl = ((MXC_SPIX->sck_fb_ctrl & ~MXC_F_SPIX_SCK_FB_CTRL_IGNORE_CLKS) | + (clocks << MXC_F_SPIX_SCK_FB_CTRL_IGNORE_CLKS_POS)); + + MXC_SPIX->sck_fb_ctrl = ((MXC_SPIX->sck_fb_ctrl & ~MXC_F_SPIX_SCK_FB_CTRL_IGNORE_CLKS_NO_CMD) | + (no_cmd_clocks << MXC_F_SPIX_SCK_FB_CTRL_IGNORE_CLKS_NO_CMD_POS)); +} +#endif /* MXC_SPIX_REV==0 */ + +/******************************************************************************/ +#if defined ( __GNUC__ ) +__attribute__ ((section(".spix_config"), noinline)) +#endif /* __GNUC */ + +#if IAR_SPIX_PRAGMA +#pragma location=".spix_config" // IAR locate function in RAM section .spix_config +#pragma optimize=no_inline // IAR no inline optimization on this function +#endif /* IAR_SPIX_PRAGMA */ +int SPIX_ConfigClock(const sys_cfg_spix_t *sys_cfg, uint32_t baud, uint8_t sample) +{ + int err; + uint32_t spix_clk, clocks; + + // Check the input parameters + if(sys_cfg == NULL) { + return E_NULL_PTR; + } + + // Set system level configurations + if ((err = SYS_SPIX_Init(sys_cfg, baud)) != E_NO_ERROR) { + return err; + } + + // Configure the mode and baud + spix_clk = SYS_SPIX_GetFreq(); + if(spix_clk <= 0) { + return E_UNINITIALIZED; + } + + // Make sure that we can generate this frequency + clocks = (spix_clk / (2*baud)); + if((clocks <= 0) || (clocks >= 0x10)) { + return E_BAD_PARAM; + } + + // Set the baud + MXC_SPIX->master_cfg = ((MXC_SPIX->master_cfg & + ~(MXC_F_SPIX_MASTER_CFG_SCK_HI_CLK | MXC_F_SPIX_MASTER_CFG_SCK_LO_CLK)) | + (clocks << MXC_F_SPIX_MASTER_CFG_SCK_HI_CLK_POS) | + (clocks << MXC_F_SPIX_MASTER_CFG_SCK_LO_CLK_POS)); + + if(sample != 0) { + // Use sample mode + MXC_SPIX->master_cfg = ((MXC_SPIX->master_cfg & ~MXC_F_SPIX_MASTER_CFG_SDIO_SAMPLE_POINT) | + (sample << MXC_F_SPIX_MASTER_CFG_SDIO_SAMPLE_POINT_POS)); + + MXC_SPIX->sck_fb_ctrl &= ~(MXC_F_SPIX_SCK_FB_CTRL_ENABLE_SCK_FB_MODE | + MXC_F_SPIX_SCK_FB_CTRL_INVERT_SCK_FB_CLK); + } else { + // Use Feedback mode + MXC_SPIX->master_cfg &= ~(MXC_F_SPIX_MASTER_CFG_SDIO_SAMPLE_POINT); + + MXC_SPIX->sck_fb_ctrl |= (MXC_F_SPIX_SCK_FB_CTRL_ENABLE_SCK_FB_MODE | + MXC_F_SPIX_SCK_FB_CTRL_INVERT_SCK_FB_CLK); + + +#if(MXC_SPIX_REV == 0) + SPIX_UpdateFBIgnore(); +#endif + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +#if defined ( __GNUC__ ) +__attribute__ ((section(".spix_config"), noinline)) +#endif /* __GNUC */ + +#if IAR_SPIX_PRAGMA +#pragma location=".spix_config" // IAR locate function in RAM section .spix_config +#pragma optimize=no_inline // IAR no inline optimization on this function +#endif /* IAR_SPIX_PRAGMA */ + +void SPIX_ConfigSlave(uint8_t ssel, uint8_t pol, uint8_t act_delay, uint8_t inact_delay) +{ + + // Set the slave select + MXC_SPIX->master_cfg = ((MXC_SPIX->master_cfg & ~MXC_F_SPIX_MASTER_CFG_SLAVE_SEL) | + (ssel << MXC_F_SPIX_MASTER_CFG_SLAVE_SEL_POS)); + + if(pol != 0) { + // Active high + MXC_SPIX->master_cfg &= ~(MXC_F_SPIX_MASTER_CFG_SS_ACT_LO); + } else { + // Active low + MXC_SPIX->master_cfg |= MXC_F_SPIX_MASTER_CFG_SS_ACT_LO; + } + + // Set the delays + MXC_SPIX->master_cfg = ((MXC_SPIX->master_cfg & ~(MXC_F_SPIX_MASTER_CFG_ACT_DELAY | + MXC_F_SPIX_MASTER_CFG_INACT_DELAY)) | + (act_delay << MXC_F_SPIX_MASTER_CFG_ACT_DELAY_POS) | + (inact_delay << MXC_F_SPIX_MASTER_CFG_INACT_DELAY_POS)); +} + +/******************************************************************************/ +#if defined ( __GNUC__ ) +__attribute__ ((section(".spix_config"), noinline)) +#endif /* __GNUC */ + +#if IAR_SPIX_PRAGMA +#pragma location=".spix_config" // IAR locate function in RAM section .spix_config +#pragma optimize=no_inline // IAR no inline optimization on this function +#endif /* IAR_SPIX_PRAGMA */ + +void SPIX_ConfigFetch(const spix_fetch_t *fetch) +{ + // Configure how the SPIX fetches data + MXC_SPIX->fetch_ctrl = (((fetch->cmd << MXC_F_SPIX_FETCH_CTRL_CMD_VALUE_POS) & MXC_F_SPIX_FETCH_CTRL_CMD_VALUE) | + ((fetch->cmd_width << MXC_F_SPIX_FETCH_CTRL_CMD_WIDTH_POS) & MXC_F_SPIX_FETCH_CTRL_CMD_WIDTH) | + ((fetch->addr_width << MXC_F_SPIX_FETCH_CTRL_ADDR_WIDTH_POS) & MXC_F_SPIX_FETCH_CTRL_ADDR_WIDTH) | + ((fetch->data_width << MXC_F_SPIX_FETCH_CTRL_DATA_WIDTH_POS) & MXC_F_SPIX_FETCH_CTRL_DATA_WIDTH) | + ((fetch->addr_size << MXC_F_SPIX_FETCH_CTRL_FOUR_BYTE_ADDR_POS) & MXC_F_SPIX_FETCH_CTRL_FOUR_BYTE_ADDR)); + + // Set the command mode and clocks + MXC_SPIX->mode_ctrl = (((fetch->mode_clocks << MXC_F_SPIX_MODE_CTRL_MODE_CLOCKS_POS) & MXC_F_SPIX_MODE_CTRL_MODE_CLOCKS) | + (!!fetch->no_cmd_mode << MXC_F_SPIX_MODE_CTRL_NO_CMD_MODE_POS)); + + MXC_SPIX->mode_data = (((fetch->mode_data << MXC_F_SPIX_MODE_DATA_MODE_DATA_BITS_POS) & MXC_F_SPIX_MODE_DATA_MODE_DATA_BITS) | + MXC_F_SPIX_MODE_DATA_MODE_DATA_OE); + +#if(MXC_SPIX_REV == 0) + SPIX_UpdateFBIgnore(); +#endif +} + +/******************************************************************************/ +#if defined ( __GNUC__ ) +__attribute__ ((section(".spix_config"), noinline)) +#endif /* __GNUC */ + +#if IAR_SPIX_PRAGMA +#pragma location=".spix_config" // IAR locate function in RAM section .spix_config +#pragma optimize=no_inline // IAR no inline optimization on this function +#endif /* IAR_SPIX_PRAGMA */ + +int SPIX_Shutdown(mxc_spix_regs_t *spix) +{ + int err; + + // Clear system level configurations + if ((err = SYS_SPIX_Shutdown()) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spix.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spix.h new file mode 100644 index 00000000000..8d7ecdeb4e3 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/spix.h @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-05-26 11:38:10 -0500 (Thu, 26 May 2016) $ + * $Revision: 23065 $ + * + ******************************************************************************/ + +/** + * @file spix.h + * @brief This is the high level API for the serial peripheral interface execute in place module. + * @warning If using this SPIX with IAR Embedded Workbench for Arm, it is required to define + * IAR_SPIX_PRAGMA=1. This should be done under Project->Options-> + * C/C++ Compiler->Preprocessor in the Defined Symbols input box. See the IAR documentation + * for additional information on how to set a preprocessor define in a project. + */ + +#include "mxc_sys.h" +#include "spix_regs.h" + +#ifndef _SPIX_H_ +#define _SPIX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/***** Definitions *****/ + +/// @brief Options for number of I/O pins to use during for each fetch stage +typedef enum { + SPIX_SINGLE_IO = MXC_V_SPIX_FETCH_CTRL_CMD_WIDTH_SINGLE, + SPIX_DUAL_IO = MXC_V_SPIX_FETCH_CTRL_CMD_WIDTH_DUAL_IO, + SPIX_QUAD_IO = MXC_V_SPIX_FETCH_CTRL_CMD_WIDTH_QUAD_IO +} spix_width_t; + +/// @brief Options for number of address bytes to use during fetch +typedef enum { + SPIX_3BYTE_FETCH_ADDR = 0, + SPIX_4BYTE_FETCH_ADDR = 1 +} spix_addr_size_t; + +/// @brief SPIX fetch configuration. +typedef struct { + spix_width_t cmd_width; ///< Number of I/O lines used for command SPI transaction. + spix_width_t addr_width; ///< Number of I/O lines used for address SPI transaction. + spix_width_t data_width; ///< Number of I/O lines used for data SPI transaction. + spix_addr_size_t addr_size; ///< Use 3 or 4 byte addresses for fetches. + uint8_t cmd; ///< Command value to initiate fetch. + uint8_t mode_clocks; ///< Number of SPI clocks required during mode phase of fetch. + uint8_t no_cmd_mode; ///< Read command sent only once. + uint16_t mode_data; ///< Data sent with mode clocks. +} spix_fetch_t; + +/***** Globals *****/ + +/***** Function Prototypes *****/ + +/** + * @brief Configure SPI execute in place clocking. + * @param sys_cfg Pointer to system level configuration structure. + * @param mode SPI mode to use for the clocking. + * @param baud Frequency in hertz to set the clock to. May not be able to achieve with + * the given clock divider. + * @param sample Number of SPIX clocks to delay the sampling of the SDIO lines. Will use + * feedback mode if set to 0. + * @returns #E_NO_ERROR if everything is successful + */ +int SPIX_ConfigClock(const sys_cfg_spix_t *sys_cfg, uint32_t baud, uint8_t sample); + +/** + * @brief Configure SPI execute in place slave select. + * @param ssel Index of which slave select line to use. + * @param pol Polarity of slave select (0 for active low, 1 for active high). + * @param act_delay SPIX clocks between slave select assert and active SPI clock. + * @param inact_delay SPIX clocks between active SPI clock and slave select deassert. + */ +void SPIX_ConfigSlave(uint8_t ssel, uint8_t pol, uint8_t act_delay, uint8_t inact_delay); + +/** + * @brief Configure how the SPIX fetches data. + * @param fetch Pointer to configuration struct that describes how to fetch data. + */ +void SPIX_ConfigFetch(const spix_fetch_t *fetch); + +/** + * @brief Shutdown SPIX module. + * @param spix Pointer to SPIX regs. + * @returns #E_NO_ERROR if everything is successful + */ +int SPIX_Shutdown(mxc_spix_regs_t *spix); + + +#ifdef __cplusplus +} +#endif + +#endif /* _SPIX_H */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr.c new file mode 100644 index 00000000000..b54ef9caf1e --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr.c @@ -0,0 +1,389 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-11 11:46:37 -0600 (Fri, 11 Mar 2016) $ + * $Revision: 21839 $ + * + ******************************************************************************/ + +#include +#include "mxc_assert.h" +#include "tmr.h" + +static tmr_prescale_t prescaler[MXC_CFG_TMR_INSTANCES]; + +/******************************************************************************/ +int TMR_Init(mxc_tmr_regs_t *tmr, tmr_prescale_t prescale, const sys_cfg_tmr_t *sysCfg) +{ + int err; + int tmrNum; + + //get the timer number + tmrNum = MXC_TMR_GET_IDX(tmr); + + //check for valid pointer + MXC_ASSERT(tmrNum >= 0); + + //steup system GPIO config + if((err = SYS_TMR_Init(tmr, sysCfg)) != E_NO_ERROR) + return err; + + //save the prescale value for this timer + prescaler[tmrNum] = prescale; + + //Disable timer and clear settings + tmr->ctrl = 0; + + //reset all counts to 0 + tmr->count32 = 0; + tmr->count16_0 = 0; + tmr->count16_1 = 0; + + // Clear interrupt flag + tmr->intfl = MXC_F_TMR_INTFL_TIMER0 | MXC_F_TMR_INTFL_TIMER1; + + return E_NO_ERROR; +} + +/******************************************************************************/ +void TMR32_Config(mxc_tmr_regs_t *tmr, const tmr32_cfg_t *config) +{ + //stop timer + TMR32_Stop(tmr); + + //setup timer configuration register + //clear tmr2x16 (32bit mode), mode and polarity bits + tmr->ctrl &= ~(MXC_F_TMR_CTRL_TMR2X16 | MXC_F_TMR_CTRL_MODE | + MXC_F_TMR_CTRL_POLARITY); + + //set mode and polarity + tmr->ctrl |= ((config->mode << MXC_F_TMR_CTRL_MODE_POS) | + (config->polarity << MXC_F_TMR_CTRL_POLARITY_POS)); + + //setup timer Tick registers + tmr->term_cnt32 = config->compareCount; + + return; +} + +/******************************************************************************/ +void TMR32_PWMConfig(mxc_tmr_regs_t *tmr, const tmr32_cfg_pwm_t *config) +{ + //stop timer + TMR32_Stop(tmr); + + //setup timer configuration register + //clear tmr2x16 (32bit mode), mode and polarity bits + tmr->ctrl &= ~(MXC_F_TMR_CTRL_TMR2X16 | MXC_F_TMR_CTRL_MODE | + MXC_F_TMR_CTRL_POLARITY); + + //set mode and polarity + tmr->ctrl |= ((TMR32_MODE_PWM << MXC_F_TMR_CTRL_MODE_POS) | + (config->polarity << MXC_F_TMR_CTRL_POLARITY_POS)); + + tmr->pwm_cap32 = config->dutyCount; + + //setup timer Tick registers + tmr->count32 = 0; + tmr->term_cnt32 = config->periodCount; + + return; +} + +/******************************************************************************/ +void TMR16_Config(mxc_tmr_regs_t *tmr, uint8_t index, const tmr16_cfg_t *config) +{ + //stop timer + TMR16_Stop(tmr, index); + + if(index > 0) { //configure timer 16_1 + + //setup timer configuration register + tmr->ctrl |= MXC_F_TMR_CTRL_TMR2X16; //1 = 16bit mode + + //set mode + if(config->mode) + tmr->ctrl |= MXC_F_TMR_CTRL_MODE_16_1; + else + tmr->ctrl &= ~MXC_F_TMR_CTRL_MODE_16_1; + + //setup timer Ticks registers + tmr->term_cnt16_1 = config->compareCount; + } else { //configure timer 16_0 + + //setup timer configuration register + tmr->ctrl |= MXC_F_TMR_CTRL_TMR2X16; //1 = 16bit mode + + //set mode + if(config->mode) + tmr->ctrl |= MXC_F_TMR_CTRL_MODE_16_0; + else + tmr->ctrl &= ~MXC_F_TMR_CTRL_MODE_16_0; + + //setup timer Ticks registers + tmr->term_cnt16_0 = config->compareCount; + } + + return; +} + +/******************************************************************************/ +void TMR32_Start(mxc_tmr_regs_t *tmr) +{ + int tmrNum; + uint32_t ctrl; + + //get the timer number + tmrNum = MXC_TMR_GET_IDX(tmr); + + //prescaler gets reset to 0 when timer is disabled + //set the prescale to the saved value for this timer + ctrl = tmr->ctrl; + ctrl &= ~(MXC_F_TMR_CTRL_PRESCALE); //clear prescaler bits + ctrl |= prescaler[tmrNum] << MXC_F_TMR_CTRL_PRESCALE_POS; //set prescaler + ctrl |= MXC_F_TMR_CTRL_ENABLE0; //set enable to start the timer + + tmr->ctrl = ctrl; + + return; +} + +/******************************************************************************/ +void TMR16_Start(mxc_tmr_regs_t *tmr, uint8_t index) +{ + int tmrNum; + uint32_t ctrl; + + //get the timer number + tmrNum = MXC_TMR_GET_IDX(tmr); + + ctrl = tmr->ctrl; + + //prescaler gets reset to 0 when both 16 bit timers are disabled + //set the prescale to the saved value for this timer if is is not already set + if((ctrl & MXC_F_TMR_CTRL_PRESCALE) != ((uint32_t)prescaler[tmrNum] << MXC_F_TMR_CTRL_PRESCALE_POS)) { + ctrl &= ~(MXC_F_TMR_CTRL_PRESCALE); //clear prescaler bits + ctrl |= prescaler[tmrNum] << MXC_F_TMR_CTRL_PRESCALE_POS; //set prescaler + } + + if(index > 0) + ctrl |= MXC_F_TMR_CTRL_ENABLE1; //start timer 16_1 + else + ctrl |= MXC_F_TMR_CTRL_ENABLE0; //start timer 16_0 + + tmr->ctrl = ctrl; + + return; +} + +/******************************************************************************/ +uint32_t TMR_GetPrescaler(mxc_tmr_regs_t *tmr) +{ + int tmrNum; + + //get the timer number + tmrNum = MXC_TMR_GET_IDX(tmr); + + return ((uint32_t)prescaler[tmrNum]); +} + + +/******************************************************************************/ +int TMR32_GetPWMTicks(mxc_tmr_regs_t *tmr, uint8_t dutyPercent, uint32_t freq, uint32_t *dutyTicks, uint32_t *periodTicks) +{ + uint32_t timerClock; + uint32_t prescale; + uint64_t ticks; + + if(dutyPercent > 100) + return E_BAD_PARAM; + + if(freq == 0) + return E_BAD_PARAM; + + timerClock = SYS_TMR_GetFreq(tmr); + prescale = TMR_GetPrescaler(tmr); + + if(timerClock == 0 || prescale > TMR_PRESCALE_DIV_2_12) + return E_UNINITIALIZED; + + ticks = timerClock / (1 << (prescale & 0xF)) / freq; + + //make sure ticks is within a 32 bit value + if (!(ticks & 0xffffffff00000000) && (ticks & 0xffffffff)) { + *periodTicks = ticks; + + *dutyTicks = ((uint64_t)*periodTicks * dutyPercent) / 100; + + return E_NO_ERROR; + } + + return E_INVALID; +} + +/******************************************************************************/ +int TMR32_TimeToTicks(mxc_tmr_regs_t *tmr, uint32_t time, tmr_unit_t units, uint32_t *ticks) +{ + uint32_t unit_div0, unit_div1; + uint32_t timerClock; + uint32_t prescale; + uint64_t temp_ticks; + + timerClock = SYS_TMR_GetFreq(tmr); + prescale = TMR_GetPrescaler(tmr); + + if(timerClock == 0 || prescale > TMR_PRESCALE_DIV_2_12) + return E_UNINITIALIZED; + + switch (units) { + case TMR_UNIT_NANOSEC: + unit_div0 = 1000000; + unit_div1 = 1000; + break; + case TMR_UNIT_MICROSEC: + unit_div0 = 1000; + unit_div1 = 1000; + break; + case TMR_UNIT_MILLISEC: + unit_div0 = 1; + unit_div1 = 1000; + break; + case TMR_UNIT_SEC: + unit_div0 = 1; + unit_div1 = 1; + break; + default: + return E_BAD_PARAM; + } + + temp_ticks = (uint64_t)time * (timerClock / unit_div0) / (unit_div1 * (1 << (prescale & 0xF))); + + //make sure ticks is within a 32 bit value + if (!(temp_ticks & 0xffffffff00000000) && (temp_ticks & 0xffffffff)) { + *ticks = temp_ticks; + return E_NO_ERROR; + } + + return E_INVALID; +} + +/******************************************************************************/ +int TMR16_TimeToTicks(mxc_tmr_regs_t *tmr, uint32_t time, tmr_unit_t units, uint16_t *ticks) +{ + uint32_t unit_div0, unit_div1; + uint32_t timerClock; + uint32_t prescale; + uint64_t temp_ticks; + + timerClock = SYS_TMR_GetFreq(tmr); + prescale = TMR_GetPrescaler(tmr); + + if(timerClock == 0 || prescale > TMR_PRESCALE_DIV_2_12) + return E_UNINITIALIZED; + + switch (units) { + case TMR_UNIT_NANOSEC: + unit_div0 = 1000000; + unit_div1 = 1000; + break; + case TMR_UNIT_MICROSEC: + unit_div0 = 1000; + unit_div1 = 1000; + break; + case TMR_UNIT_MILLISEC: + unit_div0 = 1; + unit_div1 = 1000; + break; + case TMR_UNIT_SEC: + unit_div0 = 1; + unit_div1 = 1; + break; + default: + return E_BAD_PARAM; + } + + temp_ticks = (uint64_t)time * (timerClock / unit_div0) / (unit_div1 * (1 << (prescale & 0xF))); + + //make sure ticks is within a 32 bit value + if (!(temp_ticks & 0xffffffffffff0000) && (temp_ticks & 0xffff)) { + *ticks = temp_ticks; + return E_NO_ERROR; + } + + return E_INVALID; +} + + +/******************************************************************************/ +int TMR_TicksToTime(mxc_tmr_regs_t *tmr, uint32_t ticks, uint32_t *time, tmr_unit_t *units) +{ + uint64_t temp_time = 0; + + uint32_t timerClock = SYS_TMR_GetFreq(tmr); + uint32_t prescale = TMR_GetPrescaler(tmr); + + if(timerClock == 0 || prescale > TMR_PRESCALE_DIV_2_12) + return E_UNINITIALIZED; + + tmr_unit_t temp_unit = TMR_UNIT_NANOSEC; + temp_time = (uint64_t)ticks * 1000 * (1 << (prescale & 0xF)) / (timerClock / 1000000); + if (!(temp_time & 0xffffffff00000000)) { + *time = temp_time; + *units = temp_unit; + return E_NO_ERROR; + } + + temp_unit = TMR_UNIT_MICROSEC; + temp_time = (uint64_t)ticks * 1000 * (1 << (prescale & 0xF)) / (timerClock / 1000); + if (!(temp_time & 0xffffffff00000000)) { + *time = temp_time; + *units = temp_unit; + return E_NO_ERROR; + } + + temp_unit = TMR_UNIT_MILLISEC; + temp_time = (uint64_t)ticks * 1000 * (1 << (prescale & 0xF)) / timerClock; + if (!(temp_time & 0xffffffff00000000)) { + *time = temp_time; + *units = temp_unit; + return E_NO_ERROR; + } + + temp_unit = TMR_UNIT_SEC; + temp_time = (uint64_t)ticks * (1 << (prescale & 0xF)) / timerClock; + if (!(temp_time & 0xffffffff00000000)) { + *time = temp_time; + *units = temp_unit; + return E_NO_ERROR; + } + + return E_INVALID; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr.h new file mode 100644 index 00000000000..e997a7ecd56 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr.h @@ -0,0 +1,619 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-21 14:44:55 -0500 (Mon, 21 Mar 2016) $ + * $Revision: 22017 $ + * + ******************************************************************************/ + +/** + * @file tmr.h + * @addtogroup timer Timer + * @{ + * @brief This is the high level API for the general purpose timer module + * + */ + +#ifndef _TIMER_H +#define _TIMER_H + +#include "mxc_config.h" +#include "tmr_regs.h" +#include "mxc_sys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +///@brief Define values for units of time +typedef enum { + /** nanosecond */ + TMR_UNIT_NANOSEC = 0, + /** microsecond */ + TMR_UNIT_MICROSEC, + /** millisecond */ + TMR_UNIT_MILLISEC, + /** second */ + TMR_UNIT_SEC, +} tmr_unit_t; + +///@brief Defines timer modes for 32-bit timers +typedef enum { + TMR32_MODE_ONE_SHOT = MXC_V_TMR_CTRL_MODE_ONE_SHOT, + TMR32_MODE_CONTINUOUS = MXC_V_TMR_CTRL_MODE_CONTINUOUS, + TMR32_MODE_COUNTER = MXC_V_TMR_CTRL_MODE_COUNTER, + TMR32_MODE_PWM = MXC_V_TMR_CTRL_MODE_PWM, + TMR32_MODE_CAPTURE = MXC_V_TMR_CTRL_MODE_CAPTURE, + TMR32_MODE_COMPARE = MXC_V_TMR_CTRL_MODE_COMPARE, + TMR32_MODE_GATED = MXC_V_TMR_CTRL_MODE_GATED, + TMR32_MODE_MEASURE = MXC_V_TMR_CTRL_MODE_MEASURE +} tmr32_mode_t; + +///@brief Defines timer modes for 16-bit timers +///@note 16-bit times only support One Shot and Continuous timers +typedef enum { + TMR16_MODE_ONE_SHOT = MXC_V_TMR_CTRL_MODE_ONE_SHOT, + TMR16_MODE_CONTINUOUS = MXC_V_TMR_CTRL_MODE_CONTINUOUS +} tmr16_mode_t; + +/// @brief Defines prescaler clock divider +typedef enum { + // divide input clock by 2^0 = 1 + TMR_PRESCALE_DIV_2_0 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_1, + // divide input clock by 2^1 = 2 + TMR_PRESCALE_DIV_2_1 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_2, + // divide input clock by 2^2 = 4 + TMR_PRESCALE_DIV_2_2 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_4, + // divide input clock by 2^3 = 8 + TMR_PRESCALE_DIV_2_3 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_8, + // divide input clock by 2^4 = 16 + TMR_PRESCALE_DIV_2_4 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_16, + // divide input clock by 2^5 = 32 + TMR_PRESCALE_DIV_2_5 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_32, + // divide input clock by 2^6 = 64 + TMR_PRESCALE_DIV_2_6 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_64, + // divide input clock by 2^7 = 128 + TMR_PRESCALE_DIV_2_7 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_128, + // divide input clock by 2^8 = 256 + TMR_PRESCALE_DIV_2_8 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_256, + // divide input clock by 2^9 = 512 + TMR_PRESCALE_DIV_2_9 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_512, + // divide input clock by 2^10 = 1024 + TMR_PRESCALE_DIV_2_10 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_1024, + // divide input clock by 2^11 = 2048 + TMR_PRESCALE_DIV_2_11 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_2048, + // divide input clock by 2^12 = 4096 + TMR_PRESCALE_DIV_2_12 = MXC_V_TMR_CTRL_PRESCALE_DIVIDE_BY_4096, +} tmr_prescale_t; + +/// @brief Defines the polarity bit for pwm timer +typedef enum { + TMR_POLARITY_UNUSED = 0, + + TMR_POLARITY_INIT_LOW = 0, ///GPIO initial output level = low + TMR_POLARITY_INIT_HIGH = 1, ///GPIO initial output level = high + + TMR_POLARITY_RISING_EDGE = 0, ///timer trigger on GPIO rising edge + TMR_POLARITY_FALLING_EDGE = 1, ///timer trigger on GPIO falling edge +} tmr_polarity_t; + +/// @brief Defines the polarity bit for pwm timer +typedef enum { + TMR_PWM_INVERTED = 0, ///duty cycle = low pulse + TMR_PWM_NONINVERTED, ///duty cycle = high pulse +} tmr_pwm_polarity_t; + +/// @brief 32bit Timer Configurations (non-PWM) +typedef struct { + tmr32_mode_t mode; /// Desired timer mode + tmr_polarity_t polarity; /// Polarity for GPIO + uint32_t compareCount; /// Ticks to stop, reset back to 1, or compare timer +} tmr32_cfg_t; + +/// @brief PWM Mode Configurations +typedef struct { + tmr_pwm_polarity_t polarity; /// PWM polarity + uint32_t periodCount; /// PWM period in timer counts + uint32_t dutyCount; /// PWM duty in timer counts +} tmr32_cfg_pwm_t; + +/// @brief 16bit Timer Configurations +typedef struct { + tmr16_mode_t mode; /// Desired timer mode (only supports one shot or continuous timers) + uint16_t compareCount; /// Ticks to stop or reset timer +} tmr16_cfg_t; + + + +/** + * @brief Initializes the timer to a known state. + * @details This function initializes the timer to a known state and saves the + * prescaler. The timer will be left disabled. TMR_Init should be called + * before TMR_Config. + * + * @param tmr timer module to operate on + * @param prescale clock divider for the timer clock + * @param cfg pointer to timer system GPIO configuration + * (can be NULL if not using GPIO timer input/output functions) + * + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int TMR_Init(mxc_tmr_regs_t *tmr, tmr_prescale_t prescale, const sys_cfg_tmr_t *sysCfg); + +/** + * @brief Configures the timer in the specified mode. + * @details The parameters in config structure must be set before calling this function. + * This function should be used for configuring the timer in all 32 bit modes other than PWM. + * @note The timer cannot be running when this function is called + * + * @param tmr timer module to operate on + * @param config pointer to timer configuration + * + */ +void TMR32_Config(mxc_tmr_regs_t *tmr, const tmr32_cfg_t *config); + +/** + * @brief Configures the timer in PWM mode. + * @details The parameters in config structure must be set before calling this function. + * This function should be used for configuring the timer in PWM mode only. + * @note The timer cannot be running when this function is called + * + * @param tmr timer module to operate on + * @param config pointer to timer configuration + * + */ +void TMR32_PWMConfig(mxc_tmr_regs_t *tmr, const tmr32_cfg_pwm_t *config); + +/** + * @brief Configures the timer in the specified mode. + * @details The parameters in config structure must be set before calling this function. + * This function should be used for configuring the timer in all 16 bit modes. + * @note The timer cannot be running when this function is called + * + * @param tmr timer module to operate on + * @param index selects which 16 bit timer (0 = 16_0 or 1 = 16_1) + * @param config pointer to timer configuration + * + */ +void TMR16_Config(mxc_tmr_regs_t *tmr, uint8_t index, const tmr16_cfg_t *config); + +/** + * @brief Starts the specified timer. + * + * @param tmr timer module to operate on + * + */ +void TMR32_Start(mxc_tmr_regs_t *tmr); + +/** + * @brief Starts the specified timer. + * + * @param tmr timer module to operate on + * @param index selects which 16 bit timer (0 = 16_0 or 1 = 16_1) + * + */ +void TMR16_Start(mxc_tmr_regs_t *tmr, uint8_t index); + +/** + * @brief Stops the specified 32 bit timer. + * @details All other timer states are left unchanged. + * + * @param tmr timer module to operate on + * + */ +__STATIC_INLINE void TMR32_Stop(mxc_tmr_regs_t *tmr) +{ + tmr->ctrl &= ~MXC_F_TMR_CTRL_ENABLE0; +} + +/** + * @brief Stop the specified 16 bit timer. + * @details All other timer states are left unchanged. + * + * @param tmr timer module to operate on + * @param index selects which 16 bit timer (0 = 16_0 or 1 = 16_1) + * + */ +__STATIC_INLINE void TMR16_Stop(mxc_tmr_regs_t *tmr, uint8_t index) +{ + if(index) + tmr->ctrl &= ~MXC_F_TMR_CTRL_ENABLE1; + else + tmr->ctrl &= ~MXC_F_TMR_CTRL_ENABLE0; +} + +/** + * @brief Determines if the timer is running + * + * @param tmr timer module to operate on + * + * @return 0 = timer is off, non-zero = timer is on + */ +__STATIC_INLINE uint32_t TMR32_IsActive(mxc_tmr_regs_t *tmr) +{ + return (tmr->ctrl & MXC_F_TMR_CTRL_ENABLE0); +} + +/** + * @brief Determines if the timer is running + * + * @param tmr timer module to operate on + * @param index selects which 16 bit timer (0 = 16_0 or 1 = 16_1) + * + * @return 0 = timer is off, non-zero = timer is on + */ +__STATIC_INLINE uint32_t TMR16_IsActive(mxc_tmr_regs_t *tmr, uint8_t index) +{ + if(index) + return (tmr->ctrl & MXC_F_TMR_CTRL_ENABLE1); + else + return (tmr->ctrl & MXC_F_TMR_CTRL_ENABLE0); +} + +/** + * @brief Enables the timer's interrupt + * + * @param tmr timer module to operate on + * + */ +__STATIC_INLINE void TMR32_EnableINT(mxc_tmr_regs_t *tmr) +{ + tmr->inten |= MXC_F_TMR_INTEN_TIMER0; +} + +/** + * @brief Enables the timer's interrupt + * + * @param tmr timer module to operate on + * @param index selects which 16 bit timer (0 = 16_0 or 1 = 16_1) + * + */ +__STATIC_INLINE void TMR16_EnableINT(mxc_tmr_regs_t *tmr, uint8_t index) +{ + if(index) + tmr->inten |= MXC_F_TMR_INTEN_TIMER1; + else + tmr->inten |= MXC_F_TMR_INTEN_TIMER0; +} + +/** + * @brief Disables the timer's interrupt + * + * @param tmr timer module to operate on + * + */ +__STATIC_INLINE void TMR32_DisableINT(mxc_tmr_regs_t *tmr) +{ + tmr->inten &= ~MXC_F_TMR_INTEN_TIMER0; +} + +/** + * @brief Disables the timer's interrupt + * + * @param tmr timer module to operate on + * @param index selects which 16 bit timer (0 = 16_0 or 1 = 16_1) + * + */ +__STATIC_INLINE void TMR16_DisableINT(mxc_tmr_regs_t *tmr, uint8_t index) +{ + if(index) + tmr->inten &= ~MXC_F_TMR_INTEN_TIMER1; + else + tmr->inten &= ~MXC_F_TMR_INTEN_TIMER0; +} + +/** + * @brief Gets the timer's interrupt flag + * + * @param tmr timer module to operate on + * + * @return 0 = flag not set, non-zero = flag is set + */ +__STATIC_INLINE uint32_t TMR32_GetFlag(mxc_tmr_regs_t *tmr) +{ + return (tmr->intfl & MXC_F_TMR_INTFL_TIMER0); +} + +/** + * @brief Gets the timer's interrupt flag + * + * @param tmr timer module to operate on + * @param index selects which 16 bit timer (0 = 16_0 or 1 = 16_1) + * + * @return 0 = flag not set, non-zero = flag is set + */ +__STATIC_INLINE uint32_t TMR16_GetFlag(mxc_tmr_regs_t *tmr, uint8_t index) +{ + if(index) + return (tmr->intfl & MXC_F_TMR_INTFL_TIMER1); + else + return (tmr->intfl & MXC_F_TMR_INTFL_TIMER0); +} + +/** + * @brief Clears the timer interrupt flag + * + * @param tmr timer module to operate on + * + */ +__STATIC_INLINE void TMR32_ClearFlag(mxc_tmr_regs_t *tmr) +{ + tmr->intfl = MXC_F_TMR_INTFL_TIMER0; +} + +/** + * @brief Clears the timer interrupt flag for the specified index + * + * @param tmr timer module to operate on + * @param index selects which 16 bit timer (0 = 16_0 or 1 = 16_1) + * + */ +__STATIC_INLINE void TMR16_ClearFlag(mxc_tmr_regs_t *tmr, uint8_t index) +{ + if(index) + tmr->intfl = MXC_F_TMR_INTFL_TIMER1; + else + tmr->intfl = MXC_F_TMR_INTFL_TIMER0; +} + +/** + * @brief Set the current tick value to start counting from. + * + * @param tmr timer module to operate on + * @param count value to set the current ticks + * + */ +__STATIC_INLINE void TMR32_SetCount(mxc_tmr_regs_t *tmr, uint32_t count) +{ + tmr->count32 = count; +} + +/** + * @brief Set the current tick value to start counting from. + * + * @param tmr timer module to operate on + * @param index selects which 16 bit timer (0 = 16_0 or 1 = 16_1) + * @param count value to set the current ticks + * + */ +__STATIC_INLINE void TMR16_SetCount(mxc_tmr_regs_t *tmr, uint8_t index, uint16_t count) +{ + if (index) + tmr->count16_1 = count; + else + tmr->count16_0 = count; +} + +/** + * @brief Gets the most current count value. + * + * @param tmr timer module to operate on + * + * @return current count value in ticks + */ +__STATIC_INLINE uint32_t TMR32_GetCount(mxc_tmr_regs_t *tmr) +{ + return (tmr->count32); +} + +/** + * @brief Gets the most current count value. + * + * @param tmr timer module to operate on + * @param index selects which 16 bit timer(0 = 16_0 or 1 = 16_1) + * + * @return current count value in ticks + */ +__STATIC_INLINE uint32_t TMR16_GetCount(mxc_tmr_regs_t *tmr, uint8_t index) +{ + if(index) + return tmr->count16_1; + else + return tmr->count16_0; +} + +/** + * @brief Gets the most recent capture value. + * @details Used in Capture or Measure timer modes + * + * @param tmr timer module to operate on + * + * @return capture value in ticks + */ +__STATIC_INLINE uint32_t TMR32_GetCapture(mxc_tmr_regs_t *tmr) +{ + return (tmr->pwm_cap32); +} + +/** + * @brief Set a new compare tick value for timer + * @details Depending on the timer mode this is the tick value to + * stop the timer, reset ticks to 1, or compare the timer + * + * @param tmr timer module to operate on + * @param count new terminal/compare value in timer counts + * + */ +__STATIC_INLINE void TMR32_SetCompare(mxc_tmr_regs_t *tmr, uint32_t count) +{ + tmr->term_cnt32 = count; +} + +/** + * @brief Get compare tick value for timer + * @param tmr timer module to operate on + * @return compare value in ticks + * + */ +__STATIC_INLINE uint32_t TMR32_GetCompare(mxc_tmr_regs_t *tmr) +{ + return tmr->term_cnt32; +} + +/** + * @brief Set a new compare tick value for timer + * @details Depending on the timer mode this is the tick value to + * stop the timer, reset ticks to 1, or compare the timer + * + * @param tmr timer module to operate on + * @param index selects which 16 bit timer (0 = 16_0 or 1 = 16_1) + * @param count new terminal/compare value in timer counts + * + */ +__STATIC_INLINE void TMR16_SetCompare(mxc_tmr_regs_t *tmr, uint8_t index, uint16_t count) +{ + if (index) + tmr->term_cnt16_1 = count; + else + tmr->term_cnt16_0 = count; +} + +/** + * @brief Get compare tick value for timer + * @param tmr timer module to operate on + * @param index selects which 16 bit timer (0 = 16_0 or 1 = 16_1) + * @return compare value in ticks + * + */ +__STATIC_INLINE uint32_t TMR16_GetCompare(mxc_tmr_regs_t *tmr, uint8_t index) +{ + if (index) + return tmr->term_cnt16_1; + return tmr->term_cnt16_0; +} + +/** + * @brief Returns the prescale value used by the timer + * + * @param tmr timer module to operate on + * + * @returns prescaler + */ +uint32_t TMR_GetPrescaler(mxc_tmr_regs_t *tmr); + +/** + * @brief Set a new duty cycle when the timer is used in PWM mode. + * + * @param tmr timer module to operate on + * @param dutyCount duty cycle value in timer counts + * + */ +__STATIC_INLINE void TMR32_SetDuty(mxc_tmr_regs_t *tmr, uint32_t dutyCount) +{ + tmr->pwm_cap32 = dutyCount; +} + +/** + * @brief Set a new duty cycle when the timer is used in PWM mode. + * + * @param tmr timer module to operate on + * @param dutyPercent duty cycle value in percent (0 to 100%) + * + */ +__STATIC_INLINE void TMR32_SetDutyPer(mxc_tmr_regs_t *tmr, uint32_t dutyPercent) +{ + uint32_t periodCount = tmr->term_cnt32; + tmr->pwm_cap32 = ((uint64_t)periodCount * dutyPercent) / 100; +} + +/** + * @brief Set a new period value for PWM timer + * + * @param tmr timer module to operate on + * @param count new period value in timer counts + * + */ +__STATIC_INLINE void TMR32_SetPeriod(mxc_tmr_regs_t *tmr, uint32_t period) +{ + tmr->term_cnt32 = period; +} + +/** + * @brief Converts frequency and duty cycle % to period and duty ticks + * @note TMR_Init should be called before this function to set the prescaler + * + * @param tmr timer module to operate on + * @param dutyPercent duty cycle in percent (0 to 100%) + * @param freq frequency of pwm signal in Hz + * @param dutyTicks calculated duty cycle in ticks + * @param periodTicks calculated period in ticks + * + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + * + */ +int TMR32_GetPWMTicks(mxc_tmr_regs_t *tmr, uint8_t dutyPercent, uint32_t freq, uint32_t *dutyTicks, uint32_t *periodTicks); + +/** + * @brief Converts a time and units to a number of ticks for the 32-bit timer. + * @note TMR_Init should be called before this function to set the prescaler + * + * @param tmr timer module to operate on + * @param time time value. + * @param unit time units. + * @param ticks calculated number of ticks. + * + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int TMR32_TimeToTicks(mxc_tmr_regs_t *tmr, uint32_t time, tmr_unit_t units, uint32_t *ticks); + +/** + * @brief Converts a time and units to a number of ticks for the 16-bit timer. + * @note TMR_Init should be called before this function to set the prescaler + * + * @param tmr timer module to operate on + * @param time time value. + * @param unit time units. + * @param ticks calculated number of ticks. + * + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int TMR16_TimeToTicks(mxc_tmr_regs_t *tmr, uint32_t time, tmr_unit_t units, uint16_t *ticks); + +/** + * @brief Converts a number of ticks to a time and units for the timer. + * @note TMR_Init should be called before this function to set the prescaler + * + * @param tmr timer module to operate on + * @param ticks number of ticks. + * @param time calculated time value. + * @param units calculated time units. + * + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int TMR_TicksToTime(mxc_tmr_regs_t *tmr, uint32_t ticks, uint32_t *time, tmr_unit_t *units); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* _TIMER_H */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr_utils.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr_utils.c new file mode 100644 index 00000000000..14f21811b6d --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr_utils.c @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-11 11:46:37 -0600 (Fri, 11 Mar 2016) $ + * $Revision: 21839 $ + * + ******************************************************************************/ + +/** + * @file tmr_utils.c + * @brief Timer utility functions. + */ + +/***** Includes *****/ +#include +#include "mxc_assert.h" +#include "tmr.h" +#include "tmr_utils.h" + +/***** Definitions *****/ + +/***** Globals *****/ + +/***** Functions *****/ + +/******************************************************************************/ +void TMR_Delay(mxc_tmr_regs_t* tmr, unsigned long us) +{ + TMR_TO_Start(tmr, us); + + while(TMR_TO_Check(tmr) != E_TIME_OUT) {} +} + +/******************************************************************************/ +void TMR_TO_Start(mxc_tmr_regs_t* tmr, unsigned long us) +{ + unsigned clk_shift = 0; + uint64_t max_us; + uint32_t ticks; + + // Adjust the clk shift amout by how long the timeout is + // Start with the fastest clock to give the greatest accuracy + do { + max_us = (uint64_t)((0xFFFFFFFFUL / ((uint64_t)SystemCoreClock >> clk_shift++)) * 1000000UL); + } while(us > max_us); + + // Calculate the number of timer ticks we need to wait + TMR_Init(tmr, (tmr_prescale_t)clk_shift, NULL); + TMR32_TimeToTicks(tmr, us, TMR_UNIT_MICROSEC, &ticks); + + // Initialize the timer in one-shot mode + tmr32_cfg_t cfg; + cfg.mode = TMR32_MODE_ONE_SHOT; + cfg.compareCount = ticks; + TMR32_Stop(tmr); + TMR32_Config(tmr, &cfg); + + TMR32_ClearFlag(tmr); + TMR32_Start(tmr); +} + +/******************************************************************************/ +int TMR_TO_Check(mxc_tmr_regs_t* tmr) +{ + if(TMR32_GetFlag(tmr)) { + return E_TIME_OUT; + } + return E_NO_ERROR; +} + +/******************************************************************************/ +void TMR_TO_Stop(mxc_tmr_regs_t* tmr) +{ + TMR32_Stop(tmr); + TMR32_SetCount(tmr, 0x0); +} + +/******************************************************************************/ +void TMR_TO_Clear(mxc_tmr_regs_t* tmr) +{ + TMR32_ClearFlag(tmr); + TMR32_SetCount(tmr, 0x0); +} + +/******************************************************************************/ +unsigned TMR_TO_Elapsed(mxc_tmr_regs_t* tmr) +{ + uint32_t elapsed; + tmr_unit_t units; + + TMR_TicksToTime(tmr, TMR32_GetCount(tmr), &elapsed, &units); + + switch(units) { + case TMR_UNIT_NANOSEC: + default: + return (elapsed / 1000); + case TMR_UNIT_MICROSEC: + return (elapsed); + case TMR_UNIT_MILLISEC: + return (elapsed * 1000); + case TMR_UNIT_SEC: + return (elapsed * 1000000); + } +} + +/******************************************************************************/ +unsigned TMR_TO_Remaining(mxc_tmr_regs_t* tmr) +{ + uint32_t remaining_ticks, remaining_time; + tmr_unit_t units; + + remaining_ticks = TMR32_GetCompare(tmr) - TMR32_GetCount(tmr); + TMR_TicksToTime(tmr, remaining_ticks, &remaining_time, &units); + + switch(units) { + case TMR_UNIT_NANOSEC: + default: + return (remaining_time / 1000); + case TMR_UNIT_MICROSEC: + return (remaining_time); + case TMR_UNIT_MILLISEC: + return (remaining_time * 1000); + case TMR_UNIT_SEC: + return (remaining_time * 1000000); + } +} + +/******************************************************************************/ +void TMR_SW_Start(mxc_tmr_regs_t* tmr) +{ + TMR_TO_Start(tmr, 0xFFFFFFFF); +} + +/******************************************************************************/ +unsigned TMR_SW_Stop(mxc_tmr_regs_t* tmr) +{ + unsigned elapsed = TMR_TO_Elapsed(tmr); + TMR_TO_Stop(tmr); + return elapsed; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr_utils.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr_utils.h new file mode 100644 index 00000000000..a6712372ba8 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/tmr_utils.h @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-21 09:04:59 -0500 (Mon, 21 Mar 2016) $ + * $Revision: 22006 $ + * + ******************************************************************************/ + +/** + * @file tmr_utils.h + * @brief Timer utility functions. + */ + +#ifndef _TMR_UTILS_H +#define _TMR_UTILS_H + +/***** Includes *****/ +#include "mxc_config.h" +#include "tmr_regs.h" +#include "mxc_sys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***** Definitions *****/ +#define SEC(s) (((unsigned long)s) * 1000000UL) +#define MSEC(ms) (ms * 1000UL) +#define USEC(us) (us) + +/***** Globals *****/ + +/***** Function Prototypes *****/ + +/** + * @brief Delays for the specified number of microseconds. + * @param tmr TMR module to operate on + * @param us Number of microseconds to delay. + */ +void TMR_Delay(mxc_tmr_regs_t* tmr, unsigned long us); + +/** + * @brief Start the timeout time for the specified number of microseconds. + * @param tmr TMR module to operate on + * @param us Number of microseconds in the timeout. + */ +void TMR_TO_Start(mxc_tmr_regs_t* tmr, unsigned long us); + +/** + * @brief Check if the timeout has occured. + * @param tmr TMR module to operate on + * @returns E_NO_ERROR if the timeout has not occurred, E_TIME_OUT if it has. + */ +int TMR_TO_Check(mxc_tmr_regs_t* tmr); + +/** + * @brief Stops the timer for the timeout. + * @param tmr TMR module to operate on + */ +void TMR_TO_Stop(mxc_tmr_regs_t* tmr); + +/** + * @brief Clears the timeout flag. + * @param tmr TMR module to operate on + */ +void TMR_TO_Clear(mxc_tmr_regs_t* tmr); + +/** + * @brief Get the number of microseconds elapsed since to_start(). + * @param tmr TMR module to operate on + * @returns Number of microseconds since to_start(). + */ +unsigned TMR_TO_Elapsed(mxc_tmr_regs_t* tmr); + +/** + * @brief Get the number of microseconds remaining in the timeout. + * @param tmr TMR module to operate on + * @returns Number of microseconds since to_start(). + */ +unsigned TMR_TO_Remaining(mxc_tmr_regs_t* tmr); + +/** + * @brief Start the stopwatch. + */ +void TMR_SW_Start(mxc_tmr_regs_t* tmr); + +/** + * @brief Stop the stopwatch and return the number of microseconds that have elapsed. + * @param tmr TMR module to operate on + * @returns Number of microseconds since sw_start(). + */ +unsigned TMR_SW_Stop(mxc_tmr_regs_t* tmr); + +#ifdef __cplusplus +} +#endif + +#endif /* _TMR_UTILS_H */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/uart.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/uart.c new file mode 100644 index 00000000000..643d3857b3c --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/uart.c @@ -0,0 +1,653 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-07-28 15:01:10 -0500 (Thu, 28 Jul 2016) $ + * $Revision: 23823 $ + * + ******************************************************************************/ + +/** + * @file uart.c + * @brief UART diver source. + */ + +/***** Includes *****/ +#include +#include "mxc_assert.h" +#include "mxc_lock.h" +#include "mxc_sys.h" +#include "uart.h" + +/***** Definitions *****/ +#define UART_ERRORS (MXC_F_UART_INTEN_RX_FIFO_OVERFLOW | \ + MXC_F_UART_INTEN_RX_FRAMING_ERR | \ + MXC_F_UART_INTEN_RX_PARITY_ERR) + +#define UART_READ_INTS (MXC_F_UART_INTEN_RX_FIFO_AF | \ + MXC_F_UART_INTEN_RX_FIFO_NOT_EMPTY | \ + MXC_F_UART_INTEN_RX_STALLED | \ + UART_ERRORS) + +#define UART_WRITE_INTS (MXC_F_UART_INTEN_TX_UNSTALLED | \ + MXC_F_UART_INTEN_TX_FIFO_AE) + +#define UART_RXFIFO_USABLE (MXC_UART_FIFO_DEPTH-3) + +/***** Globals *****/ + +// Saves the state of the non-blocking read requests +static uart_req_t *rx_states[MXC_CFG_UART_INSTANCES]; + +// Saves the state of the non-blocking write requests +static uart_req_t *tx_states[MXC_CFG_UART_INSTANCES]; + +/***** Functions *****/ +static void UART_WriteHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num); +static void UART_ReadHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num, + uint32_t flags); + +/******************************************************************************/ +int UART_Init(mxc_uart_regs_t *uart, const uart_cfg_t *cfg, const sys_cfg_uart_t *sys_cfg) +{ + int err; + int uart_num; + uint32_t uart_clk; + uint8_t baud_shift; + uint16_t baud_div; + uint32_t baud, diff_baud; + uint32_t baud_1, diff_baud_1; + + // Check the input parameters + uart_num = MXC_UART_GET_IDX(uart); + MXC_ASSERT(uart_num >= 0); + + // Set system level configurations + if(sys_cfg != NULL) { + if ((err = SYS_UART_Init(uart, cfg, sys_cfg)) != E_NO_ERROR) { + return err; + } + } + + // Initialize state pointers + rx_states[uart_num] = NULL; + tx_states[uart_num] = NULL; + + // Drain FIFOs and enable UART + uart->ctrl = 0; + uart->ctrl = (MXC_F_UART_CTRL_UART_EN | MXC_F_UART_CTRL_TX_FIFO_EN | + MXC_F_UART_CTRL_RX_FIFO_EN | + (UART_RXFIFO_USABLE << MXC_F_UART_CTRL_RTS_LEVEL_POS)); + + // Configure data size, stop bit, parity, cts, and rts + uart->ctrl |= ((cfg->size << MXC_F_UART_CTRL_DATA_SIZE_POS) | + (cfg->extra_stop << MXC_F_UART_CTRL_EXTRA_STOP_POS) | + (cfg->parity << MXC_F_UART_CTRL_PARITY_POS) | + (cfg->cts << MXC_F_UART_CTRL_CTS_EN_POS) | + (cfg->rts << MXC_F_UART_CTRL_RTS_EN_POS)); + + // Configure the baud rate and divisor + uart_clk = SYS_UART_GetFreq(uart); + MXC_ASSERT(uart_clk > 0); + + baud_shift = 2; + baud_div = (uart_clk / (cfg->baud * 4)); + + // Can not support higher frequencies + if(!baud_div) { + return E_NOT_SUPPORTED; + } + + // Decrease the divisor if baud_div is overflowing + while(baud_div > 0xFF) { + if(baud_shift == 0) { + return E_NOT_SUPPORTED; + } + baud_shift--; + baud_div = (uart_clk / (cfg->baud * (16 >> baud_shift))); + } + + // Adjust baud_div so we don't overflow with the calculations below + if(baud_div == 0xFF) { + baud_div = 0xFE; + } + if(baud_div == 0) { + baud_div = 1; + } + + // Figure out if the truncation increased the error + baud = (uart_clk / (baud_div * (16 >> baud_shift))); + baud_1 = (uart_clk / ((baud_div+1) * (16 >> baud_shift))); + + if(cfg->baud > baud) { + diff_baud = cfg->baud - baud; + } else { + diff_baud = baud - cfg->baud; + } + + if(cfg->baud > baud_1) { + diff_baud_1 = cfg->baud - baud_1; + } else { + diff_baud_1 = baud_1 - cfg->baud; + } + + if(diff_baud < diff_baud_1) { + uart->baud = ((baud_div & MXC_F_UART_BAUD_BAUD_DIVISOR) | + (baud_shift << MXC_F_UART_BAUD_BAUD_MODE_POS)); + } else { + uart->baud = (((baud_div+1) & MXC_F_UART_BAUD_BAUD_DIVISOR) | + (baud_shift << MXC_F_UART_BAUD_BAUD_MODE_POS)); + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int UART_Shutdown(mxc_uart_regs_t *uart) +{ + int uart_num, err; + uart_req_t *temp_req; + + uart_num = MXC_UART_GET_IDX(uart); + MXC_ASSERT(uart_num >= 0); + + // Disable and clear interrupts + uart->inten = 0; + uart->intfl = uart->intfl; + + // Disable UART and FIFOS + uart->ctrl &= ~(MXC_F_UART_CTRL_UART_EN | MXC_F_UART_CTRL_TX_FIFO_EN | + MXC_F_UART_CTRL_RX_FIFO_EN); + + // Call all of the pending callbacks for this UART + if(rx_states[uart_num] != NULL) { + + // Save the request + temp_req = rx_states[uart_num]; + + // Unlock this UART to read + mxc_free_lock((uint32_t*)&rx_states[uart_num]); + + // Callback if not NULL + if(temp_req->callback != NULL) { + temp_req->callback(temp_req, E_SHUTDOWN); + } + } + + if(tx_states[uart_num] != NULL) { + + // Save the request + temp_req = tx_states[uart_num]; + + // Unlock this UART to write + mxc_free_lock((uint32_t*)&tx_states[uart_num]); + + // Callback if not NULL + if(temp_req->callback != NULL) { + temp_req->callback(temp_req, E_SHUTDOWN); + } + } + + // Clears system level configurations + if ((err = SYS_UART_Shutdown(uart)) != E_NO_ERROR) { + return err; + } + + return E_NO_ERROR; +} + +/******************************************************************************/ +int UART_Write(mxc_uart_regs_t *uart, uint8_t* data, int len) +{ + int num, uart_num; + mxc_uart_fifo_regs_t *fifo; + + uart_num = MXC_UART_GET_IDX(uart); + MXC_ASSERT(uart_num >= 0); + + if(data == NULL) { + return E_NULL_PTR; + } + + // Make sure the UART has been initialized + if(!(uart->ctrl & MXC_F_UART_CTRL_UART_EN)) { + return E_UNINITIALIZED; + } + + if(!(len > 0)) { + return E_NO_ERROR; + } + + // Lock this UART from writing + while(mxc_get_lock((uint32_t*)&tx_states[uart_num], 1) != E_NO_ERROR) {} + + // Get the FIFO for this UART + fifo = MXC_UART_GET_FIFO(uart_num); + + num = 0; + + while(num < len) { + + // Wait for TXFIFO to not be full + while((uart->tx_fifo_ctrl & MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY) == + MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY) {} + + // Write the data to the FIFO +#if(MXC_UART_REV == 0) + uart->intfl = MXC_F_UART_INTFL_TX_DONE; +#endif + fifo->tx = data[num++]; + } + + // Unlock this UART to write + mxc_free_lock((uint32_t*)&tx_states[uart_num]); + + return num; +} + +/******************************************************************************/ +int UART_Read(mxc_uart_regs_t *uart, uint8_t* data, int len, int *num) +{ + int num_local, remain, uart_num; + mxc_uart_fifo_regs_t *fifo; + + uart_num = MXC_UART_GET_IDX(uart); + MXC_ASSERT(uart_num >= 0); + + if(data == NULL) { + return E_NULL_PTR; + } + + // Make sure the UART has been initialized + if(!(uart->ctrl & MXC_F_UART_CTRL_UART_EN)) { + return E_UNINITIALIZED; + } + + if(!(len > 0)) { + return E_NO_ERROR; + } + + // Lock this UART from reading + while(mxc_get_lock((uint32_t*)&rx_states[uart_num], 1) != E_NO_ERROR) {} + + // Get the FIFO for this UART + fifo = MXC_UART_GET_FIFO(uart_num); + + num_local = 0; + remain = len; + while(remain) { + + // Save the data in the FIFO + while((uart->rx_fifo_ctrl & MXC_F_UART_RX_FIFO_CTRL_FIFO_ENTRY) && remain) { + data[num_local] = fifo->rx; + num_local++; + remain--; + } + + // Break if there is an error + if(uart->intfl & UART_ERRORS) { + break; + } + } + + // Save the number of bytes read if pointer is valid + if(num != NULL) { + *num = num_local; + } + + // Check for errors + if(uart->intfl & MXC_F_UART_INTFL_RX_FIFO_OVERFLOW) { + + // Clear errors and return error code + uart->intfl = UART_ERRORS; + + + // Unlock this UART to read + mxc_free_lock((uint32_t*)&rx_states[uart_num]); + + return E_OVERFLOW; + + } else if(uart->intfl & (MXC_F_UART_INTFL_RX_FRAMING_ERR | + MXC_F_UART_INTFL_RX_PARITY_ERR)) { + + // Clear errors and return error code + uart->intfl = UART_ERRORS; + + + // Unlock this UART to read + mxc_free_lock((uint32_t*)&rx_states[uart_num]); + + return E_COMM_ERR; + } + + // Unlock this UART to read + mxc_free_lock((uint32_t*)&rx_states[uart_num]); + + return num_local; +} + +/******************************************************************************/ +int UART_WriteAsync(mxc_uart_regs_t *uart, uart_req_t *req) +{ + int uart_num = MXC_UART_GET_IDX(uart); + MXC_ASSERT(uart_num >= 0); + + // Check the input parameters + if(req->data == NULL) { + return E_NULL_PTR; + } + + // Make sure the UART has been initialized + if(!(uart->ctrl & MXC_F_UART_CTRL_UART_EN)) { + return E_UNINITIALIZED; + } + + if(!(req->len > 0)) { + return E_NO_ERROR; + } + + // Attempt to register this write request + if(mxc_get_lock((uint32_t*)&tx_states[uart_num], (uint32_t)req) != E_NO_ERROR) { + return E_BUSY; + } + + // Clear the number of bytes counter + req->num = 0; + + // Start the write + UART_WriteHandler(uart, req, uart_num); + + return E_NO_ERROR; +} + +/******************************************************************************/ +int UART_ReadAsync(mxc_uart_regs_t *uart, uart_req_t *req) +{ + int uart_num; + uint32_t flags; + + uart_num = MXC_UART_GET_IDX(uart); + MXC_ASSERT(uart_num >= 0); + + if(req->data == NULL) { + return E_NULL_PTR; + } + + // Make sure the UART has been initialized + if(!(uart->ctrl & MXC_F_UART_CTRL_UART_EN)) { + return E_UNINITIALIZED; + } + + if(!(req->len > 0)) { + return E_NO_ERROR; + } + + // Attempt to register this write request + if(mxc_get_lock((uint32_t*)&rx_states[uart_num], (uint32_t)req) != E_NO_ERROR) { + return E_BUSY; + } + + // Clear the number of bytes counter + req->num = 0; + + // Start the read + flags = uart->intfl; + uart->intfl = flags; + UART_ReadHandler(uart, req, uart_num, flags); + + return E_NO_ERROR; +} + +/******************************************************************************/ +int UART_AbortAsync(uart_req_t *req) +{ + int uart_num; + + // Figure out if this was a read or write request, find the request, set to NULL + for(uart_num = 0; uart_num < MXC_CFG_UART_INSTANCES; uart_num++) { + if(req == rx_states[uart_num]) { + + // Disable read interrupts, clear flags. + MXC_UART_GET_UART(uart_num)->inten &= ~UART_READ_INTS; + MXC_UART_GET_UART(uart_num)->intfl = UART_READ_INTS; + + // Unlock this UART to read + mxc_free_lock((uint32_t*)&rx_states[uart_num]); + + // Callback if not NULL + if(req->callback != NULL) { + req->callback(req, E_ABORT); + } + + return E_NO_ERROR; + } + + if(req == tx_states[uart_num]) { + + // Disable write interrupts, clear flags. + MXC_UART_GET_UART(uart_num)->inten &= ~(UART_WRITE_INTS); + MXC_UART_GET_UART(uart_num)->intfl = UART_WRITE_INTS; + + // Unlock this UART to write + mxc_free_lock((uint32_t*)&tx_states[uart_num]); + + // Callback if not NULL + if(req->callback != NULL) { + req->callback(req, E_ABORT); + } + + return E_NO_ERROR; + } + } + + return E_BAD_PARAM; +} + +/******************************************************************************/ +void UART_Handler(mxc_uart_regs_t *uart) +{ + int uart_num; + uint32_t flags; + + uart_num = MXC_UART_GET_IDX(uart); + MXC_ASSERT(uart_num >= 0); + + flags = uart->intfl; + uart->intfl = flags; + + // Figure out if this UART has an active Read request + if((rx_states[uart_num] != NULL) && (flags & UART_READ_INTS)) { + UART_ReadHandler(uart, rx_states[uart_num], uart_num, flags); + } + + // Figure out if this UART has an active Write request + if((tx_states[uart_num] != NULL) && (flags & (UART_WRITE_INTS))) { + + UART_WriteHandler(uart, tx_states[uart_num], uart_num); + } +} +/******************************************************************************/ +int UART_Busy(mxc_uart_regs_t *uart) +{ + int uart_num = MXC_UART_GET_IDX(uart); + MXC_ASSERT(uart_num >= 0); + + // Check to see if there are any ongoing transactions or if the UART is disabled + if(((tx_states[uart_num] == NULL) && + !(uart->tx_fifo_ctrl & MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY) && +#if(MXC_UART_REV == 0) + (uart->intfl & MXC_F_UART_INTFL_TX_DONE)) || +#else + (uart->idle & MXC_F_UART_IDLE_TX_RX_IDLE)) || +#endif + !(uart->ctrl & MXC_F_UART_CTRL_UART_EN)) { + + return E_NO_ERROR; + } + + return E_BUSY; +} + +/******************************************************************************/ +int UART_PrepForSleep(mxc_uart_regs_t *uart) +{ + if(UART_Busy(uart) != E_NO_ERROR) { + return E_BUSY; + } + + // Leave read interrupts enabled, if already enabled + uart->inten &= UART_READ_INTS; + + return E_NO_ERROR; +} + +/******************************************************************************/ +static void UART_WriteHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num) +{ + int avail, remain; + mxc_uart_fifo_regs_t *fifo; + + // Disable write interrupts + uart->inten &= ~(UART_WRITE_INTS); + + // Get the FIFO for this UART + fifo = MXC_UART_GET_FIFO(uart_num); + + // Refill the TX FIFO + avail = UART_NumWriteAvail(uart); + remain = req->len - req->num; + + while(avail && remain) { + + // Write the data to the FIFO +#if(MXC_UART_REV == 0) + uart->intfl = MXC_F_UART_INTFL_TX_DONE; +#endif + fifo->tx = req->data[req->num++]; + remain--; + avail--; + } + + // All of the bytes have been written to the FIFO + if(!remain) { + + // Unlock this UART to write + mxc_free_lock((uint32_t*)&tx_states[uart_num]); + + if(req->callback != NULL) { + req->callback(req, E_NO_ERROR); + } + + } else { + + // Interrupt when there is one byte left in the TXFIFO + uart->tx_fifo_ctrl = ((MXC_UART_FIFO_DEPTH - 1) << MXC_F_UART_TX_FIFO_CTRL_FIFO_AE_LVL_POS); + + // Enable almost empty interrupt + uart->inten |= (MXC_F_UART_INTEN_TX_FIFO_AE); + } +} + +/******************************************************************************/ +static void UART_ReadHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num, + uint32_t flags) +{ + int avail, remain; + mxc_uart_fifo_regs_t *fifo; + + // Disable interrupts + uart->inten &= ~UART_READ_INTS; + + // Get the FIFO for this UART, uart_num + fifo = MXC_UART_GET_FIFO(uart_num); + + // Save the data in the FIFO while we still need data + avail = UART_NumReadAvail(uart); + remain = req->len - req->num; + while(avail && remain) { + req->data[req->num++] = fifo->rx; + remain--; + avail--; + } + + // Check for errors + if(flags & MXC_F_UART_INTFL_RX_FIFO_OVERFLOW) { + + // Unlock this UART to read + mxc_free_lock((uint32_t*)&rx_states[uart_num]); + + if(req->callback != NULL) { + req->callback(req, E_OVERFLOW); + } + + return; + } + + if(flags & (MXC_F_UART_INTFL_RX_FRAMING_ERR | + MXC_F_UART_INTFL_RX_PARITY_ERR)) { + + // Unlock this UART to read + mxc_free_lock((uint32_t*)&rx_states[uart_num]); + + if(req->callback != NULL) { + req->callback(req, E_COMM_ERR); + } + + return; + } + + // Check to see if we're done receiving + if(remain == 0) { + + // Unlock this UART to read + mxc_free_lock((uint32_t*)&rx_states[uart_num]); + + if(req->callback != NULL) { + req->callback(req, E_NO_ERROR); + } + + return; + } + + if(remain == 1) { + uart->inten |= (MXC_F_UART_INTEN_RX_FIFO_NOT_EMPTY | UART_ERRORS); + + } else { + // Set the RX FIFO AF threshold + if(remain < UART_RXFIFO_USABLE) { + uart->rx_fifo_ctrl = ((remain - 1) << + MXC_F_UART_RX_FIFO_CTRL_FIFO_AF_LVL_POS); + } else { + uart->rx_fifo_ctrl = (UART_RXFIFO_USABLE << + MXC_F_UART_RX_FIFO_CTRL_FIFO_AF_LVL_POS); + } + uart->inten |= (MXC_F_UART_INTEN_RX_FIFO_AF | UART_ERRORS); + } +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/uart.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/uart.h new file mode 100644 index 00000000000..0d57373a514 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/uart.h @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-06-21 16:16:33 -0500 (Tue, 21 Jun 2016) $ + * $Revision: 23447 $ + * + ******************************************************************************/ + +/** + * @file uart.h + * @brief UART driver header file. + */ + +#include "mxc_config.h" +#include "mxc_sys.h" +#include "uart_regs.h" + +#ifndef _UART_H_ +#define _UART_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/***** Definitions *****/ + +/// @brief Defines number of data bits per transmission/reception +typedef enum { + UART_DATA_SIZE_5_BITS = MXC_V_UART_CTRL_DATA_SIZE_5_BITS, + UART_DATA_SIZE_6_BITS = MXC_V_UART_CTRL_DATA_SIZE_6_BITS, + UART_DATA_SIZE_7_BITS = MXC_V_UART_CTRL_DATA_SIZE_7_BITS, + UART_DATA_SIZE_8_BITS = MXC_V_UART_CTRL_DATA_SIZE_8_BITS +} +uart_data_size_t; + +/// @brief Defines number of data bits per transmission/reception +typedef enum { + UART_PARITY_DISABLE = MXC_V_UART_CTRL_PARITY_DISABLE, + UART_PARITY_ODD = MXC_V_UART_CTRL_PARITY_ODD, + UART_PARITY_EVEN = MXC_V_UART_CTRL_PARITY_EVEN, + UART_PARITY_MARK = MXC_V_UART_CTRL_PARITY_MARK +} uart_parity_t; + +/// @brief UART configuration type. +typedef struct { + uint8_t extra_stop; ///< 0 for one stop bit, 1 for two stop bits. + uint8_t cts; ///< 1 to enable CTS. + uint8_t rts; ///< 1 to enable RTS. + uint32_t baud; ///< Baud rate in Hz. + uart_data_size_t size; ///< Number of bits in each character. + uart_parity_t parity; ///< Even or odd parity. +} uart_cfg_t; + +/** + * @brief Type alias for UART request structure + */ +typedef struct uart_req uart_req_t; + +/** + * @brief Type alias \c uart_async_callback for function signature: \code void callback)(uart_req_t* , int error_code) \endcode + * @param uart_req_t* Pointer to the transaction request. + * @param error_code Return code for the UART request. @see mxc_errors.h. + */ +typedef void (*uart_async_callback)(uart_req_t*, int); + +/// @brief UART Transaction request, must remain allocated until callback has completed. +struct uart_req { + uint8_t *data; ///< Data buffer for characters. + unsigned len; ///< Length of characters in data to send or receive. + unsigned num; ///< Number of characters actually sent or received. + uart_async_callback callback; ///< A callback function pointer with alias signature \c uart_async_callback +}; + + +/***** Globals *****/ + +/***** Function Prototypes *****/ + +/** + * @brief Initialize and enable UART module. + * @param uart Pointer to UART regs. + * @param cfg Pointer to UART configuration. + * @param sys_cfg Pointer to system configuration object + * @returns #E_NO_ERROR if everything is successful + */ +int UART_Init(mxc_uart_regs_t *uart, const uart_cfg_t *cfg, const sys_cfg_uart_t *sys_cfg); + +/** + * @brief Shutdown UART module. + * @param uart Pointer to UART regs. + * @returns #E_NO_ERROR if everything is successful + */ +int UART_Shutdown(mxc_uart_regs_t *uart); + +/** + * @brief Write UART data. Will block until transaction is complete. + * @param uart Pointer to UART regs. + * @param data Pointer to buffer for write data. + * @param len Number of bytes to write. + * @note Will return once data has been put into FIFO, not necessarily transmitted. + * @returns Number of bytes written if successful, error if unsuccessful. + */ +int UART_Write(mxc_uart_regs_t *uart, uint8_t* data, int len); + +/** + * @brief Read UART data. Will block until transaction is complete. + * @param uart Pointer to UART regs. + * @param data Pointer to buffer for read data. + * @param len Number of bytes to read. + * @param num Optional pointer to number of bytes actually read. + * Pass NULL if undesired. + * @returns Number of bytes read is successful, error if unsuccessful. + */ +int UART_Read(mxc_uart_regs_t *uart, uint8_t* data, int len, int *num); + +/** + * @brief Asynchronously Write UART data. + * @param uart Pointer to UART regs. + * @param req Request for a UART transaction. + * @note Request struct must remain allocated until callback. + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int UART_WriteAsync(mxc_uart_regs_t *uart, uart_req_t *req); + +/** + * @brief Asynchronously Read UART data. + * @param uart Pointer to UART regs. + * @param req Pointer to request for a UART transaction. + * @note Request struct must remain allocated until callback. + * @returns #E_NO_ERROR if everything is successful, error if unsuccessful. + */ +int UART_ReadAsync(mxc_uart_regs_t *uart, uart_req_t *req); + +/** + * @brief Abort asynchronous request. + * @param req Pointer to request for a UART transaction. + * @returns #E_NO_ERROR if request aborted, error if unsuccessful. + */ +int UART_AbortAsync(uart_req_t *req); + +/** + * @brief UART interrupt handler. + * @details This function should be called by the application from the interrupt + * handler if UART interrupts are enabled. Alternately, this function + * can be periodically called by the application if UART interrupts are + * disabled. Only necessary to call this when using asynchronous functions. + * @param uart Pointer to UART regs. + */ +void UART_Handler(mxc_uart_regs_t *uart); + +/** + * @brief Check to see if the UART is busy. + * @param uart Pointer to UART regs. + * @returns #E_NO_ERROR if idle, #E_BUSY if in use. + */ +int UART_Busy(mxc_uart_regs_t *uart); + +/** + * @brief Attempt to prepare the UART for sleep. + * @param uart Pointer to UART regs. + * @details Checks for any ongoing transactions. Disables interrupts if the I2CM + is idle. + * @returns #E_NO_ERROR if ready to sleep, #E_BUSY if not ready for sleep. + */ +int UART_PrepForSleep(mxc_uart_regs_t *uart); + +/** + * @brief Enables the UART without overwriting existing configuration. + * @param uart Pointer to UART regs. + */ +__STATIC_INLINE void UART_Enable(mxc_uart_regs_t *uart) +{ + uart->ctrl |= (MXC_F_UART_CTRL_UART_EN | MXC_F_UART_CTRL_TX_FIFO_EN | + MXC_F_UART_CTRL_RX_FIFO_EN); +} + +/** + * @brief Drain all of the data in the RXFIFO. + * @param uart Pointer to UART regs. + */ +__STATIC_INLINE void UART_DrainRX(mxc_uart_regs_t *uart) +{ + uint32_t ctrl_save = uart->ctrl; + uart->ctrl = (ctrl_save & ~MXC_F_UART_CTRL_RX_FIFO_EN); + uart->ctrl = ctrl_save; +} + +/** + * @brief Drain all of the data in the TXFIFO. + * @param uart Pointer to UART regs. + */ +__STATIC_INLINE void UART_DrainTX(mxc_uart_regs_t *uart) +{ + uint32_t ctrl_save = uart->ctrl; + uart->ctrl = (ctrl_save & ~MXC_F_UART_CTRL_TX_FIFO_EN); + uart->ctrl = ctrl_save; +} + +/** + * @brief Write FIFO availability. + * @param uart Pointer to UART regs. + * @returns Number of empty bytes available in write FIFO. + */ +__STATIC_INLINE unsigned UART_NumWriteAvail(mxc_uart_regs_t *uart) +{ + return (MXC_UART_FIFO_DEPTH - (uart->tx_fifo_ctrl & MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY)); +} + +/** + * @brief Read FIFO availability. + * @param uart Pointer to UART regs. + * @returns Number of bytes in read FIFO. + */ +__STATIC_INLINE unsigned UART_NumReadAvail(mxc_uart_regs_t *uart) +{ + return (uart->rx_fifo_ctrl & MXC_F_UART_RX_FIFO_CTRL_FIFO_ENTRY); +} + +/** + * @brief Clear interrupt flags. + * @param uart Pointer to UART regs. + * @param mask Mask of interrupts to clear. + */ +__STATIC_INLINE void UART_ClearFlags(mxc_uart_regs_t *uart, uint32_t mask) +{ + uart->intfl = mask; +} + +/** + * @brief Get interrupt flags. + * @param uart Pointer to UART regs. + * @returns Mask of active flags. + */ +__STATIC_INLINE unsigned UART_GetFlags(mxc_uart_regs_t *uart) +{ + return (uart->intfl); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _UART_H_ */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt.c new file mode 100644 index 00000000000..d9b90958ee7 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt.c @@ -0,0 +1,286 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-21 15:44:11 -0500 (Mon, 21 Mar 2016) $ + * $Revision: 22024 $ + * + ******************************************************************************/ + +/** + * @file wdt.c + * @brief Watchdog driver source. + */ + +#include +#include "wdt.h" + +static uint32_t interruptEnable = 0; //keeps track to interrupts to enable in start function + +/******************************************************************************/ +int WDT_Init(mxc_wdt_regs_t *wdt, const sys_cfg_wdt_t *cfg, uint8_t unlock_key) +{ + if ((wdt == NULL) || (cfg == NULL)) + return E_NULL_PTR; + + //setup watchdog clock + SYS_WDT_Init(wdt, cfg); + + //unlock ctrl to be writable + wdt->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (wdt->lock_ctrl & 0x01) + return E_BAD_STATE; + + //disable all interrupts + interruptEnable = 0; + wdt->enable = interruptEnable; + + //enable the watchdog clock and clear all other settings + wdt->ctrl = MXC_F_WDT_CTRL_EN_CLOCK; + + //clear all interrupt flags + wdt->flags = WDT_FLAGS_CLEAR_ALL; + + //lock ctrl to read-only + wdt->lock_ctrl = MXC_V_WDT_LOCK_KEY; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int WDT_EnableInt(mxc_wdt_regs_t *wdt, wdt_period_t int_period, uint8_t unlock_key) +{ + //unlock ctrl to be writable + wdt->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (wdt->lock_ctrl & 0x01) + return E_BAD_STATE; + + //stop timer and clear interval period + wdt->ctrl &= ~(MXC_F_WDT_CTRL_INT_PERIOD | MXC_F_WDT_CTRL_EN_TIMER); + + //set interval period + wdt->ctrl |= (int_period << MXC_F_WDT_CTRL_INT_PERIOD_POS); + + //enable timeout interrupt + interruptEnable |= MXC_F_WDT_ENABLE_TIMEOUT; + + //lock ctrl to read-only + wdt->lock_ctrl = MXC_V_WDT_LOCK_KEY; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int WDT_DisableInt(mxc_wdt_regs_t *wdt, uint8_t unlock_key) +{ + //unlock register to be writable + wdt->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (wdt->lock_ctrl & 0x01) + return E_BAD_STATE; + + //disable timeout interrupt + interruptEnable &= ~MXC_F_WDT_ENABLE_TIMEOUT; + wdt->enable = interruptEnable; + + //lock register to read-only + wdt->lock_ctrl = MXC_V_WDT_LOCK_KEY; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int WDT_EnableWait(mxc_wdt_regs_t *wdt, wdt_period_t wait_period, uint8_t unlock_key) +{ + // Make sure wait_period is valid + if (wait_period >= WDT_PERIOD_MAX) + return E_INVALID; + + //unlock ctrl to be writable + wdt->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (wdt->lock_ctrl & 0x01) + return E_BAD_STATE; + + //stop timer and clear wait period + wdt->ctrl &= ~(MXC_F_WDT_CTRL_WAIT_PERIOD | MXC_F_WDT_CTRL_EN_TIMER); + + //set wait period + wdt->ctrl |= (wait_period << MXC_F_WDT_CTRL_WAIT_PERIOD_POS); + + //enable wait interrupt + interruptEnable |= MXC_F_WDT_ENABLE_PRE_WIN; + + //lock ctrl to read-only + wdt->lock_ctrl = MXC_V_WDT_LOCK_KEY; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int WDT_DisableWait(mxc_wdt_regs_t *wdt, uint8_t unlock_key) +{ + //unlock register to be writable + wdt->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (wdt->lock_ctrl & 0x01) + return E_BAD_STATE; + + //disable wait interrupt + interruptEnable &= ~MXC_F_WDT_ENABLE_PRE_WIN; + wdt->enable = interruptEnable; + + //lock register to read-only + wdt->lock_ctrl = MXC_V_WDT_LOCK_KEY; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int WDT_EnableReset(mxc_wdt_regs_t *wdt, wdt_period_t rst_period, uint8_t unlock_key) +{ + // Make sure wait_period is valid + if (rst_period >= WDT_PERIOD_MAX) + return E_INVALID; + + //unlock ctrl to be writable + wdt->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (wdt->lock_ctrl & 0x01) + return E_BAD_STATE; + + //stop timer and clear reset period + wdt->ctrl &= ~(MXC_F_WDT_CTRL_RST_PERIOD | MXC_F_WDT_CTRL_EN_TIMER); + + //set reset period + wdt->ctrl |= (rst_period << MXC_F_WDT_CTRL_RST_PERIOD_POS); + + //enable reset0 + interruptEnable |= MXC_F_WDT_ENABLE_RESET_OUT; + + //lock ctrl to read-only + wdt->lock_ctrl = MXC_V_WDT_LOCK_KEY; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int WDT_DisableReset(mxc_wdt_regs_t *wdt, uint8_t unlock_key) +{ + //unlock register to be writable + wdt->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (wdt->lock_ctrl & 0x01) + return E_BAD_STATE; + + //disable reset0 + interruptEnable &= ~MXC_F_WDT_ENABLE_RESET_OUT; + wdt->enable = interruptEnable; + + //lock register to read-only + wdt->lock_ctrl = MXC_V_WDT_LOCK_KEY; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int WDT_Start(mxc_wdt_regs_t *wdt, uint8_t unlock_key) +{ + //check if watchdog is already running + if(WDT_IsActive(wdt)) + return E_BAD_STATE; + + //unlock ctrl to be writable + wdt->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (wdt->lock_ctrl & 0x01) + return E_BAD_STATE; + + WDT_Reset(wdt); + + //enable interrupts + wdt->enable = interruptEnable; + + //start timer + wdt->ctrl |= MXC_F_WDT_CTRL_EN_TIMER; + + //lock ctrl to read-only + wdt->lock_ctrl = MXC_V_WDT_LOCK_KEY; + + return E_NO_ERROR; +} + +/******************************************************************************/ +void WDT_Reset(mxc_wdt_regs_t *wdt) +{ + //reset the watchdog counter + wdt->clear = MXC_V_WDT_RESET_KEY_0; + wdt->clear = MXC_V_WDT_RESET_KEY_1; + + //clear all interrupt flags + wdt->flags = WDT_FLAGS_CLEAR_ALL; + + //wait for all interrupts to clear + while(wdt->flags != 0) { + wdt->flags = WDT_FLAGS_CLEAR_ALL; + } + + return; +} + +/******************************************************************************/ +int WDT_Stop(mxc_wdt_regs_t *wdt, uint8_t unlock_key) +{ + //unlock ctrl to be writable + wdt->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (wdt->lock_ctrl & 0x01) + return E_BAD_STATE; + + //disabled the timer and interrupts + wdt->enable = 0; + wdt->ctrl &= ~(MXC_F_WDT_CTRL_EN_TIMER); + + //lock ctrl to read-only + wdt->lock_ctrl = MXC_V_WDT_LOCK_KEY; + + return E_NO_ERROR; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt.h new file mode 100644 index 00000000000..ffcabad5e91 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt.h @@ -0,0 +1,245 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-21 15:44:11 -0500 (Mon, 21 Mar 2016) $ + * $Revision: 22024 $ + * + ******************************************************************************/ + +/** + * @file wdt.h + * @addtogroup wdt WDT + * @{ + * @brief This is the high level API for the watchdog timer interface module + * + */ + +#ifndef _WDT_H +#define _WDT_H + +#include "mxc_config.h" +#include "wdt_regs.h" +#include "mxc_assert.h" +#include "mxc_sys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define WDT_FLAGS_CLEAR_ALL (MXC_F_WDT_FLAGS_TIMEOUT| \ + MXC_F_WDT_FLAGS_PRE_WIN | \ + MXC_F_WDT_FLAGS_RESET_OUT) +/** @enum wdt_period_t */ +/** @brief Enumeration for the Watchdog Timer Period */ +typedef enum { + WDT_PERIOD_2_31_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_31_CLKS, /**< 2^31 WDT clocks. */ + WDT_PERIOD_2_30_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_30_CLKS, /**< 2^30 WDT clocks. */ + WDT_PERIOD_2_29_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_29_CLKS, /**< 2^29 WDT clocks. */ + WDT_PERIOD_2_28_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_28_CLKS, /**< 2^28 WDT clocks. */ + WDT_PERIOD_2_27_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_27_CLKS, /**< 2^27 WDT clocks. */ + WDT_PERIOD_2_26_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_26_CLKS, /**< 2^26 WDT clocks. */ + WDT_PERIOD_2_25_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_25_CLKS, /**< 2^25 WDT clocks. */ + WDT_PERIOD_2_24_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_24_CLKS, /**< 2^24 WDT clocks. */ + WDT_PERIOD_2_23_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_23_CLKS, /**< 2^23 WDT clocks. */ + WDT_PERIOD_2_22_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_22_CLKS, /**< 2^22 WDT clocks. */ + WDT_PERIOD_2_21_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_21_CLKS, /**< 2^21 WDT clocks. */ + WDT_PERIOD_2_20_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_20_CLKS, /**< 2^20 WDT clocks. */ + WDT_PERIOD_2_19_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_19_CLKS, /**< 2^19 WDT clocks. */ + WDT_PERIOD_2_18_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_18_CLKS, /**< 2^18 WDT clocks. */ + WDT_PERIOD_2_17_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_17_CLKS, /**< 2^17 WDT clocks. */ + WDT_PERIOD_2_16_CLKS = MXC_V_WDT_CTRL_INT_PERIOD_2_16_CLKS, /**< 2^16 WDT clocks. */ + WDT_PERIOD_MAX /**< Maximum Period is Max - 1 */ +} wdt_period_t; + +/** + * @brief Initializes system level clocks and sets watchdog in a known disabled state + * @note The clk_scale in cfg is only used if the system clock is selected for clk. + * + * @param wdt Pointer to the Watchdog Timer Instance + * @param cfg Watchdog system configuration, see sys_cfg_wdt_t. + * @param unlock_key Watchdog unlock key + * + * @retval E_NO_ERROR Watchdog Timer initialized as requested + * @retval E_NULL_PTR NULL pointer for Watchdog Timer Instance or Configuration parameters. + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + */ +int WDT_Init(mxc_wdt_regs_t *wdt, const sys_cfg_wdt_t *cfg, uint8_t unlock_key); + +/** + * @brief Configures and enables the interrupt timeout for the watchdog specified. + * + * @param wdt Watchdog module to operate on + * @param int_period Interrupt period as defined by wdt_period_t. + * @param unlock_key Key to unlock watchdog. See MXC_WDT_UNLOCK_KEY. + * + * @retval E_NO_ERROR Interrupt enabled + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + */ +int WDT_EnableInt(mxc_wdt_regs_t *wdt, wdt_period_t int_period, uint8_t unlock_key); + +/** + * @brief Disables the interrupt timeout for the watchdog specified. + * + * @param wdt Pointer to the Watchdog Timer Instance + * @param unlock_key Key to unlock watchdog. See MXC_WDT_UNLOCK_KEY. + * + * @retval E_NO_ERROR Interrupt disabled. + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + */ +int WDT_DisableInt(mxc_wdt_regs_t *wdt, uint8_t unlock_key); + +/** + * @brief Configures and enables the pre-window timeout for the watchdog specified. + * + * @param wdt Pointer to the Watchdog Timer Instance + * @param wait_period Pre-window period, see wdt_period_t for accepted values. + * @param unlock_key Key to unlock watchdog. See MXC_WDT_UNLOCK_KEY. + * + * @retval E_NO_ERROR Pre-window timeout set to wait_period + * @retval E_BAD_STATE WDT unable to be unlocked + * @retval E_INVALID Requested Period is greater than the maximum supported + */ +int WDT_EnableWait(mxc_wdt_regs_t *wdt, wdt_period_t wait_period, uint8_t unlock_key); + +/** + * @brief Disables the pre-window timeout for the watchdog specified. + * + * @param wdt Pointer to the Watchdog Timer Instance + * @param unlock_key Key to unlock watchdog. See MXC_WDT_UNLOCK_KEY. + * + * @retval E_NO_ERROR Wait disabled. + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + */ +int WDT_DisableWait(mxc_wdt_regs_t *wdt, uint8_t unlock_key); + +/** + * @brief Configures and enables the reset timeout for the watchdog specified. + * + * @param wdt Pointer to the Watchdog Timer Instance + * @param rst_period Reset period, see wdt_period_t for accepted values. + * @param unlock_key Key to unlock watchdog. See MXC_WDT_UNLOCK_KEY. + * + * @retval E_NO_ERROR Watchdog Timer Reset enabled with the rst_period time. + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + * @retval E_INVALID Requested Period is greater than the maximum supported + */ +int WDT_EnableReset(mxc_wdt_regs_t *wdt, wdt_period_t rst_period, uint8_t unlock_key); + +/** + * @brief Disables the reset timeout for the watchdog specified. + * + * @param wdt Pointer to the Watchdog Timer Instance + * @param unlock_key Key to unlock watchdog. See MXC_WDT_UNLOCK_KEY. + * + * @retval E_NO_ERROR Reset disabled. + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + */ +int WDT_DisableReset(mxc_wdt_regs_t *wdt, uint8_t unlock_key); + +/** + * @brief Gets the watchdog interrupt flags + * + * @param wdt Pointer to the Watchdog Timer Instance. + * + * @retval uint32_t Value of the Watchdog Timer Flags. + * + */ +__STATIC_INLINE uint32_t WDT_GetFlags(mxc_wdt_regs_t *wdt) +{ + return (wdt->flags); +} + +/** + * @brief Clears the watchdog interrupt flags based on the mask + * + * @param wdt Pointer to the Watchdog Timer Instance + * @param mask Watchdog Flags to clear + * + */ +__STATIC_INLINE void WDT_ClearFlags(mxc_wdt_regs_t *wdt, uint32_t mask) +{ + wdt->flags = mask; +} + +/** + * @brief Starts the specified Watchdog Timer instance. + * + * @param wdt Pointer to the Watchdog Timer instance + * @param unlock_key Key to unlock watchdog. + * + * @retval E_NO_ERROR Interrupt enabled. + * @retval E_BAD_STATE WDT2 Already Running + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + * + */ +int WDT_Start(mxc_wdt_regs_t *wdt, uint8_t unlock_key); + +/** + * @brief Feeds the watchdog specified. + * + * @param wdt Watchdog module to operate on + * + */ +void WDT_Reset(mxc_wdt_regs_t *wdt); + +/** + * @brief Stops the watchdog specified. + * + * @param wdt Pointer to the Watchdog Timer Instance + * @param unlock_key Key to unlock watchdog. + * + * @retval E_NO_ERROR Interrupt enabled. + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + */ +int WDT_Stop(mxc_wdt_regs_t *wdt, uint8_t unlock_key); + +/** + * @brief Determines if the watchdog is running + * + * @param wdt Pointer to the Watchdog Timer Instance + * + * @retval 0 Watchdog timer is Disabled. + * @retval non-zero Watchdog timer is Active + */ +__STATIC_INLINE int WDT_IsActive(mxc_wdt_regs_t *wdt) +{ + return (!!(wdt->ctrl & MXC_F_WDT_CTRL_EN_TIMER)); +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* _WDT_H */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt2.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt2.c new file mode 100644 index 00000000000..d0c93fcf242 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt2.c @@ -0,0 +1,269 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-21 15:44:11 -0500 (Mon, 21 Mar 2016) $ + * $Revision: 22024 $ + * + ******************************************************************************/ + +/** + * @file wdt2.c + * @brief Watchdog 2 driver source. + */ +#include +#include "wdt2.h" +#include "pwrseq_regs.h" + +static uint32_t interruptEnable = 0; //keeps track to interrupts to enable in start function + +/******************************************************************************/ +int WDT2_Init(uint8_t runInSleep, uint8_t unlock_key) +{ + //enable nanoring in run and sleep mode + MXC_PWRSEQ->reg0 |= (MXC_F_PWRSEQ_REG0_PWR_NREN_RUN); + + //unlock ctrl to be writable + MXC_WDT2->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (MXC_WDT2->lock_ctrl & 0x01) + return E_BAD_STATE; + + //disable all interrupts + interruptEnable = 0; + MXC_WDT2->enable = interruptEnable; + + //enable the watchdog clock and clear all other settings + MXC_WDT2->ctrl = (MXC_F_WDT2_CTRL_EN_CLOCK); + + //clear all interrupt flags + MXC_WDT2->flags = WDT2_FLAGS_CLEAR_ALL; + + if(runInSleep) { + // turn on nanoring during sleep + MXC_PWRSEQ->reg0 |= (MXC_F_PWRSEQ_REG0_PWR_NREN_SLP); + //turn on timer during sleep + MXC_WDT2->ctrl |= MXC_F_WDT2_CTRL_EN_TIMER_SLP; + } else { + // turn off nanoring during sleep + MXC_PWRSEQ->reg0 &= ~(MXC_F_PWRSEQ_REG0_PWR_NREN_SLP); + //turn off timer during sleep + MXC_WDT2->ctrl &= ~(MXC_F_WDT2_CTRL_EN_TIMER_SLP); + } + + //lock ctrl to read-only + MXC_WDT2->lock_ctrl = MXC_V_WDT2_LOCK_KEY; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int WDT2_EnableWakeUp(wdt2_period_t int_period, uint8_t unlock_key) +{ + // Make sure interrupt period is valid + if (int_period >= WDT2_PERIOD_MAX) + return E_INVALID; + + //unlock ctrl to be writable + MXC_WDT2->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (MXC_WDT2->lock_ctrl & 0x01) + return E_BAD_STATE; + + //stop timer and clear interval period + MXC_WDT2->ctrl &= ~(MXC_F_WDT2_CTRL_INT_PERIOD | MXC_F_WDT2_CTRL_EN_TIMER); + + //set interval period + MXC_WDT2->ctrl |= (int_period << MXC_F_WDT2_CTRL_INT_PERIOD_POS); + + //enable timeout wake-up + interruptEnable |= MXC_F_WDT2_ENABLE_TIMEOUT; + + //lock ctrl to read-only + MXC_WDT2->lock_ctrl = MXC_V_WDT2_LOCK_KEY; + + // Enable wake-up + MXC_PWRSEQ->msk_flags |= MXC_F_PWRSEQ_MSK_FLAGS_PWR_NANORING_WAKEUP_FLAG; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int WDT2_DisableWakeUp(uint8_t unlock_key) +{ + //unlock register to be writable + MXC_WDT2->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (MXC_WDT2->lock_ctrl & 0x01) + return E_BAD_STATE; + + //disable timeout wake-up + interruptEnable &= ~MXC_F_WDT2_ENABLE_TIMEOUT; + MXC_WDT2->enable = interruptEnable; + + //lock register to read-only + MXC_WDT2->lock_ctrl = MXC_V_WDT2_LOCK_KEY; + + // disable wake-up + MXC_PWRSEQ->msk_flags &= ~MXC_F_PWRSEQ_MSK_FLAGS_PWR_NANORING_WAKEUP_FLAG; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int WDT2_EnableReset(wdt2_period_t rst_period, uint8_t unlock_key) +{ + // Make sure reset period is valid + if (rst_period >= WDT2_PERIOD_MAX) + return E_INVALID; + + //unlock ctrl to be writable + MXC_WDT2->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (MXC_WDT2->lock_ctrl & 0x01) + return E_BAD_STATE; + + //stop timer and clear reset period + MXC_WDT2->ctrl &= ~(MXC_F_WDT2_CTRL_RST_PERIOD | MXC_F_WDT2_CTRL_EN_TIMER); + + //set reset period + MXC_WDT2->ctrl |= (rst_period << MXC_F_WDT2_CTRL_RST_PERIOD_POS); + + //int flag has to be clear before interrupt enable can be written + MXC_WDT2->flags = MXC_F_WDT2_FLAGS_RESET_OUT; + + //enable reset0 + interruptEnable |= MXC_F_WDT2_ENABLE_RESET_OUT; + + //lock ctrl to read-only + MXC_WDT2->lock_ctrl = MXC_V_WDT2_LOCK_KEY; + + //enable RSTN on WDT2 reset + MXC_PWRSEQ->msk_flags |= MXC_F_PWRSEQ_MSK_FLAGS_PWR_WATCHDOG_RSTN_FLAG; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int WDT2_DisableReset(uint8_t unlock_key) +{ + //unlock register to be writable + MXC_WDT2->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (MXC_WDT2->lock_ctrl & 0x01) + return E_BAD_STATE; + + //disable reset + interruptEnable &= ~MXC_F_WDT2_ENABLE_RESET_OUT; + MXC_WDT2->enable = interruptEnable; + + //lock register to read-only + MXC_WDT2->lock_ctrl = MXC_V_WDT2_LOCK_KEY; + + //disable RSTN on WDT2 reset + MXC_PWRSEQ->msk_flags &= ~MXC_F_PWRSEQ_MSK_FLAGS_PWR_WATCHDOG_RSTN_FLAG; + + return E_NO_ERROR; +} + +/******************************************************************************/ +int WDT2_Start(uint8_t unlock_key) +{ + //check if watchdog is already running + if(WDT2_IsActive()) + return E_BAD_STATE; + + //unlock ctrl to be writable + MXC_WDT2->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (MXC_WDT2->lock_ctrl & 0x01) + return E_BAD_STATE; + + WDT2_Reset(); + + //enable interrupts + MXC_WDT2->enable = interruptEnable; + + //start timer + MXC_WDT2->ctrl |= (MXC_F_WDT2_CTRL_EN_TIMER); + + //lock ctrl to read-only + MXC_WDT2->lock_ctrl = MXC_V_WDT2_LOCK_KEY; + + return E_NO_ERROR; +} + +/******************************************************************************/ +void WDT2_Reset(void) +{ + //reset the watchdog counter + MXC_WDT2->clear = MXC_V_WDT2_RESET_KEY_0; + MXC_WDT2->clear = MXC_V_WDT2_RESET_KEY_1; + + //clear all interrupt flags + MXC_WDT2->flags = WDT2_FLAGS_CLEAR_ALL; + + //wait for all interrupts to clear + while(MXC_WDT2->flags != 0) { + MXC_WDT2->flags = WDT2_FLAGS_CLEAR_ALL; + } + + return; +} + +/******************************************************************************/ +int WDT2_Stop(uint8_t unlock_key) +{ + //check if watchdog is not running + if(!WDT2_IsActive()) + return E_BAD_STATE; + + //unlock ctrl to be writable + MXC_WDT2->lock_ctrl = unlock_key; + + //check to make sure it unlocked + if (MXC_WDT2->lock_ctrl & 0x01) + return E_BAD_STATE; + + //disabled the timer and interrupts + MXC_WDT2->enable = 0; + MXC_WDT2->ctrl &= ~(MXC_F_WDT2_CTRL_EN_TIMER); + + //lock ctrl to read-only + MXC_WDT2->lock_ctrl = MXC_V_WDT2_LOCK_KEY; + + return E_NO_ERROR; +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt2.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt2.h new file mode 100644 index 00000000000..856aa5b99e4 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/wdt2.h @@ -0,0 +1,207 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + * $Date: 2016-03-21 15:44:11 -0500 (Mon, 21 Mar 2016) $ + * $Revision: 22024 $ + * + ******************************************************************************/ + +/** + * @file wdt2.h + * @addtogroup wdt WDT + * @{ + * @brief This is the high level API for the watchdog timer interface module + * + */ + +#ifndef _WDT2_H +#define _WDT2_H + +#include "mxc_config.h" +#include "wdt2_regs.h" +#include "mxc_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define WDT2_FLAGS_CLEAR_ALL (MXC_F_WDT2_FLAGS_TIMEOUT| \ + MXC_F_WDT2_FLAGS_RESET_OUT) +/** + * @enum wdt2_period_t + * @brief WatchDog Timer 2 Period Settings + */ +typedef enum { + WDT2_PERIOD_2_25_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_25_NANO_CLKS, /**< 2^25 WDT clocks. */ + WDT2_PERIOD_2_24_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_24_NANO_CLKS, /**< 2^24 WDT clocks. */ + WDT2_PERIOD_2_23_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_23_NANO_CLKS, /**< 2^23 WDT clocks. */ + WDT2_PERIOD_2_22_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_22_NANO_CLKS, /**< 2^22 WDT clocks. */ + WDT2_PERIOD_2_21_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_21_NANO_CLKS, /**< 2^21 WDT clocks. */ + WDT2_PERIOD_2_20_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_20_NANO_CLKS, /**< 2^20 WDT clocks. */ + WDT2_PERIOD_2_19_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_19_NANO_CLKS, /**< 2^19 WDT clocks. */ + WDT2_PERIOD_2_18_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_18_NANO_CLKS, /**< 2^18 WDT clocks. */ + WDT2_PERIOD_2_17_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_17_NANO_CLKS, /**< 2^17 WDT clocks. */ + WDT2_PERIOD_2_16_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_16_NANO_CLKS, /**< 2^16 WDT clocks. */ + WDT2_PERIOD_2_15_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_15_NANO_CLKS, /**< 2^15 WDT clocks. */ + WDT2_PERIOD_2_14_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_14_NANO_CLKS, /**< 2^14 WDT clocks. */ + WDT2_PERIOD_2_13_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_13_NANO_CLKS, /**< 2^13 WDT clocks. */ + WDT2_PERIOD_2_12_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_12_NANO_CLKS, /**< 2^12 WDT clocks. */ + WDT2_PERIOD_2_11_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_11_NANO_CLKS, /**< 2^11 WDT clocks. */ + WDT2_PERIOD_2_10_CLKS = MXC_V_WDT2_CTRL_INT_PERIOD_2_10_NANO_CLKS, /**< 2^10 WDT clocks. */ + WDT2_PERIOD_MAX /**< Maximum Period is Max - 1 */ +} wdt2_period_t; + + + +/** + * @brief Initializes the NanoRing for the watchdog clock and sets watchdog in a known disabled state + * @param runInSleep If non-zero, the WDT2 operates in Sleep Modes for the device, + * 0 disables the WDT2 during Sleep Modes. + * @param unlock_key The WDT2 unlock key value, use MXC_V_WDT2_UNLOCK_KEY + * + * @retval E_NO_ERROR Watchdog Timer initialized as requested + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + + */ +int WDT2_Init(uint8_t runInSleep, uint8_t unlock_key); + +/** + * @brief Configures and enables the wake-up timeout for the watchdog specified. + * + * @param int_period Interrupt period. + * @param unlock_key Key to unlock watchdog. + * + * @retval E_NO_ERROR WDT2 Interrupt period enabled with the int_period time. + * @retval E_INVALID Requested Period is greater than the maximum supported + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + * + */ +int WDT2_EnableWakeUp(wdt2_period_t int_period, uint8_t unlock_key); + +/** + * @brief Disables the interrupt timeout for the watchdog specified. + * + * @param unlock_key Key to unlock watchdog. + * + * @retval E_NO_ERROR Wakeup disabled. + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + */ +int WDT2_DisableWakeUp(uint8_t unlock_key); + +/** + * @brief Configures and enables the reset timeout for the watchdog specified. + * + * @param rst_period Reset period. + * @param unlock_key Key to unlock watchdog. + * + * @retval E_NO_ERROR Reset timeout enabled with the rst_period time. + * @retval E_INVALID Requested Period is greater than the maximum supported + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + */ +int WDT2_EnableReset(wdt2_period_t rst_period, uint8_t unlock_key); + +/** + * @brief Disables the reset timeout for the watchdog specified. + * + * @param unlock_key Key to unlock watchdog. + * + * @retval E_NO_ERROR Reset disabled. + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + */ +int WDT2_DisableReset(uint8_t unlock_key); + +/** + * @brief Gets the watchdog interrupt flags + * + * @retval 0 = flags not set, non-zero = flag is set + */ +__STATIC_INLINE uint32_t WDT2_GetFlags(void) +{ + return (MXC_WDT2->flags); +} + +/** + * @brief Clears the watchdog interrupt flags based on the mask + * + * @param mask bits to clear + * + */ +__STATIC_INLINE void WDT2_ClearFlags(uint32_t mask) +{ + MXC_WDT2->flags = mask; +} + +/** + * @brief Starts the watchdog specified. + * + * @param unlock_key Key to unlock watchdog. + * + * @retval E_NO_ERROR if everything is successful, error if unsuccessful. + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + */ +int WDT2_Start(uint8_t unlock_key); + +/** + * @brief Feeds the watchdog specified. + * + * @retval E_NO_ERROR if everything is successful, error if unsuccessful. + */ +void WDT2_Reset(void); + +/** + * @brief Stops the WatchDog Timer 2. + * + * @param unlock_key Key to unlock watchdog. + * + * @retval E_NO_ERROR if everything is successful, error if unsuccessful. + * @retval E_BAD_STATE Invalid unlock_key, WDT failed to unlock. + */ +int WDT2_Stop(uint8_t unlock_key); + +/** + * @brief Determines if the watchdog is running + * + * @retval 0 = watchdog timer is off, non-zero = watchdog timer is on + */ +__STATIC_INLINE int WDT2_IsActive(void) +{ + return (!!(MXC_WDT2->ctrl & MXC_F_WDT2_CTRL_EN_TIMER)); +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* _WDT_H */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/objects.h b/targets/TARGET_Maxim/TARGET_MAX32625/objects.h new file mode 100644 index 00000000000..53d1371a4e2 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/objects.h @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" +#include "gpio_object.h" +#include "gpio_regs.h" +#include "uart_regs.h" +#include "i2cm_regs.h" +#include "spim_regs.h" +#include "pt_regs.h" +#include "adc_regs.h" +#include "uart.h" +#include "adc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct port_s { + PortName port; + uint32_t mask; + __IO uint32_t *reg_out; + __I uint32_t *reg_in; + PinMode mode; +}; + +struct gpio_irq_s { + uint8_t port; + uint8_t pin; + uint8_t rise_en; + uint8_t fall_en; + uint32_t id; +}; + +struct serial_s { + int index; + mxc_uart_regs_t *uart; + mxc_uart_fifo_regs_t *fifo; + uint32_t id; + uart_cfg_t cfg; + sys_cfg_uart_t sys_cfg; + PinName tx_pin; +}; + +struct i2c_s { + mxc_i2cm_regs_t *i2c; + mxc_i2cm_fifo_regs_t *fifo; + int start_pending; +}; + +struct spi_s { + int index; + mxc_spim_regs_t *spi; +}; + +struct pwmout_s { + mxc_pt_regs_t *pwm; + int period; + int pulse_width; +}; + +struct analogin_s { + mxc_adc_regs_t *adc; + mxc_adc_chsel_t channel; +}; + +typedef struct { + volatile uint32_t *reg_req; + volatile uint32_t *reg_ack; + uint32_t req_val; + uint32_t ack_mask; +} pin_function_t; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/pinmap.c b/targets/TARGET_Maxim/TARGET_MAX32625/pinmap.c new file mode 100644 index 00000000000..d2ca7aab255 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/pinmap.c @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "mbed_assert.h" +#include "pinmap.h" +#include "objects.h" +#include "gpio_regs.h" + +void pin_function(PinName name, int function) +{ + MBED_ASSERT(name != (PinName)NC); + + if ((function >= 0) && (function <= 0xF)) { + unsigned int port = PINNAME_TO_PORT(name); + unsigned int pin = PINNAME_TO_PIN(name); + uint32_t temp = MXC_GPIO->func_sel[port] & ~(0xF << (pin*4)); + MXC_GPIO->func_sel[port] = temp | ((uint32_t)function << (pin*4)); + } else { + /* Assume this is a pointer to a pin function object */ + pin_function_t *obj = (pin_function_t*)function; + + if ((*obj->reg_ack & obj->ack_mask) != obj->req_val) { + /* Request pin mapping */ + *obj->reg_req |= obj->req_val; + + /* Check for acknowledgment */ + MBED_ASSERT((*obj->reg_ack & obj->ack_mask) == obj->req_val); + } + } +} + +void pin_mode(PinName name, PinMode mode) +{ + MBED_ASSERT(name != (PinName)NC); + unsigned int port = PINNAME_TO_PORT(name); + unsigned int pin = PINNAME_TO_PIN(name); + + /* Must set mode while retaining direction */ + + /* Get the current direction */ + uint32_t curr_mode = (MXC_GPIO->out_mode[port] >> (pin * 4)) & 0xF; + PinDirection direction = PIN_OUTPUT; + if ((curr_mode == MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLUP) || + (curr_mode == MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLDOWN) || + (curr_mode == MXC_V_GPIO_OUT_MODE_NORMAL_HIGH_Z)) { + direction = PIN_INPUT; + } + + /* Set mode based on current direction */ + pin_dir_mode(name, direction, mode); +} + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/port_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/port_api.c new file mode 100644 index 00000000000..adce69af0da --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/port_api.c @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" +#include "gpio_regs.h" +#include "clkman_regs.h" + +PinName port_pin(PortName port, int pin_n) +{ + return (PinName)((port << PORT_SHIFT) | pin_n); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection direction) +{ + obj->port = port; + obj->mask = mask; + obj->reg_out = &MXC_GPIO->out_val[port]; + obj->reg_in = &MXC_GPIO->in_val[port]; + obj->mode = PullDefault; + + /* Ensure that the GPIO clock is enabled */ + MXC_CLKMAN->sys_clk_ctrl_6_gpio = MXC_S_CLKMAN_CLK_SCALE_DIV_1; + + uint32_t i; + // The function is set per pin: reuse gpio logic + for (i = 0; i < MXC_GPIO_MAX_PINS_PER_PORT; i++) { + if (obj->mask & (1 << i)) { + gpio_set(port_pin(obj->port, i)); + pin_dir_mode(port_pin(obj->port, i), direction, obj->mode); + } + } +} + +void port_mode(port_t *obj, PinMode mode) +{ + uint32_t i; + obj->mode = mode; + // The mode is set per pin: reuse pinmap logic + for (i = 0; i < MXC_GPIO_MAX_PINS_PER_PORT; i++) { + if (obj->mask & (1 << i)) { + pin_mode(port_pin(obj->port, i), mode); + } + } +} + +void port_dir(port_t *obj, PinDirection direction) +{ + uint32_t i; + // The mode is set per pin: reuse gpio logic + for (i = 0; i < MXC_GPIO_MAX_PINS_PER_PORT; i++) { + if (obj->mask & (1 << i)) { + pin_dir_mode(port_pin(obj->port, i), direction, obj->mode); + } + } +} + +void port_write(port_t *obj, int value) +{ + *obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask); +} + +int port_read(port_t *obj) +{ + return (*obj->reg_in & obj->mask); +} + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/pwmout_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/pwmout_api.c new file mode 100644 index 00000000000..ec8a3cfca4d --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/pwmout_api.c @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright (c) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "mbed_assert.h" +#include "cmsis.h" +#include "pwmout_api.h" +#include "pinmap.h" +#include "clkman_regs.h" +#include "PeripheralPins.h" + +#define MXC_GPIO_OUT_MODE_FIELD_WIDTH 4 +#define MXC_GPIO_OUT_MODE_FIELD_MASK ((uint32_t)0xFFFFFFFF >> (32 - MXC_GPIO_OUT_MODE_FIELD_WIDTH)) +#define MXC_GPIO_FUNC_SEL_FIELD_WIDTH 4 +#define MXC_GPIO_FUNC_SEL_FIELD_MASK ((uint32_t)0xFFFFFFFF >> (32 - MXC_GPIO_FUNC_SEL_FIELD_WIDTH)) + + +//****************************************************************************** +void pwmout_init(pwmout_t* obj, PinName pin) +{ + // Make sure the pin is free for GPIO use + unsigned int port = (unsigned int)pin >> PORT_SHIFT; + unsigned int port_pin = (unsigned int)pin & ~(0xFFFFFFFF << PORT_SHIFT); + MBED_ASSERT(MXC_GPIO->free[port] & (0x1 << port_pin)); + + int i = 0; + PinMap pwm = PinMap_PWM[0]; + + // Check if there is a pulse train already active on this port + int pin_func = (MXC_GPIO->func_sel[port] & (MXC_GPIO_FUNC_SEL_FIELD_MASK << (port_pin * MXC_GPIO_FUNC_SEL_FIELD_WIDTH))) >> + (port_pin * MXC_GPIO_FUNC_SEL_FIELD_WIDTH); + MBED_ASSERT((pin_func < 1) || (pin_func > 3)); + + // Search through PinMap_PWM to find the pin + while (pwm.pin != pin) { + pwm = PinMap_PWM[++i]; + } + + // Find a free PT instance on this pin + while (pwm.pin == pin) { + + // Check to see if this PT instance is free + if (((mxc_pt_regs_t*)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) { + break; + } + + pwm = PinMap_PWM[++i]; + + // Raise an assertion if we can not allocate another PT instance. + MBED_ASSERT(pwm.pin == pin); + } + + // Enable the clock + MXC_CLKMAN->sys_clk_ctrl_7_pt = MXC_S_CLKMAN_CLK_SCALE_DIV_1; + + // Set the obj pointer to the propper PWM instance + obj->pwm = (mxc_pt_regs_t*)pwm.peripheral; + + // Initialize object period and pulse width + obj->period = -1; + obj->pulse_width = -1; + + // Disable the output + obj->pwm->train = 0x0; + obj->pwm->rate_length = 0x0; + + // Configure the pin + pin_mode(pin, (PinMode)PullNone); + pin_function(pin, pwm.function); + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_us(obj, 20000); + pwmout_write (obj, 0); + + // Set the drive mode to normal + MXC_SET_FIELD(&MXC_GPIO->out_mode[port], + (MXC_GPIO_OUT_MODE_FIELD_MASK << (port_pin * MXC_GPIO_OUT_MODE_FIELD_WIDTH)), + (MXC_V_GPIO_OUT_MODE_NORMAL << (port_pin * MXC_GPIO_OUT_MODE_FIELD_WIDTH))); + + // Enable this PWM channel + MXC_PTG->enable |= (1 << MXC_PT_GET_IDX(obj->pwm)); +} + +//****************************************************************************** +void pwmout_free(pwmout_t* obj) +{ + // Set the registers to the reset value + obj->pwm->train = 0; + obj->pwm->rate_length = 0x08000000; +} + +//****************************************************************************** +static void pwmout_update(pwmout_t* obj) +{ + // Calculate and set the divider ratio + int div = (obj->period * (SystemCoreClock / 1000000))/32; + if (div < 2) { + div = 2; + } + MXC_SET_FIELD(&obj->pwm->rate_length, MXC_F_PT_RATE_LENGTH_RATE_CONTROL, div); + + // Change the duty cycle to adjust the pulse width + obj->pwm->train = (0xFFFFFFFF << (32 - ((32 * obj->pulse_width) / obj->period))); +} + + +//****************************************************************************** +void pwmout_write(pwmout_t* obj, float percent) +{ + // Saturate percent if outside of range + if(percent < 0.0f) { + percent = 0.0f; + } else if(percent > 1.0f) { + percent = 1.0f; + } + + // Resize the pulse width to set the duty cycle + pwmout_pulsewidth_us(obj, (int)(percent*obj->period)); +} + +//****************************************************************************** +float pwmout_read(pwmout_t* obj) +{ + // Check for when pulsewidth or period equals 0 + if((obj->pulse_width == 0) || (obj->period == 0)) { + return 0; + } + + // Return the duty cycle + return ((float)obj->pulse_width / (float)obj->period); +} + +//****************************************************************************** +void pwmout_period(pwmout_t* obj, float seconds) +{ + pwmout_period_us(obj, (int)(seconds * 1000000.0f)); +} + +//****************************************************************************** +void pwmout_period_ms(pwmout_t* obj, int ms) +{ + pwmout_period_us(obj, ms * 1000); +} + +//****************************************************************************** +void pwmout_period_us(pwmout_t* obj, int us) +{ + // Check the range of the period + MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); + + // Set pulse width to half the period if uninitialized + if (obj->pulse_width == -1) { + obj->pulse_width = us / 2; + } + + // Save the period + obj->period = us; + + // Update the registers + pwmout_update(obj); +} + +//****************************************************************************** +void pwmout_pulsewidth(pwmout_t* obj, float seconds) +{ + pwmout_pulsewidth_us(obj, (int)(seconds * 1000000.0f)); +} + +//****************************************************************************** +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) +{ + pwmout_pulsewidth_us(obj, ms * 1000); +} + +//****************************************************************************** +void pwmout_pulsewidth_us(pwmout_t* obj, int us) +{ + // Check the range of the pulsewidth + MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); + + // Initialize period to double the pulsewidth if uninitialized + if (obj->period == -1) { + obj->period = 2 * us; + } + + // Save the pulsewidth + obj->pulse_width = us; + + // Update the register + pwmout_update(obj); +} + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/rtc_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/rtc_api.c new file mode 100644 index 00000000000..703ea7954c4 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/rtc_api.c @@ -0,0 +1,253 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "rtc_api.h" +#include "lp_ticker_api.h" +#include "rtc.h" +#include "lp.h" + +#define PRESCALE_VAL RTC_PRESCALE_DIV_2_0 // Set the divider for the 4kHz clock +#define SHIFT_AMT (RTC_PRESCALE_DIV_2_12 - PRESCALE_VAL) + +#define WINDOW 1000 + +static int rtc_inited = 0; +static volatile uint32_t overflow_cnt = 0; + +static uint64_t rtc_read64(void); + +//****************************************************************************** +static void overflow_handler(void) +{ + overflow_cnt++; + RTC_ClearFlags(MXC_F_RTC_FLAGS_ASYNC_CLR_FLAGS); +} + +//****************************************************************************** +void rtc_init(void) +{ + if (rtc_inited) { + return; + } + rtc_inited = 1; + + overflow_cnt = 0; + + /* Enable power for RTC for all LPx states */ + MXC_PWRSEQ->reg0 |= (MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN | + MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP); + + /* Enable clock to synchronizers */ + CLKMAN_SetClkScale(CLKMAN_CLK_SYNC, CLKMAN_SCALE_DIV_1); + + // Prepare interrupt handlers + NVIC_SetVector(RTC0_IRQn, (uint32_t)lp_ticker_irq_handler); + NVIC_EnableIRQ(RTC0_IRQn); + NVIC_SetVector(RTC3_IRQn, (uint32_t)overflow_handler); + NVIC_EnableIRQ(RTC3_IRQn); + + // Enable wakeup on RTC rollover + LP_ConfigRTCWakeUp(0, 0, 0, 1); + + /* RTC registers are only reset on a power cycle. Do not reconfigure the RTC + * if it is already running. + */ + if (!RTC_IsActive()) { + rtc_cfg_t cfg = {0}; + cfg.prescaler = PRESCALE_VAL; + cfg.snoozeMode = RTC_SNOOZE_DISABLE; + + int retval = RTC_Init(&cfg); + MBED_ASSERT(retval == E_NO_ERROR); + + RTC_EnableINT(MXC_F_RTC_FLAGS_OVERFLOW); + RTC_Start(); + } +} + +//****************************************************************************** +void lp_ticker_init(void) +{ + rtc_init(); +} + +//****************************************************************************** +void rtc_free(void) +{ + if (RTC_IsActive()) { + // Clear and disable RTC + MXC_RTCTMR->ctrl |= MXC_F_RTC_CTRL_CLEAR; + RTC_Stop(); + } +} + +//****************************************************************************** +int rtc_isenabled(void) +{ + return RTC_IsActive(); +} + +//****************************************************************************** +time_t rtc_read(void) +{ + uint32_t ovf_cnt_1, ovf_cnt_2, timer_cnt; + uint32_t ovf1, ovf2; + + // Make sure RTC is setup before trying to read + if (!rtc_inited) { + rtc_init(); + } + + // Ensure coherency between overflow_cnt and timer + do { + ovf_cnt_1 = overflow_cnt; + ovf1 = RTC_GetFlags() & MXC_F_RTC_FLAGS_OVERFLOW; + timer_cnt = RTC_GetCount(); + ovf2 = RTC_GetFlags() & MXC_F_RTC_FLAGS_OVERFLOW; + ovf_cnt_2 = overflow_cnt; + } while ((ovf_cnt_1 != ovf_cnt_2) || (ovf1 != ovf2)); + + // Account for an unserviced interrupt + if (ovf1) { + ovf_cnt_1++; + } + + return (timer_cnt >> SHIFT_AMT) + (ovf_cnt_1 << (32 - SHIFT_AMT)); +} + +//****************************************************************************** +static uint64_t rtc_read64(void) +{ + uint32_t ovf_cnt_1, ovf_cnt_2, timer_cnt; + uint32_t ovf1, ovf2; + uint64_t current_us; + + // Make sure RTC is setup before trying to read + if (!rtc_inited) { + rtc_init(); + } + + // Ensure coherency between overflow_cnt and timer + do { + ovf_cnt_1 = overflow_cnt; + ovf1 = RTC_GetFlags() & MXC_F_RTC_FLAGS_OVERFLOW; + timer_cnt = RTC_GetCount(); + ovf2 = RTC_GetFlags() & MXC_F_RTC_FLAGS_OVERFLOW; + ovf_cnt_2 = overflow_cnt; + } while ((ovf_cnt_1 != ovf_cnt_2) || (ovf1 != ovf2)); + + // Account for an unserviced interrupt + if (ovf1) { + ovf_cnt_1++; + } + + current_us = (((uint64_t)timer_cnt * 1000000) >> SHIFT_AMT) + (((uint64_t)ovf_cnt_1 * 1000000) << (32 - SHIFT_AMT)); + + return current_us; +} + +//****************************************************************************** +void rtc_write(time_t t) +{ + // Make sure RTC is setup before accessing + if (!rtc_inited) { + rtc_init(); + } + + RTC_Stop(); + RTC_SetCount(t << SHIFT_AMT); + overflow_cnt = t >> (32 - SHIFT_AMT); + RTC_Start(); +} + +//****************************************************************************** +void lp_ticker_set_interrupt(timestamp_t timestamp) +{ + uint32_t comp_value; + uint64_t curr_ts64; + uint64_t ts64; + + // Note: interrupts are disabled before this function is called. + + // Disable the alarm while it is prepared + RTC_DisableINT(MXC_F_RTC_INTEN_COMP0); + + curr_ts64 = rtc_read64(); + ts64 = (uint64_t)timestamp | (curr_ts64 & 0xFFFFFFFF00000000ULL); + + // If this event is older than a recent window, it must be in the future + if ((ts64 < (curr_ts64 - WINDOW)) && ((curr_ts64 - WINDOW) < curr_ts64)) { + ts64 += 0x100000000ULL; + } + + uint32_t timer = RTC_GetCount(); + if (ts64 <= curr_ts64) { + // This event has already occurred. Set the alarm to expire immediately. + comp_value = timer + 1; + } else { + comp_value = (ts64 << SHIFT_AMT) / 1000000; + } + + // Ensure that the compare value is far enough in the future to guarantee the interrupt occurs. + if ((comp_value < (timer + 2)) && (comp_value > (timer - 10))) { + comp_value = timer + 2; + } + + MXC_RTCTMR->comp[0] = comp_value; + MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_ASYNC_CLR_FLAGS; + RTC_EnableINT(MXC_F_RTC_INTEN_COMP0); + + // Enable wakeup from RTC + LP_ConfigRTCWakeUp(1, 0, 0, 1); + + // Wait for pending transactions + while (MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); +} + +//****************************************************************************** +inline void lp_ticker_disable_interrupt(void) +{ + RTC_DisableINT(MXC_F_RTC_INTEN_COMP0); +} + +//****************************************************************************** +inline void lp_ticker_clear_interrupt(void) +{ + RTC_ClearFlags(MXC_F_RTC_FLAGS_ASYNC_CLR_FLAGS); +} + +//****************************************************************************** +inline uint32_t lp_ticker_read(void) +{ + return rtc_read64(); +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/serial_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/serial_api.c new file mode 100644 index 00000000000..eab9d1e05b9 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/serial_api.c @@ -0,0 +1,371 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include +#include "mbed_assert.h" +#include "cmsis.h" +#include "serial_api.h" +#include "gpio_api.h" +#include "uart.h" +#include "uart_regs.h" +#include "ioman_regs.h" +#include "PeripheralPins.h" + +#define DEFAULT_BAUD 9600 + +#define UART_ERRORS (MXC_F_UART_INTFL_RX_FRAMING_ERR | \ + MXC_F_UART_INTFL_RX_PARITY_ERR | \ + MXC_F_UART_INTFL_RX_FIFO_OVERFLOW) + +// Variables for managing the stdio UART +int stdio_uart_inited; +serial_t stdio_uart; + +// Variables for interrupt driven +static uart_irq_handler irq_handler; +static serial_t *objs[MXC_CFG_UART_INSTANCES]; + +static void usurp_pin(PinName, int); + +//****************************************************************************** +void serial_init(serial_t *obj, PinName tx, PinName rx) +{ + // Determine which uart is associated with each pin + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + + // Make sure that both pins are pointing to the same uart + MBED_ASSERT(uart != (UARTName)NC); + + // Set the obj pointer to the proper uart + obj->uart = (mxc_uart_regs_t*)uart; + + // Set the uart index + obj->index = MXC_UART_GET_IDX(obj->uart); + obj->fifo = (mxc_uart_fifo_regs_t*)MXC_UART_GET_BASE_FIFO(obj->index); + + // Manage stdio UART + if (uart == STDIO_UART) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } + + // Save transmit pin for break function + obj->tx_pin = tx; + + // Merge pin function requests for use with CMSIS init func + ioman_req_t io_req = {0}; + pin_function_t *pin_func = NULL; + if (tx != NC) { + pin_func = (pin_function_t *)pinmap_find_function(tx, PinMap_UART_TX); + io_req.value = pin_func->req_val; + } + if (rx != NC) { + pin_func = (pin_function_t *)pinmap_find_function(rx, PinMap_UART_RX); + io_req.value |= pin_func->req_val; + } + + // Using req and ack pointers of last pin function lookup + obj->sys_cfg.io_cfg.req_reg = pin_func->reg_req; + obj->sys_cfg.io_cfg.ack_reg = pin_func->reg_ack; + obj->sys_cfg.io_cfg.req_val = io_req; + obj->sys_cfg.clk_scale = CLKMAN_SCALE_DIV_8; + + // Configure the UART with default parameters + obj->cfg.extra_stop = 0; + obj->cfg.cts = 0; + obj->cfg.rts = 0; + obj->cfg.baud = DEFAULT_BAUD; + obj->cfg.size = UART_DATA_SIZE_8_BITS; + obj->cfg.parity = UART_PARITY_DISABLE; + + int retval = UART_Init(obj->uart, &obj->cfg, &obj->sys_cfg); + MBED_ASSERT(retval == E_NO_ERROR); +} + +//****************************************************************************** +void serial_baud(serial_t *obj, int baudrate) +{ + obj->cfg.baud = baudrate; + int retval = UART_Init(obj->uart, &obj->cfg, NULL); + MBED_ASSERT(retval == E_NO_ERROR); +} + +//****************************************************************************** +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) +{ + switch (data_bits) { + case 5: + obj->cfg.size = UART_DATA_SIZE_5_BITS; + break; + case 6: + obj->cfg.size = UART_DATA_SIZE_6_BITS; + break; + case 7: + obj->cfg.size = UART_DATA_SIZE_7_BITS; + break; + case 8: + obj->cfg.size = UART_DATA_SIZE_8_BITS; + break; + default: + MBED_ASSERT(0); + break; + } + + switch (parity) { + case ParityNone: + obj->cfg.parity = UART_PARITY_DISABLE; + break; + case ParityOdd : + obj->cfg.parity = UART_PARITY_ODD; + break; + case ParityEven: + obj->cfg.parity = UART_PARITY_EVEN; + break; + case ParityForced1: + case ParityForced0: + default: + MBED_ASSERT(0); + break; + } + + switch (stop_bits) { + case 1: + obj->cfg.extra_stop = 0; + break; + case 2: + obj->cfg.extra_stop = 1; + break; + default: + MBED_ASSERT(0); + break; + } + + int retval = UART_Init(obj->uart, &obj->cfg, NULL); + MBED_ASSERT(retval == E_NO_ERROR); +} + +//****************************************************************************** +void uart_handler(serial_t *obj) +{ + if (obj && obj->id) { + irq_handler(obj->id, RxIrq); + } +} + +void uart0_handler(void) { uart_handler(objs[0]); } +void uart1_handler(void) { uart_handler(objs[1]); } +void uart2_handler(void) { uart_handler(objs[2]); } + +//****************************************************************************** +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) +{ + irq_handler = handler; + obj->id = id; +} + +//****************************************************************************** +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) +{ + switch (obj->index) { + case 0: + NVIC_SetVector(UART0_IRQn, (uint32_t)uart0_handler); + NVIC_EnableIRQ(UART0_IRQn); + break; + case 1: + NVIC_SetVector(UART1_IRQn, (uint32_t)uart1_handler); + NVIC_EnableIRQ(UART1_IRQn); + break; + case 2: + NVIC_SetVector(UART2_IRQn, (uint32_t)uart2_handler); + NVIC_EnableIRQ(UART2_IRQn); + break; + default: + MBED_ASSERT(0); + } + + if (irq == RxIrq) { + // Enable RX FIFO Threshold Interrupt + if (enable) { + // Clear pending interrupts + obj->uart->intfl = obj->uart->intfl; + obj->uart->inten |= (MXC_F_UART_INTFL_RX_FIFO_NOT_EMPTY | UART_ERRORS); + } else { + // Clear pending interrupts + obj->uart->intfl = obj->uart->intfl; + obj->uart->inten &= ~(MXC_F_UART_INTFL_RX_FIFO_NOT_EMPTY | UART_ERRORS); + } + } else if (irq == TxIrq) { + // Set TX Almost Empty level to interrupt when empty + MXC_SET_FIELD(&obj->uart->tx_fifo_ctrl, MXC_F_UART_RX_FIFO_CTRL_FIFO_AF_LVL, + (MXC_UART_FIFO_DEPTH - 1) << MXC_F_UART_TX_FIFO_CTRL_FIFO_AE_LVL_POS); + + // Enable TX Almost Empty Interrupt + if (enable) { + // Clear pending interrupts + obj->uart->intfl = obj->uart->intfl; + obj->uart->inten |= MXC_F_UART_INTFL_TX_FIFO_AE; + } else { + // Clear pending interrupts + obj->uart->intfl = obj->uart->intfl; + obj->uart->inten &= ~MXC_F_UART_INTFL_TX_FIFO_AE; + } + } else { + MBED_ASSERT(0); + } +} + +//****************************************************************************** +int serial_getc(serial_t *obj) +{ + int c; + + // Wait for data to be available + while ((obj->uart->rx_fifo_ctrl & MXC_F_UART_RX_FIFO_CTRL_FIFO_ENTRY) == 0); + + c = obj->fifo->rx; + + return c; +} + +//****************************************************************************** +void serial_putc(serial_t *obj, int c) +{ + // Wait for room in the FIFO without blocking interrupts. + while (UART_NumWriteAvail(obj->uart) == 0); + + // Must clear before every write to the buffer to know that the FIFO + // is empty when the TX DONE bit is set + obj->uart->intfl = MXC_F_UART_INTFL_TX_DONE; + obj->fifo->tx = (uint8_t)c; +} + +//****************************************************************************** +int serial_readable(serial_t *obj) +{ + return UART_NumReadAvail(obj->uart); +} + +//****************************************************************************** +int serial_writable(serial_t *obj) +{ + return UART_NumWriteAvail(obj->uart); +} + +//****************************************************************************** +void serial_clear(serial_t *obj) +{ + // Clear the RX and TX FIFOs + UART_DrainRX(obj->uart); + UART_DrainTX(obj->uart); +} + +//****************************************************************************** +void serial_break_set(serial_t *obj) +{ + // Make sure that nothing is being sent + while (((obj->uart->tx_fifo_ctrl & MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY) + >> MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY_POS) > 0); + while (!(obj->uart->intfl & MXC_F_UART_INTFL_TX_DONE)); + + // Configure TX to output 0 + usurp_pin(obj->tx_pin, 0); + + // GPIO is setup now, but we need to unmap UART from the pin + pin_function_t *pin_func = (pin_function_t *)pinmap_find_function(obj->tx_pin, PinMap_UART_TX); + *pin_func->reg_req &= ~MXC_F_IOMAN_UART_REQ_IO_REQ; + MBED_ASSERT((*pin_func->reg_ack & MXC_F_IOMAN_UART_ACK_IO_ACK) == 0); +} + +//****************************************************************************** +void serial_break_clear(serial_t *obj) +{ + // Configure TX to output 1 + usurp_pin(obj->tx_pin, 1); + // Return TX to UART control + serial_pinout_tx(obj->tx_pin); +} + +//****************************************************************************** +void serial_pinout_tx(PinName tx) +{ + pinmap_pinout(tx, PinMap_UART_TX); +} + +//****************************************************************************** +void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) +{ + pin_function_t rtscts_pin_func = {0}; + + obj->cfg.cts = 0; + obj->cfg.rts = 0; + + if ((FlowControlCTS == type) || (FlowControlRTSCTS == type)) { + UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS); + UARTName uart = (UARTName)pinmap_merge(uart_cts, (UARTName)obj->uart); + // Assert pin is usable with existing uart + MBED_ASSERT(uart != (UARTName)NC); + + pin_function_t *pin_func; + pin_func = (pin_function_t *)pinmap_find_function(txflow, PinMap_UART_CTS); + rtscts_pin_func.req_val |= pin_func->req_val; + + obj->cfg.cts = 1; + } + + if ((FlowControlRTS == type) || (FlowControlRTSCTS == type)) { + UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS); + UARTName uart = (UARTName)pinmap_merge(uart_rts, (UARTName)obj->uart); + MBED_ASSERT(uart != (UARTName)NC); + + pin_function_t *pin_func; + pin_func = (pin_function_t *)pinmap_find_function(rxflow, PinMap_UART_RTS); + rtscts_pin_func.req_val |= pin_func->req_val; + + obj->cfg.rts = 1; + } + + obj->sys_cfg.io_cfg.req_val.value |= rtscts_pin_func.req_val; + + int retval = UART_Init(obj->uart, &obj->cfg, &obj->sys_cfg); + MBED_ASSERT(retval == E_NO_ERROR); +} + +//****************************************************************************** +static void usurp_pin(PinName pin, int state) +{ + gpio_t gpio; + gpio_init_out(&gpio, pin); + gpio_write(&gpio, state); +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/sleep.c b/targets/TARGET_Maxim/TARGET_MAX32625/sleep.c new file mode 100644 index 00000000000..560a4409293 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/sleep.c @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "sleep_api.h" +#include "lp.h" + +void sleep(void) +{ + LP_EnterLP2(); +} + +// Low-power stop mode +void deepsleep(void) +{ + sleep(); +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/spi_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/spi_api.c new file mode 100644 index 00000000000..e8bb11a3021 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/spi_api.c @@ -0,0 +1,181 @@ +/******************************************************************************* + * Copyright (c) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "mbed_assert.h" +#include "spi_api.h" // mbed HAL +#include "spim_regs.h" // bare metal +#include "spim.h" // Maxim CMSIS driver +#include "pinmap.h" +#include "PeripheralPins.h" + +//****************************************************************************** +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) +{ + // Make sure pins are pointing to the same SPI instance + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl; + + // Control is SCK and optionaly SS + if ((SPIName)spi_ssel != (SPIName)NC) { + spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + } else { + spi_cntl = spi_sclk; + } + + SPIName spi = (SPIName)pinmap_merge(spi_data, spi_cntl); + + MBED_ASSERT((SPIName)spi != (SPIName)NC); + + obj->spi = (mxc_spim_regs_t *)spi; + + // Merge pin function requests for use with CMSIS init func + ioman_req_t io_req; + pin_function_t *pin_func; + pin_func = (pin_function_t *)pinmap_find_function(mosi, PinMap_SPI_MOSI); + io_req.value = pin_func->req_val; + pin_func = (pin_function_t *)pinmap_find_function(miso, PinMap_SPI_MISO); + io_req.value |= pin_func->req_val; + pin_func = (pin_function_t *)pinmap_find_function(sclk, PinMap_SPI_SCLK); + io_req.value |= pin_func->req_val; + if ((SPIName)spi_ssel != (SPIName)NC) { + pin_func = (pin_function_t *)pinmap_find_function(ssel, PinMap_SPI_SSEL); + io_req.value |= pin_func->req_val; + } + + // Using req and ack pointers of last pin function lookup + sys_cfg_spim_t sys_cfg; + sys_cfg.io_cfg.req_reg = pin_func->reg_req; + sys_cfg.io_cfg.ack_reg = pin_func->reg_ack; + sys_cfg.io_cfg.req_val = io_req; + sys_cfg.clk_scale = CLKMAN_SCALE_AUTO; + + // Defaults + spim_cfg_t spim_cfg; + spim_cfg.mode = 0; + spim_cfg.ssel_pol = 0; + spim_cfg.baud = 1000000; + + SPIM_Init(obj->spi, &spim_cfg, &sys_cfg); + + obj->index = MXC_SPIM_GET_IDX(obj->spi); +} + +//****************************************************************************** +void spi_format(spi_t *obj, int bits, int mode, int slave) +{ + // Check the validity of the inputs + MBED_ASSERT(bits == 8); + + // Only supports master mode + MBED_ASSERT(!slave); + + // Set the mode + obj->spi->mstr_cfg &= ~(MXC_F_SPIM_MSTR_CFG_SPI_MODE); + obj->spi->mstr_cfg |= (mode << MXC_F_SPIM_MSTR_CFG_SPI_MODE_POS); +} + +//****************************************************************************** +void spi_frequency(spi_t *obj, int hz) +{ + // Maximum frequency is half the system frequency + MBED_ASSERT((unsigned int)hz <= (SystemCoreClock / 2)); + unsigned clocks = ((SystemCoreClock / 2) / hz); + + // Figure out the divider ratio + int clk_div = 1; + while(clk_div < 10) { + if(clocks < 0x10) { + break; + } + clk_div++; + clocks = clocks >> 1; + } + + // Turn on the SPI clock + if(obj->index == 0) { + MXC_CLKMAN->sys_clk_ctrl_11_spi0 = clk_div; + } else if(obj->index == 1) { + MXC_CLKMAN->sys_clk_ctrl_12_spi1 = clk_div; + } else if(obj->index == 2) { + MXC_CLKMAN->sys_clk_ctrl_13_spi2 = clk_div; + } else { + MBED_ASSERT(0); + } + + // Set the number of clocks to hold sclk high and low + MXC_SET_FIELD(&obj->spi->mstr_cfg, + (MXC_F_SPIM_MSTR_CFG_SCK_HI_CLK | MXC_F_SPIM_MSTR_CFG_SCK_LO_CLK), + ((clocks << MXC_F_SPIM_MSTR_CFG_SCK_HI_CLK_POS) | (clocks << MXC_F_SPIM_MSTR_CFG_SCK_LO_CLK_POS))); +} + +//****************************************************************************** +int spi_master_write(spi_t *obj, int value) +{ + spim_req_t req; + uint8_t out; + uint8_t in; + + out = value; + + req.ssel = 0; + req.deass = 0; + req.tx_data = &out; + req.rx_data = ∈ + req.width = SPIM_WIDTH_1; + req.len = 1; + req.ssel = 0; + req.deass = 1; + req.callback = NULL; + + SPIM_Trans(obj->spi, &req); + + return *req.rx_data; +} + +//****************************************************************************** +int spi_busy(spi_t *obj) +{ + return SPIM_Busy(obj->spi); +} + +//****************************************************************************** +uint8_t spi_get_module(spi_t *obj) +{ + return obj->index; +} + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/us_ticker.c b/targets/TARGET_Maxim/TARGET_MAX32625/us_ticker.c new file mode 100644 index 00000000000..5da2417d897 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/us_ticker.c @@ -0,0 +1,257 @@ +/******************************************************************************* + * Copyright (c) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include +#include "mbed_error.h" +#include "us_ticker_api.h" +#include "PeripheralNames.h" +#include "tmr.h" + +#define US_TIMER MXC_TMR0 +#define US_TIMER_IRQn TMR0_0_IRQn + +static int us_ticker_inited = 0; +static uint32_t ticks_per_us; +static uint32_t tick_win; +static volatile uint64_t current_cnt; // Hold the current ticks +static volatile uint64_t event_cnt; // Holds the value of the next event + +#define MAX_TICK_VAL ((uint64_t)0xFFFFFFFF * ticks_per_us) + +//****************************************************************************** +static inline void inc_current_cnt(uint32_t inc) +{ + // Overflow the ticker when the us ticker overflows + current_cnt += inc; + if (current_cnt > MAX_TICK_VAL) { + current_cnt -= (MAX_TICK_VAL + 1); + } +} + +//****************************************************************************** +static inline int event_passed(uint64_t current, uint64_t event) +{ + // Determine if the event has already happened. + // If the event is behind the current ticker, within a window, + // then the event has already happened. + if (((current < tick_win) && ((event < current) || + (event > (MAX_TICK_VAL - (tick_win - current))))) || + ((event < current) && (event > (current - tick_win)))) { + return 1; + } + + return 0; +} + +//****************************************************************************** +static inline uint64_t event_diff(uint64_t current, uint64_t event) +{ + // Check to see if the ticker will overflow before the event + if(current <= event) { + return (event - current); + } + + return ((MAX_TICK_VAL - current) + event); +} + +//****************************************************************************** +static void tmr_handler(void) +{ + uint32_t cmp = TMR32_GetCompare(US_TIMER); + TMR32_SetCompare(US_TIMER, 0xFFFFFFFF); // reset to max value to prevent further interrupts + TMR32_ClearFlag(US_TIMER); + NVIC_ClearPendingIRQ(US_TIMER_IRQn); + + inc_current_cnt(cmp); + + if (event_passed(current_cnt + TMR32_GetCount(US_TIMER), event_cnt)) { + // the timestamp has expired + event_cnt = 0xFFFFFFFFFFFFFFFFULL; // reset to max value + us_ticker_irq_handler(); + } else { + uint64_t diff = event_diff(current_cnt, event_cnt); + if (diff < (uint64_t)0xFFFFFFFF) { + // the event occurs before the next overflow + TMR32_SetCompare(US_TIMER, diff); + + // Since the timer keeps counting after the terminal value is reached, it is possible that the new + // terminal value is in the past. + if (TMR32_GetCompare(US_TIMER) < TMR32_GetCount(US_TIMER)) { + // the timestamp has expired + TMR32_SetCompare(US_TIMER, 0xFFFFFFFF); // reset to max value to prevent further interrupts + TMR32_ClearFlag(US_TIMER); + NVIC_ClearPendingIRQ(US_TIMER_IRQn); + event_cnt = 0xFFFFFFFFFFFFFFFFULL; // reset to max value + us_ticker_irq_handler(); + } + } + } +} + +//****************************************************************************** +void us_ticker_init(void) +{ + if (us_ticker_inited) { + return; + } + + us_ticker_inited = 1; + current_cnt = 0; + event_cnt = 0xFFFFFFFFFFFFFFFFULL; // reset to max value + ticks_per_us = SystemCoreClock / 1000000; + tick_win = SystemCoreClock / 100; // Set the tick window to 10ms + + int retval = TMR_Init(US_TIMER, TMR_PRESCALE_DIV_2_0, NULL); + MBED_ASSERT(retval == E_NO_ERROR); + + tmr32_cfg_t cfg; + cfg.mode = TMR32_MODE_CONTINUOUS; + cfg.polarity = TMR_POLARITY_UNUSED; + cfg.compareCount = 0xFFFFFFFF; + TMR32_Config(US_TIMER, &cfg); + + NVIC_SetVector(US_TIMER_IRQn, (uint32_t)tmr_handler); + NVIC_EnableIRQ(US_TIMER_IRQn); + TMR32_EnableINT(US_TIMER); + + TMR32_Start(US_TIMER); +} + +//****************************************************************************** +void us_ticker_deinit(void) +{ + TMR32_Stop(US_TIMER); + TMR32_DisableINT(US_TIMER); + TMR32_ClearFlag(US_TIMER); + us_ticker_inited = 0; +} + +//****************************************************************************** +uint32_t us_ticker_read(void) +{ + uint64_t current_cnt1, current_cnt2; + uint32_t cmp, cnt; + uint32_t flag1, flag2; + + if (!us_ticker_inited) { + us_ticker_init(); + } + + // Ensure coherency between current_cnt and TMR32_GetCount() + do { + current_cnt1 = current_cnt; + flag1 = TMR32_GetFlag(US_TIMER); + cmp = TMR32_GetCompare(US_TIMER); + cnt = TMR32_GetCount(US_TIMER); + flag2 = TMR32_GetFlag(US_TIMER); + current_cnt2 = current_cnt; + } while ((current_cnt1 != current_cnt2) || (flag1 != flag2)); + + // Account for an unserviced interrupt + if (flag1) { + current_cnt1 += cmp; + } + + current_cnt1 += cnt; + + return (current_cnt1 / ticks_per_us); +} + +//****************************************************************************** +void us_ticker_set_interrupt(timestamp_t timestamp) +{ + // Note: interrupts are disabled before this function is called. + + TMR32_Stop(US_TIMER); + + if (TMR32_GetFlag(US_TIMER)) { + TMR32_ClearFlag(US_TIMER); + NVIC_ClearPendingIRQ(US_TIMER_IRQn); + inc_current_cnt(TMR32_GetCompare(US_TIMER)); + } + + // add and reset the current count value + inc_current_cnt(TMR32_GetCount(US_TIMER)); + TMR32_SetCount(US_TIMER, 0); + + // add the number of cycles that the timer is disabled here for + inc_current_cnt(200); + + event_cnt = (uint64_t)timestamp * ticks_per_us; + + // Check to see if the event has already passed + if (!event_passed(current_cnt, event_cnt)) { + uint64_t diff = event_diff(current_cnt, event_cnt); + if (diff < (uint64_t)0xFFFFFFFF) { + // the event occurs before the next overflow + TMR32_SetCompare(US_TIMER, diff); + } else { + // the event occurs after the next overflow + TMR32_SetCompare(US_TIMER, 0xFFFFFFFF); // set to max + } + } else { + // the requested timestamp occurs in the past + // set the timer up to immediately expire + TMR32_SetCompare(US_TIMER, 1); + } + + TMR32_Start(US_TIMER); +} + +//****************************************************************************** +void us_ticker_disable_interrupt(void) +{ + // There are no more events, set timer overflow to the max + TMR32_SetCompare(US_TIMER, 0xFFFFFFFF); +} + +//****************************************************************************** +void us_ticker_clear_interrupt(void) +{ + // cleared in the local handler +} + +//****************************************************************************** +void us_ticker_set(timestamp_t timestamp) +{ + TMR32_Stop(US_TIMER); + current_cnt = (uint64_t)timestamp * ticks_per_us; + TMR32_SetCount(US_TIMER, 0); + TMR32_SetCompare(US_TIMER, 0xFFFFFFFF); + TMR32_Start(US_TIMER); + + if (((uint64_t)timestamp * ticks_per_us) >= event_cnt) { + // The next timestamp has elapsed. Trigger the interrupt to handle it. + NVIC_SetPendingIRQ(US_TIMER_IRQn); + } +} diff --git a/targets/TARGET_Maxim/mbed_rtx.h b/targets/TARGET_Maxim/mbed_rtx.h index f8ad272f5fc..1099d4a501d 100644 --- a/targets/TARGET_Maxim/mbed_rtx.h +++ b/targets/TARGET_Maxim/mbed_rtx.h @@ -62,6 +62,21 @@ #define OS_CLOCK 48000000 #endif +#elif defined(TARGET_MAX32625) + +#ifndef INITIAL_SP +#define INITIAL_SP (0x20028000UL) +#endif +#ifndef OS_TASKCNT +#define OS_TASKCNT 14 +#endif +#ifndef OS_MAINSTKSIZE +#define OS_MAINSTKSIZE 256 +#endif +#ifndef OS_CLOCK +#define OS_CLOCK 96000000 +#endif + #endif #endif // MBED_MBED_RTX_H diff --git a/targets/targets.json b/targets/targets.json index 31a6912723d..00fab151c43 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1816,6 +1816,16 @@ "features": ["BLE"], "release_versions": ["2", "5"] }, + "MAX32625NEXPAQ": { + "inherits": ["Target"], + "core": "Cortex-M4F", + "macros": ["__SYSTEM_HFX=96000000","TARGET=MAX32625","TARGET_REV=0x4132"], + "extra_labels": ["Maxim", "MAX32625"], + "supported_toolchains": ["GCC_ARM", "IAR", "ARM"], + "progen": {"target": "max32625nexpaq"}, + "device_has": ["ANALOGIN", "ERROR_RED", "I2C", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "STDIO_MESSAGES"], + "release_versions": ["2", "5"] + }, "EFM32": { "inherits": ["Target"], "extra_labels": ["Silicon_Labs", "EFM32"], From 8d9174e9e51e6c8833ecaa5c6f32fd4c8b11d3cf Mon Sep 17 00:00:00 2001 From: Jeremy Brodt Date: Fri, 7 Oct 2016 14:07:05 -0500 Subject: [PATCH 059/107] Adding new Maxim Integrated target. --- .../TARGET_MAX32625MBED/PeripheralNames.h | 88 +++++++++ .../TARGET_MAX32625MBED/PinNames.h | 146 +++++++++++++++ .../TARGET_MAX32625MBED/MAX32625.sct | 16 ++ .../TARGET_MAX32625MBED/max32625.ld | 176 ++++++++++++++++++ .../TARGET_MAX32625MBED/MAX32625.icf | 29 +++ targets/targets.json | 10 + 6 files changed, 465 insertions(+) create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625MBED/PeripheralNames.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625MBED/PinNames.h create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/TARGET_MAX32625MBED/MAX32625.sct create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/TARGET_MAX32625MBED/max32625.ld create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/TARGET_MAX32625MBED/MAX32625.icf diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625MBED/PeripheralNames.h b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625MBED/PeripheralNames.h new file mode 100644 index 00000000000..4686ef9c91f --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625MBED/PeripheralNames.h @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = MXC_BASE_UART0, + UART_1 = MXC_BASE_UART1, + UART_2 = MXC_BASE_UART2, + STDIO_UART = UART_1 +} UARTName; + +typedef enum { + I2C_0 = MXC_BASE_I2CM0, + I2C_1 = MXC_BASE_I2CM1 +} I2CName; + +typedef enum { + SPI_0 = MXC_BASE_SPIM0, + SPI_1 = MXC_BASE_SPIM1, + SPI_2 = MXC_BASE_SPIM2 +} SPIName; + +typedef enum { + PWM_0 = MXC_BASE_PT0, + PWM_1 = MXC_BASE_PT1, + PWM_2 = MXC_BASE_PT2, + PWM_3 = MXC_BASE_PT3, + PWM_4 = MXC_BASE_PT4, + PWM_5 = MXC_BASE_PT5, + PWM_6 = MXC_BASE_PT6, + PWM_7 = MXC_BASE_PT7, + PWM_8 = MXC_BASE_PT8, + PWM_9 = MXC_BASE_PT9, + PWM_10 = MXC_BASE_PT10, + PWM_11 = MXC_BASE_PT11, + PWM_12 = MXC_BASE_PT12, + PWM_13 = MXC_BASE_PT13, + PWM_14 = MXC_BASE_PT14, + PWM_15 = MXC_BASE_PT15 +} PWMName; + +typedef enum { + ADC = MXC_BASE_ADC +} ADCName; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625MBED/PinNames.h b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625MBED/PinNames.h new file mode 100644 index 00000000000..9ed4f7d85ec --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625MBED/PinNames.h @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" +#include "gpio_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT = 0, /* MXC_V_GPIO_OUT_MODE_HIGH_Z,*/ + PIN_OUTPUT = 1 /* MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE */ +} PinDirection; + +#define PORT_SHIFT 12 +#define PINNAME_TO_PORT(name) ((unsigned int)(name) >> PORT_SHIFT) +#define PINNAME_TO_PIN(name) ((unsigned int)(name) & ~(0xFFFFFFFF << PORT_SHIFT)) + +#define NOT_CONNECTED (int)0xFFFFFFFF + +typedef enum { + P0_0 = (0 << PORT_SHIFT), P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, + P1_0 = (1 << PORT_SHIFT), P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, + P2_0 = (2 << PORT_SHIFT), P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, + P3_0 = (3 << PORT_SHIFT), P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, + P4_0 = (4 << PORT_SHIFT), P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, + + // Analog input pins + AIN_0 = (0xA << PORT_SHIFT), AIN_1, AIN_2, AIN_3, AIN_4, AIN_5, + + LED_GREEN = P3_1, + LED_RED = P3_0, + LED_YELLOW = P3_3, + LED_BLUE = P3_2, + + // mbed original LED naming + LED1 = LED_RED, + LED2 = LED_GREEN, + LED3 = LED_BLUE, + LED4 = LED_YELLOW, + + // Push button + SW2 = P2_2, + SW3 = P2_3, + + // USB bridge connected UART pins + USBTX = P2_1, + USBRX = P2_0, + STDIO_UART_TX = USBTX, + STDIO_UART_RX = USBRX, + + // I2C pins + I2C0_SCL = P1_7, + I2C0_SDA = P1_6, + + I2C1_SCL = P3_5, + I2C1_SDA = P3_4, + + // UART pins + UART0_RX = P0_0, + UART0_TX = P0_1, + UART0_CTS = P0_2, + UART0_RTS = P0_3, + + UART1_RX = P2_0, + UART1_TX = P2_1, + UART1_CTS = P2_2, + UART1_RTS = P2_3, + + UART2_RX = P3_0, + UART2_TX = P3_1, + UART2_CTS = P3_2, + UART2_RTS = P3_3, + + // SPI pins + SPI0_SCK = P0_4, + SPI0_MOSI = P0_5, + SPI0_MISO = P0_6, + SPI0_SS = P0_7, + + SPI1_SCK = P1_0, + SPI1_MOSI = P1_1, + SPI1_MISO = P1_2, + SPI1_SS = P1_3, + + SPI2_SCK = P2_4, + SPI2_MOSI = P2_5, + SPI2_MISO = P2_6, + SPI2_SS = P2_7, + + // Not connected + NC = NOT_CONNECTED +} PinName; + +typedef enum { + PullUp, + PullDown, + OpenDrain, + PullNone, + PullDefault = PullUp +} PinMode; + +typedef enum { + LED_ON = 0, + LED_OFF = 1 +} LedStates; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/TARGET_MAX32625MBED/MAX32625.sct b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/TARGET_MAX32625MBED/MAX32625.sct new file mode 100644 index 00000000000..0c3bb3a099a --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/TARGET_MAX32625MBED/MAX32625.sct @@ -0,0 +1,16 @@ +; MAX32625 +; 512KB FLASH (0x80000) @ 0x000000000 +; 160KB RAM (0x28000) @ 0x20000000 + +LR_IROM1 0x000000000 0x80000 { ; load region size_region + ER_IROM1 0x000000000 0x80000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + + ; [RAM] Vector table dynamic copy: 68 vectors * 4 bytes = 272 (0x110) + RW_IRAM1 (0x20000000+0x110) (0x28000-0x110) { ; RW data + .ANY (+RW +ZI) + } +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/TARGET_MAX32625MBED/max32625.ld b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/TARGET_MAX32625MBED/max32625.ld new file mode 100644 index 00000000000..e709485e1e1 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/TARGET_MAX32625MBED/max32625.ld @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00028000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + __bss_start__ = .; + *(.bss*) + *(COMMON) + __bss_end__ = .; + } > RAM + + .heap : + { + __end__ = .; + end = __end__; + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy : + { + *(.stack) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/TARGET_MAX32625MBED/MAX32625.icf b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/TARGET_MAX32625MBED/MAX32625.icf new file mode 100644 index 00000000000..a6728f41336 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/TARGET_MAX32625MBED/MAX32625.icf @@ -0,0 +1,29 @@ +/* [ROM] */ +define symbol __intvec_start__ = 0x00000000; +define symbol __region_ROM_start__ = 0x00000000; +define symbol __region_ROM_end__ = 0x0007FFFF; + +/* [RAM] Vector table dynamic copy: 68 vectors * 4 bytes = 272 (0x110) bytes */ +define symbol __NVIC_start__ = 0x00000000; +define symbol __NVIC_end__ = 0x00000110; /* to be aligned on 8 bytes */ +define symbol __region_RAM_start__ = 0x20000000; +define symbol __region_RAM_end__ = 0x20027FFF; + +/* Memory regions */ +define memory mem with size = 4G; +define region ROM_region = mem:[from __region_ROM_start__ to __region_ROM_end__]; +define region RAM_region = mem:[from __region_RAM_start__ to __region_RAM_end__]; + +/* Stack and Heap */ +define symbol __size_cstack__ = 0x5000; +define symbol __size_heap__ = 0xA000; +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; diff --git a/targets/targets.json b/targets/targets.json index 00fab151c43..c0be9c89f50 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1816,6 +1816,16 @@ "features": ["BLE"], "release_versions": ["2", "5"] }, + "MAX32625MBED": { + "inherits": ["Target"], + "core": "Cortex-M4F", + "macros": ["__SYSTEM_HFX=96000000","TARGET=MAX32625","TARGET_REV=0x4132"], + "extra_labels": ["Maxim", "MAX32625"], + "supported_toolchains": ["GCC_ARM", "IAR", "ARM"], + "progen": {"target": "max32625mbed"}, + "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "STDIO_MESSAGES"], + "release_versions": ["2", "5"] + }, "MAX32625NEXPAQ": { "inherits": ["Target"], "core": "Cortex-M4F", From 5d9df77d6eb085cae3584ef526fad20c4a18f717 Mon Sep 17 00:00:00 2001 From: Jeremy Brodt Date: Tue, 25 Oct 2016 09:44:54 -0500 Subject: [PATCH 060/107] Prevent serial activity if tx/rx pin is NC. --- .../TARGET_Maxim/TARGET_MAX32625/objects.h | 3 +- .../TARGET_Maxim/TARGET_MAX32625/serial_api.c | 39 +++++++++++-------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/objects.h b/targets/TARGET_Maxim/TARGET_MAX32625/objects.h index 53d1371a4e2..26b4488ee3c 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/objects.h +++ b/targets/TARGET_Maxim/TARGET_MAX32625/objects.h @@ -75,7 +75,8 @@ struct serial_s { uint32_t id; uart_cfg_t cfg; sys_cfg_uart_t sys_cfg; - PinName tx_pin; + PinName tx; + PinName rx; }; struct i2c_s { diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/serial_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/serial_api.c index eab9d1e05b9..6b2d85b75d6 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/serial_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32625/serial_api.c @@ -81,8 +81,9 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) memcpy(&stdio_uart, obj, sizeof(serial_t)); } - // Save transmit pin for break function - obj->tx_pin = tx; + // Record the pins requested + obj->tx = tx; + obj->rx = rx; // Merge pin function requests for use with CMSIS init func ioman_req_t io_req = {0}; @@ -249,12 +250,14 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) //****************************************************************************** int serial_getc(serial_t *obj) { - int c; + int c = 0; - // Wait for data to be available - while ((obj->uart->rx_fifo_ctrl & MXC_F_UART_RX_FIFO_CTRL_FIFO_ENTRY) == 0); + if (obj->rx != NC) { + // Wait for data to be available + while ((obj->uart->rx_fifo_ctrl & MXC_F_UART_RX_FIFO_CTRL_FIFO_ENTRY) == 0); - c = obj->fifo->rx; + c = obj->fifo->rx; + } return c; } @@ -262,13 +265,15 @@ int serial_getc(serial_t *obj) //****************************************************************************** void serial_putc(serial_t *obj, int c) { - // Wait for room in the FIFO without blocking interrupts. - while (UART_NumWriteAvail(obj->uart) == 0); - - // Must clear before every write to the buffer to know that the FIFO - // is empty when the TX DONE bit is set - obj->uart->intfl = MXC_F_UART_INTFL_TX_DONE; - obj->fifo->tx = (uint8_t)c; + if (obj->tx != NC) { + // Wait for room in the FIFO without blocking interrupts. + while (UART_NumWriteAvail(obj->uart) == 0); + + // Must clear before every write to the buffer to know that the FIFO + // is empty when the TX DONE bit is set + obj->uart->intfl = MXC_F_UART_INTFL_TX_DONE; + obj->fifo->tx = (uint8_t)c; + } } //****************************************************************************** @@ -300,10 +305,10 @@ void serial_break_set(serial_t *obj) while (!(obj->uart->intfl & MXC_F_UART_INTFL_TX_DONE)); // Configure TX to output 0 - usurp_pin(obj->tx_pin, 0); + usurp_pin(obj->tx, 0); // GPIO is setup now, but we need to unmap UART from the pin - pin_function_t *pin_func = (pin_function_t *)pinmap_find_function(obj->tx_pin, PinMap_UART_TX); + pin_function_t *pin_func = (pin_function_t *)pinmap_find_function(obj->tx, PinMap_UART_TX); *pin_func->reg_req &= ~MXC_F_IOMAN_UART_REQ_IO_REQ; MBED_ASSERT((*pin_func->reg_ack & MXC_F_IOMAN_UART_ACK_IO_ACK) == 0); } @@ -312,9 +317,9 @@ void serial_break_set(serial_t *obj) void serial_break_clear(serial_t *obj) { // Configure TX to output 1 - usurp_pin(obj->tx_pin, 1); + usurp_pin(obj->tx, 1); // Return TX to UART control - serial_pinout_tx(obj->tx_pin); + serial_pinout_tx(obj->tx); } //****************************************************************************** From 9363f2bb0027641548a57dfd6e40e2715ed862de Mon Sep 17 00:00:00 2001 From: Jeremy Brodt Date: Tue, 25 Oct 2016 09:45:42 -0500 Subject: [PATCH 061/107] Add wait for serial characters to transmit before deleting serial object. --- features/unsupported/tests/mbed/echo/main.cpp | 1 + features/unsupported/tests/mbed/serial_nc_rx/main.cpp | 3 +++ features/unsupported/tests/mbed/serial_nc_tx/main.cpp | 5 +++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/features/unsupported/tests/mbed/echo/main.cpp b/features/unsupported/tests/mbed/echo/main.cpp index ccd882560cb..df29e605282 100644 --- a/features/unsupported/tests/mbed/echo/main.cpp +++ b/features/unsupported/tests/mbed/echo/main.cpp @@ -15,6 +15,7 @@ int main() { MBED_HOSTTEST_SELECT(echo); MBED_HOSTTEST_DESCRIPTION(Serial Echo at 115200); MBED_HOSTTEST_START("MBED_A9"); + wait(0.5); // wait for characters to finish transmitting Serial pc(TXPIN, RXPIN); pc.baud(115200); diff --git a/features/unsupported/tests/mbed/serial_nc_rx/main.cpp b/features/unsupported/tests/mbed/serial_nc_rx/main.cpp index 5f1ebc9dd88..fd6f0f7755b 100644 --- a/features/unsupported/tests/mbed/serial_nc_rx/main.cpp +++ b/features/unsupported/tests/mbed/serial_nc_rx/main.cpp @@ -15,6 +15,7 @@ int main() { // This should be true, sync the start of test if (c == 'S') { pc->printf("RX OK - Start NC test\r\n"); + wait(0.25); // wait for characters to finish transmitting // disconnect TX and get char delete pc; @@ -25,11 +26,13 @@ int main() { delete pc; pc = new Serial(USBTX, NC); pc->printf("RX OK - Expected\r\n"); + wait(0.25); // wait for characters to finish transmitting c = pc->getc(); // This should be false/not get here if (c == 'U') { pc->printf("RX OK - Unexpected\r\n"); + wait(0.25); // wait for characters to finish transmitting } } delete pc; diff --git a/features/unsupported/tests/mbed/serial_nc_tx/main.cpp b/features/unsupported/tests/mbed/serial_nc_tx/main.cpp index 8dae9e50bc9..6b92cecac0f 100644 --- a/features/unsupported/tests/mbed/serial_nc_tx/main.cpp +++ b/features/unsupported/tests/mbed/serial_nc_tx/main.cpp @@ -17,15 +17,16 @@ int main() { if (c == 'S') { Serial *pc = new Serial(USBTX, NC); pc->printf("TX OK - Expected\r\n"); + wait(0.5); // wait for characters to finish transmitting + delete pc; pc = new Serial(NC, USBRX); pc->printf("TX OK - Unexpected\r\n"); + wait(0.5); // wait for characters to finish transmitting delete pc; } - - while (1) { } } From 8e9e595dedf8bc05d79db5a02de6bb967ff991bc Mon Sep 17 00:00:00 2001 From: Jeremy Brodt Date: Wed, 2 Nov 2016 09:58:17 -0500 Subject: [PATCH 062/107] Removed progen from target configuration. --- targets/targets.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/targets/targets.json b/targets/targets.json index c0be9c89f50..c7ffd80cd09 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1822,7 +1822,6 @@ "macros": ["__SYSTEM_HFX=96000000","TARGET=MAX32625","TARGET_REV=0x4132"], "extra_labels": ["Maxim", "MAX32625"], "supported_toolchains": ["GCC_ARM", "IAR", "ARM"], - "progen": {"target": "max32625mbed"}, "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "STDIO_MESSAGES"], "release_versions": ["2", "5"] }, @@ -1832,7 +1831,6 @@ "macros": ["__SYSTEM_HFX=96000000","TARGET=MAX32625","TARGET_REV=0x4132"], "extra_labels": ["Maxim", "MAX32625"], "supported_toolchains": ["GCC_ARM", "IAR", "ARM"], - "progen": {"target": "max32625nexpaq"}, "device_has": ["ANALOGIN", "ERROR_RED", "I2C", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "STDIO_MESSAGES"], "release_versions": ["2", "5"] }, From c1403a9b7832cbd212ebdc419854f2f3149f1a17 Mon Sep 17 00:00:00 2001 From: Mahadevan Mahesh Date: Tue, 20 Sep 2016 12:49:47 -0500 Subject: [PATCH 063/107] Add support for FRDM-K82F Signed-off-by: Mahadevan Mahesh --- .../TARGET_K82F/TARGET_FRDM/PeripheralNames.h | 113 + .../TARGET_K82F/TARGET_FRDM/PeripheralPins.c | 267 + .../TARGET_K82F/TARGET_FRDM/PinNames.h | 188 + .../TARGET_K82F/TARGET_FRDM/device.h | 39 + .../TARGET_FRDM/fsl_clock_config.c | 164 + .../TARGET_FRDM/fsl_clock_config.h | 55 + .../TARGET_K82F/TARGET_FRDM/mbed_overrides.c | 39 + .../TARGET_K82F/device/MK82F25615.h | 15528 ++++++++++++++++ .../TARGET_K82F/device/MK82F25615_features.h | 2171 +++ .../TOOLCHAIN_ARM_STD/MK82FN256xxx15.sct | 127 + .../TOOLCHAIN_ARM_STD/startup_MK82F25615.S | 965 + .../device/TOOLCHAIN_ARM_STD/sys.cpp | 31 + .../TOOLCHAIN_GCC_ARM/MK82FN256xxx15.ld | 275 + .../TOOLCHAIN_GCC_ARM/startup_MK82F25615.S | 868 + .../device/TOOLCHAIN_IAR/MK82FN256xxx15.icf | 124 + .../device/TOOLCHAIN_IAR/startup_MK82F25615.S | 816 + .../TARGET_K82F/device/cmsis.h | 13 + .../TARGET_K82F/device/cmsis_nvic.c | 42 + .../TARGET_K82F/device/cmsis_nvic.h | 51 + .../TARGET_K82F/device/fsl_device_registers.h | 57 + .../TARGET_K82F/device/system_MK82F25615.c | 221 + .../TARGET_K82F/device/system_MK82F25615.h | 141 + .../TARGET_K82F/drivers/fsl_adc16.c | 370 + .../TARGET_K82F/drivers/fsl_adc16.h | 525 + .../TARGET_K82F/drivers/fsl_clock.c | 1797 ++ .../TARGET_K82F/drivers/fsl_clock.h | 1608 ++ .../TARGET_K82F/drivers/fsl_cmp.c | 285 + .../TARGET_K82F/drivers/fsl_cmp.h | 343 + .../TARGET_K82F/drivers/fsl_cmt.c | 265 + .../TARGET_K82F/drivers/fsl_cmt.h | 401 + .../TARGET_K82F/drivers/fsl_common.c | 161 + .../TARGET_K82F/drivers/fsl_common.h | 309 + .../TARGET_K82F/drivers/fsl_crc.c | 282 + .../TARGET_K82F/drivers/fsl_crc.h | 194 + .../TARGET_K82F/drivers/fsl_dac.c | 220 + .../TARGET_K82F/drivers/fsl_dac.h | 378 + .../TARGET_K82F/drivers/fsl_dmamux.c | 93 + .../TARGET_K82F/drivers/fsl_dmamux.h | 200 + .../TARGET_K82F/drivers/fsl_dspi.c | 1670 ++ .../TARGET_K82F/drivers/fsl_dspi.h | 1180 ++ .../TARGET_K82F/drivers/fsl_dspi_edma.c | 1156 ++ .../TARGET_K82F/drivers/fsl_dspi_edma.h | 281 + .../TARGET_K82F/drivers/fsl_edma.c | 1759 ++ .../TARGET_K82F/drivers/fsl_edma.h | 910 + .../TARGET_K82F/drivers/fsl_ewm.c | 96 + .../TARGET_K82F/drivers/fsl_ewm.h | 241 + .../TARGET_K82F/drivers/fsl_flash.c | 3264 ++++ .../TARGET_K82F/drivers/fsl_flash.h | 1368 ++ .../TARGET_K82F/drivers/fsl_flexbus.c | 202 + .../TARGET_K82F/drivers/fsl_flexbus.h | 265 + .../TARGET_K82F/drivers/fsl_flexio.c | 296 + .../TARGET_K82F/drivers/fsl_flexio.h | 705 + .../TARGET_K82F/drivers/fsl_flexio_camera.c | 193 + .../TARGET_K82F/drivers/fsl_flexio_camera.h | 258 + .../drivers/fsl_flexio_camera_edma.c | 223 + .../drivers/fsl_flexio_camera_edma.h | 147 + .../drivers/fsl_flexio_i2c_master.c | 804 + .../drivers/fsl_flexio_i2c_master.h | 486 + .../TARGET_K82F/drivers/fsl_flexio_i2s.c | 665 + .../TARGET_K82F/drivers/fsl_flexio_i2s.h | 569 + .../TARGET_K82F/drivers/fsl_flexio_i2s_edma.c | 361 + .../TARGET_K82F/drivers/fsl_flexio_i2s_edma.h | 218 + .../TARGET_K82F/drivers/fsl_flexio_spi.c | 1012 + .../TARGET_K82F/drivers/fsl_flexio_spi.h | 707 + .../TARGET_K82F/drivers/fsl_flexio_spi_edma.c | 432 + .../TARGET_K82F/drivers/fsl_flexio_spi_edma.h | 222 + .../TARGET_K82F/drivers/fsl_flexio_uart.c | 734 + .../TARGET_K82F/drivers/fsl_flexio_uart.h | 586 + .../drivers/fsl_flexio_uart_edma.c | 350 + .../drivers/fsl_flexio_uart_edma.h | 195 + .../TARGET_K82F/drivers/fsl_ftm.c | 908 + .../TARGET_K82F/drivers/fsl_ftm.h | 931 + .../TARGET_K82F/drivers/fsl_gpio.c | 195 + .../TARGET_K82F/drivers/fsl_gpio.h | 440 + .../TARGET_K82F/drivers/fsl_i2c.c | 1750 ++ .../TARGET_K82F/drivers/fsl_i2c.h | 800 + .../TARGET_K82F/drivers/fsl_i2c_edma.c | 568 + .../TARGET_K82F/drivers/fsl_i2c_edma.h | 132 + .../TARGET_K82F/drivers/fsl_llwu.c | 404 + .../TARGET_K82F/drivers/fsl_llwu.h | 320 + .../TARGET_K82F/drivers/fsl_lmem_cache.c | 464 + .../TARGET_K82F/drivers/fsl_lmem_cache.h | 488 + .../TARGET_K82F/drivers/fsl_lptmr.c | 123 + .../TARGET_K82F/drivers/fsl_lptmr.h | 369 + .../TARGET_K82F/drivers/fsl_lpuart.c | 1276 ++ .../TARGET_K82F/drivers/fsl_lpuart.h | 814 + .../TARGET_K82F/drivers/fsl_lpuart_edma.c | 341 + .../TARGET_K82F/drivers/fsl_lpuart_edma.h | 190 + .../TARGET_K82F/drivers/fsl_ltc.c | 4296 +++++ .../TARGET_K82F/drivers/fsl_ltc.h | 1578 ++ .../TARGET_K82F/drivers/fsl_ltc_edma.c | 1247 ++ .../TARGET_K82F/drivers/fsl_ltc_edma.h | 850 + .../TARGET_K82F/drivers/fsl_mpu.c | 247 + .../TARGET_K82F/drivers/fsl_mpu.h | 427 + .../TARGET_K82F/drivers/fsl_pdb.c | 141 + .../TARGET_K82F/drivers/fsl_pdb.h | 576 + .../TARGET_K82F/drivers/fsl_pit.c | 125 + .../TARGET_K82F/drivers/fsl_pit.h | 354 + .../TARGET_K82F/drivers/fsl_pmc.c | 93 + .../TARGET_K82F/drivers/fsl_pmc.h | 421 + .../TARGET_K82F/drivers/fsl_port.h | 431 + .../TARGET_K82F/drivers/fsl_qspi.c | 368 + .../TARGET_K82F/drivers/fsl_qspi.h | 636 + .../TARGET_K82F/drivers/fsl_qspi_edma.c | 331 + .../TARGET_K82F/drivers/fsl_qspi_edma.h | 175 + .../TARGET_K82F/drivers/fsl_rcm.c | 65 + .../TARGET_K82F/drivers/fsl_rcm.h | 431 + .../TARGET_K82F/drivers/fsl_rtc.c | 381 + .../TARGET_K82F/drivers/fsl_rtc.h | 414 + .../TARGET_K82F/drivers/fsl_sai.c | 1074 ++ .../TARGET_K82F/drivers/fsl_sai.h | 849 + .../TARGET_K82F/drivers/fsl_sai_edma.c | 393 + .../TARGET_K82F/drivers/fsl_sai_edma.h | 231 + .../TARGET_K82F/drivers/fsl_sdhc.c | 1356 ++ .../TARGET_K82F/drivers/fsl_sdhc.h | 1087 ++ .../TARGET_K82F/drivers/fsl_sdramc.c | 162 + .../TARGET_K82F/drivers/fsl_sdramc.h | 284 + .../TARGET_K82F/drivers/fsl_sim.c | 53 + .../TARGET_K82F/drivers/fsl_sim.h | 127 + .../TARGET_K82F/drivers/fsl_smartcard.h | 296 + .../drivers/fsl_smartcard_emvsim.c | 978 + .../drivers/fsl_smartcard_emvsim.h | 205 + .../drivers/fsl_smartcard_phy_emvsim.c | 234 + .../drivers/fsl_smartcard_phy_emvsim.h | 140 + .../drivers/fsl_smartcard_phy_ncn8025.c | 506 + .../drivers/fsl_smartcard_phy_ncn8025.h | 154 + .../drivers/fsl_smartcard_phy_tda8035.c | 563 + .../drivers/fsl_smartcard_phy_tda8035.h | 153 + .../TARGET_K82F/drivers/fsl_smc.c | 400 + .../TARGET_K82F/drivers/fsl_smc.h | 456 + .../TARGET_K82F/drivers/fsl_tpm.c | 731 + .../TARGET_K82F/drivers/fsl_tpm.h | 589 + .../TARGET_K82F/drivers/fsl_trng.c | 1622 ++ .../TARGET_K82F/drivers/fsl_trng.h | 239 + .../TARGET_K82F/drivers/fsl_tsi_v4.c | 203 + .../TARGET_K82F/drivers/fsl_tsi_v4.h | 706 + .../TARGET_K82F/drivers/fsl_vref.c | 230 + .../TARGET_K82F/drivers/fsl_vref.h | 256 + .../TARGET_K82F/drivers/fsl_wdog.c | 153 + .../TARGET_K82F/drivers/fsl_wdog.h | 433 + .../TARGET_K82F/peripheral_clock_defines.h | 54 + .../TARGET_K82F/pwmout_api.c | 143 + .../TARGET_K82F/serial_api.c | 274 + .../TARGET_KSDK2_MCUS/TARGET_K82F/spi_api.c | 132 + .../TARGET_KSDK2_MCUS/TARGET_K82F/us_ticker.c | 87 + .../TARGET_KSDK2_MCUS/api/i2c_api.c | 11 +- targets/TARGET_Freescale/mbed_rtx.h | 15 + targets/targets.json | 21 +- 148 files changed, 90976 insertions(+), 5 deletions(-) create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/PeripheralNames.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/PeripheralPins.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/PinNames.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/device.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/fsl_clock_config.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/fsl_clock_config.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/mbed_overrides.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/MK82F25615.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/MK82F25615_features.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_ARM_STD/MK82FN256xxx15.sct create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_ARM_STD/startup_MK82F25615.S create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_ARM_STD/sys.cpp create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_GCC_ARM/MK82FN256xxx15.ld create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_GCC_ARM/startup_MK82F25615.S create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_IAR/MK82FN256xxx15.icf create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_IAR/startup_MK82F25615.S create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/cmsis.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/cmsis_nvic.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/cmsis_nvic.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/fsl_device_registers.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/system_MK82F25615.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/system_MK82F25615.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_adc16.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_adc16.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_clock.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_clock.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmp.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmp.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmt.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmt.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_common.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_common.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_crc.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_crc.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dac.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dac.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dmamux.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dmamux.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi_edma.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi_edma.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_edma.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_edma.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ewm.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ewm.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flash.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flash.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexbus.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexbus.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera_edma.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera_edma.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2c_master.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2c_master.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s_edma.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s_edma.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi_edma.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi_edma.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart_edma.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart_edma.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ftm.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ftm.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_gpio.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_gpio.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c_edma.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c_edma.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_llwu.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_llwu.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lmem_cache.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lmem_cache.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lptmr.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lptmr.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart_edma.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart_edma.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc_edma.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc_edma.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_mpu.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_mpu.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pdb.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pdb.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pit.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pit.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pmc.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pmc.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_port.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi_edma.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi_edma.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rcm.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rcm.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rtc.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rtc.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai_edma.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai_edma.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdhc.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdhc.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdramc.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdramc.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sim.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sim.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_emvsim.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_emvsim.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_emvsim.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_emvsim.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_ncn8025.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_ncn8025.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_tda8035.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_tda8035.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smc.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smc.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tpm.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tpm.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_trng.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_trng.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tsi_v4.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tsi_v4.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_vref.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_vref.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_wdog.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_wdog.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/peripheral_clock_defines.h create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/pwmout_api.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/serial_api.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/spi_api.c create mode 100644 targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/us_ticker.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/PeripheralNames.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/PeripheralNames.h new file mode 100644 index 00000000000..84677008859 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/PeripheralNames.h @@ -0,0 +1,113 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + OSC32KCLK = 0, +} RTCName; + +typedef enum { + LPUART_0 = 0, + LPUART_1 = 1, + LPUART_2 = 2, + LPUART_3 = 3, + LPUART_4 = 4, +} UARTName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART LPUART_4 + +/* LPTMR interrupt is defined differently in K82F */ +#define LPTMR0_IRQn LPTMR0_LPTMR1_IRQn + +typedef enum { + I2C_0 = 0, + I2C_1 = 1, + I2C_2 = 2, + I2C_3 = 3, +} I2CName; + +#define TPM_SHIFT 8 +typedef enum { + PWM_1 = (0 << TPM_SHIFT) | (0), // FTM0 CH0 + PWM_2 = (0 << TPM_SHIFT) | (1), // FTM0 CH1 + PWM_3 = (0 << TPM_SHIFT) | (2), // FTM0 CH2 + PWM_4 = (0 << TPM_SHIFT) | (3), // FTM0 CH3 + PWM_5 = (0 << TPM_SHIFT) | (4), // FTM0 CH4 + PWM_6 = (0 << TPM_SHIFT) | (5), // FTM0 CH5 + PWM_7 = (0 << TPM_SHIFT) | (6), // FTM0 CH6 + PWM_8 = (0 << TPM_SHIFT) | (7), // FTM0 CH7 + PWM_9 = (1 << TPM_SHIFT) | (0), // FTM1 CH0 + PWM_10 = (1 << TPM_SHIFT) | (1), // FTM1 CH1 + PWM_11 = (2 << TPM_SHIFT) | (0), // FTM2 CH0 + PWM_12 = (2 << TPM_SHIFT) | (1), // FTM2 CH1 + PWM_13 = (3 << TPM_SHIFT) | (0), // FTM3 CH0 + PWM_14 = (3 << TPM_SHIFT) | (1), // FTM3 CH1 + PWM_15 = (3 << TPM_SHIFT) | (2), // FTM3 CH2 + PWM_16 = (3 << TPM_SHIFT) | (3), // FTM3 CH3 + PWM_17 = (3 << TPM_SHIFT) | (4), // FTM3 CH4 + PWM_18 = (3 << TPM_SHIFT) | (5), // FTM3 CH5 + PWM_19 = (3 << TPM_SHIFT) | (6), // FTM3 CH6 + PWM_20 = (3 << TPM_SHIFT) | (7), // FTM3 CH7 +} PWMName; + +#define ADC_INSTANCE_SHIFT 8 +#define ADC_B_CHANNEL_SHIFT 5 +typedef enum { + ADC0_SE4a = (0 << ADC_INSTANCE_SHIFT) | 4, + ADC0_SE4b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 4, + ADC0_SE5a = (0 << ADC_INSTANCE_SHIFT) | 5, + ADC0_SE5b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 5, + ADC0_SE6a = (0 << ADC_INSTANCE_SHIFT) | 6, + ADC0_SE6b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 6, + ADC0_SE7a = (0 << ADC_INSTANCE_SHIFT) | 7, + ADC0_SE7b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 7, + ADC0_SE8 = (0 << ADC_INSTANCE_SHIFT) | 8, + ADC0_SE9 = (0 << ADC_INSTANCE_SHIFT) | 9, + ADC0_SE10 = (0 << ADC_INSTANCE_SHIFT) | 10, + ADC0_SE11 = (0 << ADC_INSTANCE_SHIFT) | 11, + ADC0_SE12 = (0 << ADC_INSTANCE_SHIFT) | 12, + ADC0_SE13 = (0 << ADC_INSTANCE_SHIFT) | 13, + ADC0_SE14 = (0 << ADC_INSTANCE_SHIFT) | 14, + ADC0_SE15 = (0 << ADC_INSTANCE_SHIFT) | 15, + ADC0_SE22 = (0 << ADC_INSTANCE_SHIFT) | 22, + ADC0_SE23 = (0 << ADC_INSTANCE_SHIFT) | 23, +} ADCName; + +typedef enum { + DAC_0 = 0 +} DACName; + + +typedef enum { + SPI_0 = 0, + SPI_1 = 1, + SPI_2 = 2, +} SPIName; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/PeripheralPins.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/PeripheralPins.c new file mode 100644 index 00000000000..8eab4d62df6 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/PeripheralPins.c @@ -0,0 +1,267 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PeripheralPins.h" + +/************RTC***************/ +const PinMap PinMap_RTC[] = { + {NC, OSC32KCLK, 0}, +}; + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + {PTE16, ADC0_SE4a, 0}, + {PTE17, ADC0_SE5a, 0}, + {PTE18, ADC0_SE6a, 0}, + {PTE19, ADC0_SE7a, 0}, + {PTB0, ADC0_SE8, 0}, + {PTB1, ADC0_SE9, 0}, + {PTA7, ADC0_SE10, 0}, + {PTA8, ADC0_SE11, 0}, + {PTB2, ADC0_SE12, 0}, + {PTB3, ADC0_SE13, 0}, + {PTC0, ADC0_SE14, 0}, + {PTC1, ADC0_SE15, 0}, + {PTC2, ADC0_SE4b, 0}, + {PTD1, ADC0_SE5b, 0}, + {PTD5, ADC0_SE6b, 0}, + {PTD6, ADC0_SE7b, 0}, + {NC , NC , 0} +}; + +/************DAC***************/ +const PinMap PinMap_DAC[] = { + {DAC0_OUT, DAC_0, 0}, + {NC , NC , 0} +}; + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + {PTE0, I2C_1, 6}, + {PTE10, I2C_3, 2}, + {PTE18, I2C_0, 4}, + {PTA21, I2C_0, 2}, + {PTA1, I2C_3, 4}, + {PTA7, I2C_2, 2}, + {PTA10, I2C_2, 2}, + {PTB1, I2C_0, 2}, + {PTB3, I2C_0, 2}, + {PTB11, I2C_2, 4}, + {PTC11, I2C_1, 2}, + {PTD3, I2C_0, 7}, + {PTD9, I2C_0, 2}, + {NC , NC , 0} +}; + +const PinMap PinMap_I2C_SCL[] = { + {PTE1, I2C_1, 6}, + {PTE11, I2C_3, 2}, + {PTE19, I2C_0, 4}, + {PTA20, I2C_0, 2}, + {PTA2, I2C_3, 4}, + {PTA6, I2C_2, 2}, + {PTA11, I2C_2, 2}, + {PTB0, I2C_0, 2}, + {PTB2, I2C_0, 2}, + {PTB10, I2C_2, 4}, + {PTC10, I2C_1, 2}, + {PTD2, I2C_0, 7}, + {PTD8, I2C_0, 2}, + {NC , NC , 0} +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + {PTE0, LPUART_1, 3}, + {PTE4, LPUART_3, 3}, + {PTE12, LPUART_2, 3}, + {PTE16, LPUART_2, 3}, + {PTA20, LPUART_4, 3}, + {PTA2, LPUART_0, 2}, + {PTA14, LPUART_0, 3}, + {PTB11, LPUART_3, 3}, + {PTB17, LPUART_0, 3}, + {PTC4, LPUART_1, 3}, + {PTC15, LPUART_4, 3}, + {PTC17, LPUART_3, 3}, + {PTD3, LPUART_2, 3}, + {PTD7, LPUART_0, 3}, + {NC , NC , 0} +}; + +const PinMap PinMap_UART_RX[] = { + {PTE1, LPUART_1, 3}, + {PTE5, LPUART_3, 3}, + {PTE13, LPUART_2, 3}, + {PTE17, LPUART_2, 3}, + {PTA21, LPUART_4, 3}, + {PTA1, LPUART_0, 2}, + {PTA15, LPUART_0, 3}, + {PTB10, LPUART_3, 3}, + {PTB16, LPUART_0, 3}, + {PTC3, LPUART_1, 3}, + {PTC14, LPUART_4, 3}, + {PTC16, LPUART_3, 3}, + {PTD2, LPUART_2, 3}, + {PTD6, LPUART_0, 3}, + {NC , NC , 0} +}; + +const PinMap PinMap_UART_CTS[] = { + {PTE2, LPUART_1, 3}, + {PTE6, LPUART_3, 3}, + {PTE18, LPUART_2, 3}, + {PTA0, LPUART_0, 2}, + {PTA16, LPUART_0, 3}, + {PTB3, LPUART_0, 3}, + {PTB9, LPUART_3, 3}, + {PTC2, LPUART_1, 3}, + {PTC13, LPUART_4, 3}, + {PTC19, LPUART_3, 3}, + {PTD1, LPUART_2, 3}, + {PTD5, LPUART_0, 3}, + {NC , NC , 0} +}; + +const PinMap PinMap_UART_RTS[] = { + {PTE3, LPUART_1, 3}, + {PTE7, LPUART_3, 3}, + {PTE19, LPUART_2, 3}, + {PTA3, LPUART_0, 2}, + {PTA17, LPUART_0, 3}, + {PTB2, LPUART_0, 3}, + {PTB8, LPUART_3, 3}, + {PTC1, LPUART_1, 3}, + {PTC12, LPUART_4, 3}, + {PTC18, LPUART_3, 3}, + {PTD0, LPUART_2, 3}, + {PTD4, LPUART_0, 3}, + {NC , NC , 0} +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + {PTE1, SPI_1, 2}, + {PTE2, SPI_1, 7}, + {PTE7, SPI_2, 2}, + {PTE17, SPI_0, 2}, + {PTA15, SPI_0, 2}, + {PTB11, SPI_1, 2}, + {PTB21, SPI_2, 2}, + {PTC5, SPI_0, 2}, + {PTD1, SPI_0, 2}, + {PTD5, SPI_1, 7}, + {PTD12, SPI_2, 2}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MOSI[] = { + {PTE2, SPI_1, 2}, + {PTE3, SPI_1, 7}, + {PTE8, SPI_2, 3}, + {PTE18, SPI_0, 2}, + {PTA16, SPI_0, 2}, + {PTB16, SPI_1, 2}, + {PTB16, SPI_1, 2}, + {PTB22, SPI_2, 2}, + {PTC6, SPI_0, 2}, + {PTD2, SPI_0, 2}, + {PTD6, SPI_1, 7}, + {PTD13, SPI_2, 2}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {PTE1, SPI_1, 7}, + {PTE4, SPI_1, 2}, + {PTE10, SPI_2, 3}, + {PTE19, SPI_0, 2}, + {PTA17, SPI_0, 2}, + {PTB17, SPI_1, 2}, + {PTB23, SPI_2, 2}, + {PTC7, SPI_0, 2}, + {PTD3, SPI_0, 2}, + {PTD7, SPI_1, 7}, + {PTD14, SPI_2, 2}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {PTE5, SPI_1, 2}, + {PTE11, SPI_2, 3}, + {PTE16, SPI_0, 2}, + {PTA14, SPI_0, 2}, + {PTB10, SPI_1, 2}, + {PTB20, SPI_2, 2}, + {PTC4, SPI_0, 2}, + {PTD0, SPI_0, 2}, + {PTD4, SPI_1, 7}, + {PTD11, SPI_2, 2}, + {NC , NC , 0} +}; + +/************PWM***************/ +const PinMap PinMap_PWM[] = { + /* FTM 0 */ + {PTA0, PWM_6, 3}, + {PTA1, PWM_7, 3}, + {PTA2, PWM_8, 3}, + {PTA3, PWM_1, 3}, + {PTA4, PWM_2, 3}, + {PTA5, PWM_3, 3}, + {PTA6, PWM_4, 3}, + {PTA7, PWM_5, 3}, + {PTC1, PWM_1, 4}, + {PTC2, PWM_2, 4}, + {PTC3, PWM_3, 4}, + {PTC4, PWM_4, 4}, + {PTC5, PWM_3, 7}, + {PTD4, PWM_5, 4}, + {PTD5, PWM_6, 4}, + {PTD6, PWM_7, 4}, + {PTD7, PWM_8, 4}, + /* FTM 1 */ + {PTA8, PWM_9, 3}, + {PTA9, PWM_10, 3}, + {PTA12, PWM_9, 3}, + {PTA13, PWM_10, 3}, + {PTB0, PWM_9, 3}, + {PTB1, PWM_10, 3}, + /* FTM 2 */ + {PTA10, PWM_11, 3}, + {PTA11, PWM_12, 3}, + {PTB18, PWM_11, 3}, + {PTB19, PWM_12, 3}, + /* FTM 3 */ + {PTE5, PWM_13, 6}, + {PTE6, PWM_14, 6}, + {PTE7, PWM_15, 6}, + {PTE8, PWM_16, 6}, + {PTE9, PWM_17, 6}, + {PTE10, PWM_18, 6}, + {PTE11, PWM_19, 6}, + {PTE12, PWM_20, 6}, + {PTC8, PWM_17, 3}, + {PTC9, PWM_18, 3}, + {PTC10, PWM_19, 3}, + {PTC11, PWM_20, 3}, + {PTD0, PWM_13, 4}, + {PTD1, PWM_14, 4}, + {PTD2, PWM_15, 4}, + {PTD3, PWM_16, 4}, + + {NC , NC , 0} +}; diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/PinNames.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/PinNames.h new file mode 100644 index 00000000000..9e88d8e830f --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/PinNames.h @@ -0,0 +1,188 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define GPIO_PORT_SHIFT 12 + +typedef enum { + PTA0 = (0 << GPIO_PORT_SHIFT | 0 ), + PTA1 = (0 << GPIO_PORT_SHIFT | 1 ), + PTA2 = (0 << GPIO_PORT_SHIFT | 2 ), + PTA3 = (0 << GPIO_PORT_SHIFT | 3 ), + PTA4 = (0 << GPIO_PORT_SHIFT | 4 ), + PTA5 = (0 << GPIO_PORT_SHIFT | 5 ), + PTA6 = (0 << GPIO_PORT_SHIFT | 6 ), + PTA7 = (0 << GPIO_PORT_SHIFT | 7 ), + PTA8 = (0 << GPIO_PORT_SHIFT | 8 ), + PTA9 = (0 << GPIO_PORT_SHIFT | 9 ), + PTA10 = (0 << GPIO_PORT_SHIFT | 10 ), + PTA11 = (0 << GPIO_PORT_SHIFT | 11 ), + PTA12 = (0 << GPIO_PORT_SHIFT | 12), + PTA13 = (0 << GPIO_PORT_SHIFT | 13), + PTA14 = (0 << GPIO_PORT_SHIFT | 14), + PTA15 = (0 << GPIO_PORT_SHIFT | 15), + PTA16 = (0 << GPIO_PORT_SHIFT | 16), + PTA17 = (0 << GPIO_PORT_SHIFT | 17), + PTA18 = (0 << GPIO_PORT_SHIFT | 18), + PTA19 = (0 << GPIO_PORT_SHIFT | 19), + PTA20 = (0 << GPIO_PORT_SHIFT | 20), + PTA21 = (0 << GPIO_PORT_SHIFT | 21), + PTB0 = (1 << GPIO_PORT_SHIFT | 0 ), + PTB1 = (1 << GPIO_PORT_SHIFT | 1 ), + PTB2 = (1 << GPIO_PORT_SHIFT | 2 ), + PTB3 = (1 << GPIO_PORT_SHIFT | 3 ), + PTB8 = (1 << GPIO_PORT_SHIFT | 8 ), + PTB9 = (1 << GPIO_PORT_SHIFT | 9 ), + PTB10 = (1 << GPIO_PORT_SHIFT | 10), + PTB11 = (1 << GPIO_PORT_SHIFT | 11), + PTB16 = (1 << GPIO_PORT_SHIFT | 16), + PTB17 = (1 << GPIO_PORT_SHIFT | 17), + PTB18 = (1 << GPIO_PORT_SHIFT | 18), + PTB19 = (1 << GPIO_PORT_SHIFT | 19), + PTB20 = (1 << GPIO_PORT_SHIFT | 20), + PTB21 = (1 << GPIO_PORT_SHIFT | 21), + PTB22 = (1 << GPIO_PORT_SHIFT | 22), + PTB23 = (1 << GPIO_PORT_SHIFT | 23), + PTC0 = (2 << GPIO_PORT_SHIFT | 0 ), + PTC1 = (2 << GPIO_PORT_SHIFT | 1 ), + PTC2 = (2 << GPIO_PORT_SHIFT | 2 ), + PTC3 = (2 << GPIO_PORT_SHIFT | 3 ), + PTC4 = (2 << GPIO_PORT_SHIFT | 4 ), + PTC5 = (2 << GPIO_PORT_SHIFT | 5 ), + PTC6 = (2 << GPIO_PORT_SHIFT | 6 ), + PTC7 = (2 << GPIO_PORT_SHIFT | 7 ), + PTC8 = (2 << GPIO_PORT_SHIFT | 8 ), + PTC9 = (2 << GPIO_PORT_SHIFT | 9 ), + PTC10 = (2 << GPIO_PORT_SHIFT | 10), + PTC11 = (2 << GPIO_PORT_SHIFT | 11), + PTC12 = (2 << GPIO_PORT_SHIFT | 12), + PTC13 = (2 << GPIO_PORT_SHIFT | 13), + PTC14 = (2 << GPIO_PORT_SHIFT | 14), + PTC15 = (2 << GPIO_PORT_SHIFT | 15), + PTC16 = (2 << GPIO_PORT_SHIFT | 16), + PTC17 = (2 << GPIO_PORT_SHIFT | 17), + PTC18 = (2 << GPIO_PORT_SHIFT | 18), + PTC19 = (2 << GPIO_PORT_SHIFT | 19), + PTD0 = (3 << GPIO_PORT_SHIFT | 0 ), + PTD1 = (3 << GPIO_PORT_SHIFT | 1 ), + PTD2 = (3 << GPIO_PORT_SHIFT | 2 ), + PTD3 = (3 << GPIO_PORT_SHIFT | 3 ), + PTD4 = (3 << GPIO_PORT_SHIFT | 4 ), + PTD5 = (3 << GPIO_PORT_SHIFT | 5 ), + PTD6 = (3 << GPIO_PORT_SHIFT | 6 ), + PTD7 = (3 << GPIO_PORT_SHIFT | 7 ), + PTD8 = (3 << GPIO_PORT_SHIFT | 8 ), + PTD9 = (3 << GPIO_PORT_SHIFT | 9 ), + PTD11 = (3 << GPIO_PORT_SHIFT | 11), + PTD12 = (3 << GPIO_PORT_SHIFT | 12), + PTD13 = (3 << GPIO_PORT_SHIFT | 13), + PTD14 = (3 << GPIO_PORT_SHIFT | 14), + PTE0 = (4 << GPIO_PORT_SHIFT | 0 ), + PTE1 = (4 << GPIO_PORT_SHIFT | 1 ), + PTE2 = (4 << GPIO_PORT_SHIFT | 2 ), + PTE3 = (4 << GPIO_PORT_SHIFT | 3 ), + PTE4 = (4 << GPIO_PORT_SHIFT | 4 ), + PTE5 = (4 << GPIO_PORT_SHIFT | 5 ), + PTE6 = (4 << GPIO_PORT_SHIFT | 6 ), + PTE7 = (4 << GPIO_PORT_SHIFT | 7 ), + PTE8 = (4 << GPIO_PORT_SHIFT | 8 ), + PTE9 = (4 << GPIO_PORT_SHIFT | 9 ), + PTE10 = (4 << GPIO_PORT_SHIFT | 10), + PTE11 = (4 << GPIO_PORT_SHIFT | 11), + PTE12 = (4 << GPIO_PORT_SHIFT | 12), + PTE13 = (4 << GPIO_PORT_SHIFT | 13), + PTE16 = (4 << GPIO_PORT_SHIFT | 16), + PTE17 = (4 << GPIO_PORT_SHIFT | 17), + PTE18 = (4 << GPIO_PORT_SHIFT | 18), + PTE19 = (4 << GPIO_PORT_SHIFT | 19), + + LED_RED = PTC8, + LED_GREEN = PTC9, + LED_BLUE = PTC10, + + // mbed original LED naming + LED1 = LED_RED, + LED2 = LED_GREEN, + LED3 = LED_BLUE, + LED4 = LED_RED, + + //Push buttons + SW2 = PTA4, + SW3 = PTC6, + + // USB Pins + USBTX = PTC15, + USBRX = PTC14, + + // Arduino Headers + D0 = PTB16, + D1 = PTB17, + D2 = PTC12, + D3 = PTD0, + D4 = PTC11, + D5 = PTC10, + D6 = PTC8, + D7 = PTC9, + D8 = PTC3, + D9 = PTC5, + D10 = PTD4, + D11 = PTD2, + D12 = PTD3, + D13 = PTD1, + D14 = PTA1, + D15 = PTA2, + + I2C_SCL = D15, + I2C_SDA = D14, + + A0 = PTB0, + A1 = PTB1, + A2 = PTC1, + A3 = PTC2, + A4 = PTB3, + A5 = PTB2, + + DAC0_OUT = 0xFEFE, /* DAC does not have Pin Name in RM */ + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + + +typedef enum { + PullNone = 0, + PullDown = 1, + PullUp = 2, + PullDefault = PullUp +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/device.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/device.h new file mode 100644 index 00000000000..29a4e7a0b18 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/device.h @@ -0,0 +1,39 @@ +// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches. +// Check the 'features' section of the target description in 'targets.json' for more details. +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + + + + + + + + + + + +#define DEVICE_ID_LENGTH 24 + + + + + +#include "objects.h" + +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/fsl_clock_config.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/fsl_clock_config.c new file mode 100644 index 00000000000..c6562e65359 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/fsl_clock_config.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_common.h" +#include "fsl_smc.h" +#include "fsl_clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/******************************************************************************* + * Code + ******************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock + * and flash clock are in allowed range during clock mode switch. + * + * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. + * + * 3. Set MCG configuration, MCG includes three parts: FLL clock, PLL clock and + * internal reference clock(MCGIRCLK). Follow the steps to setup: + * + * 1). Call CLOCK_BootToXxxMode to set MCG to target mode. + * + * 2). If target mode is FBI/BLPI/PBI mode, the MCGIRCLK has been configured + * correctly. For other modes, need to call CLOCK_SetInternalRefClkConfig + * explicitly to setup MCGIRCLK. + * + * 3). Don't need to configure FLL explicitly, because if target mode is FLL + * mode, then FLL has been configured by the function CLOCK_BootToXxxMode, + * if the target mode is not FLL mode, the FLL is disabled. + * + * 4). If target mode is PEE/PBE/PEI/PBI mode, then the related PLL has been + * setup by CLOCK_BootToXxxMode. In FBE/FBI/FEE/FBE mode, the PLL could + * be enabled independently, call CLOCK_EnablePll0 explicitly in this case. + * + * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. + */ + +void BOARD_BootClockVLPR(void) +{ + const sim_clock_config_t simConfig = { + .pllFllSel = 3U, .pllFllDiv = 0U, .pllFllFrac = 0U, .er32kSrc = 2U, .clkdiv1 = 0x00040000U, + }; + + CLOCK_SetSimSafeDivs(); + + CLOCK_BootToBlpiMode(0U, kMCG_IrcFast, kMCG_IrclkEnable); + + CLOCK_SetSimConfig(&simConfig); + + SystemCoreClock = 4000000U; + + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); + SMC_SetPowerModeVlpr(SMC); + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) + { + } +} + +void BOARD_BootClockRUN(void) +{ + const mcg_pll_config_t pll0Config = { + .enableMode = 0U, .prdiv = 0x00U, .vdiv = 0x04U, + }; + + const sim_clock_config_t simConfig = { + .pllFllSel = 1U, .pllFllDiv = 0U, .pllFllFrac = 0U, .er32kSrc = 2U, .clkdiv1 = 0x01140000U, + }; + + CLOCK_SetSimSafeDivs(); + + BOARD_InitOsc0(); + + CLOCK_BootToPeeMode(kMCG_OscselOsc, kMCG_PllClkSelPll0, &pll0Config); + + CLOCK_SetInternalRefClkConfig(kMCG_IrclkEnable, kMCG_IrcSlow, 0U); + + CLOCK_SetSimConfig(&simConfig); + + SystemCoreClock = 120000000U; +} + +void BOARD_BootClockHSRUN(void) +{ + const mcg_pll_config_t pll0Config = { + .enableMode = 0U, .prdiv = 0x00U, .vdiv = 0x09U, + }; + const sim_clock_config_t simConfig = { + .pllFllSel = 1U, .pllFllDiv = 0U, .pllFllFrac = 0U, .er32kSrc = 2U, .clkdiv1 = 0x01150000U, + }; + + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); + SMC_SetPowerModeHsrun(SMC); + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateHsrun) + { + } + + CLOCK_SetSimSafeDivs(); + + BOARD_InitOsc0(); + + CLOCK_BootToPeeMode(kMCG_OscselOsc, kMCG_PllClkSelPll0, &pll0Config); + + CLOCK_SetInternalRefClkConfig(kMCG_IrclkEnable, kMCG_IrcSlow, 0U); + + CLOCK_SetSimConfig(&simConfig); + + SystemCoreClock = 150000000U; +} + +void BOARD_InitOsc0(void) +{ + const osc_config_t oscConfig = {.freq = BOARD_XTAL0_CLK_HZ, + .capLoad = 0, + .workMode = kOSC_ModeOscLowPower, + .oscerConfig = { + .enableMode = kOSC_ErClkEnable, +#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) + .erclkDiv = 0U, +#endif + }}; + + CLOCK_InitOsc0(&oscConfig); + + /* Passing the XTAL0 frequency to clock driver. */ + CLOCK_SetXtal0Freq(BOARD_XTAL0_CLK_HZ); +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/fsl_clock_config.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/fsl_clock_config.h new file mode 100644 index 00000000000..006747ed549 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/fsl_clock_config.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +/******************************************************************************* + * DEFINITION + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 12000000U +#define BOARD_XTAL32K_CLK_HZ 32768U + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +void BOARD_InitOsc0(void); +void BOARD_BootClockVLPR(void); +void BOARD_BootClockRUN(void); +void BOARD_BootClockHSRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/mbed_overrides.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/mbed_overrides.c new file mode 100644 index 00000000000..ac9be918ce0 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/TARGET_FRDM/mbed_overrides.c @@ -0,0 +1,39 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "gpio_api.h" +#include "fsl_clock_config.h" + +// called before main +void mbed_sdk_init() +{ + BOARD_BootClockRUN(); +} + +// Change the NMI pin to an input. This allows NMI pin to +// be used as a low power mode wakeup. The application will +// need to change the pin back to NMI_b or wakeup only occurs once! +void NMI_Handler(void) +{ + gpio_t gpio; + gpio_init_in(&gpio, PTA4); +} + +// Enable the RTC oscillator if available on the board +void rtc_setup_oscillator(RTC_Type *base) +{ + /* Enable the RTC oscillator */ + RTC->CR |= RTC_CR_OSCE_MASK; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/MK82F25615.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/MK82F25615.h new file mode 100644 index 00000000000..ec05414e6b3 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/MK82F25615.h @@ -0,0 +1,15528 @@ +/* +** ################################################################### +** Processors: MK82FN256CAx15 +** MK82FN256VDC15 +** MK82FN256VLL15 +** MK82FN256VLQ15 +** +** Compilers: Keil ARM C/C++ Compiler +** Freescale C/C++ for Embedded ARM +** GNU C Compiler +** IAR ANSI C/C++ Compiler for ARM +** +** Reference manual: K82P121M150SF5RM, Rev. 0, May 2015 +** Version: rev. 1.2, 2015-07-29 +** Build: b151218 +** +** Abstract: +** CMSIS Peripheral Access Layer for MK82F25615 +** +** Copyright (c) 1997 - 2015 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** Revisions: +** - rev. 1.0 (2015-04-09) +** Initial version +** - rev. 1.1 (2015-05-28) +** Update according to the reference manual Rev. 0. +** - rev. 1.2 (2015-07-29) +** Correction of backward compatibility. +** +** ################################################################### +*/ + +/*! + * @file MK82F25615.h + * @version 1.2 + * @date 2015-07-29 + * @brief CMSIS Peripheral Access Layer for MK82F25615 + * + * CMSIS Peripheral Access Layer for MK82F25615 + */ + +#ifndef _MK82F25615_H_ +#define _MK82F25615_H_ /**< Symbol preventing repeated inclusion */ + +/** Memory map major version (memory maps with equal major version number are + * compatible) */ +#define MCU_MEM_MAP_VERSION 0x0100U +/** Memory map minor version */ +#define MCU_MEM_MAP_VERSION_MINOR 0x0002U + +/** + * @brief Macro to calculate address of an aliased word in the peripheral + * bitband area for a peripheral register and bit (bit band region 0x40000000 to + * 0x400FFFFF). + * @param Reg Register to access. + * @param Bit Bit number to access. + * @return Address of the aliased word in the peripheral bitband area. + */ +#define BITBAND_REGADDR(Reg,Bit) (0x42000000u + (32u*((uint32_t)&(Reg) - (uint32_t)0x40000000u)) + (4u*((uint32_t)(Bit)))) +/** + * @brief Macro to access a single bit of a peripheral register (bit band region + * 0x40000000 to 0x400FFFFF) using the bit-band alias region access. Can + * be used for peripherals with 32bit access allowed. + * @param Reg Register to access. + * @param Bit Bit number to access. + * @return Value of the targeted bit in the bit band region. + */ +#define BITBAND_REG32(Reg,Bit) (*((uint32_t volatile*)(BITBAND_REGADDR((Reg),(Bit))))) +#define BITBAND_REG(Reg,Bit) (BITBAND_REG32((Reg),(Bit))) +/** + * @brief Macro to access a single bit of a peripheral register (bit band region + * 0x40000000 to 0x400FFFFF) using the bit-band alias region access. Can + * be used for peripherals with 16bit access allowed. + * @param Reg Register to access. + * @param Bit Bit number to access. + * @return Value of the targeted bit in the bit band region. + */ +#define BITBAND_REG16(Reg,Bit) (*((uint16_t volatile*)(BITBAND_REGADDR((Reg),(Bit))))) +/** + * @brief Macro to access a single bit of a peripheral register (bit band region + * 0x40000000 to 0x400FFFFF) using the bit-band alias region access. Can + * be used for peripherals with 8bit access allowed. + * @param Reg Register to access. + * @param Bit Bit number to access. + * @return Value of the targeted bit in the bit band region. + */ +#define BITBAND_REG8(Reg,Bit) (*((uint8_t volatile*)(BITBAND_REGADDR((Reg),(Bit))))) + +/* ---------------------------------------------------------------------------- + -- Interrupt vector numbers + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Interrupt_vector_numbers Interrupt vector numbers + * @{ + */ + +/** Interrupt Number Definitions */ +#define NUMBER_OF_INT_VECTORS 123 /**< Number of interrupts in the Vector table */ + +typedef enum IRQn { + /* Auxiliary constants */ + NotAvail_IRQn = -128, /**< Not available device specific interrupt */ + + /* Core interrupts */ + NonMaskableInt_IRQn = -14, /**< Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< Cortex-M4 SV Hard Fault Interrupt */ + MemoryManagement_IRQn = -12, /**< Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /**< Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /**< Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /**< Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /**< Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /**< Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< Cortex-M4 System Tick Interrupt */ + + /* Device specific interrupts */ + DMA0_DMA16_IRQn = 0, /**< DMA channel 0,16 transfer complete */ + DMA1_DMA17_IRQn = 1, /**< DMA channel 1,17 transfer complete */ + DMA2_DMA18_IRQn = 2, /**< DMA channel 2,18 transfer complete */ + DMA3_DMA19_IRQn = 3, /**< DMA channel 3,19 transfer complete */ + DMA4_DMA20_IRQn = 4, /**< DMA channel 4,20 transfer complete */ + DMA5_DMA21_IRQn = 5, /**< DMA channel 5,21 transfer complete */ + DMA6_DMA22_IRQn = 6, /**< DMA channel 6,22 transfer complete */ + DMA7_DMA23_IRQn = 7, /**< DMA channel 7,23 transfer complete */ + DMA8_DMA24_IRQn = 8, /**< DMA channel 8,24 transfer complete */ + DMA9_DMA25_IRQn = 9, /**< DMA channel 9,25 transfer complete */ + DMA10_DMA26_IRQn = 10, /**< DMA channel 10,26 transfer complete */ + DMA11_DMA27_IRQn = 11, /**< DMA channel 11,27 transfer complete */ + DMA12_DMA28_IRQn = 12, /**< DMA channel 12,28 transfer complete */ + DMA13_DMA29_IRQn = 13, /**< DMA channel 13,29 transfer complete */ + DMA14_DMA30_IRQn = 14, /**< DMA channel 14,30 transfer complete */ + DMA15_DMA31_IRQn = 15, /**< DMA channel 15,31 transfer complete */ + DMA_Error_IRQn = 16, /**< DMA channel 0 - 31 error */ + MCM_IRQn = 17, /**< MCM normal interrupt */ + FTFA_IRQn = 18, /**< FTFA command complete */ + Read_Collision_IRQn = 19, /**< FTFA read collision */ + LVD_LVW_IRQn = 20, /**< PMC controller low-voltage detect, low-voltage warning */ + LLWU_IRQn = 21, /**< Low leakage wakeup unit */ + WDOG_EWM_IRQn = 22, /**< Single interrupt vector for WDOG and EWM */ + TRNG0_IRQn = 23, /**< True randon number generator */ + I2C0_IRQn = 24, /**< Inter-integrated circuit 0 */ + I2C1_IRQn = 25, /**< Inter-integrated circuit 1 */ + SPI0_IRQn = 26, /**< Serial peripheral Interface 0 */ + SPI1_IRQn = 27, /**< Serial peripheral Interface 1 */ + I2S0_Tx_IRQn = 28, /**< Integrated interchip sound 0 transmit interrupt */ + I2S0_Rx_IRQn = 29, /**< Integrated interchip sound 0 receive interrupt */ + LPUART0_IRQn = 30, /**< LPUART0 receive/transmit/error interrupt */ + LPUART1_IRQn = 31, /**< LPUART1 receive/transmit/error interrupt */ + LPUART2_IRQn = 32, /**< LPUART2 receive/transmit/error interrupt */ + LPUART3_IRQn = 33, /**< LPUART3 receive/transmit/error interrupt */ + LPUART4_IRQn = 34, /**< LPUART4 receive/transmit/error interrupt */ + Reserved51_IRQn = 35, /**< Reserved interrupt */ + Reserved52_IRQn = 36, /**< Reserved interrupt */ + EMVSIM0_IRQn = 37, /**< EMVSIM0 common interrupt */ + EMVSIM1_IRQn = 38, /**< EMVSIM1 common interrupt */ + ADC0_IRQn = 39, /**< Analog-to-digital converter 0 */ + CMP0_IRQn = 40, /**< Comparator 0 */ + CMP1_IRQn = 41, /**< Comparator 1 */ + FTM0_IRQn = 42, /**< FlexTimer module 0 fault, overflow and channels interrupt */ + FTM1_IRQn = 43, /**< FlexTimer module 1 fault, overflow and channels interrupt */ + FTM2_IRQn = 44, /**< FlexTimer module 2 fault, overflow and channels interrupt */ + CMT_IRQn = 45, /**< Carrier modulator transmitter */ + RTC_IRQn = 46, /**< Real time clock */ + RTC_Seconds_IRQn = 47, /**< Real time clock seconds */ + PIT0CH0_IRQn = 48, /**< Periodic interrupt timer 0 channel 0 */ + PIT0CH1_IRQn = 49, /**< Periodic interrupt timer 0 channel 1 */ + PIT0CH2_IRQn = 50, /**< Periodic interrupt timer 0 channel 2 */ + PIT0CH3_IRQn = 51, /**< Periodic interrupt timer 0 channel 3 */ + PDB0_IRQn = 52, /**< Programmable delay block */ + USB0_IRQn = 53, /**< USB OTG interrupt */ + USBDCD_IRQn = 54, /**< USB charger detect */ + Reserved71_IRQn = 55, /**< Reserved interrupt */ + DAC0_IRQn = 56, /**< Digital-to-analog converter 0 */ + MCG_IRQn = 57, /**< Multipurpose clock generator */ + LPTMR0_LPTMR1_IRQn = 58, /**< Single interrupt vector for Low Power Timer 0 and 1 */ + PORTA_IRQn = 59, /**< Port A pin detect interrupt */ + PORTB_IRQn = 60, /**< Port B pin detect interrupt */ + PORTC_IRQn = 61, /**< Port C pin detect interrupt */ + PORTD_IRQn = 62, /**< Port D pin detect interrupt */ + PORTE_IRQn = 63, /**< Port E pin detect interrupt */ + SWI_IRQn = 64, /**< Software interrupt */ + SPI2_IRQn = 65, /**< Serial peripheral Interface 2 */ + Reserved82_IRQn = 66, /**< Reserved interrupt */ + Reserved83_IRQn = 67, /**< Reserved interrupt */ + Reserved84_IRQn = 68, /**< Reserved interrupt */ + Reserved85_IRQn = 69, /**< Reserved interrupt */ + FLEXIO0_IRQn = 70, /**< FLEXIO0 */ + FTM3_IRQn = 71, /**< FlexTimer module 3 fault, overflow and channels interrupt */ + Reserved88_IRQn = 72, /**< Reserved interrupt */ + Reserved89_IRQn = 73, /**< Reserved interrupt */ + I2C2_IRQn = 74, /**< Inter-integrated circuit 2 */ + Reserved91_IRQn = 75, /**< Reserved interrupt */ + Reserved92_IRQn = 76, /**< Reserved interrupt */ + Reserved93_IRQn = 77, /**< Reserved interrupt */ + Reserved94_IRQn = 78, /**< Reserved interrupt */ + Reserved95_IRQn = 79, /**< Reserved interrupt */ + Reserved96_IRQn = 80, /**< Reserved interrupt */ + SDHC_IRQn = 81, /**< Secured digital host controller */ + Reserved98_IRQn = 82, /**< Reserved interrupt */ + Reserved99_IRQn = 83, /**< Reserved interrupt */ + Reserved100_IRQn = 84, /**< Reserved interrupt */ + Reserved101_IRQn = 85, /**< Reserved interrupt */ + Reserved102_IRQn = 86, /**< Reserved interrupt */ + TSI0_IRQn = 87, /**< Touch Sensing Input */ + TPM1_IRQn = 88, /**< TPM1 single interrupt vector for all sources */ + TPM2_IRQn = 89, /**< TPM2 single interrupt vector for all sources */ + Reserved106_IRQn = 90, /**< Reserved interrupt */ + I2C3_IRQn = 91, /**< Inter-integrated circuit 3 */ + Reserved108_IRQn = 92, /**< Reserved interrupt */ + Reserved109_IRQn = 93, /**< Reserved interrupt */ + Reserved110_IRQn = 94, /**< Reserved interrupt */ + Reserved111_IRQn = 95, /**< Reserved interrupt */ + Reserved112_IRQn = 96, /**< Reserved interrupt */ + Reserved113_IRQn = 97, /**< Reserved interrupt */ + Reserved114_IRQn = 98, /**< Reserved interrupt */ + Reserved115_IRQn = 99, /**< Reserved interrupt */ + QuadSPI0_IRQn = 100, /**< qspi */ + Reserved117_IRQn = 101, /**< Reserved interrupt */ + Reserved118_IRQn = 102, /**< Reserved interrupt */ + Reserved119_IRQn = 103, /**< Reserved interrupt */ + LTC0_IRQn = 104, /**< LP Trusted Cryptography */ + Reserved121_IRQn = 105, /**< Reserved interrupt */ + Reserved122_IRQn = 106 /**< Reserved interrupt */ +} IRQn_Type; + +/*! + * @} + */ /* end of group Interrupt_vector_numbers */ + + +/* ---------------------------------------------------------------------------- + -- Cortex M4 Core Configuration + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Cortex_Core_Configuration Cortex M4 Core Configuration + * @{ + */ + +#define __MPU_PRESENT 0 /**< Defines if an MPU is present or not */ +#define __NVIC_PRIO_BITS 4 /**< Number of priority bits implemented in the NVIC */ +#define __Vendor_SysTickConfig 0 /**< Vendor specific implementation of SysTickConfig is defined */ +#define __FPU_PRESENT 1 /**< Defines if an FPU is present or not */ + +#include "core_cm4.h" /* Core Peripheral Access Layer */ +#include "system_MK82F25615.h" /* Device specific configuration file */ + +/*! + * @} + */ /* end of group Cortex_Core_Configuration */ + + +/* ---------------------------------------------------------------------------- + -- Mapping Information + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Mapping_Information Mapping Information + * @{ + */ + +/** Mapping Information */ +/*! + * @addtogroup edma_request + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Structure for the DMA hardware request + * + * Defines the structure for the DMA hardware request collections. The user can configure the + * hardware request into DMAMUX to trigger the DMA transfer accordingly. The index + * of the hardware request varies according to the to SoC. + */ +typedef enum _dma_request_source +{ + kDmaRequestMux0Disable = 0|0x100U, /**< DMAMUX TriggerDisabled. */ + kDmaRequestMux0TSI0 = 1|0x100U, /**< TSI0. */ + kDmaRequestMux0LPUART0Rx = 2|0x100U, /**< LPUART0 Receive. */ + kDmaRequestMux0LPUART0Tx = 3|0x100U, /**< LPUART0 Transmit. */ + kDmaRequestMux0LPUART1Rx = 4|0x100U, /**< LPUART1 Receive. */ + kDmaRequestMux0LPUART1Tx = 5|0x100U, /**< LPUART1 Transmit. */ + kDmaRequestMux0LPUART2Rx = 6|0x100U, /**< LPUART2 Receive. */ + kDmaRequestMux0LPUART2Tx = 7|0x100U, /**< LPUART2 Transmit. */ + kDmaRequestMux0LPUART3Rx = 8|0x100U, /**< LPUART3 Receive. */ + kDmaRequestMux0LPUART3Tx = 9|0x100U, /**< LPUART3 Transmit. */ + kDmaRequestMux0LPUART4Rx = 10|0x100U, /**< LPUART4 Receive. */ + kDmaRequestMux0LPUART4Tx = 11|0x100U, /**< LPUART4 Transmit. */ + kDmaRequestMux0I2S0Rx = 12|0x100U, /**< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 13|0x100U, /**< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /**< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /**< SPI0 Transmit. */ + kDmaRequestMux0SPI1Rx = 16|0x100U, /**< SPI1 Receive. */ + kDmaRequestMux0SPI1Tx = 17|0x100U, /**< SPI1 Transmit. */ + kDmaRequestMux0I2C0I2C3 = 18|0x100U, /**< I2C0 and I2C3. */ + kDmaRequestMux0I2C0 = 18|0x100U, /**< I2C0 and I2C3. */ + kDmaRequestMux0I2C3 = 18|0x100U, /**< I2C0 and I2C3. */ + kDmaRequestMux0I2C1I2C2 = 19|0x100U, /**< I2C1 and I2C2. */ + kDmaRequestMux0I2C1 = 19|0x100U, /**< I2C1 and I2C2. */ + kDmaRequestMux0I2C2 = 19|0x100U, /**< I2C1 and I2C2. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /**< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /**< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /**< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /**< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /**< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /**< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /**< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /**< FTM0 C7V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /**< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /**< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /**< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /**< FTM2 C1V. */ + kDmaRequestMux0FTM3Channel0 = 32|0x100U, /**< FTM3 C0V. */ + kDmaRequestMux0FTM3Channel1 = 33|0x100U, /**< FTM3 C1V. */ + kDmaRequestMux0FTM3Channel2 = 34|0x100U, /**< FTM3 C2V. */ + kDmaRequestMux0FTM3Channel3 = 35|0x100U, /**< FTM3 C3V. */ + kDmaRequestMux0FTM3Channel4 = 36|0x100U, /**< FTM3 C4V. */ + kDmaRequestMux0FTM3Channel5 = 37|0x100U, /**< FTM3 C5V. */ + kDmaRequestMux0FTM3Channel6 = 38|0x100U, /**< FTM3 C6V. */ + kDmaRequestMux0FTM3Channel7 = 39|0x100U, /**< FTM3 C7V. */ + kDmaRequestMux0ADC0 = 40|0x100U, /**< ADC0. */ + kDmaRequestMux0Reserved41 = 41|0x100U, /**< Reserved41 */ + kDmaRequestMux0CMP0 = 42|0x100U, /**< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /**< CMP1. */ + kDmaRequestMux0Reserved44 = 44|0x100U, /**< Reserved44 */ + kDmaRequestMux0DAC0 = 45|0x100U, /**< DAC0. */ + kDmaRequestMux0Reserved46 = 46|0x100U, /**< Reserved46 */ + kDmaRequestMux0CMT = 47|0x100U, /**< CMT. */ + kDmaRequestMux0PDB = 48|0x100U, /**< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /**< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /**< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /**< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /**< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /**< PTE. */ + kDmaRequestMux0Reserved54 = 54|0x100U, /**< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /**< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /**< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /**< Reserved57 */ + kDmaRequestMux0SPI2Rx = 58|0x100U, /**< SPI2 Receive. */ + kDmaRequestMux0SPI2Tx = 59|0x100U, /**< SPI2 Transmit. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /**< DMAMUX Always Enabled slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /**< DMAMUX Always Enabled slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /**< DMAMUX Always Enabled slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /**< DMAMUX Always Enabled slot. */ + kDmaRequestMux0Group1Disable = 0|0x200U, /**< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Group1FlexIO0Channel0 = 1|0x200U, /**< FLEXIO0. */ + kDmaRequestMux0Group1FlexIO0Channel1 = 2|0x200U, /**< FLEXIO0. */ + kDmaRequestMux0Group1FlexIO0Channel2 = 3|0x200U, /**< FLEXIO0. */ + kDmaRequestMux0Group1FlexIO0Channel3 = 4|0x200U, /**< FLEXIO0. */ + kDmaRequestMux0Group1FlexIO0Channel4 = 5|0x200U, /**< FLEXIO0. */ + kDmaRequestMux0Group1FlexIO0Channel5 = 6|0x200U, /**< FLEXIO0. */ + kDmaRequestMux0Group1FlexIO0Channel6 = 7|0x200U, /**< FLEXIO0. */ + kDmaRequestMux0Group1FlexIO0Channel7 = 8|0x200U, /**< FLEXIO0. */ + kDmaRequestMux0Group1Reserved9 = 9|0x200U, /**< Reserved9 */ + kDmaRequestMux0Group1Reserved10 = 10|0x200U, /**< Reserved10 */ + kDmaRequestMux0Group1Reserved11 = 11|0x200U, /**< Reserved11 */ + kDmaRequestMux0Group1Reserved12 = 12|0x200U, /**< Reserved12 */ + kDmaRequestMux0Group1Reserved13 = 13|0x200U, /**< Reserved13 */ + kDmaRequestMux0Group1Reserved14 = 14|0x200U, /**< Reserved14 */ + kDmaRequestMux0Group1Reserved15 = 15|0x200U, /**< Reserved15 */ + kDmaRequestMux0Group1Reserved16 = 16|0x200U, /**< Reserved16 */ + kDmaRequestMux0Group1LTC0InputFIFO = 17|0x200U, /**< LTC0 Input FIFO. */ + kDmaRequestMux0Group1LTC0OutputFIFO = 18|0x200U, /**< LTC0 Output FIFO. */ + kDmaRequestMux0Group1LTC0PKHA = 19|0x200U, /**< LTC0 PKHA. */ + kDmaRequestMux0Group1EMVSIM0Rx = 20|0x200U, /**< EMVSIM0 Receive. */ + kDmaRequestMux0Group1EMVSIM0Tx = 21|0x200U, /**< EMVSIM0 Transmit. */ + kDmaRequestMux0Group1EMVSIM1Rx = 22|0x200U, /**< EMVSIM1 Receive. */ + kDmaRequestMux0Group1EMVSIM1Tx = 23|0x200U, /**< EMVSIM1 Transmit. */ + kDmaRequestMux0Group1QSPI0Rx = 24|0x200U, /**< QuadSPI0 Receive. */ + kDmaRequestMux0Group1QSPI0Tx = 25|0x200U, /**< QuadSPI0 Transmit. */ + kDmaRequestMux0Group1Reserved26 = 26|0x200U, /**< Reserved26 */ + kDmaRequestMux0Group1Reserved27 = 27|0x200U, /**< Reserved27 */ + kDmaRequestMux0Group1SPI0Rx = 28|0x200U, /**< SPI0 Receive. */ + kDmaRequestMux0Group1SPI0Tx = 29|0x200U, /**< SPI0 Transmit. */ + kDmaRequestMux0Group1SPI1Rx = 30|0x200U, /**< SPI1 Receive. */ + kDmaRequestMux0Group1SPI1Tx = 31|0x200U, /**< SPI1 Transmit. */ + kDmaRequestMux0Group1Reserved32 = 32|0x200U, /**< Reserved32 */ + kDmaRequestMux0Group1Reserved33 = 33|0x200U, /**< Reserved33 */ + kDmaRequestMux0Group1Reserved34 = 34|0x200U, /**< Reserved34 */ + kDmaRequestMux0Group1Reserved35 = 35|0x200U, /**< Reserved35 */ + kDmaRequestMux0Group1Reserved36 = 36|0x200U, /**< Reserved36 */ + kDmaRequestMux0Group1Reserved37 = 37|0x200U, /**< Reserved37 */ + kDmaRequestMux0Group1Reserved38 = 38|0x200U, /**< Reserved38 */ + kDmaRequestMux0Group1Reserved39 = 39|0x200U, /**< Reserved39 */ + kDmaRequestMux0Group1Reserved40 = 40|0x200U, /**< Reserved40 */ + kDmaRequestMux0Group1Reserved41 = 41|0x200U, /**< Reserved41 */ + kDmaRequestMux0Group1TPM1Channel0 = 42|0x200U, /**< TPM1 C0V. */ + kDmaRequestMux0Group1TPM1Channel1 = 43|0x200U, /**< TPM1 C1V. */ + kDmaRequestMux0Group1TPM2Channel0 = 44|0x200U, /**< TPM2 C0V. */ + kDmaRequestMux0Group1TPM2Channel1 = 45|0x200U, /**< TPM2 C1V. */ + kDmaRequestMux0Group1Reserved46 = 46|0x200U, /**< Reserved46 */ + kDmaRequestMux0Group1Reserved47 = 47|0x200U, /**< Reserved47 */ + kDmaRequestMux0Group1Reserved48 = 48|0x200U, /**< Reserved48 */ + kDmaRequestMux0Group1Reserved49 = 49|0x200U, /**< Reserved49 */ + kDmaRequestMux0Group1Reserved50 = 50|0x200U, /**< Reserved50 */ + kDmaRequestMux0Group1Reserved51 = 51|0x200U, /**< Reserved51 */ + kDmaRequestMux0Group1Reserved52 = 52|0x200U, /**< Reserved52 */ + kDmaRequestMux0Group1Reserved53 = 53|0x200U, /**< Reserved53 */ + kDmaRequestMux0Group1Reserved54 = 54|0x200U, /**< Reserved54 */ + kDmaRequestMux0Group1TPM1Overflow = 55|0x200U, /**< TPM1. */ + kDmaRequestMux0Group1TPM2Overflow = 56|0x200U, /**< TPM2. */ + kDmaRequestMux0Group1Reserved57 = 57|0x200U, /**< Reserved57 */ + kDmaRequestMux0Group1Reserved58 = 58|0x200U, /**< Reserved58 */ + kDmaRequestMux0Group1Reserved59 = 59|0x200U, /**< Reserved59 */ + kDmaRequestMux0Group1AlwaysOn60 = 60|0x200U, /**< DMAMUX Always Enabled slot. */ + kDmaRequestMux0Group1AlwaysOn61 = 61|0x200U, /**< DMAMUX Always Enabled slot. */ + kDmaRequestMux0Group1AlwaysOn62 = 62|0x200U, /**< DMAMUX Always Enabled slot. */ + kDmaRequestMux0Group1AlwaysOn63 = 63|0x200U, /**< DMAMUX Always Enabled slot. */ +} dma_request_source_t; + +/* @} */ + + +/*! + * @} + */ /* end of group Mapping_Information */ + + +/* ---------------------------------------------------------------------------- + -- Device Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Peripheral_access_layer Device Peripheral Access Layer + * @{ + */ + + +/* +** Start of section using anonymous unions +*/ + +#if defined(__ARMCC_VERSION) + #pragma push + #pragma anon_unions +#elif defined(__CWCC__) + #pragma push + #pragma cpp_extensions on +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma language=extended +#else + #error Not supported compiler type +#endif + +/* ---------------------------------------------------------------------------- + -- ADC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ADC_Peripheral_Access_Layer ADC Peripheral Access Layer + * @{ + */ + +/** ADC - Register Layout Typedef */ +typedef struct { + __IO uint32_t SC1[2]; /**< ADC Status and Control Registers 1, array offset: 0x0, array step: 0x4 */ + __IO uint32_t CFG1; /**< ADC Configuration Register 1, offset: 0x8 */ + __IO uint32_t CFG2; /**< ADC Configuration Register 2, offset: 0xC */ + __I uint32_t R[2]; /**< ADC Data Result Register, array offset: 0x10, array step: 0x4 */ + __IO uint32_t CV1; /**< Compare Value Registers, offset: 0x18 */ + __IO uint32_t CV2; /**< Compare Value Registers, offset: 0x1C */ + __IO uint32_t SC2; /**< Status and Control Register 2, offset: 0x20 */ + __IO uint32_t SC3; /**< Status and Control Register 3, offset: 0x24 */ + __IO uint32_t OFS; /**< ADC Offset Correction Register, offset: 0x28 */ + __IO uint32_t PG; /**< ADC Plus-Side Gain Register, offset: 0x2C */ + __IO uint32_t MG; /**< ADC Minus-Side Gain Register, offset: 0x30 */ + __IO uint32_t CLPD; /**< ADC Plus-Side General Calibration Value Register, offset: 0x34 */ + __IO uint32_t CLPS; /**< ADC Plus-Side General Calibration Value Register, offset: 0x38 */ + __IO uint32_t CLP4; /**< ADC Plus-Side General Calibration Value Register, offset: 0x3C */ + __IO uint32_t CLP3; /**< ADC Plus-Side General Calibration Value Register, offset: 0x40 */ + __IO uint32_t CLP2; /**< ADC Plus-Side General Calibration Value Register, offset: 0x44 */ + __IO uint32_t CLP1; /**< ADC Plus-Side General Calibration Value Register, offset: 0x48 */ + __IO uint32_t CLP0; /**< ADC Plus-Side General Calibration Value Register, offset: 0x4C */ + uint8_t RESERVED_0[4]; + __IO uint32_t CLMD; /**< ADC Minus-Side General Calibration Value Register, offset: 0x54 */ + __IO uint32_t CLMS; /**< ADC Minus-Side General Calibration Value Register, offset: 0x58 */ + __IO uint32_t CLM4; /**< ADC Minus-Side General Calibration Value Register, offset: 0x5C */ + __IO uint32_t CLM3; /**< ADC Minus-Side General Calibration Value Register, offset: 0x60 */ + __IO uint32_t CLM2; /**< ADC Minus-Side General Calibration Value Register, offset: 0x64 */ + __IO uint32_t CLM1; /**< ADC Minus-Side General Calibration Value Register, offset: 0x68 */ + __IO uint32_t CLM0; /**< ADC Minus-Side General Calibration Value Register, offset: 0x6C */ +} ADC_Type; + +/* ---------------------------------------------------------------------------- + -- ADC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ADC_Register_Masks ADC Register Masks + * @{ + */ + +/*! @name SC1 - ADC Status and Control Registers 1 */ +#define ADC_SC1_ADCH_MASK (0x1FU) +#define ADC_SC1_ADCH_SHIFT (0U) +#define ADC_SC1_ADCH(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC1_ADCH_SHIFT)) & ADC_SC1_ADCH_MASK) +#define ADC_SC1_DIFF_MASK (0x20U) +#define ADC_SC1_DIFF_SHIFT (5U) +#define ADC_SC1_DIFF(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC1_DIFF_SHIFT)) & ADC_SC1_DIFF_MASK) +#define ADC_SC1_AIEN_MASK (0x40U) +#define ADC_SC1_AIEN_SHIFT (6U) +#define ADC_SC1_AIEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC1_AIEN_SHIFT)) & ADC_SC1_AIEN_MASK) +#define ADC_SC1_COCO_MASK (0x80U) +#define ADC_SC1_COCO_SHIFT (7U) +#define ADC_SC1_COCO(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC1_COCO_SHIFT)) & ADC_SC1_COCO_MASK) + +/* The count of ADC_SC1 */ +#define ADC_SC1_COUNT (2U) + +/*! @name CFG1 - ADC Configuration Register 1 */ +#define ADC_CFG1_ADICLK_MASK (0x3U) +#define ADC_CFG1_ADICLK_SHIFT (0U) +#define ADC_CFG1_ADICLK(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_ADICLK_SHIFT)) & ADC_CFG1_ADICLK_MASK) +#define ADC_CFG1_MODE_MASK (0xCU) +#define ADC_CFG1_MODE_SHIFT (2U) +#define ADC_CFG1_MODE(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_MODE_SHIFT)) & ADC_CFG1_MODE_MASK) +#define ADC_CFG1_ADLSMP_MASK (0x10U) +#define ADC_CFG1_ADLSMP_SHIFT (4U) +#define ADC_CFG1_ADLSMP(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_ADLSMP_SHIFT)) & ADC_CFG1_ADLSMP_MASK) +#define ADC_CFG1_ADIV_MASK (0x60U) +#define ADC_CFG1_ADIV_SHIFT (5U) +#define ADC_CFG1_ADIV(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_ADIV_SHIFT)) & ADC_CFG1_ADIV_MASK) +#define ADC_CFG1_ADLPC_MASK (0x80U) +#define ADC_CFG1_ADLPC_SHIFT (7U) +#define ADC_CFG1_ADLPC(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_ADLPC_SHIFT)) & ADC_CFG1_ADLPC_MASK) + +/*! @name CFG2 - ADC Configuration Register 2 */ +#define ADC_CFG2_ADLSTS_MASK (0x3U) +#define ADC_CFG2_ADLSTS_SHIFT (0U) +#define ADC_CFG2_ADLSTS(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG2_ADLSTS_SHIFT)) & ADC_CFG2_ADLSTS_MASK) +#define ADC_CFG2_ADHSC_MASK (0x4U) +#define ADC_CFG2_ADHSC_SHIFT (2U) +#define ADC_CFG2_ADHSC(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG2_ADHSC_SHIFT)) & ADC_CFG2_ADHSC_MASK) +#define ADC_CFG2_ADACKEN_MASK (0x8U) +#define ADC_CFG2_ADACKEN_SHIFT (3U) +#define ADC_CFG2_ADACKEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG2_ADACKEN_SHIFT)) & ADC_CFG2_ADACKEN_MASK) +#define ADC_CFG2_MUXSEL_MASK (0x10U) +#define ADC_CFG2_MUXSEL_SHIFT (4U) +#define ADC_CFG2_MUXSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG2_MUXSEL_SHIFT)) & ADC_CFG2_MUXSEL_MASK) + +/*! @name R - ADC Data Result Register */ +#define ADC_R_D_MASK (0xFFFFU) +#define ADC_R_D_SHIFT (0U) +#define ADC_R_D(x) (((uint32_t)(((uint32_t)(x)) << ADC_R_D_SHIFT)) & ADC_R_D_MASK) + +/* The count of ADC_R */ +#define ADC_R_COUNT (2U) + +/*! @name CV1 - Compare Value Registers */ +#define ADC_CV1_CV_MASK (0xFFFFU) +#define ADC_CV1_CV_SHIFT (0U) +#define ADC_CV1_CV(x) (((uint32_t)(((uint32_t)(x)) << ADC_CV1_CV_SHIFT)) & ADC_CV1_CV_MASK) + +/*! @name CV2 - Compare Value Registers */ +#define ADC_CV2_CV_MASK (0xFFFFU) +#define ADC_CV2_CV_SHIFT (0U) +#define ADC_CV2_CV(x) (((uint32_t)(((uint32_t)(x)) << ADC_CV2_CV_SHIFT)) & ADC_CV2_CV_MASK) + +/*! @name SC2 - Status and Control Register 2 */ +#define ADC_SC2_REFSEL_MASK (0x3U) +#define ADC_SC2_REFSEL_SHIFT (0U) +#define ADC_SC2_REFSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_REFSEL_SHIFT)) & ADC_SC2_REFSEL_MASK) +#define ADC_SC2_DMAEN_MASK (0x4U) +#define ADC_SC2_DMAEN_SHIFT (2U) +#define ADC_SC2_DMAEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_DMAEN_SHIFT)) & ADC_SC2_DMAEN_MASK) +#define ADC_SC2_ACREN_MASK (0x8U) +#define ADC_SC2_ACREN_SHIFT (3U) +#define ADC_SC2_ACREN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ACREN_SHIFT)) & ADC_SC2_ACREN_MASK) +#define ADC_SC2_ACFGT_MASK (0x10U) +#define ADC_SC2_ACFGT_SHIFT (4U) +#define ADC_SC2_ACFGT(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ACFGT_SHIFT)) & ADC_SC2_ACFGT_MASK) +#define ADC_SC2_ACFE_MASK (0x20U) +#define ADC_SC2_ACFE_SHIFT (5U) +#define ADC_SC2_ACFE(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ACFE_SHIFT)) & ADC_SC2_ACFE_MASK) +#define ADC_SC2_ADTRG_MASK (0x40U) +#define ADC_SC2_ADTRG_SHIFT (6U) +#define ADC_SC2_ADTRG(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ADTRG_SHIFT)) & ADC_SC2_ADTRG_MASK) +#define ADC_SC2_ADACT_MASK (0x80U) +#define ADC_SC2_ADACT_SHIFT (7U) +#define ADC_SC2_ADACT(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ADACT_SHIFT)) & ADC_SC2_ADACT_MASK) + +/*! @name SC3 - Status and Control Register 3 */ +#define ADC_SC3_AVGS_MASK (0x3U) +#define ADC_SC3_AVGS_SHIFT (0U) +#define ADC_SC3_AVGS(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_AVGS_SHIFT)) & ADC_SC3_AVGS_MASK) +#define ADC_SC3_AVGE_MASK (0x4U) +#define ADC_SC3_AVGE_SHIFT (2U) +#define ADC_SC3_AVGE(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_AVGE_SHIFT)) & ADC_SC3_AVGE_MASK) +#define ADC_SC3_ADCO_MASK (0x8U) +#define ADC_SC3_ADCO_SHIFT (3U) +#define ADC_SC3_ADCO(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_ADCO_SHIFT)) & ADC_SC3_ADCO_MASK) +#define ADC_SC3_CALF_MASK (0x40U) +#define ADC_SC3_CALF_SHIFT (6U) +#define ADC_SC3_CALF(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_CALF_SHIFT)) & ADC_SC3_CALF_MASK) +#define ADC_SC3_CAL_MASK (0x80U) +#define ADC_SC3_CAL_SHIFT (7U) +#define ADC_SC3_CAL(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_CAL_SHIFT)) & ADC_SC3_CAL_MASK) + +/*! @name OFS - ADC Offset Correction Register */ +#define ADC_OFS_OFS_MASK (0xFFFFU) +#define ADC_OFS_OFS_SHIFT (0U) +#define ADC_OFS_OFS(x) (((uint32_t)(((uint32_t)(x)) << ADC_OFS_OFS_SHIFT)) & ADC_OFS_OFS_MASK) + +/*! @name PG - ADC Plus-Side Gain Register */ +#define ADC_PG_PG_MASK (0xFFFFU) +#define ADC_PG_PG_SHIFT (0U) +#define ADC_PG_PG(x) (((uint32_t)(((uint32_t)(x)) << ADC_PG_PG_SHIFT)) & ADC_PG_PG_MASK) + +/*! @name MG - ADC Minus-Side Gain Register */ +#define ADC_MG_MG_MASK (0xFFFFU) +#define ADC_MG_MG_SHIFT (0U) +#define ADC_MG_MG(x) (((uint32_t)(((uint32_t)(x)) << ADC_MG_MG_SHIFT)) & ADC_MG_MG_MASK) + +/*! @name CLPD - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLPD_CLPD_MASK (0x3FU) +#define ADC_CLPD_CLPD_SHIFT (0U) +#define ADC_CLPD_CLPD(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLPD_CLPD_SHIFT)) & ADC_CLPD_CLPD_MASK) + +/*! @name CLPS - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLPS_CLPS_MASK (0x3FU) +#define ADC_CLPS_CLPS_SHIFT (0U) +#define ADC_CLPS_CLPS(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLPS_CLPS_SHIFT)) & ADC_CLPS_CLPS_MASK) + +/*! @name CLP4 - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLP4_CLP4_MASK (0x3FFU) +#define ADC_CLP4_CLP4_SHIFT (0U) +#define ADC_CLP4_CLP4(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP4_CLP4_SHIFT)) & ADC_CLP4_CLP4_MASK) + +/*! @name CLP3 - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLP3_CLP3_MASK (0x1FFU) +#define ADC_CLP3_CLP3_SHIFT (0U) +#define ADC_CLP3_CLP3(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP3_CLP3_SHIFT)) & ADC_CLP3_CLP3_MASK) + +/*! @name CLP2 - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLP2_CLP2_MASK (0xFFU) +#define ADC_CLP2_CLP2_SHIFT (0U) +#define ADC_CLP2_CLP2(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP2_CLP2_SHIFT)) & ADC_CLP2_CLP2_MASK) + +/*! @name CLP1 - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLP1_CLP1_MASK (0x7FU) +#define ADC_CLP1_CLP1_SHIFT (0U) +#define ADC_CLP1_CLP1(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP1_CLP1_SHIFT)) & ADC_CLP1_CLP1_MASK) + +/*! @name CLP0 - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLP0_CLP0_MASK (0x3FU) +#define ADC_CLP0_CLP0_SHIFT (0U) +#define ADC_CLP0_CLP0(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP0_CLP0_SHIFT)) & ADC_CLP0_CLP0_MASK) + +/*! @name CLMD - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLMD_CLMD_MASK (0x3FU) +#define ADC_CLMD_CLMD_SHIFT (0U) +#define ADC_CLMD_CLMD(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLMD_CLMD_SHIFT)) & ADC_CLMD_CLMD_MASK) + +/*! @name CLMS - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLMS_CLMS_MASK (0x3FU) +#define ADC_CLMS_CLMS_SHIFT (0U) +#define ADC_CLMS_CLMS(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLMS_CLMS_SHIFT)) & ADC_CLMS_CLMS_MASK) + +/*! @name CLM4 - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLM4_CLM4_MASK (0x3FFU) +#define ADC_CLM4_CLM4_SHIFT (0U) +#define ADC_CLM4_CLM4(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM4_CLM4_SHIFT)) & ADC_CLM4_CLM4_MASK) + +/*! @name CLM3 - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLM3_CLM3_MASK (0x1FFU) +#define ADC_CLM3_CLM3_SHIFT (0U) +#define ADC_CLM3_CLM3(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM3_CLM3_SHIFT)) & ADC_CLM3_CLM3_MASK) + +/*! @name CLM2 - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLM2_CLM2_MASK (0xFFU) +#define ADC_CLM2_CLM2_SHIFT (0U) +#define ADC_CLM2_CLM2(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM2_CLM2_SHIFT)) & ADC_CLM2_CLM2_MASK) + +/*! @name CLM1 - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLM1_CLM1_MASK (0x7FU) +#define ADC_CLM1_CLM1_SHIFT (0U) +#define ADC_CLM1_CLM1(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM1_CLM1_SHIFT)) & ADC_CLM1_CLM1_MASK) + +/*! @name CLM0 - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLM0_CLM0_MASK (0x3FU) +#define ADC_CLM0_CLM0_SHIFT (0U) +#define ADC_CLM0_CLM0(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM0_CLM0_SHIFT)) & ADC_CLM0_CLM0_MASK) + + +/*! + * @} + */ /* end of group ADC_Register_Masks */ + + +/* ADC - Peripheral instance base addresses */ +/** Peripheral ADC0 base address */ +#define ADC0_BASE (0x4003B000u) +/** Peripheral ADC0 base pointer */ +#define ADC0 ((ADC_Type *)ADC0_BASE) +/** Array initializer of ADC peripheral base addresses */ +#define ADC_BASE_ADDRS { ADC0_BASE } +/** Array initializer of ADC peripheral base pointers */ +#define ADC_BASE_PTRS { ADC0 } +/** Interrupt vectors for the ADC peripheral type */ +#define ADC_IRQS { ADC0_IRQn } + +/*! + * @} + */ /* end of group ADC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- AIPS Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup AIPS_Peripheral_Access_Layer AIPS Peripheral Access Layer + * @{ + */ + +/** AIPS - Register Layout Typedef */ +typedef struct { + __IO uint32_t MPRA; /**< Master Privilege Register A, offset: 0x0 */ + uint8_t RESERVED_0[28]; + __IO uint32_t PACRA; /**< Peripheral Access Control Register, offset: 0x20 */ + __IO uint32_t PACRB; /**< Peripheral Access Control Register, offset: 0x24 */ + __IO uint32_t PACRC; /**< Peripheral Access Control Register, offset: 0x28 */ + __IO uint32_t PACRD; /**< Peripheral Access Control Register, offset: 0x2C */ + uint8_t RESERVED_1[16]; + __IO uint32_t PACRE; /**< Peripheral Access Control Register, offset: 0x40 */ + __IO uint32_t PACRF; /**< Peripheral Access Control Register, offset: 0x44 */ + __IO uint32_t PACRG; /**< Peripheral Access Control Register, offset: 0x48 */ + __IO uint32_t PACRH; /**< Peripheral Access Control Register, offset: 0x4C */ + __IO uint32_t PACRI; /**< Peripheral Access Control Register, offset: 0x50 */ + __IO uint32_t PACRJ; /**< Peripheral Access Control Register, offset: 0x54 */ + __IO uint32_t PACRK; /**< Peripheral Access Control Register, offset: 0x58 */ + __IO uint32_t PACRL; /**< Peripheral Access Control Register, offset: 0x5C */ + __IO uint32_t PACRM; /**< Peripheral Access Control Register, offset: 0x60 */ + __IO uint32_t PACRN; /**< Peripheral Access Control Register, offset: 0x64 */ + __IO uint32_t PACRO; /**< Peripheral Access Control Register, offset: 0x68 */ + __IO uint32_t PACRP; /**< Peripheral Access Control Register, offset: 0x6C */ +} AIPS_Type; + +/* ---------------------------------------------------------------------------- + -- AIPS Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup AIPS_Register_Masks AIPS Register Masks + * @{ + */ + +/*! @name MPRA - Master Privilege Register A */ +#define AIPS_MPRA_MPL4_MASK (0x1000U) +#define AIPS_MPRA_MPL4_SHIFT (12U) +#define AIPS_MPRA_MPL4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MPL4_SHIFT)) & AIPS_MPRA_MPL4_MASK) +#define AIPS_MPRA_MTW4_MASK (0x2000U) +#define AIPS_MPRA_MTW4_SHIFT (13U) +#define AIPS_MPRA_MTW4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTW4_SHIFT)) & AIPS_MPRA_MTW4_MASK) +#define AIPS_MPRA_MTR4_MASK (0x4000U) +#define AIPS_MPRA_MTR4_SHIFT (14U) +#define AIPS_MPRA_MTR4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTR4_SHIFT)) & AIPS_MPRA_MTR4_MASK) +#define AIPS_MPRA_MPL3_MASK (0x10000U) +#define AIPS_MPRA_MPL3_SHIFT (16U) +#define AIPS_MPRA_MPL3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MPL3_SHIFT)) & AIPS_MPRA_MPL3_MASK) +#define AIPS_MPRA_MTW3_MASK (0x20000U) +#define AIPS_MPRA_MTW3_SHIFT (17U) +#define AIPS_MPRA_MTW3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTW3_SHIFT)) & AIPS_MPRA_MTW3_MASK) +#define AIPS_MPRA_MTR3_MASK (0x40000U) +#define AIPS_MPRA_MTR3_SHIFT (18U) +#define AIPS_MPRA_MTR3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTR3_SHIFT)) & AIPS_MPRA_MTR3_MASK) +#define AIPS_MPRA_MPL2_MASK (0x100000U) +#define AIPS_MPRA_MPL2_SHIFT (20U) +#define AIPS_MPRA_MPL2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MPL2_SHIFT)) & AIPS_MPRA_MPL2_MASK) +#define AIPS_MPRA_MTW2_MASK (0x200000U) +#define AIPS_MPRA_MTW2_SHIFT (21U) +#define AIPS_MPRA_MTW2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTW2_SHIFT)) & AIPS_MPRA_MTW2_MASK) +#define AIPS_MPRA_MTR2_MASK (0x400000U) +#define AIPS_MPRA_MTR2_SHIFT (22U) +#define AIPS_MPRA_MTR2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTR2_SHIFT)) & AIPS_MPRA_MTR2_MASK) +#define AIPS_MPRA_MPL1_MASK (0x1000000U) +#define AIPS_MPRA_MPL1_SHIFT (24U) +#define AIPS_MPRA_MPL1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MPL1_SHIFT)) & AIPS_MPRA_MPL1_MASK) +#define AIPS_MPRA_MTW1_MASK (0x2000000U) +#define AIPS_MPRA_MTW1_SHIFT (25U) +#define AIPS_MPRA_MTW1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTW1_SHIFT)) & AIPS_MPRA_MTW1_MASK) +#define AIPS_MPRA_MTR1_MASK (0x4000000U) +#define AIPS_MPRA_MTR1_SHIFT (26U) +#define AIPS_MPRA_MTR1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTR1_SHIFT)) & AIPS_MPRA_MTR1_MASK) +#define AIPS_MPRA_MPL0_MASK (0x10000000U) +#define AIPS_MPRA_MPL0_SHIFT (28U) +#define AIPS_MPRA_MPL0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MPL0_SHIFT)) & AIPS_MPRA_MPL0_MASK) +#define AIPS_MPRA_MTW0_MASK (0x20000000U) +#define AIPS_MPRA_MTW0_SHIFT (29U) +#define AIPS_MPRA_MTW0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTW0_SHIFT)) & AIPS_MPRA_MTW0_MASK) +#define AIPS_MPRA_MTR0_MASK (0x40000000U) +#define AIPS_MPRA_MTR0_SHIFT (30U) +#define AIPS_MPRA_MTR0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTR0_SHIFT)) & AIPS_MPRA_MTR0_MASK) + +/*! @name PACRA - Peripheral Access Control Register */ +#define AIPS_PACRA_TP7_MASK (0x1U) +#define AIPS_PACRA_TP7_SHIFT (0U) +#define AIPS_PACRA_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP7_SHIFT)) & AIPS_PACRA_TP7_MASK) +#define AIPS_PACRA_WP7_MASK (0x2U) +#define AIPS_PACRA_WP7_SHIFT (1U) +#define AIPS_PACRA_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP7_SHIFT)) & AIPS_PACRA_WP7_MASK) +#define AIPS_PACRA_SP7_MASK (0x4U) +#define AIPS_PACRA_SP7_SHIFT (2U) +#define AIPS_PACRA_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP7_SHIFT)) & AIPS_PACRA_SP7_MASK) +#define AIPS_PACRA_TP6_MASK (0x10U) +#define AIPS_PACRA_TP6_SHIFT (4U) +#define AIPS_PACRA_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP6_SHIFT)) & AIPS_PACRA_TP6_MASK) +#define AIPS_PACRA_WP6_MASK (0x20U) +#define AIPS_PACRA_WP6_SHIFT (5U) +#define AIPS_PACRA_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP6_SHIFT)) & AIPS_PACRA_WP6_MASK) +#define AIPS_PACRA_SP6_MASK (0x40U) +#define AIPS_PACRA_SP6_SHIFT (6U) +#define AIPS_PACRA_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP6_SHIFT)) & AIPS_PACRA_SP6_MASK) +#define AIPS_PACRA_TP5_MASK (0x100U) +#define AIPS_PACRA_TP5_SHIFT (8U) +#define AIPS_PACRA_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP5_SHIFT)) & AIPS_PACRA_TP5_MASK) +#define AIPS_PACRA_WP5_MASK (0x200U) +#define AIPS_PACRA_WP5_SHIFT (9U) +#define AIPS_PACRA_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP5_SHIFT)) & AIPS_PACRA_WP5_MASK) +#define AIPS_PACRA_SP5_MASK (0x400U) +#define AIPS_PACRA_SP5_SHIFT (10U) +#define AIPS_PACRA_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP5_SHIFT)) & AIPS_PACRA_SP5_MASK) +#define AIPS_PACRA_TP4_MASK (0x1000U) +#define AIPS_PACRA_TP4_SHIFT (12U) +#define AIPS_PACRA_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP4_SHIFT)) & AIPS_PACRA_TP4_MASK) +#define AIPS_PACRA_WP4_MASK (0x2000U) +#define AIPS_PACRA_WP4_SHIFT (13U) +#define AIPS_PACRA_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP4_SHIFT)) & AIPS_PACRA_WP4_MASK) +#define AIPS_PACRA_SP4_MASK (0x4000U) +#define AIPS_PACRA_SP4_SHIFT (14U) +#define AIPS_PACRA_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP4_SHIFT)) & AIPS_PACRA_SP4_MASK) +#define AIPS_PACRA_TP3_MASK (0x10000U) +#define AIPS_PACRA_TP3_SHIFT (16U) +#define AIPS_PACRA_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP3_SHIFT)) & AIPS_PACRA_TP3_MASK) +#define AIPS_PACRA_WP3_MASK (0x20000U) +#define AIPS_PACRA_WP3_SHIFT (17U) +#define AIPS_PACRA_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP3_SHIFT)) & AIPS_PACRA_WP3_MASK) +#define AIPS_PACRA_SP3_MASK (0x40000U) +#define AIPS_PACRA_SP3_SHIFT (18U) +#define AIPS_PACRA_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP3_SHIFT)) & AIPS_PACRA_SP3_MASK) +#define AIPS_PACRA_TP2_MASK (0x100000U) +#define AIPS_PACRA_TP2_SHIFT (20U) +#define AIPS_PACRA_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP2_SHIFT)) & AIPS_PACRA_TP2_MASK) +#define AIPS_PACRA_WP2_MASK (0x200000U) +#define AIPS_PACRA_WP2_SHIFT (21U) +#define AIPS_PACRA_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP2_SHIFT)) & AIPS_PACRA_WP2_MASK) +#define AIPS_PACRA_SP2_MASK (0x400000U) +#define AIPS_PACRA_SP2_SHIFT (22U) +#define AIPS_PACRA_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP2_SHIFT)) & AIPS_PACRA_SP2_MASK) +#define AIPS_PACRA_TP1_MASK (0x1000000U) +#define AIPS_PACRA_TP1_SHIFT (24U) +#define AIPS_PACRA_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP1_SHIFT)) & AIPS_PACRA_TP1_MASK) +#define AIPS_PACRA_WP1_MASK (0x2000000U) +#define AIPS_PACRA_WP1_SHIFT (25U) +#define AIPS_PACRA_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP1_SHIFT)) & AIPS_PACRA_WP1_MASK) +#define AIPS_PACRA_SP1_MASK (0x4000000U) +#define AIPS_PACRA_SP1_SHIFT (26U) +#define AIPS_PACRA_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP1_SHIFT)) & AIPS_PACRA_SP1_MASK) +#define AIPS_PACRA_TP0_MASK (0x10000000U) +#define AIPS_PACRA_TP0_SHIFT (28U) +#define AIPS_PACRA_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP0_SHIFT)) & AIPS_PACRA_TP0_MASK) +#define AIPS_PACRA_WP0_MASK (0x20000000U) +#define AIPS_PACRA_WP0_SHIFT (29U) +#define AIPS_PACRA_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP0_SHIFT)) & AIPS_PACRA_WP0_MASK) +#define AIPS_PACRA_SP0_MASK (0x40000000U) +#define AIPS_PACRA_SP0_SHIFT (30U) +#define AIPS_PACRA_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP0_SHIFT)) & AIPS_PACRA_SP0_MASK) + +/*! @name PACRB - Peripheral Access Control Register */ +#define AIPS_PACRB_TP7_MASK (0x1U) +#define AIPS_PACRB_TP7_SHIFT (0U) +#define AIPS_PACRB_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP7_SHIFT)) & AIPS_PACRB_TP7_MASK) +#define AIPS_PACRB_WP7_MASK (0x2U) +#define AIPS_PACRB_WP7_SHIFT (1U) +#define AIPS_PACRB_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP7_SHIFT)) & AIPS_PACRB_WP7_MASK) +#define AIPS_PACRB_SP7_MASK (0x4U) +#define AIPS_PACRB_SP7_SHIFT (2U) +#define AIPS_PACRB_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP7_SHIFT)) & AIPS_PACRB_SP7_MASK) +#define AIPS_PACRB_TP6_MASK (0x10U) +#define AIPS_PACRB_TP6_SHIFT (4U) +#define AIPS_PACRB_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP6_SHIFT)) & AIPS_PACRB_TP6_MASK) +#define AIPS_PACRB_WP6_MASK (0x20U) +#define AIPS_PACRB_WP6_SHIFT (5U) +#define AIPS_PACRB_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP6_SHIFT)) & AIPS_PACRB_WP6_MASK) +#define AIPS_PACRB_SP6_MASK (0x40U) +#define AIPS_PACRB_SP6_SHIFT (6U) +#define AIPS_PACRB_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP6_SHIFT)) & AIPS_PACRB_SP6_MASK) +#define AIPS_PACRB_TP5_MASK (0x100U) +#define AIPS_PACRB_TP5_SHIFT (8U) +#define AIPS_PACRB_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP5_SHIFT)) & AIPS_PACRB_TP5_MASK) +#define AIPS_PACRB_WP5_MASK (0x200U) +#define AIPS_PACRB_WP5_SHIFT (9U) +#define AIPS_PACRB_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP5_SHIFT)) & AIPS_PACRB_WP5_MASK) +#define AIPS_PACRB_SP5_MASK (0x400U) +#define AIPS_PACRB_SP5_SHIFT (10U) +#define AIPS_PACRB_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP5_SHIFT)) & AIPS_PACRB_SP5_MASK) +#define AIPS_PACRB_TP4_MASK (0x1000U) +#define AIPS_PACRB_TP4_SHIFT (12U) +#define AIPS_PACRB_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP4_SHIFT)) & AIPS_PACRB_TP4_MASK) +#define AIPS_PACRB_WP4_MASK (0x2000U) +#define AIPS_PACRB_WP4_SHIFT (13U) +#define AIPS_PACRB_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP4_SHIFT)) & AIPS_PACRB_WP4_MASK) +#define AIPS_PACRB_SP4_MASK (0x4000U) +#define AIPS_PACRB_SP4_SHIFT (14U) +#define AIPS_PACRB_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP4_SHIFT)) & AIPS_PACRB_SP4_MASK) +#define AIPS_PACRB_TP3_MASK (0x10000U) +#define AIPS_PACRB_TP3_SHIFT (16U) +#define AIPS_PACRB_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP3_SHIFT)) & AIPS_PACRB_TP3_MASK) +#define AIPS_PACRB_WP3_MASK (0x20000U) +#define AIPS_PACRB_WP3_SHIFT (17U) +#define AIPS_PACRB_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP3_SHIFT)) & AIPS_PACRB_WP3_MASK) +#define AIPS_PACRB_SP3_MASK (0x40000U) +#define AIPS_PACRB_SP3_SHIFT (18U) +#define AIPS_PACRB_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP3_SHIFT)) & AIPS_PACRB_SP3_MASK) +#define AIPS_PACRB_TP2_MASK (0x100000U) +#define AIPS_PACRB_TP2_SHIFT (20U) +#define AIPS_PACRB_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP2_SHIFT)) & AIPS_PACRB_TP2_MASK) +#define AIPS_PACRB_WP2_MASK (0x200000U) +#define AIPS_PACRB_WP2_SHIFT (21U) +#define AIPS_PACRB_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP2_SHIFT)) & AIPS_PACRB_WP2_MASK) +#define AIPS_PACRB_SP2_MASK (0x400000U) +#define AIPS_PACRB_SP2_SHIFT (22U) +#define AIPS_PACRB_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP2_SHIFT)) & AIPS_PACRB_SP2_MASK) +#define AIPS_PACRB_TP1_MASK (0x1000000U) +#define AIPS_PACRB_TP1_SHIFT (24U) +#define AIPS_PACRB_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP1_SHIFT)) & AIPS_PACRB_TP1_MASK) +#define AIPS_PACRB_WP1_MASK (0x2000000U) +#define AIPS_PACRB_WP1_SHIFT (25U) +#define AIPS_PACRB_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP1_SHIFT)) & AIPS_PACRB_WP1_MASK) +#define AIPS_PACRB_SP1_MASK (0x4000000U) +#define AIPS_PACRB_SP1_SHIFT (26U) +#define AIPS_PACRB_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP1_SHIFT)) & AIPS_PACRB_SP1_MASK) +#define AIPS_PACRB_TP0_MASK (0x10000000U) +#define AIPS_PACRB_TP0_SHIFT (28U) +#define AIPS_PACRB_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP0_SHIFT)) & AIPS_PACRB_TP0_MASK) +#define AIPS_PACRB_WP0_MASK (0x20000000U) +#define AIPS_PACRB_WP0_SHIFT (29U) +#define AIPS_PACRB_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP0_SHIFT)) & AIPS_PACRB_WP0_MASK) +#define AIPS_PACRB_SP0_MASK (0x40000000U) +#define AIPS_PACRB_SP0_SHIFT (30U) +#define AIPS_PACRB_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP0_SHIFT)) & AIPS_PACRB_SP0_MASK) + +/*! @name PACRC - Peripheral Access Control Register */ +#define AIPS_PACRC_TP7_MASK (0x1U) +#define AIPS_PACRC_TP7_SHIFT (0U) +#define AIPS_PACRC_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP7_SHIFT)) & AIPS_PACRC_TP7_MASK) +#define AIPS_PACRC_WP7_MASK (0x2U) +#define AIPS_PACRC_WP7_SHIFT (1U) +#define AIPS_PACRC_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP7_SHIFT)) & AIPS_PACRC_WP7_MASK) +#define AIPS_PACRC_SP7_MASK (0x4U) +#define AIPS_PACRC_SP7_SHIFT (2U) +#define AIPS_PACRC_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP7_SHIFT)) & AIPS_PACRC_SP7_MASK) +#define AIPS_PACRC_TP6_MASK (0x10U) +#define AIPS_PACRC_TP6_SHIFT (4U) +#define AIPS_PACRC_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP6_SHIFT)) & AIPS_PACRC_TP6_MASK) +#define AIPS_PACRC_WP6_MASK (0x20U) +#define AIPS_PACRC_WP6_SHIFT (5U) +#define AIPS_PACRC_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP6_SHIFT)) & AIPS_PACRC_WP6_MASK) +#define AIPS_PACRC_SP6_MASK (0x40U) +#define AIPS_PACRC_SP6_SHIFT (6U) +#define AIPS_PACRC_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP6_SHIFT)) & AIPS_PACRC_SP6_MASK) +#define AIPS_PACRC_TP5_MASK (0x100U) +#define AIPS_PACRC_TP5_SHIFT (8U) +#define AIPS_PACRC_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP5_SHIFT)) & AIPS_PACRC_TP5_MASK) +#define AIPS_PACRC_WP5_MASK (0x200U) +#define AIPS_PACRC_WP5_SHIFT (9U) +#define AIPS_PACRC_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP5_SHIFT)) & AIPS_PACRC_WP5_MASK) +#define AIPS_PACRC_SP5_MASK (0x400U) +#define AIPS_PACRC_SP5_SHIFT (10U) +#define AIPS_PACRC_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP5_SHIFT)) & AIPS_PACRC_SP5_MASK) +#define AIPS_PACRC_TP4_MASK (0x1000U) +#define AIPS_PACRC_TP4_SHIFT (12U) +#define AIPS_PACRC_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP4_SHIFT)) & AIPS_PACRC_TP4_MASK) +#define AIPS_PACRC_WP4_MASK (0x2000U) +#define AIPS_PACRC_WP4_SHIFT (13U) +#define AIPS_PACRC_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP4_SHIFT)) & AIPS_PACRC_WP4_MASK) +#define AIPS_PACRC_SP4_MASK (0x4000U) +#define AIPS_PACRC_SP4_SHIFT (14U) +#define AIPS_PACRC_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP4_SHIFT)) & AIPS_PACRC_SP4_MASK) +#define AIPS_PACRC_TP3_MASK (0x10000U) +#define AIPS_PACRC_TP3_SHIFT (16U) +#define AIPS_PACRC_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP3_SHIFT)) & AIPS_PACRC_TP3_MASK) +#define AIPS_PACRC_WP3_MASK (0x20000U) +#define AIPS_PACRC_WP3_SHIFT (17U) +#define AIPS_PACRC_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP3_SHIFT)) & AIPS_PACRC_WP3_MASK) +#define AIPS_PACRC_SP3_MASK (0x40000U) +#define AIPS_PACRC_SP3_SHIFT (18U) +#define AIPS_PACRC_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP3_SHIFT)) & AIPS_PACRC_SP3_MASK) +#define AIPS_PACRC_TP2_MASK (0x100000U) +#define AIPS_PACRC_TP2_SHIFT (20U) +#define AIPS_PACRC_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP2_SHIFT)) & AIPS_PACRC_TP2_MASK) +#define AIPS_PACRC_WP2_MASK (0x200000U) +#define AIPS_PACRC_WP2_SHIFT (21U) +#define AIPS_PACRC_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP2_SHIFT)) & AIPS_PACRC_WP2_MASK) +#define AIPS_PACRC_SP2_MASK (0x400000U) +#define AIPS_PACRC_SP2_SHIFT (22U) +#define AIPS_PACRC_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP2_SHIFT)) & AIPS_PACRC_SP2_MASK) +#define AIPS_PACRC_TP1_MASK (0x1000000U) +#define AIPS_PACRC_TP1_SHIFT (24U) +#define AIPS_PACRC_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP1_SHIFT)) & AIPS_PACRC_TP1_MASK) +#define AIPS_PACRC_WP1_MASK (0x2000000U) +#define AIPS_PACRC_WP1_SHIFT (25U) +#define AIPS_PACRC_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP1_SHIFT)) & AIPS_PACRC_WP1_MASK) +#define AIPS_PACRC_SP1_MASK (0x4000000U) +#define AIPS_PACRC_SP1_SHIFT (26U) +#define AIPS_PACRC_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP1_SHIFT)) & AIPS_PACRC_SP1_MASK) +#define AIPS_PACRC_TP0_MASK (0x10000000U) +#define AIPS_PACRC_TP0_SHIFT (28U) +#define AIPS_PACRC_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP0_SHIFT)) & AIPS_PACRC_TP0_MASK) +#define AIPS_PACRC_WP0_MASK (0x20000000U) +#define AIPS_PACRC_WP0_SHIFT (29U) +#define AIPS_PACRC_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP0_SHIFT)) & AIPS_PACRC_WP0_MASK) +#define AIPS_PACRC_SP0_MASK (0x40000000U) +#define AIPS_PACRC_SP0_SHIFT (30U) +#define AIPS_PACRC_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP0_SHIFT)) & AIPS_PACRC_SP0_MASK) + +/*! @name PACRD - Peripheral Access Control Register */ +#define AIPS_PACRD_TP7_MASK (0x1U) +#define AIPS_PACRD_TP7_SHIFT (0U) +#define AIPS_PACRD_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP7_SHIFT)) & AIPS_PACRD_TP7_MASK) +#define AIPS_PACRD_WP7_MASK (0x2U) +#define AIPS_PACRD_WP7_SHIFT (1U) +#define AIPS_PACRD_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP7_SHIFT)) & AIPS_PACRD_WP7_MASK) +#define AIPS_PACRD_SP7_MASK (0x4U) +#define AIPS_PACRD_SP7_SHIFT (2U) +#define AIPS_PACRD_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP7_SHIFT)) & AIPS_PACRD_SP7_MASK) +#define AIPS_PACRD_TP6_MASK (0x10U) +#define AIPS_PACRD_TP6_SHIFT (4U) +#define AIPS_PACRD_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP6_SHIFT)) & AIPS_PACRD_TP6_MASK) +#define AIPS_PACRD_WP6_MASK (0x20U) +#define AIPS_PACRD_WP6_SHIFT (5U) +#define AIPS_PACRD_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP6_SHIFT)) & AIPS_PACRD_WP6_MASK) +#define AIPS_PACRD_SP6_MASK (0x40U) +#define AIPS_PACRD_SP6_SHIFT (6U) +#define AIPS_PACRD_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP6_SHIFT)) & AIPS_PACRD_SP6_MASK) +#define AIPS_PACRD_TP5_MASK (0x100U) +#define AIPS_PACRD_TP5_SHIFT (8U) +#define AIPS_PACRD_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP5_SHIFT)) & AIPS_PACRD_TP5_MASK) +#define AIPS_PACRD_WP5_MASK (0x200U) +#define AIPS_PACRD_WP5_SHIFT (9U) +#define AIPS_PACRD_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP5_SHIFT)) & AIPS_PACRD_WP5_MASK) +#define AIPS_PACRD_SP5_MASK (0x400U) +#define AIPS_PACRD_SP5_SHIFT (10U) +#define AIPS_PACRD_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP5_SHIFT)) & AIPS_PACRD_SP5_MASK) +#define AIPS_PACRD_TP4_MASK (0x1000U) +#define AIPS_PACRD_TP4_SHIFT (12U) +#define AIPS_PACRD_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP4_SHIFT)) & AIPS_PACRD_TP4_MASK) +#define AIPS_PACRD_WP4_MASK (0x2000U) +#define AIPS_PACRD_WP4_SHIFT (13U) +#define AIPS_PACRD_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP4_SHIFT)) & AIPS_PACRD_WP4_MASK) +#define AIPS_PACRD_SP4_MASK (0x4000U) +#define AIPS_PACRD_SP4_SHIFT (14U) +#define AIPS_PACRD_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP4_SHIFT)) & AIPS_PACRD_SP4_MASK) +#define AIPS_PACRD_TP3_MASK (0x10000U) +#define AIPS_PACRD_TP3_SHIFT (16U) +#define AIPS_PACRD_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP3_SHIFT)) & AIPS_PACRD_TP3_MASK) +#define AIPS_PACRD_WP3_MASK (0x20000U) +#define AIPS_PACRD_WP3_SHIFT (17U) +#define AIPS_PACRD_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP3_SHIFT)) & AIPS_PACRD_WP3_MASK) +#define AIPS_PACRD_SP3_MASK (0x40000U) +#define AIPS_PACRD_SP3_SHIFT (18U) +#define AIPS_PACRD_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP3_SHIFT)) & AIPS_PACRD_SP3_MASK) +#define AIPS_PACRD_TP2_MASK (0x100000U) +#define AIPS_PACRD_TP2_SHIFT (20U) +#define AIPS_PACRD_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP2_SHIFT)) & AIPS_PACRD_TP2_MASK) +#define AIPS_PACRD_WP2_MASK (0x200000U) +#define AIPS_PACRD_WP2_SHIFT (21U) +#define AIPS_PACRD_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP2_SHIFT)) & AIPS_PACRD_WP2_MASK) +#define AIPS_PACRD_SP2_MASK (0x400000U) +#define AIPS_PACRD_SP2_SHIFT (22U) +#define AIPS_PACRD_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP2_SHIFT)) & AIPS_PACRD_SP2_MASK) +#define AIPS_PACRD_TP1_MASK (0x1000000U) +#define AIPS_PACRD_TP1_SHIFT (24U) +#define AIPS_PACRD_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP1_SHIFT)) & AIPS_PACRD_TP1_MASK) +#define AIPS_PACRD_WP1_MASK (0x2000000U) +#define AIPS_PACRD_WP1_SHIFT (25U) +#define AIPS_PACRD_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP1_SHIFT)) & AIPS_PACRD_WP1_MASK) +#define AIPS_PACRD_SP1_MASK (0x4000000U) +#define AIPS_PACRD_SP1_SHIFT (26U) +#define AIPS_PACRD_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP1_SHIFT)) & AIPS_PACRD_SP1_MASK) +#define AIPS_PACRD_TP0_MASK (0x10000000U) +#define AIPS_PACRD_TP0_SHIFT (28U) +#define AIPS_PACRD_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP0_SHIFT)) & AIPS_PACRD_TP0_MASK) +#define AIPS_PACRD_WP0_MASK (0x20000000U) +#define AIPS_PACRD_WP0_SHIFT (29U) +#define AIPS_PACRD_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP0_SHIFT)) & AIPS_PACRD_WP0_MASK) +#define AIPS_PACRD_SP0_MASK (0x40000000U) +#define AIPS_PACRD_SP0_SHIFT (30U) +#define AIPS_PACRD_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP0_SHIFT)) & AIPS_PACRD_SP0_MASK) + +/*! @name PACRE - Peripheral Access Control Register */ +#define AIPS_PACRE_TP7_MASK (0x1U) +#define AIPS_PACRE_TP7_SHIFT (0U) +#define AIPS_PACRE_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP7_SHIFT)) & AIPS_PACRE_TP7_MASK) +#define AIPS_PACRE_WP7_MASK (0x2U) +#define AIPS_PACRE_WP7_SHIFT (1U) +#define AIPS_PACRE_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP7_SHIFT)) & AIPS_PACRE_WP7_MASK) +#define AIPS_PACRE_SP7_MASK (0x4U) +#define AIPS_PACRE_SP7_SHIFT (2U) +#define AIPS_PACRE_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP7_SHIFT)) & AIPS_PACRE_SP7_MASK) +#define AIPS_PACRE_TP6_MASK (0x10U) +#define AIPS_PACRE_TP6_SHIFT (4U) +#define AIPS_PACRE_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP6_SHIFT)) & AIPS_PACRE_TP6_MASK) +#define AIPS_PACRE_WP6_MASK (0x20U) +#define AIPS_PACRE_WP6_SHIFT (5U) +#define AIPS_PACRE_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP6_SHIFT)) & AIPS_PACRE_WP6_MASK) +#define AIPS_PACRE_SP6_MASK (0x40U) +#define AIPS_PACRE_SP6_SHIFT (6U) +#define AIPS_PACRE_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP6_SHIFT)) & AIPS_PACRE_SP6_MASK) +#define AIPS_PACRE_TP5_MASK (0x100U) +#define AIPS_PACRE_TP5_SHIFT (8U) +#define AIPS_PACRE_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP5_SHIFT)) & AIPS_PACRE_TP5_MASK) +#define AIPS_PACRE_WP5_MASK (0x200U) +#define AIPS_PACRE_WP5_SHIFT (9U) +#define AIPS_PACRE_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP5_SHIFT)) & AIPS_PACRE_WP5_MASK) +#define AIPS_PACRE_SP5_MASK (0x400U) +#define AIPS_PACRE_SP5_SHIFT (10U) +#define AIPS_PACRE_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP5_SHIFT)) & AIPS_PACRE_SP5_MASK) +#define AIPS_PACRE_TP4_MASK (0x1000U) +#define AIPS_PACRE_TP4_SHIFT (12U) +#define AIPS_PACRE_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP4_SHIFT)) & AIPS_PACRE_TP4_MASK) +#define AIPS_PACRE_WP4_MASK (0x2000U) +#define AIPS_PACRE_WP4_SHIFT (13U) +#define AIPS_PACRE_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP4_SHIFT)) & AIPS_PACRE_WP4_MASK) +#define AIPS_PACRE_SP4_MASK (0x4000U) +#define AIPS_PACRE_SP4_SHIFT (14U) +#define AIPS_PACRE_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP4_SHIFT)) & AIPS_PACRE_SP4_MASK) +#define AIPS_PACRE_TP3_MASK (0x10000U) +#define AIPS_PACRE_TP3_SHIFT (16U) +#define AIPS_PACRE_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP3_SHIFT)) & AIPS_PACRE_TP3_MASK) +#define AIPS_PACRE_WP3_MASK (0x20000U) +#define AIPS_PACRE_WP3_SHIFT (17U) +#define AIPS_PACRE_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP3_SHIFT)) & AIPS_PACRE_WP3_MASK) +#define AIPS_PACRE_SP3_MASK (0x40000U) +#define AIPS_PACRE_SP3_SHIFT (18U) +#define AIPS_PACRE_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP3_SHIFT)) & AIPS_PACRE_SP3_MASK) +#define AIPS_PACRE_TP2_MASK (0x100000U) +#define AIPS_PACRE_TP2_SHIFT (20U) +#define AIPS_PACRE_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP2_SHIFT)) & AIPS_PACRE_TP2_MASK) +#define AIPS_PACRE_WP2_MASK (0x200000U) +#define AIPS_PACRE_WP2_SHIFT (21U) +#define AIPS_PACRE_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP2_SHIFT)) & AIPS_PACRE_WP2_MASK) +#define AIPS_PACRE_SP2_MASK (0x400000U) +#define AIPS_PACRE_SP2_SHIFT (22U) +#define AIPS_PACRE_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP2_SHIFT)) & AIPS_PACRE_SP2_MASK) +#define AIPS_PACRE_TP1_MASK (0x1000000U) +#define AIPS_PACRE_TP1_SHIFT (24U) +#define AIPS_PACRE_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP1_SHIFT)) & AIPS_PACRE_TP1_MASK) +#define AIPS_PACRE_WP1_MASK (0x2000000U) +#define AIPS_PACRE_WP1_SHIFT (25U) +#define AIPS_PACRE_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP1_SHIFT)) & AIPS_PACRE_WP1_MASK) +#define AIPS_PACRE_SP1_MASK (0x4000000U) +#define AIPS_PACRE_SP1_SHIFT (26U) +#define AIPS_PACRE_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP1_SHIFT)) & AIPS_PACRE_SP1_MASK) +#define AIPS_PACRE_TP0_MASK (0x10000000U) +#define AIPS_PACRE_TP0_SHIFT (28U) +#define AIPS_PACRE_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP0_SHIFT)) & AIPS_PACRE_TP0_MASK) +#define AIPS_PACRE_WP0_MASK (0x20000000U) +#define AIPS_PACRE_WP0_SHIFT (29U) +#define AIPS_PACRE_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP0_SHIFT)) & AIPS_PACRE_WP0_MASK) +#define AIPS_PACRE_SP0_MASK (0x40000000U) +#define AIPS_PACRE_SP0_SHIFT (30U) +#define AIPS_PACRE_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP0_SHIFT)) & AIPS_PACRE_SP0_MASK) + +/*! @name PACRF - Peripheral Access Control Register */ +#define AIPS_PACRF_TP7_MASK (0x1U) +#define AIPS_PACRF_TP7_SHIFT (0U) +#define AIPS_PACRF_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP7_SHIFT)) & AIPS_PACRF_TP7_MASK) +#define AIPS_PACRF_WP7_MASK (0x2U) +#define AIPS_PACRF_WP7_SHIFT (1U) +#define AIPS_PACRF_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP7_SHIFT)) & AIPS_PACRF_WP7_MASK) +#define AIPS_PACRF_SP7_MASK (0x4U) +#define AIPS_PACRF_SP7_SHIFT (2U) +#define AIPS_PACRF_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP7_SHIFT)) & AIPS_PACRF_SP7_MASK) +#define AIPS_PACRF_TP6_MASK (0x10U) +#define AIPS_PACRF_TP6_SHIFT (4U) +#define AIPS_PACRF_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP6_SHIFT)) & AIPS_PACRF_TP6_MASK) +#define AIPS_PACRF_WP6_MASK (0x20U) +#define AIPS_PACRF_WP6_SHIFT (5U) +#define AIPS_PACRF_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP6_SHIFT)) & AIPS_PACRF_WP6_MASK) +#define AIPS_PACRF_SP6_MASK (0x40U) +#define AIPS_PACRF_SP6_SHIFT (6U) +#define AIPS_PACRF_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP6_SHIFT)) & AIPS_PACRF_SP6_MASK) +#define AIPS_PACRF_TP5_MASK (0x100U) +#define AIPS_PACRF_TP5_SHIFT (8U) +#define AIPS_PACRF_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP5_SHIFT)) & AIPS_PACRF_TP5_MASK) +#define AIPS_PACRF_WP5_MASK (0x200U) +#define AIPS_PACRF_WP5_SHIFT (9U) +#define AIPS_PACRF_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP5_SHIFT)) & AIPS_PACRF_WP5_MASK) +#define AIPS_PACRF_SP5_MASK (0x400U) +#define AIPS_PACRF_SP5_SHIFT (10U) +#define AIPS_PACRF_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP5_SHIFT)) & AIPS_PACRF_SP5_MASK) +#define AIPS_PACRF_TP4_MASK (0x1000U) +#define AIPS_PACRF_TP4_SHIFT (12U) +#define AIPS_PACRF_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP4_SHIFT)) & AIPS_PACRF_TP4_MASK) +#define AIPS_PACRF_WP4_MASK (0x2000U) +#define AIPS_PACRF_WP4_SHIFT (13U) +#define AIPS_PACRF_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP4_SHIFT)) & AIPS_PACRF_WP4_MASK) +#define AIPS_PACRF_SP4_MASK (0x4000U) +#define AIPS_PACRF_SP4_SHIFT (14U) +#define AIPS_PACRF_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP4_SHIFT)) & AIPS_PACRF_SP4_MASK) +#define AIPS_PACRF_TP3_MASK (0x10000U) +#define AIPS_PACRF_TP3_SHIFT (16U) +#define AIPS_PACRF_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP3_SHIFT)) & AIPS_PACRF_TP3_MASK) +#define AIPS_PACRF_WP3_MASK (0x20000U) +#define AIPS_PACRF_WP3_SHIFT (17U) +#define AIPS_PACRF_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP3_SHIFT)) & AIPS_PACRF_WP3_MASK) +#define AIPS_PACRF_SP3_MASK (0x40000U) +#define AIPS_PACRF_SP3_SHIFT (18U) +#define AIPS_PACRF_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP3_SHIFT)) & AIPS_PACRF_SP3_MASK) +#define AIPS_PACRF_TP2_MASK (0x100000U) +#define AIPS_PACRF_TP2_SHIFT (20U) +#define AIPS_PACRF_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP2_SHIFT)) & AIPS_PACRF_TP2_MASK) +#define AIPS_PACRF_WP2_MASK (0x200000U) +#define AIPS_PACRF_WP2_SHIFT (21U) +#define AIPS_PACRF_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP2_SHIFT)) & AIPS_PACRF_WP2_MASK) +#define AIPS_PACRF_SP2_MASK (0x400000U) +#define AIPS_PACRF_SP2_SHIFT (22U) +#define AIPS_PACRF_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP2_SHIFT)) & AIPS_PACRF_SP2_MASK) +#define AIPS_PACRF_TP1_MASK (0x1000000U) +#define AIPS_PACRF_TP1_SHIFT (24U) +#define AIPS_PACRF_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP1_SHIFT)) & AIPS_PACRF_TP1_MASK) +#define AIPS_PACRF_WP1_MASK (0x2000000U) +#define AIPS_PACRF_WP1_SHIFT (25U) +#define AIPS_PACRF_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP1_SHIFT)) & AIPS_PACRF_WP1_MASK) +#define AIPS_PACRF_SP1_MASK (0x4000000U) +#define AIPS_PACRF_SP1_SHIFT (26U) +#define AIPS_PACRF_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP1_SHIFT)) & AIPS_PACRF_SP1_MASK) +#define AIPS_PACRF_TP0_MASK (0x10000000U) +#define AIPS_PACRF_TP0_SHIFT (28U) +#define AIPS_PACRF_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP0_SHIFT)) & AIPS_PACRF_TP0_MASK) +#define AIPS_PACRF_WP0_MASK (0x20000000U) +#define AIPS_PACRF_WP0_SHIFT (29U) +#define AIPS_PACRF_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP0_SHIFT)) & AIPS_PACRF_WP0_MASK) +#define AIPS_PACRF_SP0_MASK (0x40000000U) +#define AIPS_PACRF_SP0_SHIFT (30U) +#define AIPS_PACRF_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP0_SHIFT)) & AIPS_PACRF_SP0_MASK) + +/*! @name PACRG - Peripheral Access Control Register */ +#define AIPS_PACRG_TP7_MASK (0x1U) +#define AIPS_PACRG_TP7_SHIFT (0U) +#define AIPS_PACRG_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP7_SHIFT)) & AIPS_PACRG_TP7_MASK) +#define AIPS_PACRG_WP7_MASK (0x2U) +#define AIPS_PACRG_WP7_SHIFT (1U) +#define AIPS_PACRG_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP7_SHIFT)) & AIPS_PACRG_WP7_MASK) +#define AIPS_PACRG_SP7_MASK (0x4U) +#define AIPS_PACRG_SP7_SHIFT (2U) +#define AIPS_PACRG_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP7_SHIFT)) & AIPS_PACRG_SP7_MASK) +#define AIPS_PACRG_TP6_MASK (0x10U) +#define AIPS_PACRG_TP6_SHIFT (4U) +#define AIPS_PACRG_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP6_SHIFT)) & AIPS_PACRG_TP6_MASK) +#define AIPS_PACRG_WP6_MASK (0x20U) +#define AIPS_PACRG_WP6_SHIFT (5U) +#define AIPS_PACRG_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP6_SHIFT)) & AIPS_PACRG_WP6_MASK) +#define AIPS_PACRG_SP6_MASK (0x40U) +#define AIPS_PACRG_SP6_SHIFT (6U) +#define AIPS_PACRG_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP6_SHIFT)) & AIPS_PACRG_SP6_MASK) +#define AIPS_PACRG_TP5_MASK (0x100U) +#define AIPS_PACRG_TP5_SHIFT (8U) +#define AIPS_PACRG_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP5_SHIFT)) & AIPS_PACRG_TP5_MASK) +#define AIPS_PACRG_WP5_MASK (0x200U) +#define AIPS_PACRG_WP5_SHIFT (9U) +#define AIPS_PACRG_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP5_SHIFT)) & AIPS_PACRG_WP5_MASK) +#define AIPS_PACRG_SP5_MASK (0x400U) +#define AIPS_PACRG_SP5_SHIFT (10U) +#define AIPS_PACRG_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP5_SHIFT)) & AIPS_PACRG_SP5_MASK) +#define AIPS_PACRG_TP4_MASK (0x1000U) +#define AIPS_PACRG_TP4_SHIFT (12U) +#define AIPS_PACRG_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP4_SHIFT)) & AIPS_PACRG_TP4_MASK) +#define AIPS_PACRG_WP4_MASK (0x2000U) +#define AIPS_PACRG_WP4_SHIFT (13U) +#define AIPS_PACRG_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP4_SHIFT)) & AIPS_PACRG_WP4_MASK) +#define AIPS_PACRG_SP4_MASK (0x4000U) +#define AIPS_PACRG_SP4_SHIFT (14U) +#define AIPS_PACRG_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP4_SHIFT)) & AIPS_PACRG_SP4_MASK) +#define AIPS_PACRG_TP3_MASK (0x10000U) +#define AIPS_PACRG_TP3_SHIFT (16U) +#define AIPS_PACRG_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP3_SHIFT)) & AIPS_PACRG_TP3_MASK) +#define AIPS_PACRG_WP3_MASK (0x20000U) +#define AIPS_PACRG_WP3_SHIFT (17U) +#define AIPS_PACRG_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP3_SHIFT)) & AIPS_PACRG_WP3_MASK) +#define AIPS_PACRG_SP3_MASK (0x40000U) +#define AIPS_PACRG_SP3_SHIFT (18U) +#define AIPS_PACRG_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP3_SHIFT)) & AIPS_PACRG_SP3_MASK) +#define AIPS_PACRG_TP2_MASK (0x100000U) +#define AIPS_PACRG_TP2_SHIFT (20U) +#define AIPS_PACRG_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP2_SHIFT)) & AIPS_PACRG_TP2_MASK) +#define AIPS_PACRG_WP2_MASK (0x200000U) +#define AIPS_PACRG_WP2_SHIFT (21U) +#define AIPS_PACRG_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP2_SHIFT)) & AIPS_PACRG_WP2_MASK) +#define AIPS_PACRG_SP2_MASK (0x400000U) +#define AIPS_PACRG_SP2_SHIFT (22U) +#define AIPS_PACRG_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP2_SHIFT)) & AIPS_PACRG_SP2_MASK) +#define AIPS_PACRG_TP1_MASK (0x1000000U) +#define AIPS_PACRG_TP1_SHIFT (24U) +#define AIPS_PACRG_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP1_SHIFT)) & AIPS_PACRG_TP1_MASK) +#define AIPS_PACRG_WP1_MASK (0x2000000U) +#define AIPS_PACRG_WP1_SHIFT (25U) +#define AIPS_PACRG_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP1_SHIFT)) & AIPS_PACRG_WP1_MASK) +#define AIPS_PACRG_SP1_MASK (0x4000000U) +#define AIPS_PACRG_SP1_SHIFT (26U) +#define AIPS_PACRG_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP1_SHIFT)) & AIPS_PACRG_SP1_MASK) +#define AIPS_PACRG_TP0_MASK (0x10000000U) +#define AIPS_PACRG_TP0_SHIFT (28U) +#define AIPS_PACRG_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP0_SHIFT)) & AIPS_PACRG_TP0_MASK) +#define AIPS_PACRG_WP0_MASK (0x20000000U) +#define AIPS_PACRG_WP0_SHIFT (29U) +#define AIPS_PACRG_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP0_SHIFT)) & AIPS_PACRG_WP0_MASK) +#define AIPS_PACRG_SP0_MASK (0x40000000U) +#define AIPS_PACRG_SP0_SHIFT (30U) +#define AIPS_PACRG_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP0_SHIFT)) & AIPS_PACRG_SP0_MASK) + +/*! @name PACRH - Peripheral Access Control Register */ +#define AIPS_PACRH_TP7_MASK (0x1U) +#define AIPS_PACRH_TP7_SHIFT (0U) +#define AIPS_PACRH_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP7_SHIFT)) & AIPS_PACRH_TP7_MASK) +#define AIPS_PACRH_WP7_MASK (0x2U) +#define AIPS_PACRH_WP7_SHIFT (1U) +#define AIPS_PACRH_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP7_SHIFT)) & AIPS_PACRH_WP7_MASK) +#define AIPS_PACRH_SP7_MASK (0x4U) +#define AIPS_PACRH_SP7_SHIFT (2U) +#define AIPS_PACRH_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP7_SHIFT)) & AIPS_PACRH_SP7_MASK) +#define AIPS_PACRH_TP6_MASK (0x10U) +#define AIPS_PACRH_TP6_SHIFT (4U) +#define AIPS_PACRH_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP6_SHIFT)) & AIPS_PACRH_TP6_MASK) +#define AIPS_PACRH_WP6_MASK (0x20U) +#define AIPS_PACRH_WP6_SHIFT (5U) +#define AIPS_PACRH_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP6_SHIFT)) & AIPS_PACRH_WP6_MASK) +#define AIPS_PACRH_SP6_MASK (0x40U) +#define AIPS_PACRH_SP6_SHIFT (6U) +#define AIPS_PACRH_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP6_SHIFT)) & AIPS_PACRH_SP6_MASK) +#define AIPS_PACRH_TP5_MASK (0x100U) +#define AIPS_PACRH_TP5_SHIFT (8U) +#define AIPS_PACRH_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP5_SHIFT)) & AIPS_PACRH_TP5_MASK) +#define AIPS_PACRH_WP5_MASK (0x200U) +#define AIPS_PACRH_WP5_SHIFT (9U) +#define AIPS_PACRH_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP5_SHIFT)) & AIPS_PACRH_WP5_MASK) +#define AIPS_PACRH_SP5_MASK (0x400U) +#define AIPS_PACRH_SP5_SHIFT (10U) +#define AIPS_PACRH_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP5_SHIFT)) & AIPS_PACRH_SP5_MASK) +#define AIPS_PACRH_TP4_MASK (0x1000U) +#define AIPS_PACRH_TP4_SHIFT (12U) +#define AIPS_PACRH_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP4_SHIFT)) & AIPS_PACRH_TP4_MASK) +#define AIPS_PACRH_WP4_MASK (0x2000U) +#define AIPS_PACRH_WP4_SHIFT (13U) +#define AIPS_PACRH_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP4_SHIFT)) & AIPS_PACRH_WP4_MASK) +#define AIPS_PACRH_SP4_MASK (0x4000U) +#define AIPS_PACRH_SP4_SHIFT (14U) +#define AIPS_PACRH_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP4_SHIFT)) & AIPS_PACRH_SP4_MASK) +#define AIPS_PACRH_TP3_MASK (0x10000U) +#define AIPS_PACRH_TP3_SHIFT (16U) +#define AIPS_PACRH_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP3_SHIFT)) & AIPS_PACRH_TP3_MASK) +#define AIPS_PACRH_WP3_MASK (0x20000U) +#define AIPS_PACRH_WP3_SHIFT (17U) +#define AIPS_PACRH_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP3_SHIFT)) & AIPS_PACRH_WP3_MASK) +#define AIPS_PACRH_SP3_MASK (0x40000U) +#define AIPS_PACRH_SP3_SHIFT (18U) +#define AIPS_PACRH_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP3_SHIFT)) & AIPS_PACRH_SP3_MASK) +#define AIPS_PACRH_TP2_MASK (0x100000U) +#define AIPS_PACRH_TP2_SHIFT (20U) +#define AIPS_PACRH_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP2_SHIFT)) & AIPS_PACRH_TP2_MASK) +#define AIPS_PACRH_WP2_MASK (0x200000U) +#define AIPS_PACRH_WP2_SHIFT (21U) +#define AIPS_PACRH_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP2_SHIFT)) & AIPS_PACRH_WP2_MASK) +#define AIPS_PACRH_SP2_MASK (0x400000U) +#define AIPS_PACRH_SP2_SHIFT (22U) +#define AIPS_PACRH_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP2_SHIFT)) & AIPS_PACRH_SP2_MASK) +#define AIPS_PACRH_TP1_MASK (0x1000000U) +#define AIPS_PACRH_TP1_SHIFT (24U) +#define AIPS_PACRH_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP1_SHIFT)) & AIPS_PACRH_TP1_MASK) +#define AIPS_PACRH_WP1_MASK (0x2000000U) +#define AIPS_PACRH_WP1_SHIFT (25U) +#define AIPS_PACRH_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP1_SHIFT)) & AIPS_PACRH_WP1_MASK) +#define AIPS_PACRH_SP1_MASK (0x4000000U) +#define AIPS_PACRH_SP1_SHIFT (26U) +#define AIPS_PACRH_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP1_SHIFT)) & AIPS_PACRH_SP1_MASK) +#define AIPS_PACRH_TP0_MASK (0x10000000U) +#define AIPS_PACRH_TP0_SHIFT (28U) +#define AIPS_PACRH_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP0_SHIFT)) & AIPS_PACRH_TP0_MASK) +#define AIPS_PACRH_WP0_MASK (0x20000000U) +#define AIPS_PACRH_WP0_SHIFT (29U) +#define AIPS_PACRH_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP0_SHIFT)) & AIPS_PACRH_WP0_MASK) +#define AIPS_PACRH_SP0_MASK (0x40000000U) +#define AIPS_PACRH_SP0_SHIFT (30U) +#define AIPS_PACRH_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP0_SHIFT)) & AIPS_PACRH_SP0_MASK) + +/*! @name PACRI - Peripheral Access Control Register */ +#define AIPS_PACRI_TP7_MASK (0x1U) +#define AIPS_PACRI_TP7_SHIFT (0U) +#define AIPS_PACRI_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP7_SHIFT)) & AIPS_PACRI_TP7_MASK) +#define AIPS_PACRI_WP7_MASK (0x2U) +#define AIPS_PACRI_WP7_SHIFT (1U) +#define AIPS_PACRI_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP7_SHIFT)) & AIPS_PACRI_WP7_MASK) +#define AIPS_PACRI_SP7_MASK (0x4U) +#define AIPS_PACRI_SP7_SHIFT (2U) +#define AIPS_PACRI_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP7_SHIFT)) & AIPS_PACRI_SP7_MASK) +#define AIPS_PACRI_TP6_MASK (0x10U) +#define AIPS_PACRI_TP6_SHIFT (4U) +#define AIPS_PACRI_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP6_SHIFT)) & AIPS_PACRI_TP6_MASK) +#define AIPS_PACRI_WP6_MASK (0x20U) +#define AIPS_PACRI_WP6_SHIFT (5U) +#define AIPS_PACRI_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP6_SHIFT)) & AIPS_PACRI_WP6_MASK) +#define AIPS_PACRI_SP6_MASK (0x40U) +#define AIPS_PACRI_SP6_SHIFT (6U) +#define AIPS_PACRI_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP6_SHIFT)) & AIPS_PACRI_SP6_MASK) +#define AIPS_PACRI_TP5_MASK (0x100U) +#define AIPS_PACRI_TP5_SHIFT (8U) +#define AIPS_PACRI_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP5_SHIFT)) & AIPS_PACRI_TP5_MASK) +#define AIPS_PACRI_WP5_MASK (0x200U) +#define AIPS_PACRI_WP5_SHIFT (9U) +#define AIPS_PACRI_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP5_SHIFT)) & AIPS_PACRI_WP5_MASK) +#define AIPS_PACRI_SP5_MASK (0x400U) +#define AIPS_PACRI_SP5_SHIFT (10U) +#define AIPS_PACRI_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP5_SHIFT)) & AIPS_PACRI_SP5_MASK) +#define AIPS_PACRI_TP4_MASK (0x1000U) +#define AIPS_PACRI_TP4_SHIFT (12U) +#define AIPS_PACRI_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP4_SHIFT)) & AIPS_PACRI_TP4_MASK) +#define AIPS_PACRI_WP4_MASK (0x2000U) +#define AIPS_PACRI_WP4_SHIFT (13U) +#define AIPS_PACRI_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP4_SHIFT)) & AIPS_PACRI_WP4_MASK) +#define AIPS_PACRI_SP4_MASK (0x4000U) +#define AIPS_PACRI_SP4_SHIFT (14U) +#define AIPS_PACRI_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP4_SHIFT)) & AIPS_PACRI_SP4_MASK) +#define AIPS_PACRI_TP3_MASK (0x10000U) +#define AIPS_PACRI_TP3_SHIFT (16U) +#define AIPS_PACRI_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP3_SHIFT)) & AIPS_PACRI_TP3_MASK) +#define AIPS_PACRI_WP3_MASK (0x20000U) +#define AIPS_PACRI_WP3_SHIFT (17U) +#define AIPS_PACRI_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP3_SHIFT)) & AIPS_PACRI_WP3_MASK) +#define AIPS_PACRI_SP3_MASK (0x40000U) +#define AIPS_PACRI_SP3_SHIFT (18U) +#define AIPS_PACRI_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP3_SHIFT)) & AIPS_PACRI_SP3_MASK) +#define AIPS_PACRI_TP2_MASK (0x100000U) +#define AIPS_PACRI_TP2_SHIFT (20U) +#define AIPS_PACRI_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP2_SHIFT)) & AIPS_PACRI_TP2_MASK) +#define AIPS_PACRI_WP2_MASK (0x200000U) +#define AIPS_PACRI_WP2_SHIFT (21U) +#define AIPS_PACRI_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP2_SHIFT)) & AIPS_PACRI_WP2_MASK) +#define AIPS_PACRI_SP2_MASK (0x400000U) +#define AIPS_PACRI_SP2_SHIFT (22U) +#define AIPS_PACRI_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP2_SHIFT)) & AIPS_PACRI_SP2_MASK) +#define AIPS_PACRI_TP1_MASK (0x1000000U) +#define AIPS_PACRI_TP1_SHIFT (24U) +#define AIPS_PACRI_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP1_SHIFT)) & AIPS_PACRI_TP1_MASK) +#define AIPS_PACRI_WP1_MASK (0x2000000U) +#define AIPS_PACRI_WP1_SHIFT (25U) +#define AIPS_PACRI_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP1_SHIFT)) & AIPS_PACRI_WP1_MASK) +#define AIPS_PACRI_SP1_MASK (0x4000000U) +#define AIPS_PACRI_SP1_SHIFT (26U) +#define AIPS_PACRI_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP1_SHIFT)) & AIPS_PACRI_SP1_MASK) +#define AIPS_PACRI_TP0_MASK (0x10000000U) +#define AIPS_PACRI_TP0_SHIFT (28U) +#define AIPS_PACRI_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP0_SHIFT)) & AIPS_PACRI_TP0_MASK) +#define AIPS_PACRI_WP0_MASK (0x20000000U) +#define AIPS_PACRI_WP0_SHIFT (29U) +#define AIPS_PACRI_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP0_SHIFT)) & AIPS_PACRI_WP0_MASK) +#define AIPS_PACRI_SP0_MASK (0x40000000U) +#define AIPS_PACRI_SP0_SHIFT (30U) +#define AIPS_PACRI_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP0_SHIFT)) & AIPS_PACRI_SP0_MASK) + +/*! @name PACRJ - Peripheral Access Control Register */ +#define AIPS_PACRJ_TP7_MASK (0x1U) +#define AIPS_PACRJ_TP7_SHIFT (0U) +#define AIPS_PACRJ_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP7_SHIFT)) & AIPS_PACRJ_TP7_MASK) +#define AIPS_PACRJ_WP7_MASK (0x2U) +#define AIPS_PACRJ_WP7_SHIFT (1U) +#define AIPS_PACRJ_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP7_SHIFT)) & AIPS_PACRJ_WP7_MASK) +#define AIPS_PACRJ_SP7_MASK (0x4U) +#define AIPS_PACRJ_SP7_SHIFT (2U) +#define AIPS_PACRJ_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP7_SHIFT)) & AIPS_PACRJ_SP7_MASK) +#define AIPS_PACRJ_TP6_MASK (0x10U) +#define AIPS_PACRJ_TP6_SHIFT (4U) +#define AIPS_PACRJ_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP6_SHIFT)) & AIPS_PACRJ_TP6_MASK) +#define AIPS_PACRJ_WP6_MASK (0x20U) +#define AIPS_PACRJ_WP6_SHIFT (5U) +#define AIPS_PACRJ_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP6_SHIFT)) & AIPS_PACRJ_WP6_MASK) +#define AIPS_PACRJ_SP6_MASK (0x40U) +#define AIPS_PACRJ_SP6_SHIFT (6U) +#define AIPS_PACRJ_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP6_SHIFT)) & AIPS_PACRJ_SP6_MASK) +#define AIPS_PACRJ_TP5_MASK (0x100U) +#define AIPS_PACRJ_TP5_SHIFT (8U) +#define AIPS_PACRJ_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP5_SHIFT)) & AIPS_PACRJ_TP5_MASK) +#define AIPS_PACRJ_WP5_MASK (0x200U) +#define AIPS_PACRJ_WP5_SHIFT (9U) +#define AIPS_PACRJ_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP5_SHIFT)) & AIPS_PACRJ_WP5_MASK) +#define AIPS_PACRJ_SP5_MASK (0x400U) +#define AIPS_PACRJ_SP5_SHIFT (10U) +#define AIPS_PACRJ_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP5_SHIFT)) & AIPS_PACRJ_SP5_MASK) +#define AIPS_PACRJ_TP4_MASK (0x1000U) +#define AIPS_PACRJ_TP4_SHIFT (12U) +#define AIPS_PACRJ_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP4_SHIFT)) & AIPS_PACRJ_TP4_MASK) +#define AIPS_PACRJ_WP4_MASK (0x2000U) +#define AIPS_PACRJ_WP4_SHIFT (13U) +#define AIPS_PACRJ_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP4_SHIFT)) & AIPS_PACRJ_WP4_MASK) +#define AIPS_PACRJ_SP4_MASK (0x4000U) +#define AIPS_PACRJ_SP4_SHIFT (14U) +#define AIPS_PACRJ_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP4_SHIFT)) & AIPS_PACRJ_SP4_MASK) +#define AIPS_PACRJ_TP3_MASK (0x10000U) +#define AIPS_PACRJ_TP3_SHIFT (16U) +#define AIPS_PACRJ_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP3_SHIFT)) & AIPS_PACRJ_TP3_MASK) +#define AIPS_PACRJ_WP3_MASK (0x20000U) +#define AIPS_PACRJ_WP3_SHIFT (17U) +#define AIPS_PACRJ_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP3_SHIFT)) & AIPS_PACRJ_WP3_MASK) +#define AIPS_PACRJ_SP3_MASK (0x40000U) +#define AIPS_PACRJ_SP3_SHIFT (18U) +#define AIPS_PACRJ_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP3_SHIFT)) & AIPS_PACRJ_SP3_MASK) +#define AIPS_PACRJ_TP2_MASK (0x100000U) +#define AIPS_PACRJ_TP2_SHIFT (20U) +#define AIPS_PACRJ_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP2_SHIFT)) & AIPS_PACRJ_TP2_MASK) +#define AIPS_PACRJ_WP2_MASK (0x200000U) +#define AIPS_PACRJ_WP2_SHIFT (21U) +#define AIPS_PACRJ_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP2_SHIFT)) & AIPS_PACRJ_WP2_MASK) +#define AIPS_PACRJ_SP2_MASK (0x400000U) +#define AIPS_PACRJ_SP2_SHIFT (22U) +#define AIPS_PACRJ_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP2_SHIFT)) & AIPS_PACRJ_SP2_MASK) +#define AIPS_PACRJ_TP1_MASK (0x1000000U) +#define AIPS_PACRJ_TP1_SHIFT (24U) +#define AIPS_PACRJ_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP1_SHIFT)) & AIPS_PACRJ_TP1_MASK) +#define AIPS_PACRJ_WP1_MASK (0x2000000U) +#define AIPS_PACRJ_WP1_SHIFT (25U) +#define AIPS_PACRJ_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP1_SHIFT)) & AIPS_PACRJ_WP1_MASK) +#define AIPS_PACRJ_SP1_MASK (0x4000000U) +#define AIPS_PACRJ_SP1_SHIFT (26U) +#define AIPS_PACRJ_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP1_SHIFT)) & AIPS_PACRJ_SP1_MASK) +#define AIPS_PACRJ_TP0_MASK (0x10000000U) +#define AIPS_PACRJ_TP0_SHIFT (28U) +#define AIPS_PACRJ_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP0_SHIFT)) & AIPS_PACRJ_TP0_MASK) +#define AIPS_PACRJ_WP0_MASK (0x20000000U) +#define AIPS_PACRJ_WP0_SHIFT (29U) +#define AIPS_PACRJ_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP0_SHIFT)) & AIPS_PACRJ_WP0_MASK) +#define AIPS_PACRJ_SP0_MASK (0x40000000U) +#define AIPS_PACRJ_SP0_SHIFT (30U) +#define AIPS_PACRJ_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP0_SHIFT)) & AIPS_PACRJ_SP0_MASK) + +/*! @name PACRK - Peripheral Access Control Register */ +#define AIPS_PACRK_TP7_MASK (0x1U) +#define AIPS_PACRK_TP7_SHIFT (0U) +#define AIPS_PACRK_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP7_SHIFT)) & AIPS_PACRK_TP7_MASK) +#define AIPS_PACRK_WP7_MASK (0x2U) +#define AIPS_PACRK_WP7_SHIFT (1U) +#define AIPS_PACRK_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP7_SHIFT)) & AIPS_PACRK_WP7_MASK) +#define AIPS_PACRK_SP7_MASK (0x4U) +#define AIPS_PACRK_SP7_SHIFT (2U) +#define AIPS_PACRK_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP7_SHIFT)) & AIPS_PACRK_SP7_MASK) +#define AIPS_PACRK_TP6_MASK (0x10U) +#define AIPS_PACRK_TP6_SHIFT (4U) +#define AIPS_PACRK_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP6_SHIFT)) & AIPS_PACRK_TP6_MASK) +#define AIPS_PACRK_WP6_MASK (0x20U) +#define AIPS_PACRK_WP6_SHIFT (5U) +#define AIPS_PACRK_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP6_SHIFT)) & AIPS_PACRK_WP6_MASK) +#define AIPS_PACRK_SP6_MASK (0x40U) +#define AIPS_PACRK_SP6_SHIFT (6U) +#define AIPS_PACRK_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP6_SHIFT)) & AIPS_PACRK_SP6_MASK) +#define AIPS_PACRK_TP5_MASK (0x100U) +#define AIPS_PACRK_TP5_SHIFT (8U) +#define AIPS_PACRK_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP5_SHIFT)) & AIPS_PACRK_TP5_MASK) +#define AIPS_PACRK_WP5_MASK (0x200U) +#define AIPS_PACRK_WP5_SHIFT (9U) +#define AIPS_PACRK_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP5_SHIFT)) & AIPS_PACRK_WP5_MASK) +#define AIPS_PACRK_SP5_MASK (0x400U) +#define AIPS_PACRK_SP5_SHIFT (10U) +#define AIPS_PACRK_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP5_SHIFT)) & AIPS_PACRK_SP5_MASK) +#define AIPS_PACRK_TP4_MASK (0x1000U) +#define AIPS_PACRK_TP4_SHIFT (12U) +#define AIPS_PACRK_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP4_SHIFT)) & AIPS_PACRK_TP4_MASK) +#define AIPS_PACRK_WP4_MASK (0x2000U) +#define AIPS_PACRK_WP4_SHIFT (13U) +#define AIPS_PACRK_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP4_SHIFT)) & AIPS_PACRK_WP4_MASK) +#define AIPS_PACRK_SP4_MASK (0x4000U) +#define AIPS_PACRK_SP4_SHIFT (14U) +#define AIPS_PACRK_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP4_SHIFT)) & AIPS_PACRK_SP4_MASK) +#define AIPS_PACRK_TP3_MASK (0x10000U) +#define AIPS_PACRK_TP3_SHIFT (16U) +#define AIPS_PACRK_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP3_SHIFT)) & AIPS_PACRK_TP3_MASK) +#define AIPS_PACRK_WP3_MASK (0x20000U) +#define AIPS_PACRK_WP3_SHIFT (17U) +#define AIPS_PACRK_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP3_SHIFT)) & AIPS_PACRK_WP3_MASK) +#define AIPS_PACRK_SP3_MASK (0x40000U) +#define AIPS_PACRK_SP3_SHIFT (18U) +#define AIPS_PACRK_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP3_SHIFT)) & AIPS_PACRK_SP3_MASK) +#define AIPS_PACRK_TP2_MASK (0x100000U) +#define AIPS_PACRK_TP2_SHIFT (20U) +#define AIPS_PACRK_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP2_SHIFT)) & AIPS_PACRK_TP2_MASK) +#define AIPS_PACRK_WP2_MASK (0x200000U) +#define AIPS_PACRK_WP2_SHIFT (21U) +#define AIPS_PACRK_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP2_SHIFT)) & AIPS_PACRK_WP2_MASK) +#define AIPS_PACRK_SP2_MASK (0x400000U) +#define AIPS_PACRK_SP2_SHIFT (22U) +#define AIPS_PACRK_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP2_SHIFT)) & AIPS_PACRK_SP2_MASK) +#define AIPS_PACRK_TP1_MASK (0x1000000U) +#define AIPS_PACRK_TP1_SHIFT (24U) +#define AIPS_PACRK_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP1_SHIFT)) & AIPS_PACRK_TP1_MASK) +#define AIPS_PACRK_WP1_MASK (0x2000000U) +#define AIPS_PACRK_WP1_SHIFT (25U) +#define AIPS_PACRK_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP1_SHIFT)) & AIPS_PACRK_WP1_MASK) +#define AIPS_PACRK_SP1_MASK (0x4000000U) +#define AIPS_PACRK_SP1_SHIFT (26U) +#define AIPS_PACRK_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP1_SHIFT)) & AIPS_PACRK_SP1_MASK) +#define AIPS_PACRK_TP0_MASK (0x10000000U) +#define AIPS_PACRK_TP0_SHIFT (28U) +#define AIPS_PACRK_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP0_SHIFT)) & AIPS_PACRK_TP0_MASK) +#define AIPS_PACRK_WP0_MASK (0x20000000U) +#define AIPS_PACRK_WP0_SHIFT (29U) +#define AIPS_PACRK_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP0_SHIFT)) & AIPS_PACRK_WP0_MASK) +#define AIPS_PACRK_SP0_MASK (0x40000000U) +#define AIPS_PACRK_SP0_SHIFT (30U) +#define AIPS_PACRK_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP0_SHIFT)) & AIPS_PACRK_SP0_MASK) + +/*! @name PACRL - Peripheral Access Control Register */ +#define AIPS_PACRL_TP7_MASK (0x1U) +#define AIPS_PACRL_TP7_SHIFT (0U) +#define AIPS_PACRL_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP7_SHIFT)) & AIPS_PACRL_TP7_MASK) +#define AIPS_PACRL_WP7_MASK (0x2U) +#define AIPS_PACRL_WP7_SHIFT (1U) +#define AIPS_PACRL_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP7_SHIFT)) & AIPS_PACRL_WP7_MASK) +#define AIPS_PACRL_SP7_MASK (0x4U) +#define AIPS_PACRL_SP7_SHIFT (2U) +#define AIPS_PACRL_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP7_SHIFT)) & AIPS_PACRL_SP7_MASK) +#define AIPS_PACRL_TP6_MASK (0x10U) +#define AIPS_PACRL_TP6_SHIFT (4U) +#define AIPS_PACRL_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP6_SHIFT)) & AIPS_PACRL_TP6_MASK) +#define AIPS_PACRL_WP6_MASK (0x20U) +#define AIPS_PACRL_WP6_SHIFT (5U) +#define AIPS_PACRL_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP6_SHIFT)) & AIPS_PACRL_WP6_MASK) +#define AIPS_PACRL_SP6_MASK (0x40U) +#define AIPS_PACRL_SP6_SHIFT (6U) +#define AIPS_PACRL_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP6_SHIFT)) & AIPS_PACRL_SP6_MASK) +#define AIPS_PACRL_TP5_MASK (0x100U) +#define AIPS_PACRL_TP5_SHIFT (8U) +#define AIPS_PACRL_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP5_SHIFT)) & AIPS_PACRL_TP5_MASK) +#define AIPS_PACRL_WP5_MASK (0x200U) +#define AIPS_PACRL_WP5_SHIFT (9U) +#define AIPS_PACRL_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP5_SHIFT)) & AIPS_PACRL_WP5_MASK) +#define AIPS_PACRL_SP5_MASK (0x400U) +#define AIPS_PACRL_SP5_SHIFT (10U) +#define AIPS_PACRL_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP5_SHIFT)) & AIPS_PACRL_SP5_MASK) +#define AIPS_PACRL_TP4_MASK (0x1000U) +#define AIPS_PACRL_TP4_SHIFT (12U) +#define AIPS_PACRL_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP4_SHIFT)) & AIPS_PACRL_TP4_MASK) +#define AIPS_PACRL_WP4_MASK (0x2000U) +#define AIPS_PACRL_WP4_SHIFT (13U) +#define AIPS_PACRL_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP4_SHIFT)) & AIPS_PACRL_WP4_MASK) +#define AIPS_PACRL_SP4_MASK (0x4000U) +#define AIPS_PACRL_SP4_SHIFT (14U) +#define AIPS_PACRL_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP4_SHIFT)) & AIPS_PACRL_SP4_MASK) +#define AIPS_PACRL_TP3_MASK (0x10000U) +#define AIPS_PACRL_TP3_SHIFT (16U) +#define AIPS_PACRL_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP3_SHIFT)) & AIPS_PACRL_TP3_MASK) +#define AIPS_PACRL_WP3_MASK (0x20000U) +#define AIPS_PACRL_WP3_SHIFT (17U) +#define AIPS_PACRL_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP3_SHIFT)) & AIPS_PACRL_WP3_MASK) +#define AIPS_PACRL_SP3_MASK (0x40000U) +#define AIPS_PACRL_SP3_SHIFT (18U) +#define AIPS_PACRL_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP3_SHIFT)) & AIPS_PACRL_SP3_MASK) +#define AIPS_PACRL_TP2_MASK (0x100000U) +#define AIPS_PACRL_TP2_SHIFT (20U) +#define AIPS_PACRL_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP2_SHIFT)) & AIPS_PACRL_TP2_MASK) +#define AIPS_PACRL_WP2_MASK (0x200000U) +#define AIPS_PACRL_WP2_SHIFT (21U) +#define AIPS_PACRL_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP2_SHIFT)) & AIPS_PACRL_WP2_MASK) +#define AIPS_PACRL_SP2_MASK (0x400000U) +#define AIPS_PACRL_SP2_SHIFT (22U) +#define AIPS_PACRL_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP2_SHIFT)) & AIPS_PACRL_SP2_MASK) +#define AIPS_PACRL_TP1_MASK (0x1000000U) +#define AIPS_PACRL_TP1_SHIFT (24U) +#define AIPS_PACRL_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP1_SHIFT)) & AIPS_PACRL_TP1_MASK) +#define AIPS_PACRL_WP1_MASK (0x2000000U) +#define AIPS_PACRL_WP1_SHIFT (25U) +#define AIPS_PACRL_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP1_SHIFT)) & AIPS_PACRL_WP1_MASK) +#define AIPS_PACRL_SP1_MASK (0x4000000U) +#define AIPS_PACRL_SP1_SHIFT (26U) +#define AIPS_PACRL_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP1_SHIFT)) & AIPS_PACRL_SP1_MASK) +#define AIPS_PACRL_TP0_MASK (0x10000000U) +#define AIPS_PACRL_TP0_SHIFT (28U) +#define AIPS_PACRL_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP0_SHIFT)) & AIPS_PACRL_TP0_MASK) +#define AIPS_PACRL_WP0_MASK (0x20000000U) +#define AIPS_PACRL_WP0_SHIFT (29U) +#define AIPS_PACRL_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP0_SHIFT)) & AIPS_PACRL_WP0_MASK) +#define AIPS_PACRL_SP0_MASK (0x40000000U) +#define AIPS_PACRL_SP0_SHIFT (30U) +#define AIPS_PACRL_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP0_SHIFT)) & AIPS_PACRL_SP0_MASK) + +/*! @name PACRM - Peripheral Access Control Register */ +#define AIPS_PACRM_TP7_MASK (0x1U) +#define AIPS_PACRM_TP7_SHIFT (0U) +#define AIPS_PACRM_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP7_SHIFT)) & AIPS_PACRM_TP7_MASK) +#define AIPS_PACRM_WP7_MASK (0x2U) +#define AIPS_PACRM_WP7_SHIFT (1U) +#define AIPS_PACRM_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP7_SHIFT)) & AIPS_PACRM_WP7_MASK) +#define AIPS_PACRM_SP7_MASK (0x4U) +#define AIPS_PACRM_SP7_SHIFT (2U) +#define AIPS_PACRM_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP7_SHIFT)) & AIPS_PACRM_SP7_MASK) +#define AIPS_PACRM_TP6_MASK (0x10U) +#define AIPS_PACRM_TP6_SHIFT (4U) +#define AIPS_PACRM_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP6_SHIFT)) & AIPS_PACRM_TP6_MASK) +#define AIPS_PACRM_WP6_MASK (0x20U) +#define AIPS_PACRM_WP6_SHIFT (5U) +#define AIPS_PACRM_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP6_SHIFT)) & AIPS_PACRM_WP6_MASK) +#define AIPS_PACRM_SP6_MASK (0x40U) +#define AIPS_PACRM_SP6_SHIFT (6U) +#define AIPS_PACRM_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP6_SHIFT)) & AIPS_PACRM_SP6_MASK) +#define AIPS_PACRM_TP5_MASK (0x100U) +#define AIPS_PACRM_TP5_SHIFT (8U) +#define AIPS_PACRM_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP5_SHIFT)) & AIPS_PACRM_TP5_MASK) +#define AIPS_PACRM_WP5_MASK (0x200U) +#define AIPS_PACRM_WP5_SHIFT (9U) +#define AIPS_PACRM_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP5_SHIFT)) & AIPS_PACRM_WP5_MASK) +#define AIPS_PACRM_SP5_MASK (0x400U) +#define AIPS_PACRM_SP5_SHIFT (10U) +#define AIPS_PACRM_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP5_SHIFT)) & AIPS_PACRM_SP5_MASK) +#define AIPS_PACRM_TP4_MASK (0x1000U) +#define AIPS_PACRM_TP4_SHIFT (12U) +#define AIPS_PACRM_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP4_SHIFT)) & AIPS_PACRM_TP4_MASK) +#define AIPS_PACRM_WP4_MASK (0x2000U) +#define AIPS_PACRM_WP4_SHIFT (13U) +#define AIPS_PACRM_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP4_SHIFT)) & AIPS_PACRM_WP4_MASK) +#define AIPS_PACRM_SP4_MASK (0x4000U) +#define AIPS_PACRM_SP4_SHIFT (14U) +#define AIPS_PACRM_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP4_SHIFT)) & AIPS_PACRM_SP4_MASK) +#define AIPS_PACRM_TP3_MASK (0x10000U) +#define AIPS_PACRM_TP3_SHIFT (16U) +#define AIPS_PACRM_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP3_SHIFT)) & AIPS_PACRM_TP3_MASK) +#define AIPS_PACRM_WP3_MASK (0x20000U) +#define AIPS_PACRM_WP3_SHIFT (17U) +#define AIPS_PACRM_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP3_SHIFT)) & AIPS_PACRM_WP3_MASK) +#define AIPS_PACRM_SP3_MASK (0x40000U) +#define AIPS_PACRM_SP3_SHIFT (18U) +#define AIPS_PACRM_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP3_SHIFT)) & AIPS_PACRM_SP3_MASK) +#define AIPS_PACRM_TP2_MASK (0x100000U) +#define AIPS_PACRM_TP2_SHIFT (20U) +#define AIPS_PACRM_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP2_SHIFT)) & AIPS_PACRM_TP2_MASK) +#define AIPS_PACRM_WP2_MASK (0x200000U) +#define AIPS_PACRM_WP2_SHIFT (21U) +#define AIPS_PACRM_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP2_SHIFT)) & AIPS_PACRM_WP2_MASK) +#define AIPS_PACRM_SP2_MASK (0x400000U) +#define AIPS_PACRM_SP2_SHIFT (22U) +#define AIPS_PACRM_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP2_SHIFT)) & AIPS_PACRM_SP2_MASK) +#define AIPS_PACRM_TP1_MASK (0x1000000U) +#define AIPS_PACRM_TP1_SHIFT (24U) +#define AIPS_PACRM_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP1_SHIFT)) & AIPS_PACRM_TP1_MASK) +#define AIPS_PACRM_WP1_MASK (0x2000000U) +#define AIPS_PACRM_WP1_SHIFT (25U) +#define AIPS_PACRM_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP1_SHIFT)) & AIPS_PACRM_WP1_MASK) +#define AIPS_PACRM_SP1_MASK (0x4000000U) +#define AIPS_PACRM_SP1_SHIFT (26U) +#define AIPS_PACRM_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP1_SHIFT)) & AIPS_PACRM_SP1_MASK) +#define AIPS_PACRM_TP0_MASK (0x10000000U) +#define AIPS_PACRM_TP0_SHIFT (28U) +#define AIPS_PACRM_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP0_SHIFT)) & AIPS_PACRM_TP0_MASK) +#define AIPS_PACRM_WP0_MASK (0x20000000U) +#define AIPS_PACRM_WP0_SHIFT (29U) +#define AIPS_PACRM_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP0_SHIFT)) & AIPS_PACRM_WP0_MASK) +#define AIPS_PACRM_SP0_MASK (0x40000000U) +#define AIPS_PACRM_SP0_SHIFT (30U) +#define AIPS_PACRM_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP0_SHIFT)) & AIPS_PACRM_SP0_MASK) + +/*! @name PACRN - Peripheral Access Control Register */ +#define AIPS_PACRN_TP7_MASK (0x1U) +#define AIPS_PACRN_TP7_SHIFT (0U) +#define AIPS_PACRN_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP7_SHIFT)) & AIPS_PACRN_TP7_MASK) +#define AIPS_PACRN_WP7_MASK (0x2U) +#define AIPS_PACRN_WP7_SHIFT (1U) +#define AIPS_PACRN_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP7_SHIFT)) & AIPS_PACRN_WP7_MASK) +#define AIPS_PACRN_SP7_MASK (0x4U) +#define AIPS_PACRN_SP7_SHIFT (2U) +#define AIPS_PACRN_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP7_SHIFT)) & AIPS_PACRN_SP7_MASK) +#define AIPS_PACRN_TP6_MASK (0x10U) +#define AIPS_PACRN_TP6_SHIFT (4U) +#define AIPS_PACRN_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP6_SHIFT)) & AIPS_PACRN_TP6_MASK) +#define AIPS_PACRN_WP6_MASK (0x20U) +#define AIPS_PACRN_WP6_SHIFT (5U) +#define AIPS_PACRN_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP6_SHIFT)) & AIPS_PACRN_WP6_MASK) +#define AIPS_PACRN_SP6_MASK (0x40U) +#define AIPS_PACRN_SP6_SHIFT (6U) +#define AIPS_PACRN_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP6_SHIFT)) & AIPS_PACRN_SP6_MASK) +#define AIPS_PACRN_TP5_MASK (0x100U) +#define AIPS_PACRN_TP5_SHIFT (8U) +#define AIPS_PACRN_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP5_SHIFT)) & AIPS_PACRN_TP5_MASK) +#define AIPS_PACRN_WP5_MASK (0x200U) +#define AIPS_PACRN_WP5_SHIFT (9U) +#define AIPS_PACRN_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP5_SHIFT)) & AIPS_PACRN_WP5_MASK) +#define AIPS_PACRN_SP5_MASK (0x400U) +#define AIPS_PACRN_SP5_SHIFT (10U) +#define AIPS_PACRN_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP5_SHIFT)) & AIPS_PACRN_SP5_MASK) +#define AIPS_PACRN_TP4_MASK (0x1000U) +#define AIPS_PACRN_TP4_SHIFT (12U) +#define AIPS_PACRN_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP4_SHIFT)) & AIPS_PACRN_TP4_MASK) +#define AIPS_PACRN_WP4_MASK (0x2000U) +#define AIPS_PACRN_WP4_SHIFT (13U) +#define AIPS_PACRN_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP4_SHIFT)) & AIPS_PACRN_WP4_MASK) +#define AIPS_PACRN_SP4_MASK (0x4000U) +#define AIPS_PACRN_SP4_SHIFT (14U) +#define AIPS_PACRN_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP4_SHIFT)) & AIPS_PACRN_SP4_MASK) +#define AIPS_PACRN_TP3_MASK (0x10000U) +#define AIPS_PACRN_TP3_SHIFT (16U) +#define AIPS_PACRN_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP3_SHIFT)) & AIPS_PACRN_TP3_MASK) +#define AIPS_PACRN_WP3_MASK (0x20000U) +#define AIPS_PACRN_WP3_SHIFT (17U) +#define AIPS_PACRN_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP3_SHIFT)) & AIPS_PACRN_WP3_MASK) +#define AIPS_PACRN_SP3_MASK (0x40000U) +#define AIPS_PACRN_SP3_SHIFT (18U) +#define AIPS_PACRN_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP3_SHIFT)) & AIPS_PACRN_SP3_MASK) +#define AIPS_PACRN_TP2_MASK (0x100000U) +#define AIPS_PACRN_TP2_SHIFT (20U) +#define AIPS_PACRN_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP2_SHIFT)) & AIPS_PACRN_TP2_MASK) +#define AIPS_PACRN_WP2_MASK (0x200000U) +#define AIPS_PACRN_WP2_SHIFT (21U) +#define AIPS_PACRN_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP2_SHIFT)) & AIPS_PACRN_WP2_MASK) +#define AIPS_PACRN_SP2_MASK (0x400000U) +#define AIPS_PACRN_SP2_SHIFT (22U) +#define AIPS_PACRN_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP2_SHIFT)) & AIPS_PACRN_SP2_MASK) +#define AIPS_PACRN_TP1_MASK (0x1000000U) +#define AIPS_PACRN_TP1_SHIFT (24U) +#define AIPS_PACRN_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP1_SHIFT)) & AIPS_PACRN_TP1_MASK) +#define AIPS_PACRN_WP1_MASK (0x2000000U) +#define AIPS_PACRN_WP1_SHIFT (25U) +#define AIPS_PACRN_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP1_SHIFT)) & AIPS_PACRN_WP1_MASK) +#define AIPS_PACRN_SP1_MASK (0x4000000U) +#define AIPS_PACRN_SP1_SHIFT (26U) +#define AIPS_PACRN_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP1_SHIFT)) & AIPS_PACRN_SP1_MASK) +#define AIPS_PACRN_TP0_MASK (0x10000000U) +#define AIPS_PACRN_TP0_SHIFT (28U) +#define AIPS_PACRN_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP0_SHIFT)) & AIPS_PACRN_TP0_MASK) +#define AIPS_PACRN_WP0_MASK (0x20000000U) +#define AIPS_PACRN_WP0_SHIFT (29U) +#define AIPS_PACRN_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP0_SHIFT)) & AIPS_PACRN_WP0_MASK) +#define AIPS_PACRN_SP0_MASK (0x40000000U) +#define AIPS_PACRN_SP0_SHIFT (30U) +#define AIPS_PACRN_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP0_SHIFT)) & AIPS_PACRN_SP0_MASK) + +/*! @name PACRO - Peripheral Access Control Register */ +#define AIPS_PACRO_TP7_MASK (0x1U) +#define AIPS_PACRO_TP7_SHIFT (0U) +#define AIPS_PACRO_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP7_SHIFT)) & AIPS_PACRO_TP7_MASK) +#define AIPS_PACRO_WP7_MASK (0x2U) +#define AIPS_PACRO_WP7_SHIFT (1U) +#define AIPS_PACRO_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP7_SHIFT)) & AIPS_PACRO_WP7_MASK) +#define AIPS_PACRO_SP7_MASK (0x4U) +#define AIPS_PACRO_SP7_SHIFT (2U) +#define AIPS_PACRO_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP7_SHIFT)) & AIPS_PACRO_SP7_MASK) +#define AIPS_PACRO_TP6_MASK (0x10U) +#define AIPS_PACRO_TP6_SHIFT (4U) +#define AIPS_PACRO_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP6_SHIFT)) & AIPS_PACRO_TP6_MASK) +#define AIPS_PACRO_WP6_MASK (0x20U) +#define AIPS_PACRO_WP6_SHIFT (5U) +#define AIPS_PACRO_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP6_SHIFT)) & AIPS_PACRO_WP6_MASK) +#define AIPS_PACRO_SP6_MASK (0x40U) +#define AIPS_PACRO_SP6_SHIFT (6U) +#define AIPS_PACRO_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP6_SHIFT)) & AIPS_PACRO_SP6_MASK) +#define AIPS_PACRO_TP5_MASK (0x100U) +#define AIPS_PACRO_TP5_SHIFT (8U) +#define AIPS_PACRO_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP5_SHIFT)) & AIPS_PACRO_TP5_MASK) +#define AIPS_PACRO_WP5_MASK (0x200U) +#define AIPS_PACRO_WP5_SHIFT (9U) +#define AIPS_PACRO_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP5_SHIFT)) & AIPS_PACRO_WP5_MASK) +#define AIPS_PACRO_SP5_MASK (0x400U) +#define AIPS_PACRO_SP5_SHIFT (10U) +#define AIPS_PACRO_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP5_SHIFT)) & AIPS_PACRO_SP5_MASK) +#define AIPS_PACRO_TP4_MASK (0x1000U) +#define AIPS_PACRO_TP4_SHIFT (12U) +#define AIPS_PACRO_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP4_SHIFT)) & AIPS_PACRO_TP4_MASK) +#define AIPS_PACRO_WP4_MASK (0x2000U) +#define AIPS_PACRO_WP4_SHIFT (13U) +#define AIPS_PACRO_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP4_SHIFT)) & AIPS_PACRO_WP4_MASK) +#define AIPS_PACRO_SP4_MASK (0x4000U) +#define AIPS_PACRO_SP4_SHIFT (14U) +#define AIPS_PACRO_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP4_SHIFT)) & AIPS_PACRO_SP4_MASK) +#define AIPS_PACRO_TP3_MASK (0x10000U) +#define AIPS_PACRO_TP3_SHIFT (16U) +#define AIPS_PACRO_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP3_SHIFT)) & AIPS_PACRO_TP3_MASK) +#define AIPS_PACRO_WP3_MASK (0x20000U) +#define AIPS_PACRO_WP3_SHIFT (17U) +#define AIPS_PACRO_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP3_SHIFT)) & AIPS_PACRO_WP3_MASK) +#define AIPS_PACRO_SP3_MASK (0x40000U) +#define AIPS_PACRO_SP3_SHIFT (18U) +#define AIPS_PACRO_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP3_SHIFT)) & AIPS_PACRO_SP3_MASK) +#define AIPS_PACRO_TP2_MASK (0x100000U) +#define AIPS_PACRO_TP2_SHIFT (20U) +#define AIPS_PACRO_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP2_SHIFT)) & AIPS_PACRO_TP2_MASK) +#define AIPS_PACRO_WP2_MASK (0x200000U) +#define AIPS_PACRO_WP2_SHIFT (21U) +#define AIPS_PACRO_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP2_SHIFT)) & AIPS_PACRO_WP2_MASK) +#define AIPS_PACRO_SP2_MASK (0x400000U) +#define AIPS_PACRO_SP2_SHIFT (22U) +#define AIPS_PACRO_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP2_SHIFT)) & AIPS_PACRO_SP2_MASK) +#define AIPS_PACRO_TP1_MASK (0x1000000U) +#define AIPS_PACRO_TP1_SHIFT (24U) +#define AIPS_PACRO_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP1_SHIFT)) & AIPS_PACRO_TP1_MASK) +#define AIPS_PACRO_WP1_MASK (0x2000000U) +#define AIPS_PACRO_WP1_SHIFT (25U) +#define AIPS_PACRO_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP1_SHIFT)) & AIPS_PACRO_WP1_MASK) +#define AIPS_PACRO_SP1_MASK (0x4000000U) +#define AIPS_PACRO_SP1_SHIFT (26U) +#define AIPS_PACRO_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP1_SHIFT)) & AIPS_PACRO_SP1_MASK) +#define AIPS_PACRO_TP0_MASK (0x10000000U) +#define AIPS_PACRO_TP0_SHIFT (28U) +#define AIPS_PACRO_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP0_SHIFT)) & AIPS_PACRO_TP0_MASK) +#define AIPS_PACRO_WP0_MASK (0x20000000U) +#define AIPS_PACRO_WP0_SHIFT (29U) +#define AIPS_PACRO_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP0_SHIFT)) & AIPS_PACRO_WP0_MASK) +#define AIPS_PACRO_SP0_MASK (0x40000000U) +#define AIPS_PACRO_SP0_SHIFT (30U) +#define AIPS_PACRO_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP0_SHIFT)) & AIPS_PACRO_SP0_MASK) + +/*! @name PACRP - Peripheral Access Control Register */ +#define AIPS_PACRP_TP7_MASK (0x1U) +#define AIPS_PACRP_TP7_SHIFT (0U) +#define AIPS_PACRP_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP7_SHIFT)) & AIPS_PACRP_TP7_MASK) +#define AIPS_PACRP_WP7_MASK (0x2U) +#define AIPS_PACRP_WP7_SHIFT (1U) +#define AIPS_PACRP_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP7_SHIFT)) & AIPS_PACRP_WP7_MASK) +#define AIPS_PACRP_SP7_MASK (0x4U) +#define AIPS_PACRP_SP7_SHIFT (2U) +#define AIPS_PACRP_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP7_SHIFT)) & AIPS_PACRP_SP7_MASK) +#define AIPS_PACRP_TP6_MASK (0x10U) +#define AIPS_PACRP_TP6_SHIFT (4U) +#define AIPS_PACRP_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP6_SHIFT)) & AIPS_PACRP_TP6_MASK) +#define AIPS_PACRP_WP6_MASK (0x20U) +#define AIPS_PACRP_WP6_SHIFT (5U) +#define AIPS_PACRP_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP6_SHIFT)) & AIPS_PACRP_WP6_MASK) +#define AIPS_PACRP_SP6_MASK (0x40U) +#define AIPS_PACRP_SP6_SHIFT (6U) +#define AIPS_PACRP_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP6_SHIFT)) & AIPS_PACRP_SP6_MASK) +#define AIPS_PACRP_TP5_MASK (0x100U) +#define AIPS_PACRP_TP5_SHIFT (8U) +#define AIPS_PACRP_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP5_SHIFT)) & AIPS_PACRP_TP5_MASK) +#define AIPS_PACRP_WP5_MASK (0x200U) +#define AIPS_PACRP_WP5_SHIFT (9U) +#define AIPS_PACRP_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP5_SHIFT)) & AIPS_PACRP_WP5_MASK) +#define AIPS_PACRP_SP5_MASK (0x400U) +#define AIPS_PACRP_SP5_SHIFT (10U) +#define AIPS_PACRP_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP5_SHIFT)) & AIPS_PACRP_SP5_MASK) +#define AIPS_PACRP_TP4_MASK (0x1000U) +#define AIPS_PACRP_TP4_SHIFT (12U) +#define AIPS_PACRP_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP4_SHIFT)) & AIPS_PACRP_TP4_MASK) +#define AIPS_PACRP_WP4_MASK (0x2000U) +#define AIPS_PACRP_WP4_SHIFT (13U) +#define AIPS_PACRP_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP4_SHIFT)) & AIPS_PACRP_WP4_MASK) +#define AIPS_PACRP_SP4_MASK (0x4000U) +#define AIPS_PACRP_SP4_SHIFT (14U) +#define AIPS_PACRP_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP4_SHIFT)) & AIPS_PACRP_SP4_MASK) +#define AIPS_PACRP_TP3_MASK (0x10000U) +#define AIPS_PACRP_TP3_SHIFT (16U) +#define AIPS_PACRP_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP3_SHIFT)) & AIPS_PACRP_TP3_MASK) +#define AIPS_PACRP_WP3_MASK (0x20000U) +#define AIPS_PACRP_WP3_SHIFT (17U) +#define AIPS_PACRP_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP3_SHIFT)) & AIPS_PACRP_WP3_MASK) +#define AIPS_PACRP_SP3_MASK (0x40000U) +#define AIPS_PACRP_SP3_SHIFT (18U) +#define AIPS_PACRP_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP3_SHIFT)) & AIPS_PACRP_SP3_MASK) +#define AIPS_PACRP_TP2_MASK (0x100000U) +#define AIPS_PACRP_TP2_SHIFT (20U) +#define AIPS_PACRP_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP2_SHIFT)) & AIPS_PACRP_TP2_MASK) +#define AIPS_PACRP_WP2_MASK (0x200000U) +#define AIPS_PACRP_WP2_SHIFT (21U) +#define AIPS_PACRP_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP2_SHIFT)) & AIPS_PACRP_WP2_MASK) +#define AIPS_PACRP_SP2_MASK (0x400000U) +#define AIPS_PACRP_SP2_SHIFT (22U) +#define AIPS_PACRP_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP2_SHIFT)) & AIPS_PACRP_SP2_MASK) +#define AIPS_PACRP_TP1_MASK (0x1000000U) +#define AIPS_PACRP_TP1_SHIFT (24U) +#define AIPS_PACRP_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP1_SHIFT)) & AIPS_PACRP_TP1_MASK) +#define AIPS_PACRP_WP1_MASK (0x2000000U) +#define AIPS_PACRP_WP1_SHIFT (25U) +#define AIPS_PACRP_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP1_SHIFT)) & AIPS_PACRP_WP1_MASK) +#define AIPS_PACRP_SP1_MASK (0x4000000U) +#define AIPS_PACRP_SP1_SHIFT (26U) +#define AIPS_PACRP_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP1_SHIFT)) & AIPS_PACRP_SP1_MASK) +#define AIPS_PACRP_TP0_MASK (0x10000000U) +#define AIPS_PACRP_TP0_SHIFT (28U) +#define AIPS_PACRP_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP0_SHIFT)) & AIPS_PACRP_TP0_MASK) +#define AIPS_PACRP_WP0_MASK (0x20000000U) +#define AIPS_PACRP_WP0_SHIFT (29U) +#define AIPS_PACRP_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP0_SHIFT)) & AIPS_PACRP_WP0_MASK) +#define AIPS_PACRP_SP0_MASK (0x40000000U) +#define AIPS_PACRP_SP0_SHIFT (30U) +#define AIPS_PACRP_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP0_SHIFT)) & AIPS_PACRP_SP0_MASK) + + +/*! + * @} + */ /* end of group AIPS_Register_Masks */ + + +/* AIPS - Peripheral instance base addresses */ +/** Peripheral AIPS0 base address */ +#define AIPS0_BASE (0x40000000u) +/** Peripheral AIPS0 base pointer */ +#define AIPS0 ((AIPS_Type *)AIPS0_BASE) +/** Peripheral AIPS1 base address */ +#define AIPS1_BASE (0x40080000u) +/** Peripheral AIPS1 base pointer */ +#define AIPS1 ((AIPS_Type *)AIPS1_BASE) +/** Array initializer of AIPS peripheral base addresses */ +#define AIPS_BASE_ADDRS { AIPS0_BASE, AIPS1_BASE } +/** Array initializer of AIPS peripheral base pointers */ +#define AIPS_BASE_PTRS { AIPS0, AIPS1 } + +/*! + * @} + */ /* end of group AIPS_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- AXBS Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup AXBS_Peripheral_Access_Layer AXBS Peripheral Access Layer + * @{ + */ + +/** AXBS - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0x100 */ + __IO uint32_t PRS; /**< Priority Registers Slave, array offset: 0x0, array step: 0x100 */ + uint8_t RESERVED_0[12]; + __IO uint32_t CRS; /**< Control Register, array offset: 0x10, array step: 0x100 */ + uint8_t RESERVED_1[236]; + } SLAVE[6]; + uint8_t RESERVED_0[512]; + __IO uint32_t MGPCR0; /**< Master General Purpose Control Register, offset: 0x800 */ + uint8_t RESERVED_1[252]; + __IO uint32_t MGPCR1; /**< Master General Purpose Control Register, offset: 0x900 */ + uint8_t RESERVED_2[252]; + __IO uint32_t MGPCR2; /**< Master General Purpose Control Register, offset: 0xA00 */ + uint8_t RESERVED_3[252]; + __IO uint32_t MGPCR3; /**< Master General Purpose Control Register, offset: 0xB00 */ + uint8_t RESERVED_4[252]; + __IO uint32_t MGPCR4; /**< Master General Purpose Control Register, offset: 0xC00 */ +} AXBS_Type; + +/* ---------------------------------------------------------------------------- + -- AXBS Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup AXBS_Register_Masks AXBS Register Masks + * @{ + */ + +/*! @name PRS - Priority Registers Slave */ +#define AXBS_PRS_M0_MASK (0x7U) +#define AXBS_PRS_M0_SHIFT (0U) +#define AXBS_PRS_M0(x) (((uint32_t)(((uint32_t)(x)) << AXBS_PRS_M0_SHIFT)) & AXBS_PRS_M0_MASK) +#define AXBS_PRS_M1_MASK (0x70U) +#define AXBS_PRS_M1_SHIFT (4U) +#define AXBS_PRS_M1(x) (((uint32_t)(((uint32_t)(x)) << AXBS_PRS_M1_SHIFT)) & AXBS_PRS_M1_MASK) +#define AXBS_PRS_M2_MASK (0x700U) +#define AXBS_PRS_M2_SHIFT (8U) +#define AXBS_PRS_M2(x) (((uint32_t)(((uint32_t)(x)) << AXBS_PRS_M2_SHIFT)) & AXBS_PRS_M2_MASK) +#define AXBS_PRS_M3_MASK (0x7000U) +#define AXBS_PRS_M3_SHIFT (12U) +#define AXBS_PRS_M3(x) (((uint32_t)(((uint32_t)(x)) << AXBS_PRS_M3_SHIFT)) & AXBS_PRS_M3_MASK) +#define AXBS_PRS_M4_MASK (0x70000U) +#define AXBS_PRS_M4_SHIFT (16U) +#define AXBS_PRS_M4(x) (((uint32_t)(((uint32_t)(x)) << AXBS_PRS_M4_SHIFT)) & AXBS_PRS_M4_MASK) + +/* The count of AXBS_PRS */ +#define AXBS_PRS_COUNT (6U) + +/*! @name CRS - Control Register */ +#define AXBS_CRS_PARK_MASK (0x7U) +#define AXBS_CRS_PARK_SHIFT (0U) +#define AXBS_CRS_PARK(x) (((uint32_t)(((uint32_t)(x)) << AXBS_CRS_PARK_SHIFT)) & AXBS_CRS_PARK_MASK) +#define AXBS_CRS_PCTL_MASK (0x30U) +#define AXBS_CRS_PCTL_SHIFT (4U) +#define AXBS_CRS_PCTL(x) (((uint32_t)(((uint32_t)(x)) << AXBS_CRS_PCTL_SHIFT)) & AXBS_CRS_PCTL_MASK) +#define AXBS_CRS_ARB_MASK (0x300U) +#define AXBS_CRS_ARB_SHIFT (8U) +#define AXBS_CRS_ARB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_CRS_ARB_SHIFT)) & AXBS_CRS_ARB_MASK) +#define AXBS_CRS_HLP_MASK (0x40000000U) +#define AXBS_CRS_HLP_SHIFT (30U) +#define AXBS_CRS_HLP(x) (((uint32_t)(((uint32_t)(x)) << AXBS_CRS_HLP_SHIFT)) & AXBS_CRS_HLP_MASK) +#define AXBS_CRS_RO_MASK (0x80000000U) +#define AXBS_CRS_RO_SHIFT (31U) +#define AXBS_CRS_RO(x) (((uint32_t)(((uint32_t)(x)) << AXBS_CRS_RO_SHIFT)) & AXBS_CRS_RO_MASK) + +/* The count of AXBS_CRS */ +#define AXBS_CRS_COUNT (6U) + +/*! @name MGPCR0 - Master General Purpose Control Register */ +#define AXBS_MGPCR0_AULB_MASK (0x7U) +#define AXBS_MGPCR0_AULB_SHIFT (0U) +#define AXBS_MGPCR0_AULB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_MGPCR0_AULB_SHIFT)) & AXBS_MGPCR0_AULB_MASK) + +/*! @name MGPCR1 - Master General Purpose Control Register */ +#define AXBS_MGPCR1_AULB_MASK (0x7U) +#define AXBS_MGPCR1_AULB_SHIFT (0U) +#define AXBS_MGPCR1_AULB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_MGPCR1_AULB_SHIFT)) & AXBS_MGPCR1_AULB_MASK) + +/*! @name MGPCR2 - Master General Purpose Control Register */ +#define AXBS_MGPCR2_AULB_MASK (0x7U) +#define AXBS_MGPCR2_AULB_SHIFT (0U) +#define AXBS_MGPCR2_AULB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_MGPCR2_AULB_SHIFT)) & AXBS_MGPCR2_AULB_MASK) + +/*! @name MGPCR3 - Master General Purpose Control Register */ +#define AXBS_MGPCR3_AULB_MASK (0x7U) +#define AXBS_MGPCR3_AULB_SHIFT (0U) +#define AXBS_MGPCR3_AULB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_MGPCR3_AULB_SHIFT)) & AXBS_MGPCR3_AULB_MASK) + +/*! @name MGPCR4 - Master General Purpose Control Register */ +#define AXBS_MGPCR4_AULB_MASK (0x7U) +#define AXBS_MGPCR4_AULB_SHIFT (0U) +#define AXBS_MGPCR4_AULB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_MGPCR4_AULB_SHIFT)) & AXBS_MGPCR4_AULB_MASK) + + +/*! + * @} + */ /* end of group AXBS_Register_Masks */ + + +/* AXBS - Peripheral instance base addresses */ +/** Peripheral AXBS base address */ +#define AXBS_BASE (0x40004000u) +/** Peripheral AXBS base pointer */ +#define AXBS ((AXBS_Type *)AXBS_BASE) +/** Array initializer of AXBS peripheral base addresses */ +#define AXBS_BASE_ADDRS { AXBS_BASE } +/** Array initializer of AXBS peripheral base pointers */ +#define AXBS_BASE_PTRS { AXBS } + +/*! + * @} + */ /* end of group AXBS_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CAU Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CAU_Peripheral_Access_Layer CAU Peripheral Access Layer + * @{ + */ + +/** CAU - Register Layout Typedef */ +typedef struct { + __O uint32_t DIRECT[16]; /**< Direct access register 0..Direct access register 15, array offset: 0x0, array step: 0x4 */ + uint8_t RESERVED_0[2048]; + __O uint32_t LDR_CASR; /**< Status register - Load Register command, offset: 0x840 */ + __O uint32_t LDR_CAA; /**< Accumulator register - Load Register command, offset: 0x844 */ + __O uint32_t LDR_CA[9]; /**< General Purpose Register 0 - Load Register command..General Purpose Register 8 - Load Register command, array offset: 0x848, array step: 0x4 */ + uint8_t RESERVED_1[20]; + __I uint32_t STR_CASR; /**< Status register - Store Register command, offset: 0x880 */ + __I uint32_t STR_CAA; /**< Accumulator register - Store Register command, offset: 0x884 */ + __I uint32_t STR_CA[9]; /**< General Purpose Register 0 - Store Register command..General Purpose Register 8 - Store Register command, array offset: 0x888, array step: 0x4 */ + uint8_t RESERVED_2[20]; + __O uint32_t ADR_CASR; /**< Status register - Add Register command, offset: 0x8C0 */ + __O uint32_t ADR_CAA; /**< Accumulator register - Add to register command, offset: 0x8C4 */ + __O uint32_t ADR_CA[9]; /**< General Purpose Register 0 - Add to register command..General Purpose Register 8 - Add to register command, array offset: 0x8C8, array step: 0x4 */ + uint8_t RESERVED_3[20]; + __O uint32_t RADR_CASR; /**< Status register - Reverse and Add to Register command, offset: 0x900 */ + __O uint32_t RADR_CAA; /**< Accumulator register - Reverse and Add to Register command, offset: 0x904 */ + __O uint32_t RADR_CA[9]; /**< General Purpose Register 0 - Reverse and Add to Register command..General Purpose Register 8 - Reverse and Add to Register command, array offset: 0x908, array step: 0x4 */ + uint8_t RESERVED_4[84]; + __O uint32_t XOR_CASR; /**< Status register - Exclusive Or command, offset: 0x980 */ + __O uint32_t XOR_CAA; /**< Accumulator register - Exclusive Or command, offset: 0x984 */ + __O uint32_t XOR_CA[9]; /**< General Purpose Register 0 - Exclusive Or command..General Purpose Register 8 - Exclusive Or command, array offset: 0x988, array step: 0x4 */ + uint8_t RESERVED_5[20]; + __O uint32_t ROTL_CASR; /**< Status register - Rotate Left command, offset: 0x9C0 */ + __O uint32_t ROTL_CAA; /**< Accumulator register - Rotate Left command, offset: 0x9C4 */ + __O uint32_t ROTL_CA[9]; /**< General Purpose Register 0 - Rotate Left command..General Purpose Register 8 - Rotate Left command, array offset: 0x9C8, array step: 0x4 */ + uint8_t RESERVED_6[276]; + __O uint32_t AESC_CASR; /**< Status register - AES Column Operation command, offset: 0xB00 */ + __O uint32_t AESC_CAA; /**< Accumulator register - AES Column Operation command, offset: 0xB04 */ + __O uint32_t AESC_CA[9]; /**< General Purpose Register 0 - AES Column Operation command..General Purpose Register 8 - AES Column Operation command, array offset: 0xB08, array step: 0x4 */ + uint8_t RESERVED_7[20]; + __O uint32_t AESIC_CASR; /**< Status register - AES Inverse Column Operation command, offset: 0xB40 */ + __O uint32_t AESIC_CAA; /**< Accumulator register - AES Inverse Column Operation command, offset: 0xB44 */ + __O uint32_t AESIC_CA[9]; /**< General Purpose Register 0 - AES Inverse Column Operation command..General Purpose Register 8 - AES Inverse Column Operation command, array offset: 0xB48, array step: 0x4 */ +} CAU_Type; + +/* ---------------------------------------------------------------------------- + -- CAU Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CAU_Register_Masks CAU Register Masks + * @{ + */ + +/*! @name DIRECT - Direct access register 0..Direct access register 15 */ +#define CAU_DIRECT_CAU_DIRECT0_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT0_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT0(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT0_SHIFT)) & CAU_DIRECT_CAU_DIRECT0_MASK) +#define CAU_DIRECT_CAU_DIRECT1_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT1_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT1(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT1_SHIFT)) & CAU_DIRECT_CAU_DIRECT1_MASK) +#define CAU_DIRECT_CAU_DIRECT2_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT2_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT2(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT2_SHIFT)) & CAU_DIRECT_CAU_DIRECT2_MASK) +#define CAU_DIRECT_CAU_DIRECT3_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT3_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT3(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT3_SHIFT)) & CAU_DIRECT_CAU_DIRECT3_MASK) +#define CAU_DIRECT_CAU_DIRECT4_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT4_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT4(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT4_SHIFT)) & CAU_DIRECT_CAU_DIRECT4_MASK) +#define CAU_DIRECT_CAU_DIRECT5_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT5_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT5(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT5_SHIFT)) & CAU_DIRECT_CAU_DIRECT5_MASK) +#define CAU_DIRECT_CAU_DIRECT6_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT6_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT6(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT6_SHIFT)) & CAU_DIRECT_CAU_DIRECT6_MASK) +#define CAU_DIRECT_CAU_DIRECT7_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT7_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT7(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT7_SHIFT)) & CAU_DIRECT_CAU_DIRECT7_MASK) +#define CAU_DIRECT_CAU_DIRECT8_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT8_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT8(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT8_SHIFT)) & CAU_DIRECT_CAU_DIRECT8_MASK) +#define CAU_DIRECT_CAU_DIRECT9_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT9_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT9(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT9_SHIFT)) & CAU_DIRECT_CAU_DIRECT9_MASK) +#define CAU_DIRECT_CAU_DIRECT10_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT10_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT10(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT10_SHIFT)) & CAU_DIRECT_CAU_DIRECT10_MASK) +#define CAU_DIRECT_CAU_DIRECT11_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT11_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT11(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT11_SHIFT)) & CAU_DIRECT_CAU_DIRECT11_MASK) +#define CAU_DIRECT_CAU_DIRECT12_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT12_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT12(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT12_SHIFT)) & CAU_DIRECT_CAU_DIRECT12_MASK) +#define CAU_DIRECT_CAU_DIRECT13_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT13_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT13(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT13_SHIFT)) & CAU_DIRECT_CAU_DIRECT13_MASK) +#define CAU_DIRECT_CAU_DIRECT14_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT14_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT14(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT14_SHIFT)) & CAU_DIRECT_CAU_DIRECT14_MASK) +#define CAU_DIRECT_CAU_DIRECT15_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT15_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT15(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT15_SHIFT)) & CAU_DIRECT_CAU_DIRECT15_MASK) + +/* The count of CAU_DIRECT */ +#define CAU_DIRECT_COUNT (16U) + +/*! @name LDR_CASR - Status register - Load Register command */ +#define CAU_LDR_CASR_IC_MASK (0x1U) +#define CAU_LDR_CASR_IC_SHIFT (0U) +#define CAU_LDR_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CASR_IC_SHIFT)) & CAU_LDR_CASR_IC_MASK) +#define CAU_LDR_CASR_DPE_MASK (0x2U) +#define CAU_LDR_CASR_DPE_SHIFT (1U) +#define CAU_LDR_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CASR_DPE_SHIFT)) & CAU_LDR_CASR_DPE_MASK) +#define CAU_LDR_CASR_VER_MASK (0xF0000000U) +#define CAU_LDR_CASR_VER_SHIFT (28U) +#define CAU_LDR_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CASR_VER_SHIFT)) & CAU_LDR_CASR_VER_MASK) + +/*! @name LDR_CAA - Accumulator register - Load Register command */ +#define CAU_LDR_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_LDR_CAA_ACC_SHIFT (0U) +#define CAU_LDR_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CAA_ACC_SHIFT)) & CAU_LDR_CAA_ACC_MASK) + +/*! @name LDR_CA - General Purpose Register 0 - Load Register command..General Purpose Register 8 - Load Register command */ +#define CAU_LDR_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA0_SHIFT (0U) +#define CAU_LDR_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA0_SHIFT)) & CAU_LDR_CA_CA0_MASK) +#define CAU_LDR_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA1_SHIFT (0U) +#define CAU_LDR_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA1_SHIFT)) & CAU_LDR_CA_CA1_MASK) +#define CAU_LDR_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA2_SHIFT (0U) +#define CAU_LDR_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA2_SHIFT)) & CAU_LDR_CA_CA2_MASK) +#define CAU_LDR_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA3_SHIFT (0U) +#define CAU_LDR_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA3_SHIFT)) & CAU_LDR_CA_CA3_MASK) +#define CAU_LDR_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA4_SHIFT (0U) +#define CAU_LDR_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA4_SHIFT)) & CAU_LDR_CA_CA4_MASK) +#define CAU_LDR_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA5_SHIFT (0U) +#define CAU_LDR_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA5_SHIFT)) & CAU_LDR_CA_CA5_MASK) +#define CAU_LDR_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA6_SHIFT (0U) +#define CAU_LDR_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA6_SHIFT)) & CAU_LDR_CA_CA6_MASK) +#define CAU_LDR_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA7_SHIFT (0U) +#define CAU_LDR_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA7_SHIFT)) & CAU_LDR_CA_CA7_MASK) +#define CAU_LDR_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA8_SHIFT (0U) +#define CAU_LDR_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA8_SHIFT)) & CAU_LDR_CA_CA8_MASK) + +/* The count of CAU_LDR_CA */ +#define CAU_LDR_CA_COUNT (9U) + +/*! @name STR_CASR - Status register - Store Register command */ +#define CAU_STR_CASR_IC_MASK (0x1U) +#define CAU_STR_CASR_IC_SHIFT (0U) +#define CAU_STR_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CASR_IC_SHIFT)) & CAU_STR_CASR_IC_MASK) +#define CAU_STR_CASR_DPE_MASK (0x2U) +#define CAU_STR_CASR_DPE_SHIFT (1U) +#define CAU_STR_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CASR_DPE_SHIFT)) & CAU_STR_CASR_DPE_MASK) +#define CAU_STR_CASR_VER_MASK (0xF0000000U) +#define CAU_STR_CASR_VER_SHIFT (28U) +#define CAU_STR_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CASR_VER_SHIFT)) & CAU_STR_CASR_VER_MASK) + +/*! @name STR_CAA - Accumulator register - Store Register command */ +#define CAU_STR_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_STR_CAA_ACC_SHIFT (0U) +#define CAU_STR_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CAA_ACC_SHIFT)) & CAU_STR_CAA_ACC_MASK) + +/*! @name STR_CA - General Purpose Register 0 - Store Register command..General Purpose Register 8 - Store Register command */ +#define CAU_STR_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA0_SHIFT (0U) +#define CAU_STR_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA0_SHIFT)) & CAU_STR_CA_CA0_MASK) +#define CAU_STR_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA1_SHIFT (0U) +#define CAU_STR_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA1_SHIFT)) & CAU_STR_CA_CA1_MASK) +#define CAU_STR_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA2_SHIFT (0U) +#define CAU_STR_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA2_SHIFT)) & CAU_STR_CA_CA2_MASK) +#define CAU_STR_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA3_SHIFT (0U) +#define CAU_STR_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA3_SHIFT)) & CAU_STR_CA_CA3_MASK) +#define CAU_STR_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA4_SHIFT (0U) +#define CAU_STR_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA4_SHIFT)) & CAU_STR_CA_CA4_MASK) +#define CAU_STR_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA5_SHIFT (0U) +#define CAU_STR_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA5_SHIFT)) & CAU_STR_CA_CA5_MASK) +#define CAU_STR_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA6_SHIFT (0U) +#define CAU_STR_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA6_SHIFT)) & CAU_STR_CA_CA6_MASK) +#define CAU_STR_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA7_SHIFT (0U) +#define CAU_STR_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA7_SHIFT)) & CAU_STR_CA_CA7_MASK) +#define CAU_STR_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA8_SHIFT (0U) +#define CAU_STR_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA8_SHIFT)) & CAU_STR_CA_CA8_MASK) + +/* The count of CAU_STR_CA */ +#define CAU_STR_CA_COUNT (9U) + +/*! @name ADR_CASR - Status register - Add Register command */ +#define CAU_ADR_CASR_IC_MASK (0x1U) +#define CAU_ADR_CASR_IC_SHIFT (0U) +#define CAU_ADR_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CASR_IC_SHIFT)) & CAU_ADR_CASR_IC_MASK) +#define CAU_ADR_CASR_DPE_MASK (0x2U) +#define CAU_ADR_CASR_DPE_SHIFT (1U) +#define CAU_ADR_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CASR_DPE_SHIFT)) & CAU_ADR_CASR_DPE_MASK) +#define CAU_ADR_CASR_VER_MASK (0xF0000000U) +#define CAU_ADR_CASR_VER_SHIFT (28U) +#define CAU_ADR_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CASR_VER_SHIFT)) & CAU_ADR_CASR_VER_MASK) + +/*! @name ADR_CAA - Accumulator register - Add to register command */ +#define CAU_ADR_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_ADR_CAA_ACC_SHIFT (0U) +#define CAU_ADR_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CAA_ACC_SHIFT)) & CAU_ADR_CAA_ACC_MASK) + +/*! @name ADR_CA - General Purpose Register 0 - Add to register command..General Purpose Register 8 - Add to register command */ +#define CAU_ADR_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA0_SHIFT (0U) +#define CAU_ADR_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA0_SHIFT)) & CAU_ADR_CA_CA0_MASK) +#define CAU_ADR_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA1_SHIFT (0U) +#define CAU_ADR_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA1_SHIFT)) & CAU_ADR_CA_CA1_MASK) +#define CAU_ADR_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA2_SHIFT (0U) +#define CAU_ADR_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA2_SHIFT)) & CAU_ADR_CA_CA2_MASK) +#define CAU_ADR_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA3_SHIFT (0U) +#define CAU_ADR_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA3_SHIFT)) & CAU_ADR_CA_CA3_MASK) +#define CAU_ADR_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA4_SHIFT (0U) +#define CAU_ADR_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA4_SHIFT)) & CAU_ADR_CA_CA4_MASK) +#define CAU_ADR_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA5_SHIFT (0U) +#define CAU_ADR_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA5_SHIFT)) & CAU_ADR_CA_CA5_MASK) +#define CAU_ADR_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA6_SHIFT (0U) +#define CAU_ADR_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA6_SHIFT)) & CAU_ADR_CA_CA6_MASK) +#define CAU_ADR_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA7_SHIFT (0U) +#define CAU_ADR_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA7_SHIFT)) & CAU_ADR_CA_CA7_MASK) +#define CAU_ADR_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA8_SHIFT (0U) +#define CAU_ADR_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA8_SHIFT)) & CAU_ADR_CA_CA8_MASK) + +/* The count of CAU_ADR_CA */ +#define CAU_ADR_CA_COUNT (9U) + +/*! @name RADR_CASR - Status register - Reverse and Add to Register command */ +#define CAU_RADR_CASR_IC_MASK (0x1U) +#define CAU_RADR_CASR_IC_SHIFT (0U) +#define CAU_RADR_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CASR_IC_SHIFT)) & CAU_RADR_CASR_IC_MASK) +#define CAU_RADR_CASR_DPE_MASK (0x2U) +#define CAU_RADR_CASR_DPE_SHIFT (1U) +#define CAU_RADR_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CASR_DPE_SHIFT)) & CAU_RADR_CASR_DPE_MASK) +#define CAU_RADR_CASR_VER_MASK (0xF0000000U) +#define CAU_RADR_CASR_VER_SHIFT (28U) +#define CAU_RADR_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CASR_VER_SHIFT)) & CAU_RADR_CASR_VER_MASK) + +/*! @name RADR_CAA - Accumulator register - Reverse and Add to Register command */ +#define CAU_RADR_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_RADR_CAA_ACC_SHIFT (0U) +#define CAU_RADR_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CAA_ACC_SHIFT)) & CAU_RADR_CAA_ACC_MASK) + +/*! @name RADR_CA - General Purpose Register 0 - Reverse and Add to Register command..General Purpose Register 8 - Reverse and Add to Register command */ +#define CAU_RADR_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA0_SHIFT (0U) +#define CAU_RADR_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA0_SHIFT)) & CAU_RADR_CA_CA0_MASK) +#define CAU_RADR_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA1_SHIFT (0U) +#define CAU_RADR_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA1_SHIFT)) & CAU_RADR_CA_CA1_MASK) +#define CAU_RADR_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA2_SHIFT (0U) +#define CAU_RADR_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA2_SHIFT)) & CAU_RADR_CA_CA2_MASK) +#define CAU_RADR_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA3_SHIFT (0U) +#define CAU_RADR_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA3_SHIFT)) & CAU_RADR_CA_CA3_MASK) +#define CAU_RADR_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA4_SHIFT (0U) +#define CAU_RADR_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA4_SHIFT)) & CAU_RADR_CA_CA4_MASK) +#define CAU_RADR_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA5_SHIFT (0U) +#define CAU_RADR_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA5_SHIFT)) & CAU_RADR_CA_CA5_MASK) +#define CAU_RADR_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA6_SHIFT (0U) +#define CAU_RADR_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA6_SHIFT)) & CAU_RADR_CA_CA6_MASK) +#define CAU_RADR_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA7_SHIFT (0U) +#define CAU_RADR_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA7_SHIFT)) & CAU_RADR_CA_CA7_MASK) +#define CAU_RADR_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA8_SHIFT (0U) +#define CAU_RADR_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA8_SHIFT)) & CAU_RADR_CA_CA8_MASK) + +/* The count of CAU_RADR_CA */ +#define CAU_RADR_CA_COUNT (9U) + +/*! @name XOR_CASR - Status register - Exclusive Or command */ +#define CAU_XOR_CASR_IC_MASK (0x1U) +#define CAU_XOR_CASR_IC_SHIFT (0U) +#define CAU_XOR_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CASR_IC_SHIFT)) & CAU_XOR_CASR_IC_MASK) +#define CAU_XOR_CASR_DPE_MASK (0x2U) +#define CAU_XOR_CASR_DPE_SHIFT (1U) +#define CAU_XOR_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CASR_DPE_SHIFT)) & CAU_XOR_CASR_DPE_MASK) +#define CAU_XOR_CASR_VER_MASK (0xF0000000U) +#define CAU_XOR_CASR_VER_SHIFT (28U) +#define CAU_XOR_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CASR_VER_SHIFT)) & CAU_XOR_CASR_VER_MASK) + +/*! @name XOR_CAA - Accumulator register - Exclusive Or command */ +#define CAU_XOR_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_XOR_CAA_ACC_SHIFT (0U) +#define CAU_XOR_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CAA_ACC_SHIFT)) & CAU_XOR_CAA_ACC_MASK) + +/*! @name XOR_CA - General Purpose Register 0 - Exclusive Or command..General Purpose Register 8 - Exclusive Or command */ +#define CAU_XOR_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA0_SHIFT (0U) +#define CAU_XOR_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA0_SHIFT)) & CAU_XOR_CA_CA0_MASK) +#define CAU_XOR_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA1_SHIFT (0U) +#define CAU_XOR_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA1_SHIFT)) & CAU_XOR_CA_CA1_MASK) +#define CAU_XOR_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA2_SHIFT (0U) +#define CAU_XOR_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA2_SHIFT)) & CAU_XOR_CA_CA2_MASK) +#define CAU_XOR_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA3_SHIFT (0U) +#define CAU_XOR_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA3_SHIFT)) & CAU_XOR_CA_CA3_MASK) +#define CAU_XOR_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA4_SHIFT (0U) +#define CAU_XOR_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA4_SHIFT)) & CAU_XOR_CA_CA4_MASK) +#define CAU_XOR_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA5_SHIFT (0U) +#define CAU_XOR_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA5_SHIFT)) & CAU_XOR_CA_CA5_MASK) +#define CAU_XOR_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA6_SHIFT (0U) +#define CAU_XOR_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA6_SHIFT)) & CAU_XOR_CA_CA6_MASK) +#define CAU_XOR_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA7_SHIFT (0U) +#define CAU_XOR_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA7_SHIFT)) & CAU_XOR_CA_CA7_MASK) +#define CAU_XOR_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA8_SHIFT (0U) +#define CAU_XOR_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA8_SHIFT)) & CAU_XOR_CA_CA8_MASK) + +/* The count of CAU_XOR_CA */ +#define CAU_XOR_CA_COUNT (9U) + +/*! @name ROTL_CASR - Status register - Rotate Left command */ +#define CAU_ROTL_CASR_IC_MASK (0x1U) +#define CAU_ROTL_CASR_IC_SHIFT (0U) +#define CAU_ROTL_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CASR_IC_SHIFT)) & CAU_ROTL_CASR_IC_MASK) +#define CAU_ROTL_CASR_DPE_MASK (0x2U) +#define CAU_ROTL_CASR_DPE_SHIFT (1U) +#define CAU_ROTL_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CASR_DPE_SHIFT)) & CAU_ROTL_CASR_DPE_MASK) +#define CAU_ROTL_CASR_VER_MASK (0xF0000000U) +#define CAU_ROTL_CASR_VER_SHIFT (28U) +#define CAU_ROTL_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CASR_VER_SHIFT)) & CAU_ROTL_CASR_VER_MASK) + +/*! @name ROTL_CAA - Accumulator register - Rotate Left command */ +#define CAU_ROTL_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CAA_ACC_SHIFT (0U) +#define CAU_ROTL_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CAA_ACC_SHIFT)) & CAU_ROTL_CAA_ACC_MASK) + +/*! @name ROTL_CA - General Purpose Register 0 - Rotate Left command..General Purpose Register 8 - Rotate Left command */ +#define CAU_ROTL_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA0_SHIFT (0U) +#define CAU_ROTL_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA0_SHIFT)) & CAU_ROTL_CA_CA0_MASK) +#define CAU_ROTL_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA1_SHIFT (0U) +#define CAU_ROTL_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA1_SHIFT)) & CAU_ROTL_CA_CA1_MASK) +#define CAU_ROTL_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA2_SHIFT (0U) +#define CAU_ROTL_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA2_SHIFT)) & CAU_ROTL_CA_CA2_MASK) +#define CAU_ROTL_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA3_SHIFT (0U) +#define CAU_ROTL_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA3_SHIFT)) & CAU_ROTL_CA_CA3_MASK) +#define CAU_ROTL_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA4_SHIFT (0U) +#define CAU_ROTL_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA4_SHIFT)) & CAU_ROTL_CA_CA4_MASK) +#define CAU_ROTL_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA5_SHIFT (0U) +#define CAU_ROTL_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA5_SHIFT)) & CAU_ROTL_CA_CA5_MASK) +#define CAU_ROTL_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA6_SHIFT (0U) +#define CAU_ROTL_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA6_SHIFT)) & CAU_ROTL_CA_CA6_MASK) +#define CAU_ROTL_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA7_SHIFT (0U) +#define CAU_ROTL_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA7_SHIFT)) & CAU_ROTL_CA_CA7_MASK) +#define CAU_ROTL_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA8_SHIFT (0U) +#define CAU_ROTL_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA8_SHIFT)) & CAU_ROTL_CA_CA8_MASK) + +/* The count of CAU_ROTL_CA */ +#define CAU_ROTL_CA_COUNT (9U) + +/*! @name AESC_CASR - Status register - AES Column Operation command */ +#define CAU_AESC_CASR_IC_MASK (0x1U) +#define CAU_AESC_CASR_IC_SHIFT (0U) +#define CAU_AESC_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CASR_IC_SHIFT)) & CAU_AESC_CASR_IC_MASK) +#define CAU_AESC_CASR_DPE_MASK (0x2U) +#define CAU_AESC_CASR_DPE_SHIFT (1U) +#define CAU_AESC_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CASR_DPE_SHIFT)) & CAU_AESC_CASR_DPE_MASK) +#define CAU_AESC_CASR_VER_MASK (0xF0000000U) +#define CAU_AESC_CASR_VER_SHIFT (28U) +#define CAU_AESC_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CASR_VER_SHIFT)) & CAU_AESC_CASR_VER_MASK) + +/*! @name AESC_CAA - Accumulator register - AES Column Operation command */ +#define CAU_AESC_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_AESC_CAA_ACC_SHIFT (0U) +#define CAU_AESC_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CAA_ACC_SHIFT)) & CAU_AESC_CAA_ACC_MASK) + +/*! @name AESC_CA - General Purpose Register 0 - AES Column Operation command..General Purpose Register 8 - AES Column Operation command */ +#define CAU_AESC_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA0_SHIFT (0U) +#define CAU_AESC_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA0_SHIFT)) & CAU_AESC_CA_CA0_MASK) +#define CAU_AESC_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA1_SHIFT (0U) +#define CAU_AESC_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA1_SHIFT)) & CAU_AESC_CA_CA1_MASK) +#define CAU_AESC_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA2_SHIFT (0U) +#define CAU_AESC_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA2_SHIFT)) & CAU_AESC_CA_CA2_MASK) +#define CAU_AESC_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA3_SHIFT (0U) +#define CAU_AESC_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA3_SHIFT)) & CAU_AESC_CA_CA3_MASK) +#define CAU_AESC_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA4_SHIFT (0U) +#define CAU_AESC_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA4_SHIFT)) & CAU_AESC_CA_CA4_MASK) +#define CAU_AESC_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA5_SHIFT (0U) +#define CAU_AESC_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA5_SHIFT)) & CAU_AESC_CA_CA5_MASK) +#define CAU_AESC_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA6_SHIFT (0U) +#define CAU_AESC_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA6_SHIFT)) & CAU_AESC_CA_CA6_MASK) +#define CAU_AESC_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA7_SHIFT (0U) +#define CAU_AESC_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA7_SHIFT)) & CAU_AESC_CA_CA7_MASK) +#define CAU_AESC_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA8_SHIFT (0U) +#define CAU_AESC_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA8_SHIFT)) & CAU_AESC_CA_CA8_MASK) + +/* The count of CAU_AESC_CA */ +#define CAU_AESC_CA_COUNT (9U) + +/*! @name AESIC_CASR - Status register - AES Inverse Column Operation command */ +#define CAU_AESIC_CASR_IC_MASK (0x1U) +#define CAU_AESIC_CASR_IC_SHIFT (0U) +#define CAU_AESIC_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CASR_IC_SHIFT)) & CAU_AESIC_CASR_IC_MASK) +#define CAU_AESIC_CASR_DPE_MASK (0x2U) +#define CAU_AESIC_CASR_DPE_SHIFT (1U) +#define CAU_AESIC_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CASR_DPE_SHIFT)) & CAU_AESIC_CASR_DPE_MASK) +#define CAU_AESIC_CASR_VER_MASK (0xF0000000U) +#define CAU_AESIC_CASR_VER_SHIFT (28U) +#define CAU_AESIC_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CASR_VER_SHIFT)) & CAU_AESIC_CASR_VER_MASK) + +/*! @name AESIC_CAA - Accumulator register - AES Inverse Column Operation command */ +#define CAU_AESIC_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CAA_ACC_SHIFT (0U) +#define CAU_AESIC_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CAA_ACC_SHIFT)) & CAU_AESIC_CAA_ACC_MASK) + +/*! @name AESIC_CA - General Purpose Register 0 - AES Inverse Column Operation command..General Purpose Register 8 - AES Inverse Column Operation command */ +#define CAU_AESIC_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA0_SHIFT (0U) +#define CAU_AESIC_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA0_SHIFT)) & CAU_AESIC_CA_CA0_MASK) +#define CAU_AESIC_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA1_SHIFT (0U) +#define CAU_AESIC_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA1_SHIFT)) & CAU_AESIC_CA_CA1_MASK) +#define CAU_AESIC_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA2_SHIFT (0U) +#define CAU_AESIC_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA2_SHIFT)) & CAU_AESIC_CA_CA2_MASK) +#define CAU_AESIC_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA3_SHIFT (0U) +#define CAU_AESIC_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA3_SHIFT)) & CAU_AESIC_CA_CA3_MASK) +#define CAU_AESIC_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA4_SHIFT (0U) +#define CAU_AESIC_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA4_SHIFT)) & CAU_AESIC_CA_CA4_MASK) +#define CAU_AESIC_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA5_SHIFT (0U) +#define CAU_AESIC_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA5_SHIFT)) & CAU_AESIC_CA_CA5_MASK) +#define CAU_AESIC_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA6_SHIFT (0U) +#define CAU_AESIC_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA6_SHIFT)) & CAU_AESIC_CA_CA6_MASK) +#define CAU_AESIC_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA7_SHIFT (0U) +#define CAU_AESIC_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA7_SHIFT)) & CAU_AESIC_CA_CA7_MASK) +#define CAU_AESIC_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA8_SHIFT (0U) +#define CAU_AESIC_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA8_SHIFT)) & CAU_AESIC_CA_CA8_MASK) + +/* The count of CAU_AESIC_CA */ +#define CAU_AESIC_CA_COUNT (9U) + + +/*! + * @} + */ /* end of group CAU_Register_Masks */ + + +/* CAU - Peripheral instance base addresses */ +/** Peripheral CAU base address */ +#define CAU_BASE (0xE0081000u) +/** Peripheral CAU base pointer */ +#define CAU ((CAU_Type *)CAU_BASE) +/** Array initializer of CAU peripheral base addresses */ +#define CAU_BASE_ADDRS { CAU_BASE } +/** Array initializer of CAU peripheral base pointers */ +#define CAU_BASE_PTRS { CAU } + +/*! + * @} + */ /* end of group CAU_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CMP Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CMP_Peripheral_Access_Layer CMP Peripheral Access Layer + * @{ + */ + +/** CMP - Register Layout Typedef */ +typedef struct { + __IO uint8_t CR0; /**< CMP Control Register 0, offset: 0x0 */ + __IO uint8_t CR1; /**< CMP Control Register 1, offset: 0x1 */ + __IO uint8_t FPR; /**< CMP Filter Period Register, offset: 0x2 */ + __IO uint8_t SCR; /**< CMP Status and Control Register, offset: 0x3 */ + __IO uint8_t DACCR; /**< DAC Control Register, offset: 0x4 */ + __IO uint8_t MUXCR; /**< MUX Control Register, offset: 0x5 */ +} CMP_Type; + +/* ---------------------------------------------------------------------------- + -- CMP Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CMP_Register_Masks CMP Register Masks + * @{ + */ + +/*! @name CR0 - CMP Control Register 0 */ +#define CMP_CR0_HYSTCTR_MASK (0x3U) +#define CMP_CR0_HYSTCTR_SHIFT (0U) +#define CMP_CR0_HYSTCTR(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR0_HYSTCTR_SHIFT)) & CMP_CR0_HYSTCTR_MASK) +#define CMP_CR0_FILTER_CNT_MASK (0x70U) +#define CMP_CR0_FILTER_CNT_SHIFT (4U) +#define CMP_CR0_FILTER_CNT(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR0_FILTER_CNT_SHIFT)) & CMP_CR0_FILTER_CNT_MASK) + +/*! @name CR1 - CMP Control Register 1 */ +#define CMP_CR1_EN_MASK (0x1U) +#define CMP_CR1_EN_SHIFT (0U) +#define CMP_CR1_EN(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_EN_SHIFT)) & CMP_CR1_EN_MASK) +#define CMP_CR1_OPE_MASK (0x2U) +#define CMP_CR1_OPE_SHIFT (1U) +#define CMP_CR1_OPE(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_OPE_SHIFT)) & CMP_CR1_OPE_MASK) +#define CMP_CR1_COS_MASK (0x4U) +#define CMP_CR1_COS_SHIFT (2U) +#define CMP_CR1_COS(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_COS_SHIFT)) & CMP_CR1_COS_MASK) +#define CMP_CR1_INV_MASK (0x8U) +#define CMP_CR1_INV_SHIFT (3U) +#define CMP_CR1_INV(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_INV_SHIFT)) & CMP_CR1_INV_MASK) +#define CMP_CR1_PMODE_MASK (0x10U) +#define CMP_CR1_PMODE_SHIFT (4U) +#define CMP_CR1_PMODE(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_PMODE_SHIFT)) & CMP_CR1_PMODE_MASK) +#define CMP_CR1_TRIGM_MASK (0x20U) +#define CMP_CR1_TRIGM_SHIFT (5U) +#define CMP_CR1_TRIGM(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_TRIGM_SHIFT)) & CMP_CR1_TRIGM_MASK) +#define CMP_CR1_WE_MASK (0x40U) +#define CMP_CR1_WE_SHIFT (6U) +#define CMP_CR1_WE(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_WE_SHIFT)) & CMP_CR1_WE_MASK) +#define CMP_CR1_SE_MASK (0x80U) +#define CMP_CR1_SE_SHIFT (7U) +#define CMP_CR1_SE(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_SE_SHIFT)) & CMP_CR1_SE_MASK) + +/*! @name FPR - CMP Filter Period Register */ +#define CMP_FPR_FILT_PER_MASK (0xFFU) +#define CMP_FPR_FILT_PER_SHIFT (0U) +#define CMP_FPR_FILT_PER(x) (((uint8_t)(((uint8_t)(x)) << CMP_FPR_FILT_PER_SHIFT)) & CMP_FPR_FILT_PER_MASK) + +/*! @name SCR - CMP Status and Control Register */ +#define CMP_SCR_COUT_MASK (0x1U) +#define CMP_SCR_COUT_SHIFT (0U) +#define CMP_SCR_COUT(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_COUT_SHIFT)) & CMP_SCR_COUT_MASK) +#define CMP_SCR_CFF_MASK (0x2U) +#define CMP_SCR_CFF_SHIFT (1U) +#define CMP_SCR_CFF(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_CFF_SHIFT)) & CMP_SCR_CFF_MASK) +#define CMP_SCR_CFR_MASK (0x4U) +#define CMP_SCR_CFR_SHIFT (2U) +#define CMP_SCR_CFR(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_CFR_SHIFT)) & CMP_SCR_CFR_MASK) +#define CMP_SCR_IEF_MASK (0x8U) +#define CMP_SCR_IEF_SHIFT (3U) +#define CMP_SCR_IEF(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_IEF_SHIFT)) & CMP_SCR_IEF_MASK) +#define CMP_SCR_IER_MASK (0x10U) +#define CMP_SCR_IER_SHIFT (4U) +#define CMP_SCR_IER(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_IER_SHIFT)) & CMP_SCR_IER_MASK) +#define CMP_SCR_DMAEN_MASK (0x40U) +#define CMP_SCR_DMAEN_SHIFT (6U) +#define CMP_SCR_DMAEN(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_DMAEN_SHIFT)) & CMP_SCR_DMAEN_MASK) + +/*! @name DACCR - DAC Control Register */ +#define CMP_DACCR_VOSEL_MASK (0x3FU) +#define CMP_DACCR_VOSEL_SHIFT (0U) +#define CMP_DACCR_VOSEL(x) (((uint8_t)(((uint8_t)(x)) << CMP_DACCR_VOSEL_SHIFT)) & CMP_DACCR_VOSEL_MASK) +#define CMP_DACCR_VRSEL_MASK (0x40U) +#define CMP_DACCR_VRSEL_SHIFT (6U) +#define CMP_DACCR_VRSEL(x) (((uint8_t)(((uint8_t)(x)) << CMP_DACCR_VRSEL_SHIFT)) & CMP_DACCR_VRSEL_MASK) +#define CMP_DACCR_DACEN_MASK (0x80U) +#define CMP_DACCR_DACEN_SHIFT (7U) +#define CMP_DACCR_DACEN(x) (((uint8_t)(((uint8_t)(x)) << CMP_DACCR_DACEN_SHIFT)) & CMP_DACCR_DACEN_MASK) + +/*! @name MUXCR - MUX Control Register */ +#define CMP_MUXCR_MSEL_MASK (0x7U) +#define CMP_MUXCR_MSEL_SHIFT (0U) +#define CMP_MUXCR_MSEL(x) (((uint8_t)(((uint8_t)(x)) << CMP_MUXCR_MSEL_SHIFT)) & CMP_MUXCR_MSEL_MASK) +#define CMP_MUXCR_PSEL_MASK (0x38U) +#define CMP_MUXCR_PSEL_SHIFT (3U) +#define CMP_MUXCR_PSEL(x) (((uint8_t)(((uint8_t)(x)) << CMP_MUXCR_PSEL_SHIFT)) & CMP_MUXCR_PSEL_MASK) + + +/*! + * @} + */ /* end of group CMP_Register_Masks */ + + +/* CMP - Peripheral instance base addresses */ +/** Peripheral CMP0 base address */ +#define CMP0_BASE (0x40073000u) +/** Peripheral CMP0 base pointer */ +#define CMP0 ((CMP_Type *)CMP0_BASE) +/** Peripheral CMP1 base address */ +#define CMP1_BASE (0x40073008u) +/** Peripheral CMP1 base pointer */ +#define CMP1 ((CMP_Type *)CMP1_BASE) +/** Array initializer of CMP peripheral base addresses */ +#define CMP_BASE_ADDRS { CMP0_BASE, CMP1_BASE } +/** Array initializer of CMP peripheral base pointers */ +#define CMP_BASE_PTRS { CMP0, CMP1 } +/** Interrupt vectors for the CMP peripheral type */ +#define CMP_IRQS { CMP0_IRQn, CMP1_IRQn } + +/*! + * @} + */ /* end of group CMP_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CMT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CMT_Peripheral_Access_Layer CMT Peripheral Access Layer + * @{ + */ + +/** CMT - Register Layout Typedef */ +typedef struct { + __IO uint8_t CGH1; /**< CMT Carrier Generator High Data Register 1, offset: 0x0 */ + __IO uint8_t CGL1; /**< CMT Carrier Generator Low Data Register 1, offset: 0x1 */ + __IO uint8_t CGH2; /**< CMT Carrier Generator High Data Register 2, offset: 0x2 */ + __IO uint8_t CGL2; /**< CMT Carrier Generator Low Data Register 2, offset: 0x3 */ + __IO uint8_t OC; /**< CMT Output Control Register, offset: 0x4 */ + __IO uint8_t MSC; /**< CMT Modulator Status and Control Register, offset: 0x5 */ + __IO uint8_t CMD1; /**< CMT Modulator Data Register Mark High, offset: 0x6 */ + __IO uint8_t CMD2; /**< CMT Modulator Data Register Mark Low, offset: 0x7 */ + __IO uint8_t CMD3; /**< CMT Modulator Data Register Space High, offset: 0x8 */ + __IO uint8_t CMD4; /**< CMT Modulator Data Register Space Low, offset: 0x9 */ + __IO uint8_t PPS; /**< CMT Primary Prescaler Register, offset: 0xA */ + __IO uint8_t DMA; /**< CMT Direct Memory Access Register, offset: 0xB */ +} CMT_Type; + +/* ---------------------------------------------------------------------------- + -- CMT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CMT_Register_Masks CMT Register Masks + * @{ + */ + +/*! @name CGH1 - CMT Carrier Generator High Data Register 1 */ +#define CMT_CGH1_PH_MASK (0xFFU) +#define CMT_CGH1_PH_SHIFT (0U) +#define CMT_CGH1_PH(x) (((uint8_t)(((uint8_t)(x)) << CMT_CGH1_PH_SHIFT)) & CMT_CGH1_PH_MASK) + +/*! @name CGL1 - CMT Carrier Generator Low Data Register 1 */ +#define CMT_CGL1_PL_MASK (0xFFU) +#define CMT_CGL1_PL_SHIFT (0U) +#define CMT_CGL1_PL(x) (((uint8_t)(((uint8_t)(x)) << CMT_CGL1_PL_SHIFT)) & CMT_CGL1_PL_MASK) + +/*! @name CGH2 - CMT Carrier Generator High Data Register 2 */ +#define CMT_CGH2_SH_MASK (0xFFU) +#define CMT_CGH2_SH_SHIFT (0U) +#define CMT_CGH2_SH(x) (((uint8_t)(((uint8_t)(x)) << CMT_CGH2_SH_SHIFT)) & CMT_CGH2_SH_MASK) + +/*! @name CGL2 - CMT Carrier Generator Low Data Register 2 */ +#define CMT_CGL2_SL_MASK (0xFFU) +#define CMT_CGL2_SL_SHIFT (0U) +#define CMT_CGL2_SL(x) (((uint8_t)(((uint8_t)(x)) << CMT_CGL2_SL_SHIFT)) & CMT_CGL2_SL_MASK) + +/*! @name OC - CMT Output Control Register */ +#define CMT_OC_IROPEN_MASK (0x20U) +#define CMT_OC_IROPEN_SHIFT (5U) +#define CMT_OC_IROPEN(x) (((uint8_t)(((uint8_t)(x)) << CMT_OC_IROPEN_SHIFT)) & CMT_OC_IROPEN_MASK) +#define CMT_OC_CMTPOL_MASK (0x40U) +#define CMT_OC_CMTPOL_SHIFT (6U) +#define CMT_OC_CMTPOL(x) (((uint8_t)(((uint8_t)(x)) << CMT_OC_CMTPOL_SHIFT)) & CMT_OC_CMTPOL_MASK) +#define CMT_OC_IROL_MASK (0x80U) +#define CMT_OC_IROL_SHIFT (7U) +#define CMT_OC_IROL(x) (((uint8_t)(((uint8_t)(x)) << CMT_OC_IROL_SHIFT)) & CMT_OC_IROL_MASK) + +/*! @name MSC - CMT Modulator Status and Control Register */ +#define CMT_MSC_MCGEN_MASK (0x1U) +#define CMT_MSC_MCGEN_SHIFT (0U) +#define CMT_MSC_MCGEN(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_MCGEN_SHIFT)) & CMT_MSC_MCGEN_MASK) +#define CMT_MSC_EOCIE_MASK (0x2U) +#define CMT_MSC_EOCIE_SHIFT (1U) +#define CMT_MSC_EOCIE(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_EOCIE_SHIFT)) & CMT_MSC_EOCIE_MASK) +#define CMT_MSC_FSK_MASK (0x4U) +#define CMT_MSC_FSK_SHIFT (2U) +#define CMT_MSC_FSK(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_FSK_SHIFT)) & CMT_MSC_FSK_MASK) +#define CMT_MSC_BASE_MASK (0x8U) +#define CMT_MSC_BASE_SHIFT (3U) +#define CMT_MSC_BASE(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_BASE_SHIFT)) & CMT_MSC_BASE_MASK) +#define CMT_MSC_EXSPC_MASK (0x10U) +#define CMT_MSC_EXSPC_SHIFT (4U) +#define CMT_MSC_EXSPC(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_EXSPC_SHIFT)) & CMT_MSC_EXSPC_MASK) +#define CMT_MSC_CMTDIV_MASK (0x60U) +#define CMT_MSC_CMTDIV_SHIFT (5U) +#define CMT_MSC_CMTDIV(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_CMTDIV_SHIFT)) & CMT_MSC_CMTDIV_MASK) +#define CMT_MSC_EOCF_MASK (0x80U) +#define CMT_MSC_EOCF_SHIFT (7U) +#define CMT_MSC_EOCF(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_EOCF_SHIFT)) & CMT_MSC_EOCF_MASK) + +/*! @name CMD1 - CMT Modulator Data Register Mark High */ +#define CMT_CMD1_MB_MASK (0xFFU) +#define CMT_CMD1_MB_SHIFT (0U) +#define CMT_CMD1_MB(x) (((uint8_t)(((uint8_t)(x)) << CMT_CMD1_MB_SHIFT)) & CMT_CMD1_MB_MASK) + +/*! @name CMD2 - CMT Modulator Data Register Mark Low */ +#define CMT_CMD2_MB_MASK (0xFFU) +#define CMT_CMD2_MB_SHIFT (0U) +#define CMT_CMD2_MB(x) (((uint8_t)(((uint8_t)(x)) << CMT_CMD2_MB_SHIFT)) & CMT_CMD2_MB_MASK) + +/*! @name CMD3 - CMT Modulator Data Register Space High */ +#define CMT_CMD3_SB_MASK (0xFFU) +#define CMT_CMD3_SB_SHIFT (0U) +#define CMT_CMD3_SB(x) (((uint8_t)(((uint8_t)(x)) << CMT_CMD3_SB_SHIFT)) & CMT_CMD3_SB_MASK) + +/*! @name CMD4 - CMT Modulator Data Register Space Low */ +#define CMT_CMD4_SB_MASK (0xFFU) +#define CMT_CMD4_SB_SHIFT (0U) +#define CMT_CMD4_SB(x) (((uint8_t)(((uint8_t)(x)) << CMT_CMD4_SB_SHIFT)) & CMT_CMD4_SB_MASK) + +/*! @name PPS - CMT Primary Prescaler Register */ +#define CMT_PPS_PPSDIV_MASK (0xFU) +#define CMT_PPS_PPSDIV_SHIFT (0U) +#define CMT_PPS_PPSDIV(x) (((uint8_t)(((uint8_t)(x)) << CMT_PPS_PPSDIV_SHIFT)) & CMT_PPS_PPSDIV_MASK) + +/*! @name DMA - CMT Direct Memory Access Register */ +#define CMT_DMA_DMA_MASK (0x1U) +#define CMT_DMA_DMA_SHIFT (0U) +#define CMT_DMA_DMA(x) (((uint8_t)(((uint8_t)(x)) << CMT_DMA_DMA_SHIFT)) & CMT_DMA_DMA_MASK) + + +/*! + * @} + */ /* end of group CMT_Register_Masks */ + + +/* CMT - Peripheral instance base addresses */ +/** Peripheral CMT base address */ +#define CMT_BASE (0x40062000u) +/** Peripheral CMT base pointer */ +#define CMT ((CMT_Type *)CMT_BASE) +/** Array initializer of CMT peripheral base addresses */ +#define CMT_BASE_ADDRS { CMT_BASE } +/** Array initializer of CMT peripheral base pointers */ +#define CMT_BASE_PTRS { CMT } +/** Interrupt vectors for the CMT peripheral type */ +#define CMT_IRQS { CMT_IRQn } + +/*! + * @} + */ /* end of group CMT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CRC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CRC_Peripheral_Access_Layer CRC Peripheral Access Layer + * @{ + */ + +/** CRC - Register Layout Typedef */ +typedef struct { + union { /* offset: 0x0 */ + struct { /* offset: 0x0 */ + __IO uint16_t DATAL; /**< CRC_DATAL register., offset: 0x0 */ + __IO uint16_t DATAH; /**< CRC_DATAH register., offset: 0x2 */ + } ACCESS16BIT; + __IO uint32_t DATA; /**< CRC Data register, offset: 0x0 */ + struct { /* offset: 0x0 */ + __IO uint8_t DATALL; /**< CRC_DATALL register., offset: 0x0 */ + __IO uint8_t DATALU; /**< CRC_DATALU register., offset: 0x1 */ + __IO uint8_t DATAHL; /**< CRC_DATAHL register., offset: 0x2 */ + __IO uint8_t DATAHU; /**< CRC_DATAHU register., offset: 0x3 */ + } ACCESS8BIT; + }; + union { /* offset: 0x4 */ + struct { /* offset: 0x4 */ + __IO uint16_t GPOLYL; /**< CRC_GPOLYL register., offset: 0x4 */ + __IO uint16_t GPOLYH; /**< CRC_GPOLYH register., offset: 0x6 */ + } GPOLY_ACCESS16BIT; + __IO uint32_t GPOLY; /**< CRC Polynomial register, offset: 0x4 */ + struct { /* offset: 0x4 */ + __IO uint8_t GPOLYLL; /**< CRC_GPOLYLL register., offset: 0x4 */ + __IO uint8_t GPOLYLU; /**< CRC_GPOLYLU register., offset: 0x5 */ + __IO uint8_t GPOLYHL; /**< CRC_GPOLYHL register., offset: 0x6 */ + __IO uint8_t GPOLYHU; /**< CRC_GPOLYHU register., offset: 0x7 */ + } GPOLY_ACCESS8BIT; + }; + union { /* offset: 0x8 */ + __IO uint32_t CTRL; /**< CRC Control register, offset: 0x8 */ + struct { /* offset: 0x8 */ + uint8_t RESERVED_0[3]; + __IO uint8_t CTRLHU; /**< CRC_CTRLHU register., offset: 0xB */ + } CTRL_ACCESS8BIT; + }; +} CRC_Type; + +/* ---------------------------------------------------------------------------- + -- CRC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CRC_Register_Masks CRC Register Masks + * @{ + */ + +/*! @name DATAL - CRC_DATAL register. */ +#define CRC_DATAL_DATAL_MASK (0xFFFFU) +#define CRC_DATAL_DATAL_SHIFT (0U) +#define CRC_DATAL_DATAL(x) (((uint16_t)(((uint16_t)(x)) << CRC_DATAL_DATAL_SHIFT)) & CRC_DATAL_DATAL_MASK) + +/*! @name DATAH - CRC_DATAH register. */ +#define CRC_DATAH_DATAH_MASK (0xFFFFU) +#define CRC_DATAH_DATAH_SHIFT (0U) +#define CRC_DATAH_DATAH(x) (((uint16_t)(((uint16_t)(x)) << CRC_DATAH_DATAH_SHIFT)) & CRC_DATAH_DATAH_MASK) + +/*! @name DATA - CRC Data register */ +#define CRC_DATA_LL_MASK (0xFFU) +#define CRC_DATA_LL_SHIFT (0U) +#define CRC_DATA_LL(x) (((uint32_t)(((uint32_t)(x)) << CRC_DATA_LL_SHIFT)) & CRC_DATA_LL_MASK) +#define CRC_DATA_LU_MASK (0xFF00U) +#define CRC_DATA_LU_SHIFT (8U) +#define CRC_DATA_LU(x) (((uint32_t)(((uint32_t)(x)) << CRC_DATA_LU_SHIFT)) & CRC_DATA_LU_MASK) +#define CRC_DATA_HL_MASK (0xFF0000U) +#define CRC_DATA_HL_SHIFT (16U) +#define CRC_DATA_HL(x) (((uint32_t)(((uint32_t)(x)) << CRC_DATA_HL_SHIFT)) & CRC_DATA_HL_MASK) +#define CRC_DATA_HU_MASK (0xFF000000U) +#define CRC_DATA_HU_SHIFT (24U) +#define CRC_DATA_HU(x) (((uint32_t)(((uint32_t)(x)) << CRC_DATA_HU_SHIFT)) & CRC_DATA_HU_MASK) + +/*! @name DATALL - CRC_DATALL register. */ +#define CRC_DATALL_DATALL_MASK (0xFFU) +#define CRC_DATALL_DATALL_SHIFT (0U) +#define CRC_DATALL_DATALL(x) (((uint8_t)(((uint8_t)(x)) << CRC_DATALL_DATALL_SHIFT)) & CRC_DATALL_DATALL_MASK) + +/*! @name DATALU - CRC_DATALU register. */ +#define CRC_DATALU_DATALU_MASK (0xFFU) +#define CRC_DATALU_DATALU_SHIFT (0U) +#define CRC_DATALU_DATALU(x) (((uint8_t)(((uint8_t)(x)) << CRC_DATALU_DATALU_SHIFT)) & CRC_DATALU_DATALU_MASK) + +/*! @name DATAHL - CRC_DATAHL register. */ +#define CRC_DATAHL_DATAHL_MASK (0xFFU) +#define CRC_DATAHL_DATAHL_SHIFT (0U) +#define CRC_DATAHL_DATAHL(x) (((uint8_t)(((uint8_t)(x)) << CRC_DATAHL_DATAHL_SHIFT)) & CRC_DATAHL_DATAHL_MASK) + +/*! @name DATAHU - CRC_DATAHU register. */ +#define CRC_DATAHU_DATAHU_MASK (0xFFU) +#define CRC_DATAHU_DATAHU_SHIFT (0U) +#define CRC_DATAHU_DATAHU(x) (((uint8_t)(((uint8_t)(x)) << CRC_DATAHU_DATAHU_SHIFT)) & CRC_DATAHU_DATAHU_MASK) + +/*! @name GPOLYL - CRC_GPOLYL register. */ +#define CRC_GPOLYL_GPOLYL_MASK (0xFFFFU) +#define CRC_GPOLYL_GPOLYL_SHIFT (0U) +#define CRC_GPOLYL_GPOLYL(x) (((uint16_t)(((uint16_t)(x)) << CRC_GPOLYL_GPOLYL_SHIFT)) & CRC_GPOLYL_GPOLYL_MASK) + +/*! @name GPOLYH - CRC_GPOLYH register. */ +#define CRC_GPOLYH_GPOLYH_MASK (0xFFFFU) +#define CRC_GPOLYH_GPOLYH_SHIFT (0U) +#define CRC_GPOLYH_GPOLYH(x) (((uint16_t)(((uint16_t)(x)) << CRC_GPOLYH_GPOLYH_SHIFT)) & CRC_GPOLYH_GPOLYH_MASK) + +/*! @name GPOLY - CRC Polynomial register */ +#define CRC_GPOLY_LOW_MASK (0xFFFFU) +#define CRC_GPOLY_LOW_SHIFT (0U) +#define CRC_GPOLY_LOW(x) (((uint32_t)(((uint32_t)(x)) << CRC_GPOLY_LOW_SHIFT)) & CRC_GPOLY_LOW_MASK) +#define CRC_GPOLY_HIGH_MASK (0xFFFF0000U) +#define CRC_GPOLY_HIGH_SHIFT (16U) +#define CRC_GPOLY_HIGH(x) (((uint32_t)(((uint32_t)(x)) << CRC_GPOLY_HIGH_SHIFT)) & CRC_GPOLY_HIGH_MASK) + +/*! @name GPOLYLL - CRC_GPOLYLL register. */ +#define CRC_GPOLYLL_GPOLYLL_MASK (0xFFU) +#define CRC_GPOLYLL_GPOLYLL_SHIFT (0U) +#define CRC_GPOLYLL_GPOLYLL(x) (((uint8_t)(((uint8_t)(x)) << CRC_GPOLYLL_GPOLYLL_SHIFT)) & CRC_GPOLYLL_GPOLYLL_MASK) + +/*! @name GPOLYLU - CRC_GPOLYLU register. */ +#define CRC_GPOLYLU_GPOLYLU_MASK (0xFFU) +#define CRC_GPOLYLU_GPOLYLU_SHIFT (0U) +#define CRC_GPOLYLU_GPOLYLU(x) (((uint8_t)(((uint8_t)(x)) << CRC_GPOLYLU_GPOLYLU_SHIFT)) & CRC_GPOLYLU_GPOLYLU_MASK) + +/*! @name GPOLYHL - CRC_GPOLYHL register. */ +#define CRC_GPOLYHL_GPOLYHL_MASK (0xFFU) +#define CRC_GPOLYHL_GPOLYHL_SHIFT (0U) +#define CRC_GPOLYHL_GPOLYHL(x) (((uint8_t)(((uint8_t)(x)) << CRC_GPOLYHL_GPOLYHL_SHIFT)) & CRC_GPOLYHL_GPOLYHL_MASK) + +/*! @name GPOLYHU - CRC_GPOLYHU register. */ +#define CRC_GPOLYHU_GPOLYHU_MASK (0xFFU) +#define CRC_GPOLYHU_GPOLYHU_SHIFT (0U) +#define CRC_GPOLYHU_GPOLYHU(x) (((uint8_t)(((uint8_t)(x)) << CRC_GPOLYHU_GPOLYHU_SHIFT)) & CRC_GPOLYHU_GPOLYHU_MASK) + +/*! @name CTRL - CRC Control register */ +#define CRC_CTRL_TCRC_MASK (0x1000000U) +#define CRC_CTRL_TCRC_SHIFT (24U) +#define CRC_CTRL_TCRC(x) (((uint32_t)(((uint32_t)(x)) << CRC_CTRL_TCRC_SHIFT)) & CRC_CTRL_TCRC_MASK) +#define CRC_CTRL_WAS_MASK (0x2000000U) +#define CRC_CTRL_WAS_SHIFT (25U) +#define CRC_CTRL_WAS(x) (((uint32_t)(((uint32_t)(x)) << CRC_CTRL_WAS_SHIFT)) & CRC_CTRL_WAS_MASK) +#define CRC_CTRL_FXOR_MASK (0x4000000U) +#define CRC_CTRL_FXOR_SHIFT (26U) +#define CRC_CTRL_FXOR(x) (((uint32_t)(((uint32_t)(x)) << CRC_CTRL_FXOR_SHIFT)) & CRC_CTRL_FXOR_MASK) +#define CRC_CTRL_TOTR_MASK (0x30000000U) +#define CRC_CTRL_TOTR_SHIFT (28U) +#define CRC_CTRL_TOTR(x) (((uint32_t)(((uint32_t)(x)) << CRC_CTRL_TOTR_SHIFT)) & CRC_CTRL_TOTR_MASK) +#define CRC_CTRL_TOT_MASK (0xC0000000U) +#define CRC_CTRL_TOT_SHIFT (30U) +#define CRC_CTRL_TOT(x) (((uint32_t)(((uint32_t)(x)) << CRC_CTRL_TOT_SHIFT)) & CRC_CTRL_TOT_MASK) + +/*! @name CTRLHU - CRC_CTRLHU register. */ +#define CRC_CTRLHU_TCRC_MASK (0x1U) +#define CRC_CTRLHU_TCRC_SHIFT (0U) +#define CRC_CTRLHU_TCRC(x) (((uint8_t)(((uint8_t)(x)) << CRC_CTRLHU_TCRC_SHIFT)) & CRC_CTRLHU_TCRC_MASK) +#define CRC_CTRLHU_WAS_MASK (0x2U) +#define CRC_CTRLHU_WAS_SHIFT (1U) +#define CRC_CTRLHU_WAS(x) (((uint8_t)(((uint8_t)(x)) << CRC_CTRLHU_WAS_SHIFT)) & CRC_CTRLHU_WAS_MASK) +#define CRC_CTRLHU_FXOR_MASK (0x4U) +#define CRC_CTRLHU_FXOR_SHIFT (2U) +#define CRC_CTRLHU_FXOR(x) (((uint8_t)(((uint8_t)(x)) << CRC_CTRLHU_FXOR_SHIFT)) & CRC_CTRLHU_FXOR_MASK) +#define CRC_CTRLHU_TOTR_MASK (0x30U) +#define CRC_CTRLHU_TOTR_SHIFT (4U) +#define CRC_CTRLHU_TOTR(x) (((uint8_t)(((uint8_t)(x)) << CRC_CTRLHU_TOTR_SHIFT)) & CRC_CTRLHU_TOTR_MASK) +#define CRC_CTRLHU_TOT_MASK (0xC0U) +#define CRC_CTRLHU_TOT_SHIFT (6U) +#define CRC_CTRLHU_TOT(x) (((uint8_t)(((uint8_t)(x)) << CRC_CTRLHU_TOT_SHIFT)) & CRC_CTRLHU_TOT_MASK) + + +/*! + * @} + */ /* end of group CRC_Register_Masks */ + + +/* CRC - Peripheral instance base addresses */ +/** Peripheral CRC base address */ +#define CRC_BASE (0x40032000u) +/** Peripheral CRC base pointer */ +#define CRC0 ((CRC_Type *)CRC_BASE) +/** Array initializer of CRC peripheral base addresses */ +#define CRC_BASE_ADDRS { CRC_BASE } +/** Array initializer of CRC peripheral base pointers */ +#define CRC_BASE_PTRS { CRC0 } + +/*! + * @} + */ /* end of group CRC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DAC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DAC_Peripheral_Access_Layer DAC Peripheral Access Layer + * @{ + */ + +/** DAC - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0x2 */ + __IO uint8_t DATL; /**< DAC Data Low Register, array offset: 0x0, array step: 0x2 */ + __IO uint8_t DATH; /**< DAC Data High Register, array offset: 0x1, array step: 0x2 */ + } DAT[16]; + __IO uint8_t SR; /**< DAC Status Register, offset: 0x20 */ + __IO uint8_t C0; /**< DAC Control Register, offset: 0x21 */ + __IO uint8_t C1; /**< DAC Control Register 1, offset: 0x22 */ + __IO uint8_t C2; /**< DAC Control Register 2, offset: 0x23 */ +} DAC_Type; + +/* ---------------------------------------------------------------------------- + -- DAC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DAC_Register_Masks DAC Register Masks + * @{ + */ + +/*! @name DATL - DAC Data Low Register */ +#define DAC_DATL_DATA0_MASK (0xFFU) +#define DAC_DATL_DATA0_SHIFT (0U) +#define DAC_DATL_DATA0(x) (((uint8_t)(((uint8_t)(x)) << DAC_DATL_DATA0_SHIFT)) & DAC_DATL_DATA0_MASK) + +/* The count of DAC_DATL */ +#define DAC_DATL_COUNT (16U) + +/*! @name DATH - DAC Data High Register */ +#define DAC_DATH_DATA1_MASK (0xFU) +#define DAC_DATH_DATA1_SHIFT (0U) +#define DAC_DATH_DATA1(x) (((uint8_t)(((uint8_t)(x)) << DAC_DATH_DATA1_SHIFT)) & DAC_DATH_DATA1_MASK) + +/* The count of DAC_DATH */ +#define DAC_DATH_COUNT (16U) + +/*! @name SR - DAC Status Register */ +#define DAC_SR_DACBFRPBF_MASK (0x1U) +#define DAC_SR_DACBFRPBF_SHIFT (0U) +#define DAC_SR_DACBFRPBF(x) (((uint8_t)(((uint8_t)(x)) << DAC_SR_DACBFRPBF_SHIFT)) & DAC_SR_DACBFRPBF_MASK) +#define DAC_SR_DACBFRPTF_MASK (0x2U) +#define DAC_SR_DACBFRPTF_SHIFT (1U) +#define DAC_SR_DACBFRPTF(x) (((uint8_t)(((uint8_t)(x)) << DAC_SR_DACBFRPTF_SHIFT)) & DAC_SR_DACBFRPTF_MASK) +#define DAC_SR_DACBFWMF_MASK (0x4U) +#define DAC_SR_DACBFWMF_SHIFT (2U) +#define DAC_SR_DACBFWMF(x) (((uint8_t)(((uint8_t)(x)) << DAC_SR_DACBFWMF_SHIFT)) & DAC_SR_DACBFWMF_MASK) + +/*! @name C0 - DAC Control Register */ +#define DAC_C0_DACBBIEN_MASK (0x1U) +#define DAC_C0_DACBBIEN_SHIFT (0U) +#define DAC_C0_DACBBIEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACBBIEN_SHIFT)) & DAC_C0_DACBBIEN_MASK) +#define DAC_C0_DACBTIEN_MASK (0x2U) +#define DAC_C0_DACBTIEN_SHIFT (1U) +#define DAC_C0_DACBTIEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACBTIEN_SHIFT)) & DAC_C0_DACBTIEN_MASK) +#define DAC_C0_DACBWIEN_MASK (0x4U) +#define DAC_C0_DACBWIEN_SHIFT (2U) +#define DAC_C0_DACBWIEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACBWIEN_SHIFT)) & DAC_C0_DACBWIEN_MASK) +#define DAC_C0_LPEN_MASK (0x8U) +#define DAC_C0_LPEN_SHIFT (3U) +#define DAC_C0_LPEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_LPEN_SHIFT)) & DAC_C0_LPEN_MASK) +#define DAC_C0_DACSWTRG_MASK (0x10U) +#define DAC_C0_DACSWTRG_SHIFT (4U) +#define DAC_C0_DACSWTRG(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACSWTRG_SHIFT)) & DAC_C0_DACSWTRG_MASK) +#define DAC_C0_DACTRGSEL_MASK (0x20U) +#define DAC_C0_DACTRGSEL_SHIFT (5U) +#define DAC_C0_DACTRGSEL(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACTRGSEL_SHIFT)) & DAC_C0_DACTRGSEL_MASK) +#define DAC_C0_DACRFS_MASK (0x40U) +#define DAC_C0_DACRFS_SHIFT (6U) +#define DAC_C0_DACRFS(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACRFS_SHIFT)) & DAC_C0_DACRFS_MASK) +#define DAC_C0_DACEN_MASK (0x80U) +#define DAC_C0_DACEN_SHIFT (7U) +#define DAC_C0_DACEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACEN_SHIFT)) & DAC_C0_DACEN_MASK) + +/*! @name C1 - DAC Control Register 1 */ +#define DAC_C1_DACBFEN_MASK (0x1U) +#define DAC_C1_DACBFEN_SHIFT (0U) +#define DAC_C1_DACBFEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C1_DACBFEN_SHIFT)) & DAC_C1_DACBFEN_MASK) +#define DAC_C1_DACBFMD_MASK (0x6U) +#define DAC_C1_DACBFMD_SHIFT (1U) +#define DAC_C1_DACBFMD(x) (((uint8_t)(((uint8_t)(x)) << DAC_C1_DACBFMD_SHIFT)) & DAC_C1_DACBFMD_MASK) +#define DAC_C1_DACBFWM_MASK (0x18U) +#define DAC_C1_DACBFWM_SHIFT (3U) +#define DAC_C1_DACBFWM(x) (((uint8_t)(((uint8_t)(x)) << DAC_C1_DACBFWM_SHIFT)) & DAC_C1_DACBFWM_MASK) +#define DAC_C1_DMAEN_MASK (0x80U) +#define DAC_C1_DMAEN_SHIFT (7U) +#define DAC_C1_DMAEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C1_DMAEN_SHIFT)) & DAC_C1_DMAEN_MASK) + +/*! @name C2 - DAC Control Register 2 */ +#define DAC_C2_DACBFUP_MASK (0xFU) +#define DAC_C2_DACBFUP_SHIFT (0U) +#define DAC_C2_DACBFUP(x) (((uint8_t)(((uint8_t)(x)) << DAC_C2_DACBFUP_SHIFT)) & DAC_C2_DACBFUP_MASK) +#define DAC_C2_DACBFRP_MASK (0xF0U) +#define DAC_C2_DACBFRP_SHIFT (4U) +#define DAC_C2_DACBFRP(x) (((uint8_t)(((uint8_t)(x)) << DAC_C2_DACBFRP_SHIFT)) & DAC_C2_DACBFRP_MASK) + + +/*! + * @} + */ /* end of group DAC_Register_Masks */ + + +/* DAC - Peripheral instance base addresses */ +/** Peripheral DAC0 base address */ +#define DAC0_BASE (0x400CC000u) +/** Peripheral DAC0 base pointer */ +#define DAC0 ((DAC_Type *)DAC0_BASE) +/** Array initializer of DAC peripheral base addresses */ +#define DAC_BASE_ADDRS { DAC0_BASE } +/** Array initializer of DAC peripheral base pointers */ +#define DAC_BASE_PTRS { DAC0 } +/** Interrupt vectors for the DAC peripheral type */ +#define DAC_IRQS { DAC0_IRQn } + +/*! + * @} + */ /* end of group DAC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DMA Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMA_Peripheral_Access_Layer DMA Peripheral Access Layer + * @{ + */ + +/** DMA - Register Layout Typedef */ +typedef struct { + __IO uint32_t CR; /**< Control Register, offset: 0x0 */ + __I uint32_t ES; /**< Error Status Register, offset: 0x4 */ + uint8_t RESERVED_0[4]; + __IO uint32_t ERQ; /**< Enable Request Register, offset: 0xC */ + uint8_t RESERVED_1[4]; + __IO uint32_t EEI; /**< Enable Error Interrupt Register, offset: 0x14 */ + __O uint8_t CEEI; /**< Clear Enable Error Interrupt Register, offset: 0x18 */ + __O uint8_t SEEI; /**< Set Enable Error Interrupt Register, offset: 0x19 */ + __O uint8_t CERQ; /**< Clear Enable Request Register, offset: 0x1A */ + __O uint8_t SERQ; /**< Set Enable Request Register, offset: 0x1B */ + __O uint8_t CDNE; /**< Clear DONE Status Bit Register, offset: 0x1C */ + __O uint8_t SSRT; /**< Set START Bit Register, offset: 0x1D */ + __O uint8_t CERR; /**< Clear Error Register, offset: 0x1E */ + __O uint8_t CINT; /**< Clear Interrupt Request Register, offset: 0x1F */ + uint8_t RESERVED_2[4]; + __IO uint32_t INT; /**< Interrupt Request Register, offset: 0x24 */ + uint8_t RESERVED_3[4]; + __IO uint32_t ERR; /**< Error Register, offset: 0x2C */ + uint8_t RESERVED_4[4]; + __I uint32_t HRS; /**< Hardware Request Status Register, offset: 0x34 */ + uint8_t RESERVED_5[12]; + __IO uint32_t EARS; /**< Enable Asynchronous Request in Stop Register, offset: 0x44 */ + uint8_t RESERVED_6[184]; + __IO uint8_t DCHPRI3; /**< Channel n Priority Register, offset: 0x100 */ + __IO uint8_t DCHPRI2; /**< Channel n Priority Register, offset: 0x101 */ + __IO uint8_t DCHPRI1; /**< Channel n Priority Register, offset: 0x102 */ + __IO uint8_t DCHPRI0; /**< Channel n Priority Register, offset: 0x103 */ + __IO uint8_t DCHPRI7; /**< Channel n Priority Register, offset: 0x104 */ + __IO uint8_t DCHPRI6; /**< Channel n Priority Register, offset: 0x105 */ + __IO uint8_t DCHPRI5; /**< Channel n Priority Register, offset: 0x106 */ + __IO uint8_t DCHPRI4; /**< Channel n Priority Register, offset: 0x107 */ + __IO uint8_t DCHPRI11; /**< Channel n Priority Register, offset: 0x108 */ + __IO uint8_t DCHPRI10; /**< Channel n Priority Register, offset: 0x109 */ + __IO uint8_t DCHPRI9; /**< Channel n Priority Register, offset: 0x10A */ + __IO uint8_t DCHPRI8; /**< Channel n Priority Register, offset: 0x10B */ + __IO uint8_t DCHPRI15; /**< Channel n Priority Register, offset: 0x10C */ + __IO uint8_t DCHPRI14; /**< Channel n Priority Register, offset: 0x10D */ + __IO uint8_t DCHPRI13; /**< Channel n Priority Register, offset: 0x10E */ + __IO uint8_t DCHPRI12; /**< Channel n Priority Register, offset: 0x10F */ + __IO uint8_t DCHPRI19; /**< Channel n Priority Register, offset: 0x110 */ + __IO uint8_t DCHPRI18; /**< Channel n Priority Register, offset: 0x111 */ + __IO uint8_t DCHPRI17; /**< Channel n Priority Register, offset: 0x112 */ + __IO uint8_t DCHPRI16; /**< Channel n Priority Register, offset: 0x113 */ + __IO uint8_t DCHPRI23; /**< Channel n Priority Register, offset: 0x114 */ + __IO uint8_t DCHPRI22; /**< Channel n Priority Register, offset: 0x115 */ + __IO uint8_t DCHPRI21; /**< Channel n Priority Register, offset: 0x116 */ + __IO uint8_t DCHPRI20; /**< Channel n Priority Register, offset: 0x117 */ + __IO uint8_t DCHPRI27; /**< Channel n Priority Register, offset: 0x118 */ + __IO uint8_t DCHPRI26; /**< Channel n Priority Register, offset: 0x119 */ + __IO uint8_t DCHPRI25; /**< Channel n Priority Register, offset: 0x11A */ + __IO uint8_t DCHPRI24; /**< Channel n Priority Register, offset: 0x11B */ + __IO uint8_t DCHPRI31; /**< Channel n Priority Register, offset: 0x11C */ + __IO uint8_t DCHPRI30; /**< Channel n Priority Register, offset: 0x11D */ + __IO uint8_t DCHPRI29; /**< Channel n Priority Register, offset: 0x11E */ + __IO uint8_t DCHPRI28; /**< Channel n Priority Register, offset: 0x11F */ + uint8_t RESERVED_7[3808]; + struct { /* offset: 0x1000, array step: 0x20 */ + __IO uint32_t SADDR; /**< TCD Source Address, array offset: 0x1000, array step: 0x20 */ + __IO uint16_t SOFF; /**< TCD Signed Source Address Offset, array offset: 0x1004, array step: 0x20 */ + __IO uint16_t ATTR; /**< TCD Transfer Attributes, array offset: 0x1006, array step: 0x20 */ + union { /* offset: 0x1008, array step: 0x20 */ + __IO uint32_t NBYTES_MLNO; /**< TCD Minor Byte Count (Minor Loop Mapping Disabled), array offset: 0x1008, array step: 0x20 */ + __IO uint32_t NBYTES_MLOFFNO; /**< TCD Signed Minor Loop Offset (Minor Loop Mapping Enabled and Offset Disabled), array offset: 0x1008, array step: 0x20 */ + __IO uint32_t NBYTES_MLOFFYES; /**< TCD Signed Minor Loop Offset (Minor Loop Mapping and Offset Enabled), array offset: 0x1008, array step: 0x20 */ + }; + __IO uint32_t SLAST; /**< TCD Last Source Address Adjustment, array offset: 0x100C, array step: 0x20 */ + __IO uint32_t DADDR; /**< TCD Destination Address, array offset: 0x1010, array step: 0x20 */ + __IO uint16_t DOFF; /**< TCD Signed Destination Address Offset, array offset: 0x1014, array step: 0x20 */ + union { /* offset: 0x1016, array step: 0x20 */ + __IO uint16_t CITER_ELINKNO; /**< TCD Current Minor Loop Link, Major Loop Count (Channel Linking Disabled), array offset: 0x1016, array step: 0x20 */ + __IO uint16_t CITER_ELINKYES; /**< TCD Current Minor Loop Link, Major Loop Count (Channel Linking Enabled), array offset: 0x1016, array step: 0x20 */ + }; + __IO uint32_t DLAST_SGA; /**< TCD Last Destination Address Adjustment/Scatter Gather Address, array offset: 0x1018, array step: 0x20 */ + __IO uint16_t CSR; /**< TCD Control and Status, array offset: 0x101C, array step: 0x20 */ + union { /* offset: 0x101E, array step: 0x20 */ + __IO uint16_t BITER_ELINKNO; /**< TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Disabled), array offset: 0x101E, array step: 0x20 */ + __IO uint16_t BITER_ELINKYES; /**< TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Enabled), array offset: 0x101E, array step: 0x20 */ + }; + } TCD[32]; +} DMA_Type; + +/* ---------------------------------------------------------------------------- + -- DMA Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMA_Register_Masks DMA Register Masks + * @{ + */ + +/*! @name CR - Control Register */ +#define DMA_CR_EDBG_MASK (0x2U) +#define DMA_CR_EDBG_SHIFT (1U) +#define DMA_CR_EDBG(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_EDBG_SHIFT)) & DMA_CR_EDBG_MASK) +#define DMA_CR_ERCA_MASK (0x4U) +#define DMA_CR_ERCA_SHIFT (2U) +#define DMA_CR_ERCA(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_ERCA_SHIFT)) & DMA_CR_ERCA_MASK) +#define DMA_CR_ERGA_MASK (0x8U) +#define DMA_CR_ERGA_SHIFT (3U) +#define DMA_CR_ERGA(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_ERGA_SHIFT)) & DMA_CR_ERGA_MASK) +#define DMA_CR_HOE_MASK (0x10U) +#define DMA_CR_HOE_SHIFT (4U) +#define DMA_CR_HOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_HOE_SHIFT)) & DMA_CR_HOE_MASK) +#define DMA_CR_HALT_MASK (0x20U) +#define DMA_CR_HALT_SHIFT (5U) +#define DMA_CR_HALT(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_HALT_SHIFT)) & DMA_CR_HALT_MASK) +#define DMA_CR_CLM_MASK (0x40U) +#define DMA_CR_CLM_SHIFT (6U) +#define DMA_CR_CLM(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_CLM_SHIFT)) & DMA_CR_CLM_MASK) +#define DMA_CR_EMLM_MASK (0x80U) +#define DMA_CR_EMLM_SHIFT (7U) +#define DMA_CR_EMLM(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_EMLM_SHIFT)) & DMA_CR_EMLM_MASK) +#define DMA_CR_GRP0PRI_MASK (0x100U) +#define DMA_CR_GRP0PRI_SHIFT (8U) +#define DMA_CR_GRP0PRI(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_GRP0PRI_SHIFT)) & DMA_CR_GRP0PRI_MASK) +#define DMA_CR_GRP1PRI_MASK (0x400U) +#define DMA_CR_GRP1PRI_SHIFT (10U) +#define DMA_CR_GRP1PRI(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_GRP1PRI_SHIFT)) & DMA_CR_GRP1PRI_MASK) +#define DMA_CR_ECX_MASK (0x10000U) +#define DMA_CR_ECX_SHIFT (16U) +#define DMA_CR_ECX(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_ECX_SHIFT)) & DMA_CR_ECX_MASK) +#define DMA_CR_CX_MASK (0x20000U) +#define DMA_CR_CX_SHIFT (17U) +#define DMA_CR_CX(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_CX_SHIFT)) & DMA_CR_CX_MASK) + +/*! @name ES - Error Status Register */ +#define DMA_ES_DBE_MASK (0x1U) +#define DMA_ES_DBE_SHIFT (0U) +#define DMA_ES_DBE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_DBE_SHIFT)) & DMA_ES_DBE_MASK) +#define DMA_ES_SBE_MASK (0x2U) +#define DMA_ES_SBE_SHIFT (1U) +#define DMA_ES_SBE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_SBE_SHIFT)) & DMA_ES_SBE_MASK) +#define DMA_ES_SGE_MASK (0x4U) +#define DMA_ES_SGE_SHIFT (2U) +#define DMA_ES_SGE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_SGE_SHIFT)) & DMA_ES_SGE_MASK) +#define DMA_ES_NCE_MASK (0x8U) +#define DMA_ES_NCE_SHIFT (3U) +#define DMA_ES_NCE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_NCE_SHIFT)) & DMA_ES_NCE_MASK) +#define DMA_ES_DOE_MASK (0x10U) +#define DMA_ES_DOE_SHIFT (4U) +#define DMA_ES_DOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_DOE_SHIFT)) & DMA_ES_DOE_MASK) +#define DMA_ES_DAE_MASK (0x20U) +#define DMA_ES_DAE_SHIFT (5U) +#define DMA_ES_DAE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_DAE_SHIFT)) & DMA_ES_DAE_MASK) +#define DMA_ES_SOE_MASK (0x40U) +#define DMA_ES_SOE_SHIFT (6U) +#define DMA_ES_SOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_SOE_SHIFT)) & DMA_ES_SOE_MASK) +#define DMA_ES_SAE_MASK (0x80U) +#define DMA_ES_SAE_SHIFT (7U) +#define DMA_ES_SAE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_SAE_SHIFT)) & DMA_ES_SAE_MASK) +#define DMA_ES_ERRCHN_MASK (0x1F00U) +#define DMA_ES_ERRCHN_SHIFT (8U) +#define DMA_ES_ERRCHN(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_ERRCHN_SHIFT)) & DMA_ES_ERRCHN_MASK) +#define DMA_ES_CPE_MASK (0x4000U) +#define DMA_ES_CPE_SHIFT (14U) +#define DMA_ES_CPE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_CPE_SHIFT)) & DMA_ES_CPE_MASK) +#define DMA_ES_GPE_MASK (0x8000U) +#define DMA_ES_GPE_SHIFT (15U) +#define DMA_ES_GPE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_GPE_SHIFT)) & DMA_ES_GPE_MASK) +#define DMA_ES_ECX_MASK (0x10000U) +#define DMA_ES_ECX_SHIFT (16U) +#define DMA_ES_ECX(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_ECX_SHIFT)) & DMA_ES_ECX_MASK) +#define DMA_ES_VLD_MASK (0x80000000U) +#define DMA_ES_VLD_SHIFT (31U) +#define DMA_ES_VLD(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_VLD_SHIFT)) & DMA_ES_VLD_MASK) + +/*! @name ERQ - Enable Request Register */ +#define DMA_ERQ_ERQ0_MASK (0x1U) +#define DMA_ERQ_ERQ0_SHIFT (0U) +#define DMA_ERQ_ERQ0(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ0_SHIFT)) & DMA_ERQ_ERQ0_MASK) +#define DMA_ERQ_ERQ1_MASK (0x2U) +#define DMA_ERQ_ERQ1_SHIFT (1U) +#define DMA_ERQ_ERQ1(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ1_SHIFT)) & DMA_ERQ_ERQ1_MASK) +#define DMA_ERQ_ERQ2_MASK (0x4U) +#define DMA_ERQ_ERQ2_SHIFT (2U) +#define DMA_ERQ_ERQ2(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ2_SHIFT)) & DMA_ERQ_ERQ2_MASK) +#define DMA_ERQ_ERQ3_MASK (0x8U) +#define DMA_ERQ_ERQ3_SHIFT (3U) +#define DMA_ERQ_ERQ3(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ3_SHIFT)) & DMA_ERQ_ERQ3_MASK) +#define DMA_ERQ_ERQ4_MASK (0x10U) +#define DMA_ERQ_ERQ4_SHIFT (4U) +#define DMA_ERQ_ERQ4(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ4_SHIFT)) & DMA_ERQ_ERQ4_MASK) +#define DMA_ERQ_ERQ5_MASK (0x20U) +#define DMA_ERQ_ERQ5_SHIFT (5U) +#define DMA_ERQ_ERQ5(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ5_SHIFT)) & DMA_ERQ_ERQ5_MASK) +#define DMA_ERQ_ERQ6_MASK (0x40U) +#define DMA_ERQ_ERQ6_SHIFT (6U) +#define DMA_ERQ_ERQ6(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ6_SHIFT)) & DMA_ERQ_ERQ6_MASK) +#define DMA_ERQ_ERQ7_MASK (0x80U) +#define DMA_ERQ_ERQ7_SHIFT (7U) +#define DMA_ERQ_ERQ7(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ7_SHIFT)) & DMA_ERQ_ERQ7_MASK) +#define DMA_ERQ_ERQ8_MASK (0x100U) +#define DMA_ERQ_ERQ8_SHIFT (8U) +#define DMA_ERQ_ERQ8(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ8_SHIFT)) & DMA_ERQ_ERQ8_MASK) +#define DMA_ERQ_ERQ9_MASK (0x200U) +#define DMA_ERQ_ERQ9_SHIFT (9U) +#define DMA_ERQ_ERQ9(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ9_SHIFT)) & DMA_ERQ_ERQ9_MASK) +#define DMA_ERQ_ERQ10_MASK (0x400U) +#define DMA_ERQ_ERQ10_SHIFT (10U) +#define DMA_ERQ_ERQ10(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ10_SHIFT)) & DMA_ERQ_ERQ10_MASK) +#define DMA_ERQ_ERQ11_MASK (0x800U) +#define DMA_ERQ_ERQ11_SHIFT (11U) +#define DMA_ERQ_ERQ11(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ11_SHIFT)) & DMA_ERQ_ERQ11_MASK) +#define DMA_ERQ_ERQ12_MASK (0x1000U) +#define DMA_ERQ_ERQ12_SHIFT (12U) +#define DMA_ERQ_ERQ12(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ12_SHIFT)) & DMA_ERQ_ERQ12_MASK) +#define DMA_ERQ_ERQ13_MASK (0x2000U) +#define DMA_ERQ_ERQ13_SHIFT (13U) +#define DMA_ERQ_ERQ13(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ13_SHIFT)) & DMA_ERQ_ERQ13_MASK) +#define DMA_ERQ_ERQ14_MASK (0x4000U) +#define DMA_ERQ_ERQ14_SHIFT (14U) +#define DMA_ERQ_ERQ14(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ14_SHIFT)) & DMA_ERQ_ERQ14_MASK) +#define DMA_ERQ_ERQ15_MASK (0x8000U) +#define DMA_ERQ_ERQ15_SHIFT (15U) +#define DMA_ERQ_ERQ15(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ15_SHIFT)) & DMA_ERQ_ERQ15_MASK) +#define DMA_ERQ_ERQ16_MASK (0x10000U) +#define DMA_ERQ_ERQ16_SHIFT (16U) +#define DMA_ERQ_ERQ16(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ16_SHIFT)) & DMA_ERQ_ERQ16_MASK) +#define DMA_ERQ_ERQ17_MASK (0x20000U) +#define DMA_ERQ_ERQ17_SHIFT (17U) +#define DMA_ERQ_ERQ17(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ17_SHIFT)) & DMA_ERQ_ERQ17_MASK) +#define DMA_ERQ_ERQ18_MASK (0x40000U) +#define DMA_ERQ_ERQ18_SHIFT (18U) +#define DMA_ERQ_ERQ18(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ18_SHIFT)) & DMA_ERQ_ERQ18_MASK) +#define DMA_ERQ_ERQ19_MASK (0x80000U) +#define DMA_ERQ_ERQ19_SHIFT (19U) +#define DMA_ERQ_ERQ19(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ19_SHIFT)) & DMA_ERQ_ERQ19_MASK) +#define DMA_ERQ_ERQ20_MASK (0x100000U) +#define DMA_ERQ_ERQ20_SHIFT (20U) +#define DMA_ERQ_ERQ20(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ20_SHIFT)) & DMA_ERQ_ERQ20_MASK) +#define DMA_ERQ_ERQ21_MASK (0x200000U) +#define DMA_ERQ_ERQ21_SHIFT (21U) +#define DMA_ERQ_ERQ21(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ21_SHIFT)) & DMA_ERQ_ERQ21_MASK) +#define DMA_ERQ_ERQ22_MASK (0x400000U) +#define DMA_ERQ_ERQ22_SHIFT (22U) +#define DMA_ERQ_ERQ22(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ22_SHIFT)) & DMA_ERQ_ERQ22_MASK) +#define DMA_ERQ_ERQ23_MASK (0x800000U) +#define DMA_ERQ_ERQ23_SHIFT (23U) +#define DMA_ERQ_ERQ23(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ23_SHIFT)) & DMA_ERQ_ERQ23_MASK) +#define DMA_ERQ_ERQ24_MASK (0x1000000U) +#define DMA_ERQ_ERQ24_SHIFT (24U) +#define DMA_ERQ_ERQ24(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ24_SHIFT)) & DMA_ERQ_ERQ24_MASK) +#define DMA_ERQ_ERQ25_MASK (0x2000000U) +#define DMA_ERQ_ERQ25_SHIFT (25U) +#define DMA_ERQ_ERQ25(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ25_SHIFT)) & DMA_ERQ_ERQ25_MASK) +#define DMA_ERQ_ERQ26_MASK (0x4000000U) +#define DMA_ERQ_ERQ26_SHIFT (26U) +#define DMA_ERQ_ERQ26(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ26_SHIFT)) & DMA_ERQ_ERQ26_MASK) +#define DMA_ERQ_ERQ27_MASK (0x8000000U) +#define DMA_ERQ_ERQ27_SHIFT (27U) +#define DMA_ERQ_ERQ27(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ27_SHIFT)) & DMA_ERQ_ERQ27_MASK) +#define DMA_ERQ_ERQ28_MASK (0x10000000U) +#define DMA_ERQ_ERQ28_SHIFT (28U) +#define DMA_ERQ_ERQ28(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ28_SHIFT)) & DMA_ERQ_ERQ28_MASK) +#define DMA_ERQ_ERQ29_MASK (0x20000000U) +#define DMA_ERQ_ERQ29_SHIFT (29U) +#define DMA_ERQ_ERQ29(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ29_SHIFT)) & DMA_ERQ_ERQ29_MASK) +#define DMA_ERQ_ERQ30_MASK (0x40000000U) +#define DMA_ERQ_ERQ30_SHIFT (30U) +#define DMA_ERQ_ERQ30(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ30_SHIFT)) & DMA_ERQ_ERQ30_MASK) +#define DMA_ERQ_ERQ31_MASK (0x80000000U) +#define DMA_ERQ_ERQ31_SHIFT (31U) +#define DMA_ERQ_ERQ31(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ31_SHIFT)) & DMA_ERQ_ERQ31_MASK) + +/*! @name EEI - Enable Error Interrupt Register */ +#define DMA_EEI_EEI0_MASK (0x1U) +#define DMA_EEI_EEI0_SHIFT (0U) +#define DMA_EEI_EEI0(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI0_SHIFT)) & DMA_EEI_EEI0_MASK) +#define DMA_EEI_EEI1_MASK (0x2U) +#define DMA_EEI_EEI1_SHIFT (1U) +#define DMA_EEI_EEI1(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI1_SHIFT)) & DMA_EEI_EEI1_MASK) +#define DMA_EEI_EEI2_MASK (0x4U) +#define DMA_EEI_EEI2_SHIFT (2U) +#define DMA_EEI_EEI2(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI2_SHIFT)) & DMA_EEI_EEI2_MASK) +#define DMA_EEI_EEI3_MASK (0x8U) +#define DMA_EEI_EEI3_SHIFT (3U) +#define DMA_EEI_EEI3(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI3_SHIFT)) & DMA_EEI_EEI3_MASK) +#define DMA_EEI_EEI4_MASK (0x10U) +#define DMA_EEI_EEI4_SHIFT (4U) +#define DMA_EEI_EEI4(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI4_SHIFT)) & DMA_EEI_EEI4_MASK) +#define DMA_EEI_EEI5_MASK (0x20U) +#define DMA_EEI_EEI5_SHIFT (5U) +#define DMA_EEI_EEI5(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI5_SHIFT)) & DMA_EEI_EEI5_MASK) +#define DMA_EEI_EEI6_MASK (0x40U) +#define DMA_EEI_EEI6_SHIFT (6U) +#define DMA_EEI_EEI6(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI6_SHIFT)) & DMA_EEI_EEI6_MASK) +#define DMA_EEI_EEI7_MASK (0x80U) +#define DMA_EEI_EEI7_SHIFT (7U) +#define DMA_EEI_EEI7(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI7_SHIFT)) & DMA_EEI_EEI7_MASK) +#define DMA_EEI_EEI8_MASK (0x100U) +#define DMA_EEI_EEI8_SHIFT (8U) +#define DMA_EEI_EEI8(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI8_SHIFT)) & DMA_EEI_EEI8_MASK) +#define DMA_EEI_EEI9_MASK (0x200U) +#define DMA_EEI_EEI9_SHIFT (9U) +#define DMA_EEI_EEI9(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI9_SHIFT)) & DMA_EEI_EEI9_MASK) +#define DMA_EEI_EEI10_MASK (0x400U) +#define DMA_EEI_EEI10_SHIFT (10U) +#define DMA_EEI_EEI10(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI10_SHIFT)) & DMA_EEI_EEI10_MASK) +#define DMA_EEI_EEI11_MASK (0x800U) +#define DMA_EEI_EEI11_SHIFT (11U) +#define DMA_EEI_EEI11(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI11_SHIFT)) & DMA_EEI_EEI11_MASK) +#define DMA_EEI_EEI12_MASK (0x1000U) +#define DMA_EEI_EEI12_SHIFT (12U) +#define DMA_EEI_EEI12(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI12_SHIFT)) & DMA_EEI_EEI12_MASK) +#define DMA_EEI_EEI13_MASK (0x2000U) +#define DMA_EEI_EEI13_SHIFT (13U) +#define DMA_EEI_EEI13(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI13_SHIFT)) & DMA_EEI_EEI13_MASK) +#define DMA_EEI_EEI14_MASK (0x4000U) +#define DMA_EEI_EEI14_SHIFT (14U) +#define DMA_EEI_EEI14(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI14_SHIFT)) & DMA_EEI_EEI14_MASK) +#define DMA_EEI_EEI15_MASK (0x8000U) +#define DMA_EEI_EEI15_SHIFT (15U) +#define DMA_EEI_EEI15(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI15_SHIFT)) & DMA_EEI_EEI15_MASK) +#define DMA_EEI_EEI16_MASK (0x10000U) +#define DMA_EEI_EEI16_SHIFT (16U) +#define DMA_EEI_EEI16(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI16_SHIFT)) & DMA_EEI_EEI16_MASK) +#define DMA_EEI_EEI17_MASK (0x20000U) +#define DMA_EEI_EEI17_SHIFT (17U) +#define DMA_EEI_EEI17(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI17_SHIFT)) & DMA_EEI_EEI17_MASK) +#define DMA_EEI_EEI18_MASK (0x40000U) +#define DMA_EEI_EEI18_SHIFT (18U) +#define DMA_EEI_EEI18(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI18_SHIFT)) & DMA_EEI_EEI18_MASK) +#define DMA_EEI_EEI19_MASK (0x80000U) +#define DMA_EEI_EEI19_SHIFT (19U) +#define DMA_EEI_EEI19(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI19_SHIFT)) & DMA_EEI_EEI19_MASK) +#define DMA_EEI_EEI20_MASK (0x100000U) +#define DMA_EEI_EEI20_SHIFT (20U) +#define DMA_EEI_EEI20(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI20_SHIFT)) & DMA_EEI_EEI20_MASK) +#define DMA_EEI_EEI21_MASK (0x200000U) +#define DMA_EEI_EEI21_SHIFT (21U) +#define DMA_EEI_EEI21(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI21_SHIFT)) & DMA_EEI_EEI21_MASK) +#define DMA_EEI_EEI22_MASK (0x400000U) +#define DMA_EEI_EEI22_SHIFT (22U) +#define DMA_EEI_EEI22(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI22_SHIFT)) & DMA_EEI_EEI22_MASK) +#define DMA_EEI_EEI23_MASK (0x800000U) +#define DMA_EEI_EEI23_SHIFT (23U) +#define DMA_EEI_EEI23(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI23_SHIFT)) & DMA_EEI_EEI23_MASK) +#define DMA_EEI_EEI24_MASK (0x1000000U) +#define DMA_EEI_EEI24_SHIFT (24U) +#define DMA_EEI_EEI24(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI24_SHIFT)) & DMA_EEI_EEI24_MASK) +#define DMA_EEI_EEI25_MASK (0x2000000U) +#define DMA_EEI_EEI25_SHIFT (25U) +#define DMA_EEI_EEI25(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI25_SHIFT)) & DMA_EEI_EEI25_MASK) +#define DMA_EEI_EEI26_MASK (0x4000000U) +#define DMA_EEI_EEI26_SHIFT (26U) +#define DMA_EEI_EEI26(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI26_SHIFT)) & DMA_EEI_EEI26_MASK) +#define DMA_EEI_EEI27_MASK (0x8000000U) +#define DMA_EEI_EEI27_SHIFT (27U) +#define DMA_EEI_EEI27(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI27_SHIFT)) & DMA_EEI_EEI27_MASK) +#define DMA_EEI_EEI28_MASK (0x10000000U) +#define DMA_EEI_EEI28_SHIFT (28U) +#define DMA_EEI_EEI28(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI28_SHIFT)) & DMA_EEI_EEI28_MASK) +#define DMA_EEI_EEI29_MASK (0x20000000U) +#define DMA_EEI_EEI29_SHIFT (29U) +#define DMA_EEI_EEI29(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI29_SHIFT)) & DMA_EEI_EEI29_MASK) +#define DMA_EEI_EEI30_MASK (0x40000000U) +#define DMA_EEI_EEI30_SHIFT (30U) +#define DMA_EEI_EEI30(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI30_SHIFT)) & DMA_EEI_EEI30_MASK) +#define DMA_EEI_EEI31_MASK (0x80000000U) +#define DMA_EEI_EEI31_SHIFT (31U) +#define DMA_EEI_EEI31(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI31_SHIFT)) & DMA_EEI_EEI31_MASK) + +/*! @name CEEI - Clear Enable Error Interrupt Register */ +#define DMA_CEEI_CEEI_MASK (0x1FU) +#define DMA_CEEI_CEEI_SHIFT (0U) +#define DMA_CEEI_CEEI(x) (((uint8_t)(((uint8_t)(x)) << DMA_CEEI_CEEI_SHIFT)) & DMA_CEEI_CEEI_MASK) +#define DMA_CEEI_CAEE_MASK (0x40U) +#define DMA_CEEI_CAEE_SHIFT (6U) +#define DMA_CEEI_CAEE(x) (((uint8_t)(((uint8_t)(x)) << DMA_CEEI_CAEE_SHIFT)) & DMA_CEEI_CAEE_MASK) +#define DMA_CEEI_NOP_MASK (0x80U) +#define DMA_CEEI_NOP_SHIFT (7U) +#define DMA_CEEI_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_CEEI_NOP_SHIFT)) & DMA_CEEI_NOP_MASK) + +/*! @name SEEI - Set Enable Error Interrupt Register */ +#define DMA_SEEI_SEEI_MASK (0x1FU) +#define DMA_SEEI_SEEI_SHIFT (0U) +#define DMA_SEEI_SEEI(x) (((uint8_t)(((uint8_t)(x)) << DMA_SEEI_SEEI_SHIFT)) & DMA_SEEI_SEEI_MASK) +#define DMA_SEEI_SAEE_MASK (0x40U) +#define DMA_SEEI_SAEE_SHIFT (6U) +#define DMA_SEEI_SAEE(x) (((uint8_t)(((uint8_t)(x)) << DMA_SEEI_SAEE_SHIFT)) & DMA_SEEI_SAEE_MASK) +#define DMA_SEEI_NOP_MASK (0x80U) +#define DMA_SEEI_NOP_SHIFT (7U) +#define DMA_SEEI_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_SEEI_NOP_SHIFT)) & DMA_SEEI_NOP_MASK) + +/*! @name CERQ - Clear Enable Request Register */ +#define DMA_CERQ_CERQ_MASK (0x1FU) +#define DMA_CERQ_CERQ_SHIFT (0U) +#define DMA_CERQ_CERQ(x) (((uint8_t)(((uint8_t)(x)) << DMA_CERQ_CERQ_SHIFT)) & DMA_CERQ_CERQ_MASK) +#define DMA_CERQ_CAER_MASK (0x40U) +#define DMA_CERQ_CAER_SHIFT (6U) +#define DMA_CERQ_CAER(x) (((uint8_t)(((uint8_t)(x)) << DMA_CERQ_CAER_SHIFT)) & DMA_CERQ_CAER_MASK) +#define DMA_CERQ_NOP_MASK (0x80U) +#define DMA_CERQ_NOP_SHIFT (7U) +#define DMA_CERQ_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_CERQ_NOP_SHIFT)) & DMA_CERQ_NOP_MASK) + +/*! @name SERQ - Set Enable Request Register */ +#define DMA_SERQ_SERQ_MASK (0x1FU) +#define DMA_SERQ_SERQ_SHIFT (0U) +#define DMA_SERQ_SERQ(x) (((uint8_t)(((uint8_t)(x)) << DMA_SERQ_SERQ_SHIFT)) & DMA_SERQ_SERQ_MASK) +#define DMA_SERQ_SAER_MASK (0x40U) +#define DMA_SERQ_SAER_SHIFT (6U) +#define DMA_SERQ_SAER(x) (((uint8_t)(((uint8_t)(x)) << DMA_SERQ_SAER_SHIFT)) & DMA_SERQ_SAER_MASK) +#define DMA_SERQ_NOP_MASK (0x80U) +#define DMA_SERQ_NOP_SHIFT (7U) +#define DMA_SERQ_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_SERQ_NOP_SHIFT)) & DMA_SERQ_NOP_MASK) + +/*! @name CDNE - Clear DONE Status Bit Register */ +#define DMA_CDNE_CDNE_MASK (0x1FU) +#define DMA_CDNE_CDNE_SHIFT (0U) +#define DMA_CDNE_CDNE(x) (((uint8_t)(((uint8_t)(x)) << DMA_CDNE_CDNE_SHIFT)) & DMA_CDNE_CDNE_MASK) +#define DMA_CDNE_CADN_MASK (0x40U) +#define DMA_CDNE_CADN_SHIFT (6U) +#define DMA_CDNE_CADN(x) (((uint8_t)(((uint8_t)(x)) << DMA_CDNE_CADN_SHIFT)) & DMA_CDNE_CADN_MASK) +#define DMA_CDNE_NOP_MASK (0x80U) +#define DMA_CDNE_NOP_SHIFT (7U) +#define DMA_CDNE_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_CDNE_NOP_SHIFT)) & DMA_CDNE_NOP_MASK) + +/*! @name SSRT - Set START Bit Register */ +#define DMA_SSRT_SSRT_MASK (0x1FU) +#define DMA_SSRT_SSRT_SHIFT (0U) +#define DMA_SSRT_SSRT(x) (((uint8_t)(((uint8_t)(x)) << DMA_SSRT_SSRT_SHIFT)) & DMA_SSRT_SSRT_MASK) +#define DMA_SSRT_SAST_MASK (0x40U) +#define DMA_SSRT_SAST_SHIFT (6U) +#define DMA_SSRT_SAST(x) (((uint8_t)(((uint8_t)(x)) << DMA_SSRT_SAST_SHIFT)) & DMA_SSRT_SAST_MASK) +#define DMA_SSRT_NOP_MASK (0x80U) +#define DMA_SSRT_NOP_SHIFT (7U) +#define DMA_SSRT_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_SSRT_NOP_SHIFT)) & DMA_SSRT_NOP_MASK) + +/*! @name CERR - Clear Error Register */ +#define DMA_CERR_CERR_MASK (0x1FU) +#define DMA_CERR_CERR_SHIFT (0U) +#define DMA_CERR_CERR(x) (((uint8_t)(((uint8_t)(x)) << DMA_CERR_CERR_SHIFT)) & DMA_CERR_CERR_MASK) +#define DMA_CERR_CAEI_MASK (0x40U) +#define DMA_CERR_CAEI_SHIFT (6U) +#define DMA_CERR_CAEI(x) (((uint8_t)(((uint8_t)(x)) << DMA_CERR_CAEI_SHIFT)) & DMA_CERR_CAEI_MASK) +#define DMA_CERR_NOP_MASK (0x80U) +#define DMA_CERR_NOP_SHIFT (7U) +#define DMA_CERR_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_CERR_NOP_SHIFT)) & DMA_CERR_NOP_MASK) + +/*! @name CINT - Clear Interrupt Request Register */ +#define DMA_CINT_CINT_MASK (0x1FU) +#define DMA_CINT_CINT_SHIFT (0U) +#define DMA_CINT_CINT(x) (((uint8_t)(((uint8_t)(x)) << DMA_CINT_CINT_SHIFT)) & DMA_CINT_CINT_MASK) +#define DMA_CINT_CAIR_MASK (0x40U) +#define DMA_CINT_CAIR_SHIFT (6U) +#define DMA_CINT_CAIR(x) (((uint8_t)(((uint8_t)(x)) << DMA_CINT_CAIR_SHIFT)) & DMA_CINT_CAIR_MASK) +#define DMA_CINT_NOP_MASK (0x80U) +#define DMA_CINT_NOP_SHIFT (7U) +#define DMA_CINT_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_CINT_NOP_SHIFT)) & DMA_CINT_NOP_MASK) + +/*! @name INT - Interrupt Request Register */ +#define DMA_INT_INT0_MASK (0x1U) +#define DMA_INT_INT0_SHIFT (0U) +#define DMA_INT_INT0(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT0_SHIFT)) & DMA_INT_INT0_MASK) +#define DMA_INT_INT1_MASK (0x2U) +#define DMA_INT_INT1_SHIFT (1U) +#define DMA_INT_INT1(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT1_SHIFT)) & DMA_INT_INT1_MASK) +#define DMA_INT_INT2_MASK (0x4U) +#define DMA_INT_INT2_SHIFT (2U) +#define DMA_INT_INT2(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT2_SHIFT)) & DMA_INT_INT2_MASK) +#define DMA_INT_INT3_MASK (0x8U) +#define DMA_INT_INT3_SHIFT (3U) +#define DMA_INT_INT3(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT3_SHIFT)) & DMA_INT_INT3_MASK) +#define DMA_INT_INT4_MASK (0x10U) +#define DMA_INT_INT4_SHIFT (4U) +#define DMA_INT_INT4(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT4_SHIFT)) & DMA_INT_INT4_MASK) +#define DMA_INT_INT5_MASK (0x20U) +#define DMA_INT_INT5_SHIFT (5U) +#define DMA_INT_INT5(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT5_SHIFT)) & DMA_INT_INT5_MASK) +#define DMA_INT_INT6_MASK (0x40U) +#define DMA_INT_INT6_SHIFT (6U) +#define DMA_INT_INT6(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT6_SHIFT)) & DMA_INT_INT6_MASK) +#define DMA_INT_INT7_MASK (0x80U) +#define DMA_INT_INT7_SHIFT (7U) +#define DMA_INT_INT7(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT7_SHIFT)) & DMA_INT_INT7_MASK) +#define DMA_INT_INT8_MASK (0x100U) +#define DMA_INT_INT8_SHIFT (8U) +#define DMA_INT_INT8(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT8_SHIFT)) & DMA_INT_INT8_MASK) +#define DMA_INT_INT9_MASK (0x200U) +#define DMA_INT_INT9_SHIFT (9U) +#define DMA_INT_INT9(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT9_SHIFT)) & DMA_INT_INT9_MASK) +#define DMA_INT_INT10_MASK (0x400U) +#define DMA_INT_INT10_SHIFT (10U) +#define DMA_INT_INT10(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT10_SHIFT)) & DMA_INT_INT10_MASK) +#define DMA_INT_INT11_MASK (0x800U) +#define DMA_INT_INT11_SHIFT (11U) +#define DMA_INT_INT11(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT11_SHIFT)) & DMA_INT_INT11_MASK) +#define DMA_INT_INT12_MASK (0x1000U) +#define DMA_INT_INT12_SHIFT (12U) +#define DMA_INT_INT12(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT12_SHIFT)) & DMA_INT_INT12_MASK) +#define DMA_INT_INT13_MASK (0x2000U) +#define DMA_INT_INT13_SHIFT (13U) +#define DMA_INT_INT13(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT13_SHIFT)) & DMA_INT_INT13_MASK) +#define DMA_INT_INT14_MASK (0x4000U) +#define DMA_INT_INT14_SHIFT (14U) +#define DMA_INT_INT14(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT14_SHIFT)) & DMA_INT_INT14_MASK) +#define DMA_INT_INT15_MASK (0x8000U) +#define DMA_INT_INT15_SHIFT (15U) +#define DMA_INT_INT15(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT15_SHIFT)) & DMA_INT_INT15_MASK) +#define DMA_INT_INT16_MASK (0x10000U) +#define DMA_INT_INT16_SHIFT (16U) +#define DMA_INT_INT16(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT16_SHIFT)) & DMA_INT_INT16_MASK) +#define DMA_INT_INT17_MASK (0x20000U) +#define DMA_INT_INT17_SHIFT (17U) +#define DMA_INT_INT17(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT17_SHIFT)) & DMA_INT_INT17_MASK) +#define DMA_INT_INT18_MASK (0x40000U) +#define DMA_INT_INT18_SHIFT (18U) +#define DMA_INT_INT18(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT18_SHIFT)) & DMA_INT_INT18_MASK) +#define DMA_INT_INT19_MASK (0x80000U) +#define DMA_INT_INT19_SHIFT (19U) +#define DMA_INT_INT19(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT19_SHIFT)) & DMA_INT_INT19_MASK) +#define DMA_INT_INT20_MASK (0x100000U) +#define DMA_INT_INT20_SHIFT (20U) +#define DMA_INT_INT20(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT20_SHIFT)) & DMA_INT_INT20_MASK) +#define DMA_INT_INT21_MASK (0x200000U) +#define DMA_INT_INT21_SHIFT (21U) +#define DMA_INT_INT21(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT21_SHIFT)) & DMA_INT_INT21_MASK) +#define DMA_INT_INT22_MASK (0x400000U) +#define DMA_INT_INT22_SHIFT (22U) +#define DMA_INT_INT22(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT22_SHIFT)) & DMA_INT_INT22_MASK) +#define DMA_INT_INT23_MASK (0x800000U) +#define DMA_INT_INT23_SHIFT (23U) +#define DMA_INT_INT23(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT23_SHIFT)) & DMA_INT_INT23_MASK) +#define DMA_INT_INT24_MASK (0x1000000U) +#define DMA_INT_INT24_SHIFT (24U) +#define DMA_INT_INT24(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT24_SHIFT)) & DMA_INT_INT24_MASK) +#define DMA_INT_INT25_MASK (0x2000000U) +#define DMA_INT_INT25_SHIFT (25U) +#define DMA_INT_INT25(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT25_SHIFT)) & DMA_INT_INT25_MASK) +#define DMA_INT_INT26_MASK (0x4000000U) +#define DMA_INT_INT26_SHIFT (26U) +#define DMA_INT_INT26(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT26_SHIFT)) & DMA_INT_INT26_MASK) +#define DMA_INT_INT27_MASK (0x8000000U) +#define DMA_INT_INT27_SHIFT (27U) +#define DMA_INT_INT27(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT27_SHIFT)) & DMA_INT_INT27_MASK) +#define DMA_INT_INT28_MASK (0x10000000U) +#define DMA_INT_INT28_SHIFT (28U) +#define DMA_INT_INT28(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT28_SHIFT)) & DMA_INT_INT28_MASK) +#define DMA_INT_INT29_MASK (0x20000000U) +#define DMA_INT_INT29_SHIFT (29U) +#define DMA_INT_INT29(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT29_SHIFT)) & DMA_INT_INT29_MASK) +#define DMA_INT_INT30_MASK (0x40000000U) +#define DMA_INT_INT30_SHIFT (30U) +#define DMA_INT_INT30(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT30_SHIFT)) & DMA_INT_INT30_MASK) +#define DMA_INT_INT31_MASK (0x80000000U) +#define DMA_INT_INT31_SHIFT (31U) +#define DMA_INT_INT31(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT31_SHIFT)) & DMA_INT_INT31_MASK) + +/*! @name ERR - Error Register */ +#define DMA_ERR_ERR0_MASK (0x1U) +#define DMA_ERR_ERR0_SHIFT (0U) +#define DMA_ERR_ERR0(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR0_SHIFT)) & DMA_ERR_ERR0_MASK) +#define DMA_ERR_ERR1_MASK (0x2U) +#define DMA_ERR_ERR1_SHIFT (1U) +#define DMA_ERR_ERR1(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR1_SHIFT)) & DMA_ERR_ERR1_MASK) +#define DMA_ERR_ERR2_MASK (0x4U) +#define DMA_ERR_ERR2_SHIFT (2U) +#define DMA_ERR_ERR2(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR2_SHIFT)) & DMA_ERR_ERR2_MASK) +#define DMA_ERR_ERR3_MASK (0x8U) +#define DMA_ERR_ERR3_SHIFT (3U) +#define DMA_ERR_ERR3(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR3_SHIFT)) & DMA_ERR_ERR3_MASK) +#define DMA_ERR_ERR4_MASK (0x10U) +#define DMA_ERR_ERR4_SHIFT (4U) +#define DMA_ERR_ERR4(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR4_SHIFT)) & DMA_ERR_ERR4_MASK) +#define DMA_ERR_ERR5_MASK (0x20U) +#define DMA_ERR_ERR5_SHIFT (5U) +#define DMA_ERR_ERR5(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR5_SHIFT)) & DMA_ERR_ERR5_MASK) +#define DMA_ERR_ERR6_MASK (0x40U) +#define DMA_ERR_ERR6_SHIFT (6U) +#define DMA_ERR_ERR6(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR6_SHIFT)) & DMA_ERR_ERR6_MASK) +#define DMA_ERR_ERR7_MASK (0x80U) +#define DMA_ERR_ERR7_SHIFT (7U) +#define DMA_ERR_ERR7(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR7_SHIFT)) & DMA_ERR_ERR7_MASK) +#define DMA_ERR_ERR8_MASK (0x100U) +#define DMA_ERR_ERR8_SHIFT (8U) +#define DMA_ERR_ERR8(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR8_SHIFT)) & DMA_ERR_ERR8_MASK) +#define DMA_ERR_ERR9_MASK (0x200U) +#define DMA_ERR_ERR9_SHIFT (9U) +#define DMA_ERR_ERR9(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR9_SHIFT)) & DMA_ERR_ERR9_MASK) +#define DMA_ERR_ERR10_MASK (0x400U) +#define DMA_ERR_ERR10_SHIFT (10U) +#define DMA_ERR_ERR10(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR10_SHIFT)) & DMA_ERR_ERR10_MASK) +#define DMA_ERR_ERR11_MASK (0x800U) +#define DMA_ERR_ERR11_SHIFT (11U) +#define DMA_ERR_ERR11(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR11_SHIFT)) & DMA_ERR_ERR11_MASK) +#define DMA_ERR_ERR12_MASK (0x1000U) +#define DMA_ERR_ERR12_SHIFT (12U) +#define DMA_ERR_ERR12(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR12_SHIFT)) & DMA_ERR_ERR12_MASK) +#define DMA_ERR_ERR13_MASK (0x2000U) +#define DMA_ERR_ERR13_SHIFT (13U) +#define DMA_ERR_ERR13(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR13_SHIFT)) & DMA_ERR_ERR13_MASK) +#define DMA_ERR_ERR14_MASK (0x4000U) +#define DMA_ERR_ERR14_SHIFT (14U) +#define DMA_ERR_ERR14(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR14_SHIFT)) & DMA_ERR_ERR14_MASK) +#define DMA_ERR_ERR15_MASK (0x8000U) +#define DMA_ERR_ERR15_SHIFT (15U) +#define DMA_ERR_ERR15(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR15_SHIFT)) & DMA_ERR_ERR15_MASK) +#define DMA_ERR_ERR16_MASK (0x10000U) +#define DMA_ERR_ERR16_SHIFT (16U) +#define DMA_ERR_ERR16(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR16_SHIFT)) & DMA_ERR_ERR16_MASK) +#define DMA_ERR_ERR17_MASK (0x20000U) +#define DMA_ERR_ERR17_SHIFT (17U) +#define DMA_ERR_ERR17(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR17_SHIFT)) & DMA_ERR_ERR17_MASK) +#define DMA_ERR_ERR18_MASK (0x40000U) +#define DMA_ERR_ERR18_SHIFT (18U) +#define DMA_ERR_ERR18(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR18_SHIFT)) & DMA_ERR_ERR18_MASK) +#define DMA_ERR_ERR19_MASK (0x80000U) +#define DMA_ERR_ERR19_SHIFT (19U) +#define DMA_ERR_ERR19(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR19_SHIFT)) & DMA_ERR_ERR19_MASK) +#define DMA_ERR_ERR20_MASK (0x100000U) +#define DMA_ERR_ERR20_SHIFT (20U) +#define DMA_ERR_ERR20(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR20_SHIFT)) & DMA_ERR_ERR20_MASK) +#define DMA_ERR_ERR21_MASK (0x200000U) +#define DMA_ERR_ERR21_SHIFT (21U) +#define DMA_ERR_ERR21(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR21_SHIFT)) & DMA_ERR_ERR21_MASK) +#define DMA_ERR_ERR22_MASK (0x400000U) +#define DMA_ERR_ERR22_SHIFT (22U) +#define DMA_ERR_ERR22(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR22_SHIFT)) & DMA_ERR_ERR22_MASK) +#define DMA_ERR_ERR23_MASK (0x800000U) +#define DMA_ERR_ERR23_SHIFT (23U) +#define DMA_ERR_ERR23(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR23_SHIFT)) & DMA_ERR_ERR23_MASK) +#define DMA_ERR_ERR24_MASK (0x1000000U) +#define DMA_ERR_ERR24_SHIFT (24U) +#define DMA_ERR_ERR24(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR24_SHIFT)) & DMA_ERR_ERR24_MASK) +#define DMA_ERR_ERR25_MASK (0x2000000U) +#define DMA_ERR_ERR25_SHIFT (25U) +#define DMA_ERR_ERR25(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR25_SHIFT)) & DMA_ERR_ERR25_MASK) +#define DMA_ERR_ERR26_MASK (0x4000000U) +#define DMA_ERR_ERR26_SHIFT (26U) +#define DMA_ERR_ERR26(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR26_SHIFT)) & DMA_ERR_ERR26_MASK) +#define DMA_ERR_ERR27_MASK (0x8000000U) +#define DMA_ERR_ERR27_SHIFT (27U) +#define DMA_ERR_ERR27(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR27_SHIFT)) & DMA_ERR_ERR27_MASK) +#define DMA_ERR_ERR28_MASK (0x10000000U) +#define DMA_ERR_ERR28_SHIFT (28U) +#define DMA_ERR_ERR28(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR28_SHIFT)) & DMA_ERR_ERR28_MASK) +#define DMA_ERR_ERR29_MASK (0x20000000U) +#define DMA_ERR_ERR29_SHIFT (29U) +#define DMA_ERR_ERR29(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR29_SHIFT)) & DMA_ERR_ERR29_MASK) +#define DMA_ERR_ERR30_MASK (0x40000000U) +#define DMA_ERR_ERR30_SHIFT (30U) +#define DMA_ERR_ERR30(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR30_SHIFT)) & DMA_ERR_ERR30_MASK) +#define DMA_ERR_ERR31_MASK (0x80000000U) +#define DMA_ERR_ERR31_SHIFT (31U) +#define DMA_ERR_ERR31(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR31_SHIFT)) & DMA_ERR_ERR31_MASK) + +/*! @name HRS - Hardware Request Status Register */ +#define DMA_HRS_HRS0_MASK (0x1U) +#define DMA_HRS_HRS0_SHIFT (0U) +#define DMA_HRS_HRS0(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS0_SHIFT)) & DMA_HRS_HRS0_MASK) +#define DMA_HRS_HRS1_MASK (0x2U) +#define DMA_HRS_HRS1_SHIFT (1U) +#define DMA_HRS_HRS1(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS1_SHIFT)) & DMA_HRS_HRS1_MASK) +#define DMA_HRS_HRS2_MASK (0x4U) +#define DMA_HRS_HRS2_SHIFT (2U) +#define DMA_HRS_HRS2(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS2_SHIFT)) & DMA_HRS_HRS2_MASK) +#define DMA_HRS_HRS3_MASK (0x8U) +#define DMA_HRS_HRS3_SHIFT (3U) +#define DMA_HRS_HRS3(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS3_SHIFT)) & DMA_HRS_HRS3_MASK) +#define DMA_HRS_HRS4_MASK (0x10U) +#define DMA_HRS_HRS4_SHIFT (4U) +#define DMA_HRS_HRS4(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS4_SHIFT)) & DMA_HRS_HRS4_MASK) +#define DMA_HRS_HRS5_MASK (0x20U) +#define DMA_HRS_HRS5_SHIFT (5U) +#define DMA_HRS_HRS5(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS5_SHIFT)) & DMA_HRS_HRS5_MASK) +#define DMA_HRS_HRS6_MASK (0x40U) +#define DMA_HRS_HRS6_SHIFT (6U) +#define DMA_HRS_HRS6(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS6_SHIFT)) & DMA_HRS_HRS6_MASK) +#define DMA_HRS_HRS7_MASK (0x80U) +#define DMA_HRS_HRS7_SHIFT (7U) +#define DMA_HRS_HRS7(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS7_SHIFT)) & DMA_HRS_HRS7_MASK) +#define DMA_HRS_HRS8_MASK (0x100U) +#define DMA_HRS_HRS8_SHIFT (8U) +#define DMA_HRS_HRS8(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS8_SHIFT)) & DMA_HRS_HRS8_MASK) +#define DMA_HRS_HRS9_MASK (0x200U) +#define DMA_HRS_HRS9_SHIFT (9U) +#define DMA_HRS_HRS9(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS9_SHIFT)) & DMA_HRS_HRS9_MASK) +#define DMA_HRS_HRS10_MASK (0x400U) +#define DMA_HRS_HRS10_SHIFT (10U) +#define DMA_HRS_HRS10(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS10_SHIFT)) & DMA_HRS_HRS10_MASK) +#define DMA_HRS_HRS11_MASK (0x800U) +#define DMA_HRS_HRS11_SHIFT (11U) +#define DMA_HRS_HRS11(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS11_SHIFT)) & DMA_HRS_HRS11_MASK) +#define DMA_HRS_HRS12_MASK (0x1000U) +#define DMA_HRS_HRS12_SHIFT (12U) +#define DMA_HRS_HRS12(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS12_SHIFT)) & DMA_HRS_HRS12_MASK) +#define DMA_HRS_HRS13_MASK (0x2000U) +#define DMA_HRS_HRS13_SHIFT (13U) +#define DMA_HRS_HRS13(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS13_SHIFT)) & DMA_HRS_HRS13_MASK) +#define DMA_HRS_HRS14_MASK (0x4000U) +#define DMA_HRS_HRS14_SHIFT (14U) +#define DMA_HRS_HRS14(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS14_SHIFT)) & DMA_HRS_HRS14_MASK) +#define DMA_HRS_HRS15_MASK (0x8000U) +#define DMA_HRS_HRS15_SHIFT (15U) +#define DMA_HRS_HRS15(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS15_SHIFT)) & DMA_HRS_HRS15_MASK) +#define DMA_HRS_HRS16_MASK (0x10000U) +#define DMA_HRS_HRS16_SHIFT (16U) +#define DMA_HRS_HRS16(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS16_SHIFT)) & DMA_HRS_HRS16_MASK) +#define DMA_HRS_HRS17_MASK (0x20000U) +#define DMA_HRS_HRS17_SHIFT (17U) +#define DMA_HRS_HRS17(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS17_SHIFT)) & DMA_HRS_HRS17_MASK) +#define DMA_HRS_HRS18_MASK (0x40000U) +#define DMA_HRS_HRS18_SHIFT (18U) +#define DMA_HRS_HRS18(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS18_SHIFT)) & DMA_HRS_HRS18_MASK) +#define DMA_HRS_HRS19_MASK (0x80000U) +#define DMA_HRS_HRS19_SHIFT (19U) +#define DMA_HRS_HRS19(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS19_SHIFT)) & DMA_HRS_HRS19_MASK) +#define DMA_HRS_HRS20_MASK (0x100000U) +#define DMA_HRS_HRS20_SHIFT (20U) +#define DMA_HRS_HRS20(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS20_SHIFT)) & DMA_HRS_HRS20_MASK) +#define DMA_HRS_HRS21_MASK (0x200000U) +#define DMA_HRS_HRS21_SHIFT (21U) +#define DMA_HRS_HRS21(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS21_SHIFT)) & DMA_HRS_HRS21_MASK) +#define DMA_HRS_HRS22_MASK (0x400000U) +#define DMA_HRS_HRS22_SHIFT (22U) +#define DMA_HRS_HRS22(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS22_SHIFT)) & DMA_HRS_HRS22_MASK) +#define DMA_HRS_HRS23_MASK (0x800000U) +#define DMA_HRS_HRS23_SHIFT (23U) +#define DMA_HRS_HRS23(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS23_SHIFT)) & DMA_HRS_HRS23_MASK) +#define DMA_HRS_HRS24_MASK (0x1000000U) +#define DMA_HRS_HRS24_SHIFT (24U) +#define DMA_HRS_HRS24(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS24_SHIFT)) & DMA_HRS_HRS24_MASK) +#define DMA_HRS_HRS25_MASK (0x2000000U) +#define DMA_HRS_HRS25_SHIFT (25U) +#define DMA_HRS_HRS25(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS25_SHIFT)) & DMA_HRS_HRS25_MASK) +#define DMA_HRS_HRS26_MASK (0x4000000U) +#define DMA_HRS_HRS26_SHIFT (26U) +#define DMA_HRS_HRS26(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS26_SHIFT)) & DMA_HRS_HRS26_MASK) +#define DMA_HRS_HRS27_MASK (0x8000000U) +#define DMA_HRS_HRS27_SHIFT (27U) +#define DMA_HRS_HRS27(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS27_SHIFT)) & DMA_HRS_HRS27_MASK) +#define DMA_HRS_HRS28_MASK (0x10000000U) +#define DMA_HRS_HRS28_SHIFT (28U) +#define DMA_HRS_HRS28(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS28_SHIFT)) & DMA_HRS_HRS28_MASK) +#define DMA_HRS_HRS29_MASK (0x20000000U) +#define DMA_HRS_HRS29_SHIFT (29U) +#define DMA_HRS_HRS29(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS29_SHIFT)) & DMA_HRS_HRS29_MASK) +#define DMA_HRS_HRS30_MASK (0x40000000U) +#define DMA_HRS_HRS30_SHIFT (30U) +#define DMA_HRS_HRS30(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS30_SHIFT)) & DMA_HRS_HRS30_MASK) +#define DMA_HRS_HRS31_MASK (0x80000000U) +#define DMA_HRS_HRS31_SHIFT (31U) +#define DMA_HRS_HRS31(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS31_SHIFT)) & DMA_HRS_HRS31_MASK) + +/*! @name EARS - Enable Asynchronous Request in Stop Register */ +#define DMA_EARS_EDREQ_0_MASK (0x1U) +#define DMA_EARS_EDREQ_0_SHIFT (0U) +#define DMA_EARS_EDREQ_0(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_0_SHIFT)) & DMA_EARS_EDREQ_0_MASK) +#define DMA_EARS_EDREQ_1_MASK (0x2U) +#define DMA_EARS_EDREQ_1_SHIFT (1U) +#define DMA_EARS_EDREQ_1(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_1_SHIFT)) & DMA_EARS_EDREQ_1_MASK) +#define DMA_EARS_EDREQ_2_MASK (0x4U) +#define DMA_EARS_EDREQ_2_SHIFT (2U) +#define DMA_EARS_EDREQ_2(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_2_SHIFT)) & DMA_EARS_EDREQ_2_MASK) +#define DMA_EARS_EDREQ_3_MASK (0x8U) +#define DMA_EARS_EDREQ_3_SHIFT (3U) +#define DMA_EARS_EDREQ_3(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_3_SHIFT)) & DMA_EARS_EDREQ_3_MASK) +#define DMA_EARS_EDREQ_4_MASK (0x10U) +#define DMA_EARS_EDREQ_4_SHIFT (4U) +#define DMA_EARS_EDREQ_4(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_4_SHIFT)) & DMA_EARS_EDREQ_4_MASK) +#define DMA_EARS_EDREQ_5_MASK (0x20U) +#define DMA_EARS_EDREQ_5_SHIFT (5U) +#define DMA_EARS_EDREQ_5(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_5_SHIFT)) & DMA_EARS_EDREQ_5_MASK) +#define DMA_EARS_EDREQ_6_MASK (0x40U) +#define DMA_EARS_EDREQ_6_SHIFT (6U) +#define DMA_EARS_EDREQ_6(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_6_SHIFT)) & DMA_EARS_EDREQ_6_MASK) +#define DMA_EARS_EDREQ_7_MASK (0x80U) +#define DMA_EARS_EDREQ_7_SHIFT (7U) +#define DMA_EARS_EDREQ_7(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_7_SHIFT)) & DMA_EARS_EDREQ_7_MASK) +#define DMA_EARS_EDREQ_8_MASK (0x100U) +#define DMA_EARS_EDREQ_8_SHIFT (8U) +#define DMA_EARS_EDREQ_8(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_8_SHIFT)) & DMA_EARS_EDREQ_8_MASK) +#define DMA_EARS_EDREQ_9_MASK (0x200U) +#define DMA_EARS_EDREQ_9_SHIFT (9U) +#define DMA_EARS_EDREQ_9(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_9_SHIFT)) & DMA_EARS_EDREQ_9_MASK) +#define DMA_EARS_EDREQ_10_MASK (0x400U) +#define DMA_EARS_EDREQ_10_SHIFT (10U) +#define DMA_EARS_EDREQ_10(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_10_SHIFT)) & DMA_EARS_EDREQ_10_MASK) +#define DMA_EARS_EDREQ_11_MASK (0x800U) +#define DMA_EARS_EDREQ_11_SHIFT (11U) +#define DMA_EARS_EDREQ_11(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_11_SHIFT)) & DMA_EARS_EDREQ_11_MASK) +#define DMA_EARS_EDREQ_12_MASK (0x1000U) +#define DMA_EARS_EDREQ_12_SHIFT (12U) +#define DMA_EARS_EDREQ_12(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_12_SHIFT)) & DMA_EARS_EDREQ_12_MASK) +#define DMA_EARS_EDREQ_13_MASK (0x2000U) +#define DMA_EARS_EDREQ_13_SHIFT (13U) +#define DMA_EARS_EDREQ_13(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_13_SHIFT)) & DMA_EARS_EDREQ_13_MASK) +#define DMA_EARS_EDREQ_14_MASK (0x4000U) +#define DMA_EARS_EDREQ_14_SHIFT (14U) +#define DMA_EARS_EDREQ_14(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_14_SHIFT)) & DMA_EARS_EDREQ_14_MASK) +#define DMA_EARS_EDREQ_15_MASK (0x8000U) +#define DMA_EARS_EDREQ_15_SHIFT (15U) +#define DMA_EARS_EDREQ_15(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_15_SHIFT)) & DMA_EARS_EDREQ_15_MASK) +#define DMA_EARS_EDREQ_16_MASK (0x10000U) +#define DMA_EARS_EDREQ_16_SHIFT (16U) +#define DMA_EARS_EDREQ_16(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_16_SHIFT)) & DMA_EARS_EDREQ_16_MASK) +#define DMA_EARS_EDREQ_17_MASK (0x20000U) +#define DMA_EARS_EDREQ_17_SHIFT (17U) +#define DMA_EARS_EDREQ_17(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_17_SHIFT)) & DMA_EARS_EDREQ_17_MASK) +#define DMA_EARS_EDREQ_18_MASK (0x40000U) +#define DMA_EARS_EDREQ_18_SHIFT (18U) +#define DMA_EARS_EDREQ_18(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_18_SHIFT)) & DMA_EARS_EDREQ_18_MASK) +#define DMA_EARS_EDREQ_19_MASK (0x80000U) +#define DMA_EARS_EDREQ_19_SHIFT (19U) +#define DMA_EARS_EDREQ_19(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_19_SHIFT)) & DMA_EARS_EDREQ_19_MASK) +#define DMA_EARS_EDREQ_20_MASK (0x100000U) +#define DMA_EARS_EDREQ_20_SHIFT (20U) +#define DMA_EARS_EDREQ_20(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_20_SHIFT)) & DMA_EARS_EDREQ_20_MASK) +#define DMA_EARS_EDREQ_21_MASK (0x200000U) +#define DMA_EARS_EDREQ_21_SHIFT (21U) +#define DMA_EARS_EDREQ_21(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_21_SHIFT)) & DMA_EARS_EDREQ_21_MASK) +#define DMA_EARS_EDREQ_22_MASK (0x400000U) +#define DMA_EARS_EDREQ_22_SHIFT (22U) +#define DMA_EARS_EDREQ_22(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_22_SHIFT)) & DMA_EARS_EDREQ_22_MASK) +#define DMA_EARS_EDREQ_23_MASK (0x800000U) +#define DMA_EARS_EDREQ_23_SHIFT (23U) +#define DMA_EARS_EDREQ_23(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_23_SHIFT)) & DMA_EARS_EDREQ_23_MASK) +#define DMA_EARS_EDREQ_24_MASK (0x1000000U) +#define DMA_EARS_EDREQ_24_SHIFT (24U) +#define DMA_EARS_EDREQ_24(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_24_SHIFT)) & DMA_EARS_EDREQ_24_MASK) +#define DMA_EARS_EDREQ_25_MASK (0x2000000U) +#define DMA_EARS_EDREQ_25_SHIFT (25U) +#define DMA_EARS_EDREQ_25(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_25_SHIFT)) & DMA_EARS_EDREQ_25_MASK) +#define DMA_EARS_EDREQ_26_MASK (0x4000000U) +#define DMA_EARS_EDREQ_26_SHIFT (26U) +#define DMA_EARS_EDREQ_26(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_26_SHIFT)) & DMA_EARS_EDREQ_26_MASK) +#define DMA_EARS_EDREQ_27_MASK (0x8000000U) +#define DMA_EARS_EDREQ_27_SHIFT (27U) +#define DMA_EARS_EDREQ_27(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_27_SHIFT)) & DMA_EARS_EDREQ_27_MASK) +#define DMA_EARS_EDREQ_28_MASK (0x10000000U) +#define DMA_EARS_EDREQ_28_SHIFT (28U) +#define DMA_EARS_EDREQ_28(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_28_SHIFT)) & DMA_EARS_EDREQ_28_MASK) +#define DMA_EARS_EDREQ_29_MASK (0x20000000U) +#define DMA_EARS_EDREQ_29_SHIFT (29U) +#define DMA_EARS_EDREQ_29(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_29_SHIFT)) & DMA_EARS_EDREQ_29_MASK) +#define DMA_EARS_EDREQ_30_MASK (0x40000000U) +#define DMA_EARS_EDREQ_30_SHIFT (30U) +#define DMA_EARS_EDREQ_30(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_30_SHIFT)) & DMA_EARS_EDREQ_30_MASK) +#define DMA_EARS_EDREQ_31_MASK (0x80000000U) +#define DMA_EARS_EDREQ_31_SHIFT (31U) +#define DMA_EARS_EDREQ_31(x) (((uint32_t)(((uint32_t)(x)) << DMA_EARS_EDREQ_31_SHIFT)) & DMA_EARS_EDREQ_31_MASK) + +/*! @name DCHPRI3 - Channel n Priority Register */ +#define DMA_DCHPRI3_CHPRI_MASK (0xFU) +#define DMA_DCHPRI3_CHPRI_SHIFT (0U) +#define DMA_DCHPRI3_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI3_CHPRI_SHIFT)) & DMA_DCHPRI3_CHPRI_MASK) +#define DMA_DCHPRI3_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI3_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI3_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI3_GRPPRI_SHIFT)) & DMA_DCHPRI3_GRPPRI_MASK) +#define DMA_DCHPRI3_DPA_MASK (0x40U) +#define DMA_DCHPRI3_DPA_SHIFT (6U) +#define DMA_DCHPRI3_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI3_DPA_SHIFT)) & DMA_DCHPRI3_DPA_MASK) +#define DMA_DCHPRI3_ECP_MASK (0x80U) +#define DMA_DCHPRI3_ECP_SHIFT (7U) +#define DMA_DCHPRI3_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI3_ECP_SHIFT)) & DMA_DCHPRI3_ECP_MASK) + +/*! @name DCHPRI2 - Channel n Priority Register */ +#define DMA_DCHPRI2_CHPRI_MASK (0xFU) +#define DMA_DCHPRI2_CHPRI_SHIFT (0U) +#define DMA_DCHPRI2_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI2_CHPRI_SHIFT)) & DMA_DCHPRI2_CHPRI_MASK) +#define DMA_DCHPRI2_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI2_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI2_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI2_GRPPRI_SHIFT)) & DMA_DCHPRI2_GRPPRI_MASK) +#define DMA_DCHPRI2_DPA_MASK (0x40U) +#define DMA_DCHPRI2_DPA_SHIFT (6U) +#define DMA_DCHPRI2_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI2_DPA_SHIFT)) & DMA_DCHPRI2_DPA_MASK) +#define DMA_DCHPRI2_ECP_MASK (0x80U) +#define DMA_DCHPRI2_ECP_SHIFT (7U) +#define DMA_DCHPRI2_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI2_ECP_SHIFT)) & DMA_DCHPRI2_ECP_MASK) + +/*! @name DCHPRI1 - Channel n Priority Register */ +#define DMA_DCHPRI1_CHPRI_MASK (0xFU) +#define DMA_DCHPRI1_CHPRI_SHIFT (0U) +#define DMA_DCHPRI1_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI1_CHPRI_SHIFT)) & DMA_DCHPRI1_CHPRI_MASK) +#define DMA_DCHPRI1_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI1_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI1_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI1_GRPPRI_SHIFT)) & DMA_DCHPRI1_GRPPRI_MASK) +#define DMA_DCHPRI1_DPA_MASK (0x40U) +#define DMA_DCHPRI1_DPA_SHIFT (6U) +#define DMA_DCHPRI1_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI1_DPA_SHIFT)) & DMA_DCHPRI1_DPA_MASK) +#define DMA_DCHPRI1_ECP_MASK (0x80U) +#define DMA_DCHPRI1_ECP_SHIFT (7U) +#define DMA_DCHPRI1_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI1_ECP_SHIFT)) & DMA_DCHPRI1_ECP_MASK) + +/*! @name DCHPRI0 - Channel n Priority Register */ +#define DMA_DCHPRI0_CHPRI_MASK (0xFU) +#define DMA_DCHPRI0_CHPRI_SHIFT (0U) +#define DMA_DCHPRI0_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI0_CHPRI_SHIFT)) & DMA_DCHPRI0_CHPRI_MASK) +#define DMA_DCHPRI0_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI0_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI0_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI0_GRPPRI_SHIFT)) & DMA_DCHPRI0_GRPPRI_MASK) +#define DMA_DCHPRI0_DPA_MASK (0x40U) +#define DMA_DCHPRI0_DPA_SHIFT (6U) +#define DMA_DCHPRI0_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI0_DPA_SHIFT)) & DMA_DCHPRI0_DPA_MASK) +#define DMA_DCHPRI0_ECP_MASK (0x80U) +#define DMA_DCHPRI0_ECP_SHIFT (7U) +#define DMA_DCHPRI0_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI0_ECP_SHIFT)) & DMA_DCHPRI0_ECP_MASK) + +/*! @name DCHPRI7 - Channel n Priority Register */ +#define DMA_DCHPRI7_CHPRI_MASK (0xFU) +#define DMA_DCHPRI7_CHPRI_SHIFT (0U) +#define DMA_DCHPRI7_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI7_CHPRI_SHIFT)) & DMA_DCHPRI7_CHPRI_MASK) +#define DMA_DCHPRI7_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI7_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI7_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI7_GRPPRI_SHIFT)) & DMA_DCHPRI7_GRPPRI_MASK) +#define DMA_DCHPRI7_DPA_MASK (0x40U) +#define DMA_DCHPRI7_DPA_SHIFT (6U) +#define DMA_DCHPRI7_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI7_DPA_SHIFT)) & DMA_DCHPRI7_DPA_MASK) +#define DMA_DCHPRI7_ECP_MASK (0x80U) +#define DMA_DCHPRI7_ECP_SHIFT (7U) +#define DMA_DCHPRI7_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI7_ECP_SHIFT)) & DMA_DCHPRI7_ECP_MASK) + +/*! @name DCHPRI6 - Channel n Priority Register */ +#define DMA_DCHPRI6_CHPRI_MASK (0xFU) +#define DMA_DCHPRI6_CHPRI_SHIFT (0U) +#define DMA_DCHPRI6_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI6_CHPRI_SHIFT)) & DMA_DCHPRI6_CHPRI_MASK) +#define DMA_DCHPRI6_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI6_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI6_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI6_GRPPRI_SHIFT)) & DMA_DCHPRI6_GRPPRI_MASK) +#define DMA_DCHPRI6_DPA_MASK (0x40U) +#define DMA_DCHPRI6_DPA_SHIFT (6U) +#define DMA_DCHPRI6_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI6_DPA_SHIFT)) & DMA_DCHPRI6_DPA_MASK) +#define DMA_DCHPRI6_ECP_MASK (0x80U) +#define DMA_DCHPRI6_ECP_SHIFT (7U) +#define DMA_DCHPRI6_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI6_ECP_SHIFT)) & DMA_DCHPRI6_ECP_MASK) + +/*! @name DCHPRI5 - Channel n Priority Register */ +#define DMA_DCHPRI5_CHPRI_MASK (0xFU) +#define DMA_DCHPRI5_CHPRI_SHIFT (0U) +#define DMA_DCHPRI5_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI5_CHPRI_SHIFT)) & DMA_DCHPRI5_CHPRI_MASK) +#define DMA_DCHPRI5_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI5_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI5_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI5_GRPPRI_SHIFT)) & DMA_DCHPRI5_GRPPRI_MASK) +#define DMA_DCHPRI5_DPA_MASK (0x40U) +#define DMA_DCHPRI5_DPA_SHIFT (6U) +#define DMA_DCHPRI5_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI5_DPA_SHIFT)) & DMA_DCHPRI5_DPA_MASK) +#define DMA_DCHPRI5_ECP_MASK (0x80U) +#define DMA_DCHPRI5_ECP_SHIFT (7U) +#define DMA_DCHPRI5_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI5_ECP_SHIFT)) & DMA_DCHPRI5_ECP_MASK) + +/*! @name DCHPRI4 - Channel n Priority Register */ +#define DMA_DCHPRI4_CHPRI_MASK (0xFU) +#define DMA_DCHPRI4_CHPRI_SHIFT (0U) +#define DMA_DCHPRI4_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI4_CHPRI_SHIFT)) & DMA_DCHPRI4_CHPRI_MASK) +#define DMA_DCHPRI4_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI4_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI4_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI4_GRPPRI_SHIFT)) & DMA_DCHPRI4_GRPPRI_MASK) +#define DMA_DCHPRI4_DPA_MASK (0x40U) +#define DMA_DCHPRI4_DPA_SHIFT (6U) +#define DMA_DCHPRI4_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI4_DPA_SHIFT)) & DMA_DCHPRI4_DPA_MASK) +#define DMA_DCHPRI4_ECP_MASK (0x80U) +#define DMA_DCHPRI4_ECP_SHIFT (7U) +#define DMA_DCHPRI4_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI4_ECP_SHIFT)) & DMA_DCHPRI4_ECP_MASK) + +/*! @name DCHPRI11 - Channel n Priority Register */ +#define DMA_DCHPRI11_CHPRI_MASK (0xFU) +#define DMA_DCHPRI11_CHPRI_SHIFT (0U) +#define DMA_DCHPRI11_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI11_CHPRI_SHIFT)) & DMA_DCHPRI11_CHPRI_MASK) +#define DMA_DCHPRI11_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI11_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI11_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI11_GRPPRI_SHIFT)) & DMA_DCHPRI11_GRPPRI_MASK) +#define DMA_DCHPRI11_DPA_MASK (0x40U) +#define DMA_DCHPRI11_DPA_SHIFT (6U) +#define DMA_DCHPRI11_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI11_DPA_SHIFT)) & DMA_DCHPRI11_DPA_MASK) +#define DMA_DCHPRI11_ECP_MASK (0x80U) +#define DMA_DCHPRI11_ECP_SHIFT (7U) +#define DMA_DCHPRI11_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI11_ECP_SHIFT)) & DMA_DCHPRI11_ECP_MASK) + +/*! @name DCHPRI10 - Channel n Priority Register */ +#define DMA_DCHPRI10_CHPRI_MASK (0xFU) +#define DMA_DCHPRI10_CHPRI_SHIFT (0U) +#define DMA_DCHPRI10_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI10_CHPRI_SHIFT)) & DMA_DCHPRI10_CHPRI_MASK) +#define DMA_DCHPRI10_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI10_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI10_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI10_GRPPRI_SHIFT)) & DMA_DCHPRI10_GRPPRI_MASK) +#define DMA_DCHPRI10_DPA_MASK (0x40U) +#define DMA_DCHPRI10_DPA_SHIFT (6U) +#define DMA_DCHPRI10_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI10_DPA_SHIFT)) & DMA_DCHPRI10_DPA_MASK) +#define DMA_DCHPRI10_ECP_MASK (0x80U) +#define DMA_DCHPRI10_ECP_SHIFT (7U) +#define DMA_DCHPRI10_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI10_ECP_SHIFT)) & DMA_DCHPRI10_ECP_MASK) + +/*! @name DCHPRI9 - Channel n Priority Register */ +#define DMA_DCHPRI9_CHPRI_MASK (0xFU) +#define DMA_DCHPRI9_CHPRI_SHIFT (0U) +#define DMA_DCHPRI9_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI9_CHPRI_SHIFT)) & DMA_DCHPRI9_CHPRI_MASK) +#define DMA_DCHPRI9_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI9_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI9_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI9_GRPPRI_SHIFT)) & DMA_DCHPRI9_GRPPRI_MASK) +#define DMA_DCHPRI9_DPA_MASK (0x40U) +#define DMA_DCHPRI9_DPA_SHIFT (6U) +#define DMA_DCHPRI9_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI9_DPA_SHIFT)) & DMA_DCHPRI9_DPA_MASK) +#define DMA_DCHPRI9_ECP_MASK (0x80U) +#define DMA_DCHPRI9_ECP_SHIFT (7U) +#define DMA_DCHPRI9_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI9_ECP_SHIFT)) & DMA_DCHPRI9_ECP_MASK) + +/*! @name DCHPRI8 - Channel n Priority Register */ +#define DMA_DCHPRI8_CHPRI_MASK (0xFU) +#define DMA_DCHPRI8_CHPRI_SHIFT (0U) +#define DMA_DCHPRI8_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI8_CHPRI_SHIFT)) & DMA_DCHPRI8_CHPRI_MASK) +#define DMA_DCHPRI8_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI8_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI8_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI8_GRPPRI_SHIFT)) & DMA_DCHPRI8_GRPPRI_MASK) +#define DMA_DCHPRI8_DPA_MASK (0x40U) +#define DMA_DCHPRI8_DPA_SHIFT (6U) +#define DMA_DCHPRI8_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI8_DPA_SHIFT)) & DMA_DCHPRI8_DPA_MASK) +#define DMA_DCHPRI8_ECP_MASK (0x80U) +#define DMA_DCHPRI8_ECP_SHIFT (7U) +#define DMA_DCHPRI8_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI8_ECP_SHIFT)) & DMA_DCHPRI8_ECP_MASK) + +/*! @name DCHPRI15 - Channel n Priority Register */ +#define DMA_DCHPRI15_CHPRI_MASK (0xFU) +#define DMA_DCHPRI15_CHPRI_SHIFT (0U) +#define DMA_DCHPRI15_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI15_CHPRI_SHIFT)) & DMA_DCHPRI15_CHPRI_MASK) +#define DMA_DCHPRI15_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI15_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI15_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI15_GRPPRI_SHIFT)) & DMA_DCHPRI15_GRPPRI_MASK) +#define DMA_DCHPRI15_DPA_MASK (0x40U) +#define DMA_DCHPRI15_DPA_SHIFT (6U) +#define DMA_DCHPRI15_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI15_DPA_SHIFT)) & DMA_DCHPRI15_DPA_MASK) +#define DMA_DCHPRI15_ECP_MASK (0x80U) +#define DMA_DCHPRI15_ECP_SHIFT (7U) +#define DMA_DCHPRI15_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI15_ECP_SHIFT)) & DMA_DCHPRI15_ECP_MASK) + +/*! @name DCHPRI14 - Channel n Priority Register */ +#define DMA_DCHPRI14_CHPRI_MASK (0xFU) +#define DMA_DCHPRI14_CHPRI_SHIFT (0U) +#define DMA_DCHPRI14_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI14_CHPRI_SHIFT)) & DMA_DCHPRI14_CHPRI_MASK) +#define DMA_DCHPRI14_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI14_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI14_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI14_GRPPRI_SHIFT)) & DMA_DCHPRI14_GRPPRI_MASK) +#define DMA_DCHPRI14_DPA_MASK (0x40U) +#define DMA_DCHPRI14_DPA_SHIFT (6U) +#define DMA_DCHPRI14_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI14_DPA_SHIFT)) & DMA_DCHPRI14_DPA_MASK) +#define DMA_DCHPRI14_ECP_MASK (0x80U) +#define DMA_DCHPRI14_ECP_SHIFT (7U) +#define DMA_DCHPRI14_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI14_ECP_SHIFT)) & DMA_DCHPRI14_ECP_MASK) + +/*! @name DCHPRI13 - Channel n Priority Register */ +#define DMA_DCHPRI13_CHPRI_MASK (0xFU) +#define DMA_DCHPRI13_CHPRI_SHIFT (0U) +#define DMA_DCHPRI13_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI13_CHPRI_SHIFT)) & DMA_DCHPRI13_CHPRI_MASK) +#define DMA_DCHPRI13_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI13_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI13_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI13_GRPPRI_SHIFT)) & DMA_DCHPRI13_GRPPRI_MASK) +#define DMA_DCHPRI13_DPA_MASK (0x40U) +#define DMA_DCHPRI13_DPA_SHIFT (6U) +#define DMA_DCHPRI13_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI13_DPA_SHIFT)) & DMA_DCHPRI13_DPA_MASK) +#define DMA_DCHPRI13_ECP_MASK (0x80U) +#define DMA_DCHPRI13_ECP_SHIFT (7U) +#define DMA_DCHPRI13_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI13_ECP_SHIFT)) & DMA_DCHPRI13_ECP_MASK) + +/*! @name DCHPRI12 - Channel n Priority Register */ +#define DMA_DCHPRI12_CHPRI_MASK (0xFU) +#define DMA_DCHPRI12_CHPRI_SHIFT (0U) +#define DMA_DCHPRI12_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI12_CHPRI_SHIFT)) & DMA_DCHPRI12_CHPRI_MASK) +#define DMA_DCHPRI12_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI12_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI12_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI12_GRPPRI_SHIFT)) & DMA_DCHPRI12_GRPPRI_MASK) +#define DMA_DCHPRI12_DPA_MASK (0x40U) +#define DMA_DCHPRI12_DPA_SHIFT (6U) +#define DMA_DCHPRI12_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI12_DPA_SHIFT)) & DMA_DCHPRI12_DPA_MASK) +#define DMA_DCHPRI12_ECP_MASK (0x80U) +#define DMA_DCHPRI12_ECP_SHIFT (7U) +#define DMA_DCHPRI12_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI12_ECP_SHIFT)) & DMA_DCHPRI12_ECP_MASK) + +/*! @name DCHPRI19 - Channel n Priority Register */ +#define DMA_DCHPRI19_CHPRI_MASK (0xFU) +#define DMA_DCHPRI19_CHPRI_SHIFT (0U) +#define DMA_DCHPRI19_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI19_CHPRI_SHIFT)) & DMA_DCHPRI19_CHPRI_MASK) +#define DMA_DCHPRI19_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI19_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI19_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI19_GRPPRI_SHIFT)) & DMA_DCHPRI19_GRPPRI_MASK) +#define DMA_DCHPRI19_DPA_MASK (0x40U) +#define DMA_DCHPRI19_DPA_SHIFT (6U) +#define DMA_DCHPRI19_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI19_DPA_SHIFT)) & DMA_DCHPRI19_DPA_MASK) +#define DMA_DCHPRI19_ECP_MASK (0x80U) +#define DMA_DCHPRI19_ECP_SHIFT (7U) +#define DMA_DCHPRI19_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI19_ECP_SHIFT)) & DMA_DCHPRI19_ECP_MASK) + +/*! @name DCHPRI18 - Channel n Priority Register */ +#define DMA_DCHPRI18_CHPRI_MASK (0xFU) +#define DMA_DCHPRI18_CHPRI_SHIFT (0U) +#define DMA_DCHPRI18_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI18_CHPRI_SHIFT)) & DMA_DCHPRI18_CHPRI_MASK) +#define DMA_DCHPRI18_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI18_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI18_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI18_GRPPRI_SHIFT)) & DMA_DCHPRI18_GRPPRI_MASK) +#define DMA_DCHPRI18_DPA_MASK (0x40U) +#define DMA_DCHPRI18_DPA_SHIFT (6U) +#define DMA_DCHPRI18_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI18_DPA_SHIFT)) & DMA_DCHPRI18_DPA_MASK) +#define DMA_DCHPRI18_ECP_MASK (0x80U) +#define DMA_DCHPRI18_ECP_SHIFT (7U) +#define DMA_DCHPRI18_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI18_ECP_SHIFT)) & DMA_DCHPRI18_ECP_MASK) + +/*! @name DCHPRI17 - Channel n Priority Register */ +#define DMA_DCHPRI17_CHPRI_MASK (0xFU) +#define DMA_DCHPRI17_CHPRI_SHIFT (0U) +#define DMA_DCHPRI17_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI17_CHPRI_SHIFT)) & DMA_DCHPRI17_CHPRI_MASK) +#define DMA_DCHPRI17_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI17_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI17_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI17_GRPPRI_SHIFT)) & DMA_DCHPRI17_GRPPRI_MASK) +#define DMA_DCHPRI17_DPA_MASK (0x40U) +#define DMA_DCHPRI17_DPA_SHIFT (6U) +#define DMA_DCHPRI17_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI17_DPA_SHIFT)) & DMA_DCHPRI17_DPA_MASK) +#define DMA_DCHPRI17_ECP_MASK (0x80U) +#define DMA_DCHPRI17_ECP_SHIFT (7U) +#define DMA_DCHPRI17_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI17_ECP_SHIFT)) & DMA_DCHPRI17_ECP_MASK) + +/*! @name DCHPRI16 - Channel n Priority Register */ +#define DMA_DCHPRI16_CHPRI_MASK (0xFU) +#define DMA_DCHPRI16_CHPRI_SHIFT (0U) +#define DMA_DCHPRI16_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI16_CHPRI_SHIFT)) & DMA_DCHPRI16_CHPRI_MASK) +#define DMA_DCHPRI16_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI16_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI16_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI16_GRPPRI_SHIFT)) & DMA_DCHPRI16_GRPPRI_MASK) +#define DMA_DCHPRI16_DPA_MASK (0x40U) +#define DMA_DCHPRI16_DPA_SHIFT (6U) +#define DMA_DCHPRI16_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI16_DPA_SHIFT)) & DMA_DCHPRI16_DPA_MASK) +#define DMA_DCHPRI16_ECP_MASK (0x80U) +#define DMA_DCHPRI16_ECP_SHIFT (7U) +#define DMA_DCHPRI16_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI16_ECP_SHIFT)) & DMA_DCHPRI16_ECP_MASK) + +/*! @name DCHPRI23 - Channel n Priority Register */ +#define DMA_DCHPRI23_CHPRI_MASK (0xFU) +#define DMA_DCHPRI23_CHPRI_SHIFT (0U) +#define DMA_DCHPRI23_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI23_CHPRI_SHIFT)) & DMA_DCHPRI23_CHPRI_MASK) +#define DMA_DCHPRI23_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI23_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI23_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI23_GRPPRI_SHIFT)) & DMA_DCHPRI23_GRPPRI_MASK) +#define DMA_DCHPRI23_DPA_MASK (0x40U) +#define DMA_DCHPRI23_DPA_SHIFT (6U) +#define DMA_DCHPRI23_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI23_DPA_SHIFT)) & DMA_DCHPRI23_DPA_MASK) +#define DMA_DCHPRI23_ECP_MASK (0x80U) +#define DMA_DCHPRI23_ECP_SHIFT (7U) +#define DMA_DCHPRI23_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI23_ECP_SHIFT)) & DMA_DCHPRI23_ECP_MASK) + +/*! @name DCHPRI22 - Channel n Priority Register */ +#define DMA_DCHPRI22_CHPRI_MASK (0xFU) +#define DMA_DCHPRI22_CHPRI_SHIFT (0U) +#define DMA_DCHPRI22_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI22_CHPRI_SHIFT)) & DMA_DCHPRI22_CHPRI_MASK) +#define DMA_DCHPRI22_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI22_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI22_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI22_GRPPRI_SHIFT)) & DMA_DCHPRI22_GRPPRI_MASK) +#define DMA_DCHPRI22_DPA_MASK (0x40U) +#define DMA_DCHPRI22_DPA_SHIFT (6U) +#define DMA_DCHPRI22_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI22_DPA_SHIFT)) & DMA_DCHPRI22_DPA_MASK) +#define DMA_DCHPRI22_ECP_MASK (0x80U) +#define DMA_DCHPRI22_ECP_SHIFT (7U) +#define DMA_DCHPRI22_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI22_ECP_SHIFT)) & DMA_DCHPRI22_ECP_MASK) + +/*! @name DCHPRI21 - Channel n Priority Register */ +#define DMA_DCHPRI21_CHPRI_MASK (0xFU) +#define DMA_DCHPRI21_CHPRI_SHIFT (0U) +#define DMA_DCHPRI21_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI21_CHPRI_SHIFT)) & DMA_DCHPRI21_CHPRI_MASK) +#define DMA_DCHPRI21_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI21_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI21_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI21_GRPPRI_SHIFT)) & DMA_DCHPRI21_GRPPRI_MASK) +#define DMA_DCHPRI21_DPA_MASK (0x40U) +#define DMA_DCHPRI21_DPA_SHIFT (6U) +#define DMA_DCHPRI21_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI21_DPA_SHIFT)) & DMA_DCHPRI21_DPA_MASK) +#define DMA_DCHPRI21_ECP_MASK (0x80U) +#define DMA_DCHPRI21_ECP_SHIFT (7U) +#define DMA_DCHPRI21_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI21_ECP_SHIFT)) & DMA_DCHPRI21_ECP_MASK) + +/*! @name DCHPRI20 - Channel n Priority Register */ +#define DMA_DCHPRI20_CHPRI_MASK (0xFU) +#define DMA_DCHPRI20_CHPRI_SHIFT (0U) +#define DMA_DCHPRI20_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI20_CHPRI_SHIFT)) & DMA_DCHPRI20_CHPRI_MASK) +#define DMA_DCHPRI20_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI20_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI20_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI20_GRPPRI_SHIFT)) & DMA_DCHPRI20_GRPPRI_MASK) +#define DMA_DCHPRI20_DPA_MASK (0x40U) +#define DMA_DCHPRI20_DPA_SHIFT (6U) +#define DMA_DCHPRI20_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI20_DPA_SHIFT)) & DMA_DCHPRI20_DPA_MASK) +#define DMA_DCHPRI20_ECP_MASK (0x80U) +#define DMA_DCHPRI20_ECP_SHIFT (7U) +#define DMA_DCHPRI20_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI20_ECP_SHIFT)) & DMA_DCHPRI20_ECP_MASK) + +/*! @name DCHPRI27 - Channel n Priority Register */ +#define DMA_DCHPRI27_CHPRI_MASK (0xFU) +#define DMA_DCHPRI27_CHPRI_SHIFT (0U) +#define DMA_DCHPRI27_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI27_CHPRI_SHIFT)) & DMA_DCHPRI27_CHPRI_MASK) +#define DMA_DCHPRI27_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI27_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI27_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI27_GRPPRI_SHIFT)) & DMA_DCHPRI27_GRPPRI_MASK) +#define DMA_DCHPRI27_DPA_MASK (0x40U) +#define DMA_DCHPRI27_DPA_SHIFT (6U) +#define DMA_DCHPRI27_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI27_DPA_SHIFT)) & DMA_DCHPRI27_DPA_MASK) +#define DMA_DCHPRI27_ECP_MASK (0x80U) +#define DMA_DCHPRI27_ECP_SHIFT (7U) +#define DMA_DCHPRI27_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI27_ECP_SHIFT)) & DMA_DCHPRI27_ECP_MASK) + +/*! @name DCHPRI26 - Channel n Priority Register */ +#define DMA_DCHPRI26_CHPRI_MASK (0xFU) +#define DMA_DCHPRI26_CHPRI_SHIFT (0U) +#define DMA_DCHPRI26_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI26_CHPRI_SHIFT)) & DMA_DCHPRI26_CHPRI_MASK) +#define DMA_DCHPRI26_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI26_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI26_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI26_GRPPRI_SHIFT)) & DMA_DCHPRI26_GRPPRI_MASK) +#define DMA_DCHPRI26_DPA_MASK (0x40U) +#define DMA_DCHPRI26_DPA_SHIFT (6U) +#define DMA_DCHPRI26_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI26_DPA_SHIFT)) & DMA_DCHPRI26_DPA_MASK) +#define DMA_DCHPRI26_ECP_MASK (0x80U) +#define DMA_DCHPRI26_ECP_SHIFT (7U) +#define DMA_DCHPRI26_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI26_ECP_SHIFT)) & DMA_DCHPRI26_ECP_MASK) + +/*! @name DCHPRI25 - Channel n Priority Register */ +#define DMA_DCHPRI25_CHPRI_MASK (0xFU) +#define DMA_DCHPRI25_CHPRI_SHIFT (0U) +#define DMA_DCHPRI25_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI25_CHPRI_SHIFT)) & DMA_DCHPRI25_CHPRI_MASK) +#define DMA_DCHPRI25_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI25_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI25_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI25_GRPPRI_SHIFT)) & DMA_DCHPRI25_GRPPRI_MASK) +#define DMA_DCHPRI25_DPA_MASK (0x40U) +#define DMA_DCHPRI25_DPA_SHIFT (6U) +#define DMA_DCHPRI25_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI25_DPA_SHIFT)) & DMA_DCHPRI25_DPA_MASK) +#define DMA_DCHPRI25_ECP_MASK (0x80U) +#define DMA_DCHPRI25_ECP_SHIFT (7U) +#define DMA_DCHPRI25_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI25_ECP_SHIFT)) & DMA_DCHPRI25_ECP_MASK) + +/*! @name DCHPRI24 - Channel n Priority Register */ +#define DMA_DCHPRI24_CHPRI_MASK (0xFU) +#define DMA_DCHPRI24_CHPRI_SHIFT (0U) +#define DMA_DCHPRI24_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI24_CHPRI_SHIFT)) & DMA_DCHPRI24_CHPRI_MASK) +#define DMA_DCHPRI24_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI24_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI24_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI24_GRPPRI_SHIFT)) & DMA_DCHPRI24_GRPPRI_MASK) +#define DMA_DCHPRI24_DPA_MASK (0x40U) +#define DMA_DCHPRI24_DPA_SHIFT (6U) +#define DMA_DCHPRI24_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI24_DPA_SHIFT)) & DMA_DCHPRI24_DPA_MASK) +#define DMA_DCHPRI24_ECP_MASK (0x80U) +#define DMA_DCHPRI24_ECP_SHIFT (7U) +#define DMA_DCHPRI24_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI24_ECP_SHIFT)) & DMA_DCHPRI24_ECP_MASK) + +/*! @name DCHPRI31 - Channel n Priority Register */ +#define DMA_DCHPRI31_CHPRI_MASK (0xFU) +#define DMA_DCHPRI31_CHPRI_SHIFT (0U) +#define DMA_DCHPRI31_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI31_CHPRI_SHIFT)) & DMA_DCHPRI31_CHPRI_MASK) +#define DMA_DCHPRI31_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI31_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI31_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI31_GRPPRI_SHIFT)) & DMA_DCHPRI31_GRPPRI_MASK) +#define DMA_DCHPRI31_DPA_MASK (0x40U) +#define DMA_DCHPRI31_DPA_SHIFT (6U) +#define DMA_DCHPRI31_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI31_DPA_SHIFT)) & DMA_DCHPRI31_DPA_MASK) +#define DMA_DCHPRI31_ECP_MASK (0x80U) +#define DMA_DCHPRI31_ECP_SHIFT (7U) +#define DMA_DCHPRI31_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI31_ECP_SHIFT)) & DMA_DCHPRI31_ECP_MASK) + +/*! @name DCHPRI30 - Channel n Priority Register */ +#define DMA_DCHPRI30_CHPRI_MASK (0xFU) +#define DMA_DCHPRI30_CHPRI_SHIFT (0U) +#define DMA_DCHPRI30_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI30_CHPRI_SHIFT)) & DMA_DCHPRI30_CHPRI_MASK) +#define DMA_DCHPRI30_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI30_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI30_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI30_GRPPRI_SHIFT)) & DMA_DCHPRI30_GRPPRI_MASK) +#define DMA_DCHPRI30_DPA_MASK (0x40U) +#define DMA_DCHPRI30_DPA_SHIFT (6U) +#define DMA_DCHPRI30_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI30_DPA_SHIFT)) & DMA_DCHPRI30_DPA_MASK) +#define DMA_DCHPRI30_ECP_MASK (0x80U) +#define DMA_DCHPRI30_ECP_SHIFT (7U) +#define DMA_DCHPRI30_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI30_ECP_SHIFT)) & DMA_DCHPRI30_ECP_MASK) + +/*! @name DCHPRI29 - Channel n Priority Register */ +#define DMA_DCHPRI29_CHPRI_MASK (0xFU) +#define DMA_DCHPRI29_CHPRI_SHIFT (0U) +#define DMA_DCHPRI29_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI29_CHPRI_SHIFT)) & DMA_DCHPRI29_CHPRI_MASK) +#define DMA_DCHPRI29_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI29_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI29_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI29_GRPPRI_SHIFT)) & DMA_DCHPRI29_GRPPRI_MASK) +#define DMA_DCHPRI29_DPA_MASK (0x40U) +#define DMA_DCHPRI29_DPA_SHIFT (6U) +#define DMA_DCHPRI29_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI29_DPA_SHIFT)) & DMA_DCHPRI29_DPA_MASK) +#define DMA_DCHPRI29_ECP_MASK (0x80U) +#define DMA_DCHPRI29_ECP_SHIFT (7U) +#define DMA_DCHPRI29_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI29_ECP_SHIFT)) & DMA_DCHPRI29_ECP_MASK) + +/*! @name DCHPRI28 - Channel n Priority Register */ +#define DMA_DCHPRI28_CHPRI_MASK (0xFU) +#define DMA_DCHPRI28_CHPRI_SHIFT (0U) +#define DMA_DCHPRI28_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI28_CHPRI_SHIFT)) & DMA_DCHPRI28_CHPRI_MASK) +#define DMA_DCHPRI28_GRPPRI_MASK (0x30U) +#define DMA_DCHPRI28_GRPPRI_SHIFT (4U) +#define DMA_DCHPRI28_GRPPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI28_GRPPRI_SHIFT)) & DMA_DCHPRI28_GRPPRI_MASK) +#define DMA_DCHPRI28_DPA_MASK (0x40U) +#define DMA_DCHPRI28_DPA_SHIFT (6U) +#define DMA_DCHPRI28_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI28_DPA_SHIFT)) & DMA_DCHPRI28_DPA_MASK) +#define DMA_DCHPRI28_ECP_MASK (0x80U) +#define DMA_DCHPRI28_ECP_SHIFT (7U) +#define DMA_DCHPRI28_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI28_ECP_SHIFT)) & DMA_DCHPRI28_ECP_MASK) + +/*! @name SADDR - TCD Source Address */ +#define DMA_SADDR_SADDR_MASK (0xFFFFFFFFU) +#define DMA_SADDR_SADDR_SHIFT (0U) +#define DMA_SADDR_SADDR(x) (((uint32_t)(((uint32_t)(x)) << DMA_SADDR_SADDR_SHIFT)) & DMA_SADDR_SADDR_MASK) + +/* The count of DMA_SADDR */ +#define DMA_SADDR_COUNT (32U) + +/*! @name SOFF - TCD Signed Source Address Offset */ +#define DMA_SOFF_SOFF_MASK (0xFFFFU) +#define DMA_SOFF_SOFF_SHIFT (0U) +#define DMA_SOFF_SOFF(x) (((uint16_t)(((uint16_t)(x)) << DMA_SOFF_SOFF_SHIFT)) & DMA_SOFF_SOFF_MASK) + +/* The count of DMA_SOFF */ +#define DMA_SOFF_COUNT (32U) + +/*! @name ATTR - TCD Transfer Attributes */ +#define DMA_ATTR_DSIZE_MASK (0x7U) +#define DMA_ATTR_DSIZE_SHIFT (0U) +#define DMA_ATTR_DSIZE(x) (((uint16_t)(((uint16_t)(x)) << DMA_ATTR_DSIZE_SHIFT)) & DMA_ATTR_DSIZE_MASK) +#define DMA_ATTR_DMOD_MASK (0xF8U) +#define DMA_ATTR_DMOD_SHIFT (3U) +#define DMA_ATTR_DMOD(x) (((uint16_t)(((uint16_t)(x)) << DMA_ATTR_DMOD_SHIFT)) & DMA_ATTR_DMOD_MASK) +#define DMA_ATTR_SSIZE_MASK (0x700U) +#define DMA_ATTR_SSIZE_SHIFT (8U) +#define DMA_ATTR_SSIZE(x) (((uint16_t)(((uint16_t)(x)) << DMA_ATTR_SSIZE_SHIFT)) & DMA_ATTR_SSIZE_MASK) +#define DMA_ATTR_SMOD_MASK (0xF800U) +#define DMA_ATTR_SMOD_SHIFT (11U) +#define DMA_ATTR_SMOD(x) (((uint16_t)(((uint16_t)(x)) << DMA_ATTR_SMOD_SHIFT)) & DMA_ATTR_SMOD_MASK) + +/* The count of DMA_ATTR */ +#define DMA_ATTR_COUNT (32U) + +/*! @name NBYTES_MLNO - TCD Minor Byte Count (Minor Loop Mapping Disabled) */ +#define DMA_NBYTES_MLNO_NBYTES_MASK (0xFFFFFFFFU) +#define DMA_NBYTES_MLNO_NBYTES_SHIFT (0U) +#define DMA_NBYTES_MLNO_NBYTES(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLNO_NBYTES_SHIFT)) & DMA_NBYTES_MLNO_NBYTES_MASK) + +/* The count of DMA_NBYTES_MLNO */ +#define DMA_NBYTES_MLNO_COUNT (32U) + +/*! @name NBYTES_MLOFFNO - TCD Signed Minor Loop Offset (Minor Loop Mapping Enabled and Offset Disabled) */ +#define DMA_NBYTES_MLOFFNO_NBYTES_MASK (0x3FFFFFFFU) +#define DMA_NBYTES_MLOFFNO_NBYTES_SHIFT (0U) +#define DMA_NBYTES_MLOFFNO_NBYTES(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFNO_NBYTES_SHIFT)) & DMA_NBYTES_MLOFFNO_NBYTES_MASK) +#define DMA_NBYTES_MLOFFNO_DMLOE_MASK (0x40000000U) +#define DMA_NBYTES_MLOFFNO_DMLOE_SHIFT (30U) +#define DMA_NBYTES_MLOFFNO_DMLOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFNO_DMLOE_SHIFT)) & DMA_NBYTES_MLOFFNO_DMLOE_MASK) +#define DMA_NBYTES_MLOFFNO_SMLOE_MASK (0x80000000U) +#define DMA_NBYTES_MLOFFNO_SMLOE_SHIFT (31U) +#define DMA_NBYTES_MLOFFNO_SMLOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFNO_SMLOE_SHIFT)) & DMA_NBYTES_MLOFFNO_SMLOE_MASK) + +/* The count of DMA_NBYTES_MLOFFNO */ +#define DMA_NBYTES_MLOFFNO_COUNT (32U) + +/*! @name NBYTES_MLOFFYES - TCD Signed Minor Loop Offset (Minor Loop Mapping and Offset Enabled) */ +#define DMA_NBYTES_MLOFFYES_NBYTES_MASK (0x3FFU) +#define DMA_NBYTES_MLOFFYES_NBYTES_SHIFT (0U) +#define DMA_NBYTES_MLOFFYES_NBYTES(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFYES_NBYTES_SHIFT)) & DMA_NBYTES_MLOFFYES_NBYTES_MASK) +#define DMA_NBYTES_MLOFFYES_MLOFF_MASK (0x3FFFFC00U) +#define DMA_NBYTES_MLOFFYES_MLOFF_SHIFT (10U) +#define DMA_NBYTES_MLOFFYES_MLOFF(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFYES_MLOFF_SHIFT)) & DMA_NBYTES_MLOFFYES_MLOFF_MASK) +#define DMA_NBYTES_MLOFFYES_DMLOE_MASK (0x40000000U) +#define DMA_NBYTES_MLOFFYES_DMLOE_SHIFT (30U) +#define DMA_NBYTES_MLOFFYES_DMLOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFYES_DMLOE_SHIFT)) & DMA_NBYTES_MLOFFYES_DMLOE_MASK) +#define DMA_NBYTES_MLOFFYES_SMLOE_MASK (0x80000000U) +#define DMA_NBYTES_MLOFFYES_SMLOE_SHIFT (31U) +#define DMA_NBYTES_MLOFFYES_SMLOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFYES_SMLOE_SHIFT)) & DMA_NBYTES_MLOFFYES_SMLOE_MASK) + +/* The count of DMA_NBYTES_MLOFFYES */ +#define DMA_NBYTES_MLOFFYES_COUNT (32U) + +/*! @name SLAST - TCD Last Source Address Adjustment */ +#define DMA_SLAST_SLAST_MASK (0xFFFFFFFFU) +#define DMA_SLAST_SLAST_SHIFT (0U) +#define DMA_SLAST_SLAST(x) (((uint32_t)(((uint32_t)(x)) << DMA_SLAST_SLAST_SHIFT)) & DMA_SLAST_SLAST_MASK) + +/* The count of DMA_SLAST */ +#define DMA_SLAST_COUNT (32U) + +/*! @name DADDR - TCD Destination Address */ +#define DMA_DADDR_DADDR_MASK (0xFFFFFFFFU) +#define DMA_DADDR_DADDR_SHIFT (0U) +#define DMA_DADDR_DADDR(x) (((uint32_t)(((uint32_t)(x)) << DMA_DADDR_DADDR_SHIFT)) & DMA_DADDR_DADDR_MASK) + +/* The count of DMA_DADDR */ +#define DMA_DADDR_COUNT (32U) + +/*! @name DOFF - TCD Signed Destination Address Offset */ +#define DMA_DOFF_DOFF_MASK (0xFFFFU) +#define DMA_DOFF_DOFF_SHIFT (0U) +#define DMA_DOFF_DOFF(x) (((uint16_t)(((uint16_t)(x)) << DMA_DOFF_DOFF_SHIFT)) & DMA_DOFF_DOFF_MASK) + +/* The count of DMA_DOFF */ +#define DMA_DOFF_COUNT (32U) + +/*! @name CITER_ELINKNO - TCD Current Minor Loop Link, Major Loop Count (Channel Linking Disabled) */ +#define DMA_CITER_ELINKNO_CITER_MASK (0x7FFFU) +#define DMA_CITER_ELINKNO_CITER_SHIFT (0U) +#define DMA_CITER_ELINKNO_CITER(x) (((uint16_t)(((uint16_t)(x)) << DMA_CITER_ELINKNO_CITER_SHIFT)) & DMA_CITER_ELINKNO_CITER_MASK) +#define DMA_CITER_ELINKNO_ELINK_MASK (0x8000U) +#define DMA_CITER_ELINKNO_ELINK_SHIFT (15U) +#define DMA_CITER_ELINKNO_ELINK(x) (((uint16_t)(((uint16_t)(x)) << DMA_CITER_ELINKNO_ELINK_SHIFT)) & DMA_CITER_ELINKNO_ELINK_MASK) + +/* The count of DMA_CITER_ELINKNO */ +#define DMA_CITER_ELINKNO_COUNT (32U) + +/*! @name CITER_ELINKYES - TCD Current Minor Loop Link, Major Loop Count (Channel Linking Enabled) */ +#define DMA_CITER_ELINKYES_CITER_MASK (0x1FFU) +#define DMA_CITER_ELINKYES_CITER_SHIFT (0U) +#define DMA_CITER_ELINKYES_CITER(x) (((uint16_t)(((uint16_t)(x)) << DMA_CITER_ELINKYES_CITER_SHIFT)) & DMA_CITER_ELINKYES_CITER_MASK) +#define DMA_CITER_ELINKYES_LINKCH_MASK (0x3E00U) +#define DMA_CITER_ELINKYES_LINKCH_SHIFT (9U) +#define DMA_CITER_ELINKYES_LINKCH(x) (((uint16_t)(((uint16_t)(x)) << DMA_CITER_ELINKYES_LINKCH_SHIFT)) & DMA_CITER_ELINKYES_LINKCH_MASK) +#define DMA_CITER_ELINKYES_ELINK_MASK (0x8000U) +#define DMA_CITER_ELINKYES_ELINK_SHIFT (15U) +#define DMA_CITER_ELINKYES_ELINK(x) (((uint16_t)(((uint16_t)(x)) << DMA_CITER_ELINKYES_ELINK_SHIFT)) & DMA_CITER_ELINKYES_ELINK_MASK) + +/* The count of DMA_CITER_ELINKYES */ +#define DMA_CITER_ELINKYES_COUNT (32U) + +/*! @name DLAST_SGA - TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define DMA_DLAST_SGA_DLASTSGA_MASK (0xFFFFFFFFU) +#define DMA_DLAST_SGA_DLASTSGA_SHIFT (0U) +#define DMA_DLAST_SGA_DLASTSGA(x) (((uint32_t)(((uint32_t)(x)) << DMA_DLAST_SGA_DLASTSGA_SHIFT)) & DMA_DLAST_SGA_DLASTSGA_MASK) + +/* The count of DMA_DLAST_SGA */ +#define DMA_DLAST_SGA_COUNT (32U) + +/*! @name CSR - TCD Control and Status */ +#define DMA_CSR_START_MASK (0x1U) +#define DMA_CSR_START_SHIFT (0U) +#define DMA_CSR_START(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_START_SHIFT)) & DMA_CSR_START_MASK) +#define DMA_CSR_INTMAJOR_MASK (0x2U) +#define DMA_CSR_INTMAJOR_SHIFT (1U) +#define DMA_CSR_INTMAJOR(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_INTMAJOR_SHIFT)) & DMA_CSR_INTMAJOR_MASK) +#define DMA_CSR_INTHALF_MASK (0x4U) +#define DMA_CSR_INTHALF_SHIFT (2U) +#define DMA_CSR_INTHALF(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_INTHALF_SHIFT)) & DMA_CSR_INTHALF_MASK) +#define DMA_CSR_DREQ_MASK (0x8U) +#define DMA_CSR_DREQ_SHIFT (3U) +#define DMA_CSR_DREQ(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_DREQ_SHIFT)) & DMA_CSR_DREQ_MASK) +#define DMA_CSR_ESG_MASK (0x10U) +#define DMA_CSR_ESG_SHIFT (4U) +#define DMA_CSR_ESG(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_ESG_SHIFT)) & DMA_CSR_ESG_MASK) +#define DMA_CSR_MAJORELINK_MASK (0x20U) +#define DMA_CSR_MAJORELINK_SHIFT (5U) +#define DMA_CSR_MAJORELINK(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_MAJORELINK_SHIFT)) & DMA_CSR_MAJORELINK_MASK) +#define DMA_CSR_ACTIVE_MASK (0x40U) +#define DMA_CSR_ACTIVE_SHIFT (6U) +#define DMA_CSR_ACTIVE(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_ACTIVE_SHIFT)) & DMA_CSR_ACTIVE_MASK) +#define DMA_CSR_DONE_MASK (0x80U) +#define DMA_CSR_DONE_SHIFT (7U) +#define DMA_CSR_DONE(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_DONE_SHIFT)) & DMA_CSR_DONE_MASK) +#define DMA_CSR_MAJORLINKCH_MASK (0x1F00U) +#define DMA_CSR_MAJORLINKCH_SHIFT (8U) +#define DMA_CSR_MAJORLINKCH(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_MAJORLINKCH_SHIFT)) & DMA_CSR_MAJORLINKCH_MASK) +#define DMA_CSR_BWC_MASK (0xC000U) +#define DMA_CSR_BWC_SHIFT (14U) +#define DMA_CSR_BWC(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_BWC_SHIFT)) & DMA_CSR_BWC_MASK) + +/* The count of DMA_CSR */ +#define DMA_CSR_COUNT (32U) + +/*! @name BITER_ELINKNO - TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Disabled) */ +#define DMA_BITER_ELINKNO_BITER_MASK (0x7FFFU) +#define DMA_BITER_ELINKNO_BITER_SHIFT (0U) +#define DMA_BITER_ELINKNO_BITER(x) (((uint16_t)(((uint16_t)(x)) << DMA_BITER_ELINKNO_BITER_SHIFT)) & DMA_BITER_ELINKNO_BITER_MASK) +#define DMA_BITER_ELINKNO_ELINK_MASK (0x8000U) +#define DMA_BITER_ELINKNO_ELINK_SHIFT (15U) +#define DMA_BITER_ELINKNO_ELINK(x) (((uint16_t)(((uint16_t)(x)) << DMA_BITER_ELINKNO_ELINK_SHIFT)) & DMA_BITER_ELINKNO_ELINK_MASK) + +/* The count of DMA_BITER_ELINKNO */ +#define DMA_BITER_ELINKNO_COUNT (32U) + +/*! @name BITER_ELINKYES - TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Enabled) */ +#define DMA_BITER_ELINKYES_BITER_MASK (0x1FFU) +#define DMA_BITER_ELINKYES_BITER_SHIFT (0U) +#define DMA_BITER_ELINKYES_BITER(x) (((uint16_t)(((uint16_t)(x)) << DMA_BITER_ELINKYES_BITER_SHIFT)) & DMA_BITER_ELINKYES_BITER_MASK) +#define DMA_BITER_ELINKYES_LINKCH_MASK (0x3E00U) +#define DMA_BITER_ELINKYES_LINKCH_SHIFT (9U) +#define DMA_BITER_ELINKYES_LINKCH(x) (((uint16_t)(((uint16_t)(x)) << DMA_BITER_ELINKYES_LINKCH_SHIFT)) & DMA_BITER_ELINKYES_LINKCH_MASK) +#define DMA_BITER_ELINKYES_ELINK_MASK (0x8000U) +#define DMA_BITER_ELINKYES_ELINK_SHIFT (15U) +#define DMA_BITER_ELINKYES_ELINK(x) (((uint16_t)(((uint16_t)(x)) << DMA_BITER_ELINKYES_ELINK_SHIFT)) & DMA_BITER_ELINKYES_ELINK_MASK) + +/* The count of DMA_BITER_ELINKYES */ +#define DMA_BITER_ELINKYES_COUNT (32U) + + +/*! + * @} + */ /* end of group DMA_Register_Masks */ + + +/* DMA - Peripheral instance base addresses */ +/** Peripheral DMA base address */ +#define DMA_BASE (0x40008000u) +/** Peripheral DMA base pointer */ +#define DMA0 ((DMA_Type *)DMA_BASE) +/** Array initializer of DMA peripheral base addresses */ +#define DMA_BASE_ADDRS { DMA_BASE } +/** Array initializer of DMA peripheral base pointers */ +#define DMA_BASE_PTRS { DMA0 } +/** Interrupt vectors for the DMA peripheral type */ +#define DMA_CHN_IRQS { DMA0_DMA16_IRQn, DMA1_DMA17_IRQn, DMA2_DMA18_IRQn, DMA3_DMA19_IRQn, DMA4_DMA20_IRQn, DMA5_DMA21_IRQn, DMA6_DMA22_IRQn, DMA7_DMA23_IRQn, DMA8_DMA24_IRQn, DMA9_DMA25_IRQn, DMA10_DMA26_IRQn, DMA11_DMA27_IRQn, DMA12_DMA28_IRQn, DMA13_DMA29_IRQn, DMA14_DMA30_IRQn, DMA15_DMA31_IRQn, DMA0_DMA16_IRQn, DMA1_DMA17_IRQn, DMA2_DMA18_IRQn, DMA3_DMA19_IRQn, DMA4_DMA20_IRQn, DMA5_DMA21_IRQn, DMA6_DMA22_IRQn, DMA7_DMA23_IRQn, DMA8_DMA24_IRQn, DMA9_DMA25_IRQn, DMA10_DMA26_IRQn, DMA11_DMA27_IRQn, DMA12_DMA28_IRQn, DMA13_DMA29_IRQn, DMA14_DMA30_IRQn, DMA15_DMA31_IRQn } +#define DMA_ERROR_IRQS { DMA_Error_IRQn } + +/*! + * @} + */ /* end of group DMA_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DMAMUX Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMAMUX_Peripheral_Access_Layer DMAMUX Peripheral Access Layer + * @{ + */ + +/** DMAMUX - Register Layout Typedef */ +typedef struct { + __IO uint8_t CHCFG[32]; /**< Channel Configuration register, array offset: 0x0, array step: 0x1 */ +} DMAMUX_Type; + +/* ---------------------------------------------------------------------------- + -- DMAMUX Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMAMUX_Register_Masks DMAMUX Register Masks + * @{ + */ + +/*! @name CHCFG - Channel Configuration register */ +#define DMAMUX_CHCFG_SOURCE_MASK (0x3FU) +#define DMAMUX_CHCFG_SOURCE_SHIFT (0U) +#define DMAMUX_CHCFG_SOURCE(x) (((uint8_t)(((uint8_t)(x)) << DMAMUX_CHCFG_SOURCE_SHIFT)) & DMAMUX_CHCFG_SOURCE_MASK) +#define DMAMUX_CHCFG_TRIG_MASK (0x40U) +#define DMAMUX_CHCFG_TRIG_SHIFT (6U) +#define DMAMUX_CHCFG_TRIG(x) (((uint8_t)(((uint8_t)(x)) << DMAMUX_CHCFG_TRIG_SHIFT)) & DMAMUX_CHCFG_TRIG_MASK) +#define DMAMUX_CHCFG_ENBL_MASK (0x80U) +#define DMAMUX_CHCFG_ENBL_SHIFT (7U) +#define DMAMUX_CHCFG_ENBL(x) (((uint8_t)(((uint8_t)(x)) << DMAMUX_CHCFG_ENBL_SHIFT)) & DMAMUX_CHCFG_ENBL_MASK) + +/* The count of DMAMUX_CHCFG */ +#define DMAMUX_CHCFG_COUNT (32U) + + +/*! + * @} + */ /* end of group DMAMUX_Register_Masks */ + + +/* DMAMUX - Peripheral instance base addresses */ +/** Peripheral DMAMUX base address */ +#define DMAMUX_BASE (0x40021000u) +/** Peripheral DMAMUX base pointer */ +#define DMAMUX ((DMAMUX_Type *)DMAMUX_BASE) +/** Array initializer of DMAMUX peripheral base addresses */ +#define DMAMUX_BASE_ADDRS { DMAMUX_BASE } +/** Array initializer of DMAMUX peripheral base pointers */ +#define DMAMUX_BASE_PTRS { DMAMUX } + +/*! + * @} + */ /* end of group DMAMUX_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- EMVSIM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup EMVSIM_Peripheral_Access_Layer EMVSIM Peripheral Access Layer + * @{ + */ + +/** EMVSIM - Register Layout Typedef */ +typedef struct { + __I uint32_t VER_ID; /**< Version ID Register, offset: 0x0 */ + __I uint32_t PARAM; /**< Parameter Register, offset: 0x4 */ + __IO uint32_t CLKCFG; /**< Clock Configuration Register, offset: 0x8 */ + __IO uint32_t DIVISOR; /**< Baud Rate Divisor Register, offset: 0xC */ + __IO uint32_t CTRL; /**< Control Register, offset: 0x10 */ + __IO uint32_t INT_MASK; /**< Interrupt Mask Register, offset: 0x14 */ + __IO uint32_t RX_THD; /**< Receiver Threshold Register, offset: 0x18 */ + __IO uint32_t TX_THD; /**< Transmitter Threshold Register, offset: 0x1C */ + __IO uint32_t RX_STATUS; /**< Receive Status Register, offset: 0x20 */ + __IO uint32_t TX_STATUS; /**< Transmitter Status Register, offset: 0x24 */ + __IO uint32_t PCSR; /**< Port Control and Status Register, offset: 0x28 */ + __I uint32_t RX_BUF; /**< Receive Data Read Buffer, offset: 0x2C */ + __IO uint32_t TX_BUF; /**< Transmit Data Buffer, offset: 0x30 */ + __IO uint32_t TX_GETU; /**< Transmitter Guard ETU Value Register, offset: 0x34 */ + __IO uint32_t CWT_VAL; /**< Character Wait Time Value Register, offset: 0x38 */ + __IO uint32_t BWT_VAL; /**< Block Wait Time Value Register, offset: 0x3C */ + __IO uint32_t BGT_VAL; /**< Block Guard Time Value Register, offset: 0x40 */ + __IO uint32_t GPCNT0_VAL; /**< General Purpose Counter 0 Timeout Value Register, offset: 0x44 */ + __IO uint32_t GPCNT1_VAL; /**< General Purpose Counter 1 Timeout Value, offset: 0x48 */ +} EMVSIM_Type; + +/* ---------------------------------------------------------------------------- + -- EMVSIM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup EMVSIM_Register_Masks EMVSIM Register Masks + * @{ + */ + +/*! @name VER_ID - Version ID Register */ +#define EMVSIM_VER_ID_VER_MASK (0xFFFFFFFFU) +#define EMVSIM_VER_ID_VER_SHIFT (0U) +#define EMVSIM_VER_ID_VER(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_VER_ID_VER_SHIFT)) & EMVSIM_VER_ID_VER_MASK) + +/*! @name PARAM - Parameter Register */ +#define EMVSIM_PARAM_RX_FIFO_DEPTH_MASK (0xFFU) +#define EMVSIM_PARAM_RX_FIFO_DEPTH_SHIFT (0U) +#define EMVSIM_PARAM_RX_FIFO_DEPTH(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PARAM_RX_FIFO_DEPTH_SHIFT)) & EMVSIM_PARAM_RX_FIFO_DEPTH_MASK) +#define EMVSIM_PARAM_TX_FIFO_DEPTH_MASK (0xFF00U) +#define EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT (8U) +#define EMVSIM_PARAM_TX_FIFO_DEPTH(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT)) & EMVSIM_PARAM_TX_FIFO_DEPTH_MASK) + +/*! @name CLKCFG - Clock Configuration Register */ +#define EMVSIM_CLKCFG_CLK_PRSC_MASK (0xFFU) +#define EMVSIM_CLKCFG_CLK_PRSC_SHIFT (0U) +#define EMVSIM_CLKCFG_CLK_PRSC(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CLKCFG_CLK_PRSC_SHIFT)) & EMVSIM_CLKCFG_CLK_PRSC_MASK) +#define EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK (0x300U) +#define EMVSIM_CLKCFG_GPCNT1_CLK_SEL_SHIFT (8U) +#define EMVSIM_CLKCFG_GPCNT1_CLK_SEL(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CLKCFG_GPCNT1_CLK_SEL_SHIFT)) & EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK) +#define EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK (0xC00U) +#define EMVSIM_CLKCFG_GPCNT0_CLK_SEL_SHIFT (10U) +#define EMVSIM_CLKCFG_GPCNT0_CLK_SEL(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CLKCFG_GPCNT0_CLK_SEL_SHIFT)) & EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK) + +/*! @name DIVISOR - Baud Rate Divisor Register */ +#define EMVSIM_DIVISOR_DIVISOR_VALUE_MASK (0x1FFU) +#define EMVSIM_DIVISOR_DIVISOR_VALUE_SHIFT (0U) +#define EMVSIM_DIVISOR_DIVISOR_VALUE(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_DIVISOR_DIVISOR_VALUE_SHIFT)) & EMVSIM_DIVISOR_DIVISOR_VALUE_MASK) + +/*! @name CTRL - Control Register */ +#define EMVSIM_CTRL_IC_MASK (0x1U) +#define EMVSIM_CTRL_IC_SHIFT (0U) +#define EMVSIM_CTRL_IC(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_IC_SHIFT)) & EMVSIM_CTRL_IC_MASK) +#define EMVSIM_CTRL_ICM_MASK (0x2U) +#define EMVSIM_CTRL_ICM_SHIFT (1U) +#define EMVSIM_CTRL_ICM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_ICM_SHIFT)) & EMVSIM_CTRL_ICM_MASK) +#define EMVSIM_CTRL_ANACK_MASK (0x4U) +#define EMVSIM_CTRL_ANACK_SHIFT (2U) +#define EMVSIM_CTRL_ANACK(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_ANACK_SHIFT)) & EMVSIM_CTRL_ANACK_MASK) +#define EMVSIM_CTRL_ONACK_MASK (0x8U) +#define EMVSIM_CTRL_ONACK_SHIFT (3U) +#define EMVSIM_CTRL_ONACK(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_ONACK_SHIFT)) & EMVSIM_CTRL_ONACK_MASK) +#define EMVSIM_CTRL_FLSH_RX_MASK (0x100U) +#define EMVSIM_CTRL_FLSH_RX_SHIFT (8U) +#define EMVSIM_CTRL_FLSH_RX(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_FLSH_RX_SHIFT)) & EMVSIM_CTRL_FLSH_RX_MASK) +#define EMVSIM_CTRL_FLSH_TX_MASK (0x200U) +#define EMVSIM_CTRL_FLSH_TX_SHIFT (9U) +#define EMVSIM_CTRL_FLSH_TX(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_FLSH_TX_SHIFT)) & EMVSIM_CTRL_FLSH_TX_MASK) +#define EMVSIM_CTRL_SW_RST_MASK (0x400U) +#define EMVSIM_CTRL_SW_RST_SHIFT (10U) +#define EMVSIM_CTRL_SW_RST(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_SW_RST_SHIFT)) & EMVSIM_CTRL_SW_RST_MASK) +#define EMVSIM_CTRL_KILL_CLOCKS_MASK (0x800U) +#define EMVSIM_CTRL_KILL_CLOCKS_SHIFT (11U) +#define EMVSIM_CTRL_KILL_CLOCKS(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_KILL_CLOCKS_SHIFT)) & EMVSIM_CTRL_KILL_CLOCKS_MASK) +#define EMVSIM_CTRL_DOZE_EN_MASK (0x1000U) +#define EMVSIM_CTRL_DOZE_EN_SHIFT (12U) +#define EMVSIM_CTRL_DOZE_EN(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_DOZE_EN_SHIFT)) & EMVSIM_CTRL_DOZE_EN_MASK) +#define EMVSIM_CTRL_STOP_EN_MASK (0x2000U) +#define EMVSIM_CTRL_STOP_EN_SHIFT (13U) +#define EMVSIM_CTRL_STOP_EN(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_STOP_EN_SHIFT)) & EMVSIM_CTRL_STOP_EN_MASK) +#define EMVSIM_CTRL_RCV_EN_MASK (0x10000U) +#define EMVSIM_CTRL_RCV_EN_SHIFT (16U) +#define EMVSIM_CTRL_RCV_EN(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_RCV_EN_SHIFT)) & EMVSIM_CTRL_RCV_EN_MASK) +#define EMVSIM_CTRL_XMT_EN_MASK (0x20000U) +#define EMVSIM_CTRL_XMT_EN_SHIFT (17U) +#define EMVSIM_CTRL_XMT_EN(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_XMT_EN_SHIFT)) & EMVSIM_CTRL_XMT_EN_MASK) +#define EMVSIM_CTRL_RCVR_11_MASK (0x40000U) +#define EMVSIM_CTRL_RCVR_11_SHIFT (18U) +#define EMVSIM_CTRL_RCVR_11(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_RCVR_11_SHIFT)) & EMVSIM_CTRL_RCVR_11_MASK) +#define EMVSIM_CTRL_RX_DMA_EN_MASK (0x80000U) +#define EMVSIM_CTRL_RX_DMA_EN_SHIFT (19U) +#define EMVSIM_CTRL_RX_DMA_EN(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_RX_DMA_EN_SHIFT)) & EMVSIM_CTRL_RX_DMA_EN_MASK) +#define EMVSIM_CTRL_TX_DMA_EN_MASK (0x100000U) +#define EMVSIM_CTRL_TX_DMA_EN_SHIFT (20U) +#define EMVSIM_CTRL_TX_DMA_EN(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_TX_DMA_EN_SHIFT)) & EMVSIM_CTRL_TX_DMA_EN_MASK) +#define EMVSIM_CTRL_INV_CRC_VAL_MASK (0x1000000U) +#define EMVSIM_CTRL_INV_CRC_VAL_SHIFT (24U) +#define EMVSIM_CTRL_INV_CRC_VAL(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_INV_CRC_VAL_SHIFT)) & EMVSIM_CTRL_INV_CRC_VAL_MASK) +#define EMVSIM_CTRL_CRC_OUT_FLIP_MASK (0x2000000U) +#define EMVSIM_CTRL_CRC_OUT_FLIP_SHIFT (25U) +#define EMVSIM_CTRL_CRC_OUT_FLIP(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_CRC_OUT_FLIP_SHIFT)) & EMVSIM_CTRL_CRC_OUT_FLIP_MASK) +#define EMVSIM_CTRL_CRC_IN_FLIP_MASK (0x4000000U) +#define EMVSIM_CTRL_CRC_IN_FLIP_SHIFT (26U) +#define EMVSIM_CTRL_CRC_IN_FLIP(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_CRC_IN_FLIP_SHIFT)) & EMVSIM_CTRL_CRC_IN_FLIP_MASK) +#define EMVSIM_CTRL_CWT_EN_MASK (0x8000000U) +#define EMVSIM_CTRL_CWT_EN_SHIFT (27U) +#define EMVSIM_CTRL_CWT_EN(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_CWT_EN_SHIFT)) & EMVSIM_CTRL_CWT_EN_MASK) +#define EMVSIM_CTRL_LRC_EN_MASK (0x10000000U) +#define EMVSIM_CTRL_LRC_EN_SHIFT (28U) +#define EMVSIM_CTRL_LRC_EN(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_LRC_EN_SHIFT)) & EMVSIM_CTRL_LRC_EN_MASK) +#define EMVSIM_CTRL_CRC_EN_MASK (0x20000000U) +#define EMVSIM_CTRL_CRC_EN_SHIFT (29U) +#define EMVSIM_CTRL_CRC_EN(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_CRC_EN_SHIFT)) & EMVSIM_CTRL_CRC_EN_MASK) +#define EMVSIM_CTRL_XMT_CRC_LRC_MASK (0x40000000U) +#define EMVSIM_CTRL_XMT_CRC_LRC_SHIFT (30U) +#define EMVSIM_CTRL_XMT_CRC_LRC(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_XMT_CRC_LRC_SHIFT)) & EMVSIM_CTRL_XMT_CRC_LRC_MASK) +#define EMVSIM_CTRL_BWT_EN_MASK (0x80000000U) +#define EMVSIM_CTRL_BWT_EN_SHIFT (31U) +#define EMVSIM_CTRL_BWT_EN(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CTRL_BWT_EN_SHIFT)) & EMVSIM_CTRL_BWT_EN_MASK) + +/*! @name INT_MASK - Interrupt Mask Register */ +#define EMVSIM_INT_MASK_RDT_IM_MASK (0x1U) +#define EMVSIM_INT_MASK_RDT_IM_SHIFT (0U) +#define EMVSIM_INT_MASK_RDT_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_RDT_IM_SHIFT)) & EMVSIM_INT_MASK_RDT_IM_MASK) +#define EMVSIM_INT_MASK_TC_IM_MASK (0x2U) +#define EMVSIM_INT_MASK_TC_IM_SHIFT (1U) +#define EMVSIM_INT_MASK_TC_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_TC_IM_SHIFT)) & EMVSIM_INT_MASK_TC_IM_MASK) +#define EMVSIM_INT_MASK_RFO_IM_MASK (0x4U) +#define EMVSIM_INT_MASK_RFO_IM_SHIFT (2U) +#define EMVSIM_INT_MASK_RFO_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_RFO_IM_SHIFT)) & EMVSIM_INT_MASK_RFO_IM_MASK) +#define EMVSIM_INT_MASK_ETC_IM_MASK (0x8U) +#define EMVSIM_INT_MASK_ETC_IM_SHIFT (3U) +#define EMVSIM_INT_MASK_ETC_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_ETC_IM_SHIFT)) & EMVSIM_INT_MASK_ETC_IM_MASK) +#define EMVSIM_INT_MASK_TFE_IM_MASK (0x10U) +#define EMVSIM_INT_MASK_TFE_IM_SHIFT (4U) +#define EMVSIM_INT_MASK_TFE_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_TFE_IM_SHIFT)) & EMVSIM_INT_MASK_TFE_IM_MASK) +#define EMVSIM_INT_MASK_TNACK_IM_MASK (0x20U) +#define EMVSIM_INT_MASK_TNACK_IM_SHIFT (5U) +#define EMVSIM_INT_MASK_TNACK_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_TNACK_IM_SHIFT)) & EMVSIM_INT_MASK_TNACK_IM_MASK) +#define EMVSIM_INT_MASK_TFF_IM_MASK (0x40U) +#define EMVSIM_INT_MASK_TFF_IM_SHIFT (6U) +#define EMVSIM_INT_MASK_TFF_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_TFF_IM_SHIFT)) & EMVSIM_INT_MASK_TFF_IM_MASK) +#define EMVSIM_INT_MASK_TDT_IM_MASK (0x80U) +#define EMVSIM_INT_MASK_TDT_IM_SHIFT (7U) +#define EMVSIM_INT_MASK_TDT_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_TDT_IM_SHIFT)) & EMVSIM_INT_MASK_TDT_IM_MASK) +#define EMVSIM_INT_MASK_GPCNT0_IM_MASK (0x100U) +#define EMVSIM_INT_MASK_GPCNT0_IM_SHIFT (8U) +#define EMVSIM_INT_MASK_GPCNT0_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_GPCNT0_IM_SHIFT)) & EMVSIM_INT_MASK_GPCNT0_IM_MASK) +#define EMVSIM_INT_MASK_CWT_ERR_IM_MASK (0x200U) +#define EMVSIM_INT_MASK_CWT_ERR_IM_SHIFT (9U) +#define EMVSIM_INT_MASK_CWT_ERR_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_CWT_ERR_IM_SHIFT)) & EMVSIM_INT_MASK_CWT_ERR_IM_MASK) +#define EMVSIM_INT_MASK_RNACK_IM_MASK (0x400U) +#define EMVSIM_INT_MASK_RNACK_IM_SHIFT (10U) +#define EMVSIM_INT_MASK_RNACK_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_RNACK_IM_SHIFT)) & EMVSIM_INT_MASK_RNACK_IM_MASK) +#define EMVSIM_INT_MASK_BWT_ERR_IM_MASK (0x800U) +#define EMVSIM_INT_MASK_BWT_ERR_IM_SHIFT (11U) +#define EMVSIM_INT_MASK_BWT_ERR_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_BWT_ERR_IM_SHIFT)) & EMVSIM_INT_MASK_BWT_ERR_IM_MASK) +#define EMVSIM_INT_MASK_BGT_ERR_IM_MASK (0x1000U) +#define EMVSIM_INT_MASK_BGT_ERR_IM_SHIFT (12U) +#define EMVSIM_INT_MASK_BGT_ERR_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_BGT_ERR_IM_SHIFT)) & EMVSIM_INT_MASK_BGT_ERR_IM_MASK) +#define EMVSIM_INT_MASK_GPCNT1_IM_MASK (0x2000U) +#define EMVSIM_INT_MASK_GPCNT1_IM_SHIFT (13U) +#define EMVSIM_INT_MASK_GPCNT1_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_GPCNT1_IM_SHIFT)) & EMVSIM_INT_MASK_GPCNT1_IM_MASK) +#define EMVSIM_INT_MASK_RX_DATA_IM_MASK (0x4000U) +#define EMVSIM_INT_MASK_RX_DATA_IM_SHIFT (14U) +#define EMVSIM_INT_MASK_RX_DATA_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_RX_DATA_IM_SHIFT)) & EMVSIM_INT_MASK_RX_DATA_IM_MASK) +#define EMVSIM_INT_MASK_PEF_IM_MASK (0x8000U) +#define EMVSIM_INT_MASK_PEF_IM_SHIFT (15U) +#define EMVSIM_INT_MASK_PEF_IM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_INT_MASK_PEF_IM_SHIFT)) & EMVSIM_INT_MASK_PEF_IM_MASK) + +/*! @name RX_THD - Receiver Threshold Register */ +#define EMVSIM_RX_THD_RDT_MASK (0xFU) +#define EMVSIM_RX_THD_RDT_SHIFT (0U) +#define EMVSIM_RX_THD_RDT(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_THD_RDT_SHIFT)) & EMVSIM_RX_THD_RDT_MASK) +#define EMVSIM_RX_THD_RNCK_THD_MASK (0xF00U) +#define EMVSIM_RX_THD_RNCK_THD_SHIFT (8U) +#define EMVSIM_RX_THD_RNCK_THD(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_THD_RNCK_THD_SHIFT)) & EMVSIM_RX_THD_RNCK_THD_MASK) + +/*! @name TX_THD - Transmitter Threshold Register */ +#define EMVSIM_TX_THD_TDT_MASK (0xFU) +#define EMVSIM_TX_THD_TDT_SHIFT (0U) +#define EMVSIM_TX_THD_TDT(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_THD_TDT_SHIFT)) & EMVSIM_TX_THD_TDT_MASK) +#define EMVSIM_TX_THD_TNCK_THD_MASK (0xF00U) +#define EMVSIM_TX_THD_TNCK_THD_SHIFT (8U) +#define EMVSIM_TX_THD_TNCK_THD(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_THD_TNCK_THD_SHIFT)) & EMVSIM_TX_THD_TNCK_THD_MASK) + +/*! @name RX_STATUS - Receive Status Register */ +#define EMVSIM_RX_STATUS_RFO_MASK (0x1U) +#define EMVSIM_RX_STATUS_RFO_SHIFT (0U) +#define EMVSIM_RX_STATUS_RFO(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_RFO_SHIFT)) & EMVSIM_RX_STATUS_RFO_MASK) +#define EMVSIM_RX_STATUS_RX_DATA_MASK (0x10U) +#define EMVSIM_RX_STATUS_RX_DATA_SHIFT (4U) +#define EMVSIM_RX_STATUS_RX_DATA(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_RX_DATA_SHIFT)) & EMVSIM_RX_STATUS_RX_DATA_MASK) +#define EMVSIM_RX_STATUS_RDTF_MASK (0x20U) +#define EMVSIM_RX_STATUS_RDTF_SHIFT (5U) +#define EMVSIM_RX_STATUS_RDTF(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_RDTF_SHIFT)) & EMVSIM_RX_STATUS_RDTF_MASK) +#define EMVSIM_RX_STATUS_LRC_OK_MASK (0x40U) +#define EMVSIM_RX_STATUS_LRC_OK_SHIFT (6U) +#define EMVSIM_RX_STATUS_LRC_OK(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_LRC_OK_SHIFT)) & EMVSIM_RX_STATUS_LRC_OK_MASK) +#define EMVSIM_RX_STATUS_CRC_OK_MASK (0x80U) +#define EMVSIM_RX_STATUS_CRC_OK_SHIFT (7U) +#define EMVSIM_RX_STATUS_CRC_OK(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_CRC_OK_SHIFT)) & EMVSIM_RX_STATUS_CRC_OK_MASK) +#define EMVSIM_RX_STATUS_CWT_ERR_MASK (0x100U) +#define EMVSIM_RX_STATUS_CWT_ERR_SHIFT (8U) +#define EMVSIM_RX_STATUS_CWT_ERR(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_CWT_ERR_SHIFT)) & EMVSIM_RX_STATUS_CWT_ERR_MASK) +#define EMVSIM_RX_STATUS_RTE_MASK (0x200U) +#define EMVSIM_RX_STATUS_RTE_SHIFT (9U) +#define EMVSIM_RX_STATUS_RTE(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_RTE_SHIFT)) & EMVSIM_RX_STATUS_RTE_MASK) +#define EMVSIM_RX_STATUS_BWT_ERR_MASK (0x400U) +#define EMVSIM_RX_STATUS_BWT_ERR_SHIFT (10U) +#define EMVSIM_RX_STATUS_BWT_ERR(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_BWT_ERR_SHIFT)) & EMVSIM_RX_STATUS_BWT_ERR_MASK) +#define EMVSIM_RX_STATUS_BGT_ERR_MASK (0x800U) +#define EMVSIM_RX_STATUS_BGT_ERR_SHIFT (11U) +#define EMVSIM_RX_STATUS_BGT_ERR(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_BGT_ERR_SHIFT)) & EMVSIM_RX_STATUS_BGT_ERR_MASK) +#define EMVSIM_RX_STATUS_PEF_MASK (0x1000U) +#define EMVSIM_RX_STATUS_PEF_SHIFT (12U) +#define EMVSIM_RX_STATUS_PEF(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_PEF_SHIFT)) & EMVSIM_RX_STATUS_PEF_MASK) +#define EMVSIM_RX_STATUS_FEF_MASK (0x2000U) +#define EMVSIM_RX_STATUS_FEF_SHIFT (13U) +#define EMVSIM_RX_STATUS_FEF(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_FEF_SHIFT)) & EMVSIM_RX_STATUS_FEF_MASK) +#define EMVSIM_RX_STATUS_RX_WPTR_MASK (0xF0000U) +#define EMVSIM_RX_STATUS_RX_WPTR_SHIFT (16U) +#define EMVSIM_RX_STATUS_RX_WPTR(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_RX_WPTR_SHIFT)) & EMVSIM_RX_STATUS_RX_WPTR_MASK) +#define EMVSIM_RX_STATUS_RX_CNT_MASK (0x1F000000U) +#define EMVSIM_RX_STATUS_RX_CNT_SHIFT (24U) +#define EMVSIM_RX_STATUS_RX_CNT(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_STATUS_RX_CNT_SHIFT)) & EMVSIM_RX_STATUS_RX_CNT_MASK) + +/*! @name TX_STATUS - Transmitter Status Register */ +#define EMVSIM_TX_STATUS_TNTE_MASK (0x1U) +#define EMVSIM_TX_STATUS_TNTE_SHIFT (0U) +#define EMVSIM_TX_STATUS_TNTE(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_STATUS_TNTE_SHIFT)) & EMVSIM_TX_STATUS_TNTE_MASK) +#define EMVSIM_TX_STATUS_TFE_MASK (0x8U) +#define EMVSIM_TX_STATUS_TFE_SHIFT (3U) +#define EMVSIM_TX_STATUS_TFE(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_STATUS_TFE_SHIFT)) & EMVSIM_TX_STATUS_TFE_MASK) +#define EMVSIM_TX_STATUS_ETCF_MASK (0x10U) +#define EMVSIM_TX_STATUS_ETCF_SHIFT (4U) +#define EMVSIM_TX_STATUS_ETCF(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_STATUS_ETCF_SHIFT)) & EMVSIM_TX_STATUS_ETCF_MASK) +#define EMVSIM_TX_STATUS_TCF_MASK (0x20U) +#define EMVSIM_TX_STATUS_TCF_SHIFT (5U) +#define EMVSIM_TX_STATUS_TCF(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_STATUS_TCF_SHIFT)) & EMVSIM_TX_STATUS_TCF_MASK) +#define EMVSIM_TX_STATUS_TFF_MASK (0x40U) +#define EMVSIM_TX_STATUS_TFF_SHIFT (6U) +#define EMVSIM_TX_STATUS_TFF(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_STATUS_TFF_SHIFT)) & EMVSIM_TX_STATUS_TFF_MASK) +#define EMVSIM_TX_STATUS_TDTF_MASK (0x80U) +#define EMVSIM_TX_STATUS_TDTF_SHIFT (7U) +#define EMVSIM_TX_STATUS_TDTF(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_STATUS_TDTF_SHIFT)) & EMVSIM_TX_STATUS_TDTF_MASK) +#define EMVSIM_TX_STATUS_GPCNT0_TO_MASK (0x100U) +#define EMVSIM_TX_STATUS_GPCNT0_TO_SHIFT (8U) +#define EMVSIM_TX_STATUS_GPCNT0_TO(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_STATUS_GPCNT0_TO_SHIFT)) & EMVSIM_TX_STATUS_GPCNT0_TO_MASK) +#define EMVSIM_TX_STATUS_GPCNT1_TO_MASK (0x200U) +#define EMVSIM_TX_STATUS_GPCNT1_TO_SHIFT (9U) +#define EMVSIM_TX_STATUS_GPCNT1_TO(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_STATUS_GPCNT1_TO_SHIFT)) & EMVSIM_TX_STATUS_GPCNT1_TO_MASK) +#define EMVSIM_TX_STATUS_TX_RPTR_MASK (0xF0000U) +#define EMVSIM_TX_STATUS_TX_RPTR_SHIFT (16U) +#define EMVSIM_TX_STATUS_TX_RPTR(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_STATUS_TX_RPTR_SHIFT)) & EMVSIM_TX_STATUS_TX_RPTR_MASK) +#define EMVSIM_TX_STATUS_TX_CNT_MASK (0x1F000000U) +#define EMVSIM_TX_STATUS_TX_CNT_SHIFT (24U) +#define EMVSIM_TX_STATUS_TX_CNT(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_STATUS_TX_CNT_SHIFT)) & EMVSIM_TX_STATUS_TX_CNT_MASK) + +/*! @name PCSR - Port Control and Status Register */ +#define EMVSIM_PCSR_SAPD_MASK (0x1U) +#define EMVSIM_PCSR_SAPD_SHIFT (0U) +#define EMVSIM_PCSR_SAPD(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PCSR_SAPD_SHIFT)) & EMVSIM_PCSR_SAPD_MASK) +#define EMVSIM_PCSR_SVCC_EN_MASK (0x2U) +#define EMVSIM_PCSR_SVCC_EN_SHIFT (1U) +#define EMVSIM_PCSR_SVCC_EN(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PCSR_SVCC_EN_SHIFT)) & EMVSIM_PCSR_SVCC_EN_MASK) +#define EMVSIM_PCSR_VCCENP_MASK (0x4U) +#define EMVSIM_PCSR_VCCENP_SHIFT (2U) +#define EMVSIM_PCSR_VCCENP(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PCSR_VCCENP_SHIFT)) & EMVSIM_PCSR_VCCENP_MASK) +#define EMVSIM_PCSR_SRST_MASK (0x8U) +#define EMVSIM_PCSR_SRST_SHIFT (3U) +#define EMVSIM_PCSR_SRST(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PCSR_SRST_SHIFT)) & EMVSIM_PCSR_SRST_MASK) +#define EMVSIM_PCSR_SCEN_MASK (0x10U) +#define EMVSIM_PCSR_SCEN_SHIFT (4U) +#define EMVSIM_PCSR_SCEN(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PCSR_SCEN_SHIFT)) & EMVSIM_PCSR_SCEN_MASK) +#define EMVSIM_PCSR_SCSP_MASK (0x20U) +#define EMVSIM_PCSR_SCSP_SHIFT (5U) +#define EMVSIM_PCSR_SCSP(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PCSR_SCSP_SHIFT)) & EMVSIM_PCSR_SCSP_MASK) +#define EMVSIM_PCSR_SPD_MASK (0x80U) +#define EMVSIM_PCSR_SPD_SHIFT (7U) +#define EMVSIM_PCSR_SPD(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PCSR_SPD_SHIFT)) & EMVSIM_PCSR_SPD_MASK) +#define EMVSIM_PCSR_SPDIM_MASK (0x1000000U) +#define EMVSIM_PCSR_SPDIM_SHIFT (24U) +#define EMVSIM_PCSR_SPDIM(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PCSR_SPDIM_SHIFT)) & EMVSIM_PCSR_SPDIM_MASK) +#define EMVSIM_PCSR_SPDIF_MASK (0x2000000U) +#define EMVSIM_PCSR_SPDIF_SHIFT (25U) +#define EMVSIM_PCSR_SPDIF(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PCSR_SPDIF_SHIFT)) & EMVSIM_PCSR_SPDIF_MASK) +#define EMVSIM_PCSR_SPDP_MASK (0x4000000U) +#define EMVSIM_PCSR_SPDP_SHIFT (26U) +#define EMVSIM_PCSR_SPDP(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PCSR_SPDP_SHIFT)) & EMVSIM_PCSR_SPDP_MASK) +#define EMVSIM_PCSR_SPDES_MASK (0x8000000U) +#define EMVSIM_PCSR_SPDES_SHIFT (27U) +#define EMVSIM_PCSR_SPDES(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_PCSR_SPDES_SHIFT)) & EMVSIM_PCSR_SPDES_MASK) + +/*! @name RX_BUF - Receive Data Read Buffer */ +#define EMVSIM_RX_BUF_RX_BYTE_MASK (0xFFU) +#define EMVSIM_RX_BUF_RX_BYTE_SHIFT (0U) +#define EMVSIM_RX_BUF_RX_BYTE(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_RX_BUF_RX_BYTE_SHIFT)) & EMVSIM_RX_BUF_RX_BYTE_MASK) + +/*! @name TX_BUF - Transmit Data Buffer */ +#define EMVSIM_TX_BUF_TX_BYTE_MASK (0xFFU) +#define EMVSIM_TX_BUF_TX_BYTE_SHIFT (0U) +#define EMVSIM_TX_BUF_TX_BYTE(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_BUF_TX_BYTE_SHIFT)) & EMVSIM_TX_BUF_TX_BYTE_MASK) + +/*! @name TX_GETU - Transmitter Guard ETU Value Register */ +#define EMVSIM_TX_GETU_GETU_MASK (0xFFU) +#define EMVSIM_TX_GETU_GETU_SHIFT (0U) +#define EMVSIM_TX_GETU_GETU(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_TX_GETU_GETU_SHIFT)) & EMVSIM_TX_GETU_GETU_MASK) + +/*! @name CWT_VAL - Character Wait Time Value Register */ +#define EMVSIM_CWT_VAL_CWT_MASK (0xFFFFU) +#define EMVSIM_CWT_VAL_CWT_SHIFT (0U) +#define EMVSIM_CWT_VAL_CWT(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_CWT_VAL_CWT_SHIFT)) & EMVSIM_CWT_VAL_CWT_MASK) + +/*! @name BWT_VAL - Block Wait Time Value Register */ +#define EMVSIM_BWT_VAL_BWT_MASK (0xFFFFFFFFU) +#define EMVSIM_BWT_VAL_BWT_SHIFT (0U) +#define EMVSIM_BWT_VAL_BWT(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_BWT_VAL_BWT_SHIFT)) & EMVSIM_BWT_VAL_BWT_MASK) + +/*! @name BGT_VAL - Block Guard Time Value Register */ +#define EMVSIM_BGT_VAL_BGT_MASK (0xFFFFU) +#define EMVSIM_BGT_VAL_BGT_SHIFT (0U) +#define EMVSIM_BGT_VAL_BGT(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_BGT_VAL_BGT_SHIFT)) & EMVSIM_BGT_VAL_BGT_MASK) + +/*! @name GPCNT0_VAL - General Purpose Counter 0 Timeout Value Register */ +#define EMVSIM_GPCNT0_VAL_GPCNT0_MASK (0xFFFFU) +#define EMVSIM_GPCNT0_VAL_GPCNT0_SHIFT (0U) +#define EMVSIM_GPCNT0_VAL_GPCNT0(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_GPCNT0_VAL_GPCNT0_SHIFT)) & EMVSIM_GPCNT0_VAL_GPCNT0_MASK) + +/*! @name GPCNT1_VAL - General Purpose Counter 1 Timeout Value */ +#define EMVSIM_GPCNT1_VAL_GPCNT1_MASK (0xFFFFU) +#define EMVSIM_GPCNT1_VAL_GPCNT1_SHIFT (0U) +#define EMVSIM_GPCNT1_VAL_GPCNT1(x) (((uint32_t)(((uint32_t)(x)) << EMVSIM_GPCNT1_VAL_GPCNT1_SHIFT)) & EMVSIM_GPCNT1_VAL_GPCNT1_MASK) + + +/*! + * @} + */ /* end of group EMVSIM_Register_Masks */ + + +/* EMVSIM - Peripheral instance base addresses */ +/** Peripheral EMVSIM0 base address */ +#define EMVSIM0_BASE (0x400D4000u) +/** Peripheral EMVSIM0 base pointer */ +#define EMVSIM0 ((EMVSIM_Type *)EMVSIM0_BASE) +/** Peripheral EMVSIM1 base address */ +#define EMVSIM1_BASE (0x400D5000u) +/** Peripheral EMVSIM1 base pointer */ +#define EMVSIM1 ((EMVSIM_Type *)EMVSIM1_BASE) +/** Array initializer of EMVSIM peripheral base addresses */ +#define EMVSIM_BASE_ADDRS { EMVSIM0_BASE, EMVSIM1_BASE } +/** Array initializer of EMVSIM peripheral base pointers */ +#define EMVSIM_BASE_PTRS { EMVSIM0, EMVSIM1 } +/** Interrupt vectors for the EMVSIM peripheral type */ +#define EMVSIM_IRQS { EMVSIM0_IRQn, EMVSIM1_IRQn } + +/*! + * @} + */ /* end of group EMVSIM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- EWM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup EWM_Peripheral_Access_Layer EWM Peripheral Access Layer + * @{ + */ + +/** EWM - Register Layout Typedef */ +typedef struct { + __IO uint8_t CTRL; /**< Control Register, offset: 0x0 */ + __O uint8_t SERV; /**< Service Register, offset: 0x1 */ + __IO uint8_t CMPL; /**< Compare Low Register, offset: 0x2 */ + __IO uint8_t CMPH; /**< Compare High Register, offset: 0x3 */ + __IO uint8_t CLKCTRL; /**< Clock Control Register, offset: 0x4 */ + __IO uint8_t CLKPRESCALER; /**< Clock Prescaler Register, offset: 0x5 */ +} EWM_Type; + +/* ---------------------------------------------------------------------------- + -- EWM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup EWM_Register_Masks EWM Register Masks + * @{ + */ + +/*! @name CTRL - Control Register */ +#define EWM_CTRL_EWMEN_MASK (0x1U) +#define EWM_CTRL_EWMEN_SHIFT (0U) +#define EWM_CTRL_EWMEN(x) (((uint8_t)(((uint8_t)(x)) << EWM_CTRL_EWMEN_SHIFT)) & EWM_CTRL_EWMEN_MASK) +#define EWM_CTRL_ASSIN_MASK (0x2U) +#define EWM_CTRL_ASSIN_SHIFT (1U) +#define EWM_CTRL_ASSIN(x) (((uint8_t)(((uint8_t)(x)) << EWM_CTRL_ASSIN_SHIFT)) & EWM_CTRL_ASSIN_MASK) +#define EWM_CTRL_INEN_MASK (0x4U) +#define EWM_CTRL_INEN_SHIFT (2U) +#define EWM_CTRL_INEN(x) (((uint8_t)(((uint8_t)(x)) << EWM_CTRL_INEN_SHIFT)) & EWM_CTRL_INEN_MASK) +#define EWM_CTRL_INTEN_MASK (0x8U) +#define EWM_CTRL_INTEN_SHIFT (3U) +#define EWM_CTRL_INTEN(x) (((uint8_t)(((uint8_t)(x)) << EWM_CTRL_INTEN_SHIFT)) & EWM_CTRL_INTEN_MASK) + +/*! @name SERV - Service Register */ +#define EWM_SERV_SERVICE_MASK (0xFFU) +#define EWM_SERV_SERVICE_SHIFT (0U) +#define EWM_SERV_SERVICE(x) (((uint8_t)(((uint8_t)(x)) << EWM_SERV_SERVICE_SHIFT)) & EWM_SERV_SERVICE_MASK) + +/*! @name CMPL - Compare Low Register */ +#define EWM_CMPL_COMPAREL_MASK (0xFFU) +#define EWM_CMPL_COMPAREL_SHIFT (0U) +#define EWM_CMPL_COMPAREL(x) (((uint8_t)(((uint8_t)(x)) << EWM_CMPL_COMPAREL_SHIFT)) & EWM_CMPL_COMPAREL_MASK) + +/*! @name CMPH - Compare High Register */ +#define EWM_CMPH_COMPAREH_MASK (0xFFU) +#define EWM_CMPH_COMPAREH_SHIFT (0U) +#define EWM_CMPH_COMPAREH(x) (((uint8_t)(((uint8_t)(x)) << EWM_CMPH_COMPAREH_SHIFT)) & EWM_CMPH_COMPAREH_MASK) + +/*! @name CLKCTRL - Clock Control Register */ +#define EWM_CLKCTRL_CLKSEL_MASK (0x3U) +#define EWM_CLKCTRL_CLKSEL_SHIFT (0U) +#define EWM_CLKCTRL_CLKSEL(x) (((uint8_t)(((uint8_t)(x)) << EWM_CLKCTRL_CLKSEL_SHIFT)) & EWM_CLKCTRL_CLKSEL_MASK) + +/*! @name CLKPRESCALER - Clock Prescaler Register */ +#define EWM_CLKPRESCALER_CLK_DIV_MASK (0xFFU) +#define EWM_CLKPRESCALER_CLK_DIV_SHIFT (0U) +#define EWM_CLKPRESCALER_CLK_DIV(x) (((uint8_t)(((uint8_t)(x)) << EWM_CLKPRESCALER_CLK_DIV_SHIFT)) & EWM_CLKPRESCALER_CLK_DIV_MASK) + + +/*! + * @} + */ /* end of group EWM_Register_Masks */ + + +/* EWM - Peripheral instance base addresses */ +/** Peripheral EWM base address */ +#define EWM_BASE (0x40061000u) +/** Peripheral EWM base pointer */ +#define EWM ((EWM_Type *)EWM_BASE) +/** Array initializer of EWM peripheral base addresses */ +#define EWM_BASE_ADDRS { EWM_BASE } +/** Array initializer of EWM peripheral base pointers */ +#define EWM_BASE_PTRS { EWM } +/** Interrupt vectors for the EWM peripheral type */ +#define EWM_IRQS { WDOG_EWM_IRQn } + +/*! + * @} + */ /* end of group EWM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- FB Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FB_Peripheral_Access_Layer FB Peripheral Access Layer + * @{ + */ + +/** FB - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0xC */ + __IO uint32_t CSAR; /**< Chip Select Address Register, array offset: 0x0, array step: 0xC */ + __IO uint32_t CSMR; /**< Chip Select Mask Register, array offset: 0x4, array step: 0xC */ + __IO uint32_t CSCR; /**< Chip Select Control Register, array offset: 0x8, array step: 0xC */ + } CS[6]; + uint8_t RESERVED_0[24]; + __IO uint32_t CSPMCR; /**< Chip Select port Multiplexing Control Register, offset: 0x60 */ +} FB_Type; + +/* ---------------------------------------------------------------------------- + -- FB Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FB_Register_Masks FB Register Masks + * @{ + */ + +/*! @name CSAR - Chip Select Address Register */ +#define FB_CSAR_BA_MASK (0xFFFF0000U) +#define FB_CSAR_BA_SHIFT (16U) +#define FB_CSAR_BA(x) (((uint32_t)(((uint32_t)(x)) << FB_CSAR_BA_SHIFT)) & FB_CSAR_BA_MASK) + +/* The count of FB_CSAR */ +#define FB_CSAR_COUNT (6U) + +/*! @name CSMR - Chip Select Mask Register */ +#define FB_CSMR_V_MASK (0x1U) +#define FB_CSMR_V_SHIFT (0U) +#define FB_CSMR_V(x) (((uint32_t)(((uint32_t)(x)) << FB_CSMR_V_SHIFT)) & FB_CSMR_V_MASK) +#define FB_CSMR_WP_MASK (0x100U) +#define FB_CSMR_WP_SHIFT (8U) +#define FB_CSMR_WP(x) (((uint32_t)(((uint32_t)(x)) << FB_CSMR_WP_SHIFT)) & FB_CSMR_WP_MASK) +#define FB_CSMR_BAM_MASK (0xFFFF0000U) +#define FB_CSMR_BAM_SHIFT (16U) +#define FB_CSMR_BAM(x) (((uint32_t)(((uint32_t)(x)) << FB_CSMR_BAM_SHIFT)) & FB_CSMR_BAM_MASK) + +/* The count of FB_CSMR */ +#define FB_CSMR_COUNT (6U) + +/*! @name CSCR - Chip Select Control Register */ +#define FB_CSCR_BSTW_MASK (0x8U) +#define FB_CSCR_BSTW_SHIFT (3U) +#define FB_CSCR_BSTW(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_BSTW_SHIFT)) & FB_CSCR_BSTW_MASK) +#define FB_CSCR_BSTR_MASK (0x10U) +#define FB_CSCR_BSTR_SHIFT (4U) +#define FB_CSCR_BSTR(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_BSTR_SHIFT)) & FB_CSCR_BSTR_MASK) +#define FB_CSCR_BEM_MASK (0x20U) +#define FB_CSCR_BEM_SHIFT (5U) +#define FB_CSCR_BEM(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_BEM_SHIFT)) & FB_CSCR_BEM_MASK) +#define FB_CSCR_PS_MASK (0xC0U) +#define FB_CSCR_PS_SHIFT (6U) +#define FB_CSCR_PS(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_PS_SHIFT)) & FB_CSCR_PS_MASK) +#define FB_CSCR_AA_MASK (0x100U) +#define FB_CSCR_AA_SHIFT (8U) +#define FB_CSCR_AA(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_AA_SHIFT)) & FB_CSCR_AA_MASK) +#define FB_CSCR_BLS_MASK (0x200U) +#define FB_CSCR_BLS_SHIFT (9U) +#define FB_CSCR_BLS(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_BLS_SHIFT)) & FB_CSCR_BLS_MASK) +#define FB_CSCR_WS_MASK (0xFC00U) +#define FB_CSCR_WS_SHIFT (10U) +#define FB_CSCR_WS(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_WS_SHIFT)) & FB_CSCR_WS_MASK) +#define FB_CSCR_WRAH_MASK (0x30000U) +#define FB_CSCR_WRAH_SHIFT (16U) +#define FB_CSCR_WRAH(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_WRAH_SHIFT)) & FB_CSCR_WRAH_MASK) +#define FB_CSCR_RDAH_MASK (0xC0000U) +#define FB_CSCR_RDAH_SHIFT (18U) +#define FB_CSCR_RDAH(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_RDAH_SHIFT)) & FB_CSCR_RDAH_MASK) +#define FB_CSCR_ASET_MASK (0x300000U) +#define FB_CSCR_ASET_SHIFT (20U) +#define FB_CSCR_ASET(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_ASET_SHIFT)) & FB_CSCR_ASET_MASK) +#define FB_CSCR_EXTS_MASK (0x400000U) +#define FB_CSCR_EXTS_SHIFT (22U) +#define FB_CSCR_EXTS(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_EXTS_SHIFT)) & FB_CSCR_EXTS_MASK) +#define FB_CSCR_SWSEN_MASK (0x800000U) +#define FB_CSCR_SWSEN_SHIFT (23U) +#define FB_CSCR_SWSEN(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_SWSEN_SHIFT)) & FB_CSCR_SWSEN_MASK) +#define FB_CSCR_SWS_MASK (0xFC000000U) +#define FB_CSCR_SWS_SHIFT (26U) +#define FB_CSCR_SWS(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_SWS_SHIFT)) & FB_CSCR_SWS_MASK) + +/* The count of FB_CSCR */ +#define FB_CSCR_COUNT (6U) + +/*! @name CSPMCR - Chip Select port Multiplexing Control Register */ +#define FB_CSPMCR_GROUP5_MASK (0xF000U) +#define FB_CSPMCR_GROUP5_SHIFT (12U) +#define FB_CSPMCR_GROUP5(x) (((uint32_t)(((uint32_t)(x)) << FB_CSPMCR_GROUP5_SHIFT)) & FB_CSPMCR_GROUP5_MASK) +#define FB_CSPMCR_GROUP4_MASK (0xF0000U) +#define FB_CSPMCR_GROUP4_SHIFT (16U) +#define FB_CSPMCR_GROUP4(x) (((uint32_t)(((uint32_t)(x)) << FB_CSPMCR_GROUP4_SHIFT)) & FB_CSPMCR_GROUP4_MASK) +#define FB_CSPMCR_GROUP3_MASK (0xF00000U) +#define FB_CSPMCR_GROUP3_SHIFT (20U) +#define FB_CSPMCR_GROUP3(x) (((uint32_t)(((uint32_t)(x)) << FB_CSPMCR_GROUP3_SHIFT)) & FB_CSPMCR_GROUP3_MASK) +#define FB_CSPMCR_GROUP2_MASK (0xF000000U) +#define FB_CSPMCR_GROUP2_SHIFT (24U) +#define FB_CSPMCR_GROUP2(x) (((uint32_t)(((uint32_t)(x)) << FB_CSPMCR_GROUP2_SHIFT)) & FB_CSPMCR_GROUP2_MASK) +#define FB_CSPMCR_GROUP1_MASK (0xF0000000U) +#define FB_CSPMCR_GROUP1_SHIFT (28U) +#define FB_CSPMCR_GROUP1(x) (((uint32_t)(((uint32_t)(x)) << FB_CSPMCR_GROUP1_SHIFT)) & FB_CSPMCR_GROUP1_MASK) + + +/*! + * @} + */ /* end of group FB_Register_Masks */ + + +/* FB - Peripheral instance base addresses */ +/** Peripheral FB base address */ +#define FB_BASE (0x4000C000u) +/** Peripheral FB base pointer */ +#define FB ((FB_Type *)FB_BASE) +/** Array initializer of FB peripheral base addresses */ +#define FB_BASE_ADDRS { FB_BASE } +/** Array initializer of FB peripheral base pointers */ +#define FB_BASE_PTRS { FB } + +/*! + * @} + */ /* end of group FB_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- FLEXIO Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FLEXIO_Peripheral_Access_Layer FLEXIO Peripheral Access Layer + * @{ + */ + +/** FLEXIO - Register Layout Typedef */ +typedef struct { + __I uint32_t VERID; /**< Version ID Register, offset: 0x0 */ + __I uint32_t PARAM; /**< Parameter Register, offset: 0x4 */ + __IO uint32_t CTRL; /**< FlexIO Control Register, offset: 0x8 */ + __I uint32_t PIN; /**< Pin State Register, offset: 0xC */ + __IO uint32_t SHIFTSTAT; /**< Shifter Status Register, offset: 0x10 */ + __IO uint32_t SHIFTERR; /**< Shifter Error Register, offset: 0x14 */ + __IO uint32_t TIMSTAT; /**< Timer Status Register, offset: 0x18 */ + uint8_t RESERVED_0[4]; + __IO uint32_t SHIFTSIEN; /**< Shifter Status Interrupt Enable, offset: 0x20 */ + __IO uint32_t SHIFTEIEN; /**< Shifter Error Interrupt Enable, offset: 0x24 */ + __IO uint32_t TIMIEN; /**< Timer Interrupt Enable Register, offset: 0x28 */ + uint8_t RESERVED_1[4]; + __IO uint32_t SHIFTSDEN; /**< Shifter Status DMA Enable, offset: 0x30 */ + uint8_t RESERVED_2[12]; + __IO uint32_t SHIFTSTATE; /**< Shifter State Register, offset: 0x40 */ + uint8_t RESERVED_3[60]; + __IO uint32_t SHIFTCTL[8]; /**< Shifter Control N Register, array offset: 0x80, array step: 0x4 */ + uint8_t RESERVED_4[96]; + __IO uint32_t SHIFTCFG[8]; /**< Shifter Configuration N Register, array offset: 0x100, array step: 0x4 */ + uint8_t RESERVED_5[224]; + __IO uint32_t SHIFTBUF[8]; /**< Shifter Buffer N Register, array offset: 0x200, array step: 0x4 */ + uint8_t RESERVED_6[96]; + __IO uint32_t SHIFTBUFBIS[8]; /**< Shifter Buffer N Bit Swapped Register, array offset: 0x280, array step: 0x4 */ + uint8_t RESERVED_7[96]; + __IO uint32_t SHIFTBUFBYS[8]; /**< Shifter Buffer N Byte Swapped Register, array offset: 0x300, array step: 0x4 */ + uint8_t RESERVED_8[96]; + __IO uint32_t SHIFTBUFBBS[8]; /**< Shifter Buffer N Bit Byte Swapped Register, array offset: 0x380, array step: 0x4 */ + uint8_t RESERVED_9[96]; + __IO uint32_t TIMCTL[8]; /**< Timer Control N Register, array offset: 0x400, array step: 0x4 */ + uint8_t RESERVED_10[96]; + __IO uint32_t TIMCFG[8]; /**< Timer Configuration N Register, array offset: 0x480, array step: 0x4 */ + uint8_t RESERVED_11[96]; + __IO uint32_t TIMCMP[8]; /**< Timer Compare N Register, array offset: 0x500, array step: 0x4 */ + uint8_t RESERVED_12[352]; + __IO uint32_t SHIFTBUFNBS[8]; /**< Shifter Buffer N Nibble Byte Swapped Register, array offset: 0x680, array step: 0x4 */ + uint8_t RESERVED_13[96]; + __IO uint32_t SHIFTBUFHWS[8]; /**< Shifter Buffer N Half Word Swapped Register, array offset: 0x700, array step: 0x4 */ + uint8_t RESERVED_14[96]; + __IO uint32_t SHIFTBUFNIS[8]; /**< Shifter Buffer N Nibble Swapped Register, array offset: 0x780, array step: 0x4 */ +} FLEXIO_Type; + +/* ---------------------------------------------------------------------------- + -- FLEXIO Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FLEXIO_Register_Masks FLEXIO Register Masks + * @{ + */ + +/*! @name VERID - Version ID Register */ +#define FLEXIO_VERID_FEATURE_MASK (0xFFFFU) +#define FLEXIO_VERID_FEATURE_SHIFT (0U) +#define FLEXIO_VERID_FEATURE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_VERID_FEATURE_SHIFT)) & FLEXIO_VERID_FEATURE_MASK) +#define FLEXIO_VERID_MINOR_MASK (0xFF0000U) +#define FLEXIO_VERID_MINOR_SHIFT (16U) +#define FLEXIO_VERID_MINOR(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_VERID_MINOR_SHIFT)) & FLEXIO_VERID_MINOR_MASK) +#define FLEXIO_VERID_MAJOR_MASK (0xFF000000U) +#define FLEXIO_VERID_MAJOR_SHIFT (24U) +#define FLEXIO_VERID_MAJOR(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_VERID_MAJOR_SHIFT)) & FLEXIO_VERID_MAJOR_MASK) + +/*! @name PARAM - Parameter Register */ +#define FLEXIO_PARAM_SHIFTER_MASK (0xFFU) +#define FLEXIO_PARAM_SHIFTER_SHIFT (0U) +#define FLEXIO_PARAM_SHIFTER(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_PARAM_SHIFTER_SHIFT)) & FLEXIO_PARAM_SHIFTER_MASK) +#define FLEXIO_PARAM_TIMER_MASK (0xFF00U) +#define FLEXIO_PARAM_TIMER_SHIFT (8U) +#define FLEXIO_PARAM_TIMER(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_PARAM_TIMER_SHIFT)) & FLEXIO_PARAM_TIMER_MASK) +#define FLEXIO_PARAM_PIN_MASK (0xFF0000U) +#define FLEXIO_PARAM_PIN_SHIFT (16U) +#define FLEXIO_PARAM_PIN(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_PARAM_PIN_SHIFT)) & FLEXIO_PARAM_PIN_MASK) +#define FLEXIO_PARAM_TRIGGER_MASK (0xFF000000U) +#define FLEXIO_PARAM_TRIGGER_SHIFT (24U) +#define FLEXIO_PARAM_TRIGGER(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_PARAM_TRIGGER_SHIFT)) & FLEXIO_PARAM_TRIGGER_MASK) + +/*! @name CTRL - FlexIO Control Register */ +#define FLEXIO_CTRL_FLEXEN_MASK (0x1U) +#define FLEXIO_CTRL_FLEXEN_SHIFT (0U) +#define FLEXIO_CTRL_FLEXEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_CTRL_FLEXEN_SHIFT)) & FLEXIO_CTRL_FLEXEN_MASK) +#define FLEXIO_CTRL_SWRST_MASK (0x2U) +#define FLEXIO_CTRL_SWRST_SHIFT (1U) +#define FLEXIO_CTRL_SWRST(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_CTRL_SWRST_SHIFT)) & FLEXIO_CTRL_SWRST_MASK) +#define FLEXIO_CTRL_FASTACC_MASK (0x4U) +#define FLEXIO_CTRL_FASTACC_SHIFT (2U) +#define FLEXIO_CTRL_FASTACC(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_CTRL_FASTACC_SHIFT)) & FLEXIO_CTRL_FASTACC_MASK) +#define FLEXIO_CTRL_DBGE_MASK (0x40000000U) +#define FLEXIO_CTRL_DBGE_SHIFT (30U) +#define FLEXIO_CTRL_DBGE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_CTRL_DBGE_SHIFT)) & FLEXIO_CTRL_DBGE_MASK) +#define FLEXIO_CTRL_DOZEN_MASK (0x80000000U) +#define FLEXIO_CTRL_DOZEN_SHIFT (31U) +#define FLEXIO_CTRL_DOZEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_CTRL_DOZEN_SHIFT)) & FLEXIO_CTRL_DOZEN_MASK) + +/*! @name PIN - Pin State Register */ +#define FLEXIO_PIN_PDI_MASK (0xFFFFFFFFU) +#define FLEXIO_PIN_PDI_SHIFT (0U) +#define FLEXIO_PIN_PDI(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_PIN_PDI_SHIFT)) & FLEXIO_PIN_PDI_MASK) + +/*! @name SHIFTSTAT - Shifter Status Register */ +#define FLEXIO_SHIFTSTAT_SSF_MASK (0xFFU) +#define FLEXIO_SHIFTSTAT_SSF_SHIFT (0U) +#define FLEXIO_SHIFTSTAT_SSF(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTSTAT_SSF_SHIFT)) & FLEXIO_SHIFTSTAT_SSF_MASK) + +/*! @name SHIFTERR - Shifter Error Register */ +#define FLEXIO_SHIFTERR_SEF_MASK (0xFFU) +#define FLEXIO_SHIFTERR_SEF_SHIFT (0U) +#define FLEXIO_SHIFTERR_SEF(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTERR_SEF_SHIFT)) & FLEXIO_SHIFTERR_SEF_MASK) + +/*! @name TIMSTAT - Timer Status Register */ +#define FLEXIO_TIMSTAT_TSF_MASK (0xFFU) +#define FLEXIO_TIMSTAT_TSF_SHIFT (0U) +#define FLEXIO_TIMSTAT_TSF(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMSTAT_TSF_SHIFT)) & FLEXIO_TIMSTAT_TSF_MASK) + +/*! @name SHIFTSIEN - Shifter Status Interrupt Enable */ +#define FLEXIO_SHIFTSIEN_SSIE_MASK (0xFFU) +#define FLEXIO_SHIFTSIEN_SSIE_SHIFT (0U) +#define FLEXIO_SHIFTSIEN_SSIE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTSIEN_SSIE_SHIFT)) & FLEXIO_SHIFTSIEN_SSIE_MASK) + +/*! @name SHIFTEIEN - Shifter Error Interrupt Enable */ +#define FLEXIO_SHIFTEIEN_SEIE_MASK (0xFFU) +#define FLEXIO_SHIFTEIEN_SEIE_SHIFT (0U) +#define FLEXIO_SHIFTEIEN_SEIE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTEIEN_SEIE_SHIFT)) & FLEXIO_SHIFTEIEN_SEIE_MASK) + +/*! @name TIMIEN - Timer Interrupt Enable Register */ +#define FLEXIO_TIMIEN_TEIE_MASK (0xFFU) +#define FLEXIO_TIMIEN_TEIE_SHIFT (0U) +#define FLEXIO_TIMIEN_TEIE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMIEN_TEIE_SHIFT)) & FLEXIO_TIMIEN_TEIE_MASK) + +/*! @name SHIFTSDEN - Shifter Status DMA Enable */ +#define FLEXIO_SHIFTSDEN_SSDE_MASK (0xFFU) +#define FLEXIO_SHIFTSDEN_SSDE_SHIFT (0U) +#define FLEXIO_SHIFTSDEN_SSDE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTSDEN_SSDE_SHIFT)) & FLEXIO_SHIFTSDEN_SSDE_MASK) + +/*! @name SHIFTSTATE - Shifter State Register */ +#define FLEXIO_SHIFTSTATE_STATE_MASK (0x7U) +#define FLEXIO_SHIFTSTATE_STATE_SHIFT (0U) +#define FLEXIO_SHIFTSTATE_STATE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTSTATE_STATE_SHIFT)) & FLEXIO_SHIFTSTATE_STATE_MASK) + +/*! @name SHIFTCTL - Shifter Control N Register */ +#define FLEXIO_SHIFTCTL_SMOD_MASK (0x7U) +#define FLEXIO_SHIFTCTL_SMOD_SHIFT (0U) +#define FLEXIO_SHIFTCTL_SMOD(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCTL_SMOD_SHIFT)) & FLEXIO_SHIFTCTL_SMOD_MASK) +#define FLEXIO_SHIFTCTL_PINPOL_MASK (0x80U) +#define FLEXIO_SHIFTCTL_PINPOL_SHIFT (7U) +#define FLEXIO_SHIFTCTL_PINPOL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCTL_PINPOL_SHIFT)) & FLEXIO_SHIFTCTL_PINPOL_MASK) +#define FLEXIO_SHIFTCTL_PINSEL_MASK (0x1F00U) +#define FLEXIO_SHIFTCTL_PINSEL_SHIFT (8U) +#define FLEXIO_SHIFTCTL_PINSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCTL_PINSEL_SHIFT)) & FLEXIO_SHIFTCTL_PINSEL_MASK) +#define FLEXIO_SHIFTCTL_PINCFG_MASK (0x30000U) +#define FLEXIO_SHIFTCTL_PINCFG_SHIFT (16U) +#define FLEXIO_SHIFTCTL_PINCFG(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCTL_PINCFG_SHIFT)) & FLEXIO_SHIFTCTL_PINCFG_MASK) +#define FLEXIO_SHIFTCTL_TIMPOL_MASK (0x800000U) +#define FLEXIO_SHIFTCTL_TIMPOL_SHIFT (23U) +#define FLEXIO_SHIFTCTL_TIMPOL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCTL_TIMPOL_SHIFT)) & FLEXIO_SHIFTCTL_TIMPOL_MASK) +#define FLEXIO_SHIFTCTL_TIMSEL_MASK (0x7000000U) +#define FLEXIO_SHIFTCTL_TIMSEL_SHIFT (24U) +#define FLEXIO_SHIFTCTL_TIMSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCTL_TIMSEL_SHIFT)) & FLEXIO_SHIFTCTL_TIMSEL_MASK) + +/* The count of FLEXIO_SHIFTCTL */ +#define FLEXIO_SHIFTCTL_COUNT (8U) + +/*! @name SHIFTCFG - Shifter Configuration N Register */ +#define FLEXIO_SHIFTCFG_SSTART_MASK (0x3U) +#define FLEXIO_SHIFTCFG_SSTART_SHIFT (0U) +#define FLEXIO_SHIFTCFG_SSTART(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCFG_SSTART_SHIFT)) & FLEXIO_SHIFTCFG_SSTART_MASK) +#define FLEXIO_SHIFTCFG_SSTOP_MASK (0x30U) +#define FLEXIO_SHIFTCFG_SSTOP_SHIFT (4U) +#define FLEXIO_SHIFTCFG_SSTOP(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCFG_SSTOP_SHIFT)) & FLEXIO_SHIFTCFG_SSTOP_MASK) +#define FLEXIO_SHIFTCFG_INSRC_MASK (0x100U) +#define FLEXIO_SHIFTCFG_INSRC_SHIFT (8U) +#define FLEXIO_SHIFTCFG_INSRC(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCFG_INSRC_SHIFT)) & FLEXIO_SHIFTCFG_INSRC_MASK) +#define FLEXIO_SHIFTCFG_PWIDTH_MASK (0x1F0000U) +#define FLEXIO_SHIFTCFG_PWIDTH_SHIFT (16U) +#define FLEXIO_SHIFTCFG_PWIDTH(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCFG_PWIDTH_SHIFT)) & FLEXIO_SHIFTCFG_PWIDTH_MASK) + +/* The count of FLEXIO_SHIFTCFG */ +#define FLEXIO_SHIFTCFG_COUNT (8U) + +/*! @name SHIFTBUF - Shifter Buffer N Register */ +#define FLEXIO_SHIFTBUF_SHIFTBUF_MASK (0xFFFFFFFFU) +#define FLEXIO_SHIFTBUF_SHIFTBUF_SHIFT (0U) +#define FLEXIO_SHIFTBUF_SHIFTBUF(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTBUF_SHIFTBUF_SHIFT)) & FLEXIO_SHIFTBUF_SHIFTBUF_MASK) + +/* The count of FLEXIO_SHIFTBUF */ +#define FLEXIO_SHIFTBUF_COUNT (8U) + +/*! @name SHIFTBUFBIS - Shifter Buffer N Bit Swapped Register */ +#define FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS_MASK (0xFFFFFFFFU) +#define FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS_SHIFT (0U) +#define FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS_SHIFT)) & FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS_MASK) + +/* The count of FLEXIO_SHIFTBUFBIS */ +#define FLEXIO_SHIFTBUFBIS_COUNT (8U) + +/*! @name SHIFTBUFBYS - Shifter Buffer N Byte Swapped Register */ +#define FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS_MASK (0xFFFFFFFFU) +#define FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS_SHIFT (0U) +#define FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS_SHIFT)) & FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS_MASK) + +/* The count of FLEXIO_SHIFTBUFBYS */ +#define FLEXIO_SHIFTBUFBYS_COUNT (8U) + +/*! @name SHIFTBUFBBS - Shifter Buffer N Bit Byte Swapped Register */ +#define FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS_MASK (0xFFFFFFFFU) +#define FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS_SHIFT (0U) +#define FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS_SHIFT)) & FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS_MASK) + +/* The count of FLEXIO_SHIFTBUFBBS */ +#define FLEXIO_SHIFTBUFBBS_COUNT (8U) + +/*! @name TIMCTL - Timer Control N Register */ +#define FLEXIO_TIMCTL_TIMOD_MASK (0x3U) +#define FLEXIO_TIMCTL_TIMOD_SHIFT (0U) +#define FLEXIO_TIMCTL_TIMOD(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_TIMOD_SHIFT)) & FLEXIO_TIMCTL_TIMOD_MASK) +#define FLEXIO_TIMCTL_PINPOL_MASK (0x80U) +#define FLEXIO_TIMCTL_PINPOL_SHIFT (7U) +#define FLEXIO_TIMCTL_PINPOL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_PINPOL_SHIFT)) & FLEXIO_TIMCTL_PINPOL_MASK) +#define FLEXIO_TIMCTL_PINSEL_MASK (0x1F00U) +#define FLEXIO_TIMCTL_PINSEL_SHIFT (8U) +#define FLEXIO_TIMCTL_PINSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_PINSEL_SHIFT)) & FLEXIO_TIMCTL_PINSEL_MASK) +#define FLEXIO_TIMCTL_PINCFG_MASK (0x30000U) +#define FLEXIO_TIMCTL_PINCFG_SHIFT (16U) +#define FLEXIO_TIMCTL_PINCFG(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_PINCFG_SHIFT)) & FLEXIO_TIMCTL_PINCFG_MASK) +#define FLEXIO_TIMCTL_TRGSRC_MASK (0x400000U) +#define FLEXIO_TIMCTL_TRGSRC_SHIFT (22U) +#define FLEXIO_TIMCTL_TRGSRC(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_TRGSRC_SHIFT)) & FLEXIO_TIMCTL_TRGSRC_MASK) +#define FLEXIO_TIMCTL_TRGPOL_MASK (0x800000U) +#define FLEXIO_TIMCTL_TRGPOL_SHIFT (23U) +#define FLEXIO_TIMCTL_TRGPOL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_TRGPOL_SHIFT)) & FLEXIO_TIMCTL_TRGPOL_MASK) +#define FLEXIO_TIMCTL_TRGSEL_MASK (0x3F000000U) +#define FLEXIO_TIMCTL_TRGSEL_SHIFT (24U) +#define FLEXIO_TIMCTL_TRGSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_TRGSEL_SHIFT)) & FLEXIO_TIMCTL_TRGSEL_MASK) + +/* The count of FLEXIO_TIMCTL */ +#define FLEXIO_TIMCTL_COUNT (8U) + +/*! @name TIMCFG - Timer Configuration N Register */ +#define FLEXIO_TIMCFG_TSTART_MASK (0x2U) +#define FLEXIO_TIMCFG_TSTART_SHIFT (1U) +#define FLEXIO_TIMCFG_TSTART(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TSTART_SHIFT)) & FLEXIO_TIMCFG_TSTART_MASK) +#define FLEXIO_TIMCFG_TSTOP_MASK (0x30U) +#define FLEXIO_TIMCFG_TSTOP_SHIFT (4U) +#define FLEXIO_TIMCFG_TSTOP(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TSTOP_SHIFT)) & FLEXIO_TIMCFG_TSTOP_MASK) +#define FLEXIO_TIMCFG_TIMENA_MASK (0x700U) +#define FLEXIO_TIMCFG_TIMENA_SHIFT (8U) +#define FLEXIO_TIMCFG_TIMENA(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TIMENA_SHIFT)) & FLEXIO_TIMCFG_TIMENA_MASK) +#define FLEXIO_TIMCFG_TIMDIS_MASK (0x7000U) +#define FLEXIO_TIMCFG_TIMDIS_SHIFT (12U) +#define FLEXIO_TIMCFG_TIMDIS(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TIMDIS_SHIFT)) & FLEXIO_TIMCFG_TIMDIS_MASK) +#define FLEXIO_TIMCFG_TIMRST_MASK (0x70000U) +#define FLEXIO_TIMCFG_TIMRST_SHIFT (16U) +#define FLEXIO_TIMCFG_TIMRST(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TIMRST_SHIFT)) & FLEXIO_TIMCFG_TIMRST_MASK) +#define FLEXIO_TIMCFG_TIMDEC_MASK (0x300000U) +#define FLEXIO_TIMCFG_TIMDEC_SHIFT (20U) +#define FLEXIO_TIMCFG_TIMDEC(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TIMDEC_SHIFT)) & FLEXIO_TIMCFG_TIMDEC_MASK) +#define FLEXIO_TIMCFG_TIMOUT_MASK (0x3000000U) +#define FLEXIO_TIMCFG_TIMOUT_SHIFT (24U) +#define FLEXIO_TIMCFG_TIMOUT(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TIMOUT_SHIFT)) & FLEXIO_TIMCFG_TIMOUT_MASK) + +/* The count of FLEXIO_TIMCFG */ +#define FLEXIO_TIMCFG_COUNT (8U) + +/*! @name TIMCMP - Timer Compare N Register */ +#define FLEXIO_TIMCMP_CMP_MASK (0xFFFFU) +#define FLEXIO_TIMCMP_CMP_SHIFT (0U) +#define FLEXIO_TIMCMP_CMP(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCMP_CMP_SHIFT)) & FLEXIO_TIMCMP_CMP_MASK) + +/* The count of FLEXIO_TIMCMP */ +#define FLEXIO_TIMCMP_COUNT (8U) + +/*! @name SHIFTBUFNBS - Shifter Buffer N Nibble Byte Swapped Register */ +#define FLEXIO_SHIFTBUFNBS_SHIFTBUFNBS_MASK (0xFFFFFFFFU) +#define FLEXIO_SHIFTBUFNBS_SHIFTBUFNBS_SHIFT (0U) +#define FLEXIO_SHIFTBUFNBS_SHIFTBUFNBS(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTBUFNBS_SHIFTBUFNBS_SHIFT)) & FLEXIO_SHIFTBUFNBS_SHIFTBUFNBS_MASK) + +/* The count of FLEXIO_SHIFTBUFNBS */ +#define FLEXIO_SHIFTBUFNBS_COUNT (8U) + +/*! @name SHIFTBUFHWS - Shifter Buffer N Half Word Swapped Register */ +#define FLEXIO_SHIFTBUFHWS_SHIFTBUFHWS_MASK (0xFFFFFFFFU) +#define FLEXIO_SHIFTBUFHWS_SHIFTBUFHWS_SHIFT (0U) +#define FLEXIO_SHIFTBUFHWS_SHIFTBUFHWS(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTBUFHWS_SHIFTBUFHWS_SHIFT)) & FLEXIO_SHIFTBUFHWS_SHIFTBUFHWS_MASK) + +/* The count of FLEXIO_SHIFTBUFHWS */ +#define FLEXIO_SHIFTBUFHWS_COUNT (8U) + +/*! @name SHIFTBUFNIS - Shifter Buffer N Nibble Swapped Register */ +#define FLEXIO_SHIFTBUFNIS_SHIFTBUFNIS_MASK (0xFFFFFFFFU) +#define FLEXIO_SHIFTBUFNIS_SHIFTBUFNIS_SHIFT (0U) +#define FLEXIO_SHIFTBUFNIS_SHIFTBUFNIS(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTBUFNIS_SHIFTBUFNIS_SHIFT)) & FLEXIO_SHIFTBUFNIS_SHIFTBUFNIS_MASK) + +/* The count of FLEXIO_SHIFTBUFNIS */ +#define FLEXIO_SHIFTBUFNIS_COUNT (8U) + + +/*! + * @} + */ /* end of group FLEXIO_Register_Masks */ + + +/* FLEXIO - Peripheral instance base addresses */ +/** Peripheral FLEXIO0 base address */ +#define FLEXIO0_BASE (0x400DF000u) +/** Peripheral FLEXIO0 base pointer */ +#define FLEXIO0 ((FLEXIO_Type *)FLEXIO0_BASE) +/** Array initializer of FLEXIO peripheral base addresses */ +#define FLEXIO_BASE_ADDRS { FLEXIO0_BASE } +/** Array initializer of FLEXIO peripheral base pointers */ +#define FLEXIO_BASE_PTRS { FLEXIO0 } +/** Interrupt vectors for the FLEXIO peripheral type */ +#define FLEXIO_IRQS { FLEXIO0_IRQn } + +/*! + * @} + */ /* end of group FLEXIO_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- FMC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FMC_Peripheral_Access_Layer FMC Peripheral Access Layer + * @{ + */ + +/** FMC - Register Layout Typedef */ +typedef struct { + __IO uint32_t PFAPR; /**< Flash Access Protection Register, offset: 0x0 */ + __IO uint32_t PFB0CR; /**< Flash Bank 0 Control Register, offset: 0x4 */ + __I uint32_t RESERVED; /**< Reserved, offset: 0x8 */ + uint8_t RESERVED_0[244]; + __IO uint32_t TAGVDW0S[4]; /**< Cache Tag Storage, array offset: 0x100, array step: 0x4 */ + __IO uint32_t TAGVDW1S[4]; /**< Cache Tag Storage, array offset: 0x110, array step: 0x4 */ + __IO uint32_t TAGVDW2S[4]; /**< Cache Tag Storage, array offset: 0x120, array step: 0x4 */ + __IO uint32_t TAGVDW3S[4]; /**< Cache Tag Storage, array offset: 0x130, array step: 0x4 */ + uint8_t RESERVED_1[192]; + struct { /* offset: 0x200, array step: index*0x40, index2*0x10 */ + __IO uint32_t DATA_UM; /**< Cache Data Storage (uppermost word), array offset: 0x200, array step: index*0x40, index2*0x10 */ + __IO uint32_t DATA_MU; /**< Cache Data Storage (mid-upper word), array offset: 0x204, array step: index*0x40, index2*0x10 */ + __IO uint32_t DATA_ML; /**< Cache Data Storage (mid-lower word), array offset: 0x208, array step: index*0x40, index2*0x10 */ + __IO uint32_t DATA_LM; /**< Cache Data Storage (lowermost word), array offset: 0x20C, array step: index*0x40, index2*0x10 */ + } SET[4][4]; +} FMC_Type; + +/* ---------------------------------------------------------------------------- + -- FMC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FMC_Register_Masks FMC Register Masks + * @{ + */ + +/*! @name PFAPR - Flash Access Protection Register */ +#define FMC_PFAPR_M0AP_MASK (0x3U) +#define FMC_PFAPR_M0AP_SHIFT (0U) +#define FMC_PFAPR_M0AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M0AP_SHIFT)) & FMC_PFAPR_M0AP_MASK) +#define FMC_PFAPR_M1AP_MASK (0xCU) +#define FMC_PFAPR_M1AP_SHIFT (2U) +#define FMC_PFAPR_M1AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M1AP_SHIFT)) & FMC_PFAPR_M1AP_MASK) +#define FMC_PFAPR_M2AP_MASK (0x30U) +#define FMC_PFAPR_M2AP_SHIFT (4U) +#define FMC_PFAPR_M2AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M2AP_SHIFT)) & FMC_PFAPR_M2AP_MASK) +#define FMC_PFAPR_M3AP_MASK (0xC0U) +#define FMC_PFAPR_M3AP_SHIFT (6U) +#define FMC_PFAPR_M3AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M3AP_SHIFT)) & FMC_PFAPR_M3AP_MASK) +#define FMC_PFAPR_M4AP_MASK (0x300U) +#define FMC_PFAPR_M4AP_SHIFT (8U) +#define FMC_PFAPR_M4AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M4AP_SHIFT)) & FMC_PFAPR_M4AP_MASK) +#define FMC_PFAPR_M0PFD_MASK (0x10000U) +#define FMC_PFAPR_M0PFD_SHIFT (16U) +#define FMC_PFAPR_M0PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M0PFD_SHIFT)) & FMC_PFAPR_M0PFD_MASK) +#define FMC_PFAPR_M1PFD_MASK (0x20000U) +#define FMC_PFAPR_M1PFD_SHIFT (17U) +#define FMC_PFAPR_M1PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M1PFD_SHIFT)) & FMC_PFAPR_M1PFD_MASK) +#define FMC_PFAPR_M2PFD_MASK (0x40000U) +#define FMC_PFAPR_M2PFD_SHIFT (18U) +#define FMC_PFAPR_M2PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M2PFD_SHIFT)) & FMC_PFAPR_M2PFD_MASK) +#define FMC_PFAPR_M3PFD_MASK (0x80000U) +#define FMC_PFAPR_M3PFD_SHIFT (19U) +#define FMC_PFAPR_M3PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M3PFD_SHIFT)) & FMC_PFAPR_M3PFD_MASK) +#define FMC_PFAPR_M4PFD_MASK (0x100000U) +#define FMC_PFAPR_M4PFD_SHIFT (20U) +#define FMC_PFAPR_M4PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M4PFD_SHIFT)) & FMC_PFAPR_M4PFD_MASK) + +/*! @name PFB0CR - Flash Bank 0 Control Register */ +#define FMC_PFB0CR_B0SEBE_MASK (0x1U) +#define FMC_PFB0CR_B0SEBE_SHIFT (0U) +#define FMC_PFB0CR_B0SEBE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0SEBE_SHIFT)) & FMC_PFB0CR_B0SEBE_MASK) +#define FMC_PFB0CR_B0IPE_MASK (0x2U) +#define FMC_PFB0CR_B0IPE_SHIFT (1U) +#define FMC_PFB0CR_B0IPE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0IPE_SHIFT)) & FMC_PFB0CR_B0IPE_MASK) +#define FMC_PFB0CR_B0DPE_MASK (0x4U) +#define FMC_PFB0CR_B0DPE_SHIFT (2U) +#define FMC_PFB0CR_B0DPE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0DPE_SHIFT)) & FMC_PFB0CR_B0DPE_MASK) +#define FMC_PFB0CR_B0ICE_MASK (0x8U) +#define FMC_PFB0CR_B0ICE_SHIFT (3U) +#define FMC_PFB0CR_B0ICE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0ICE_SHIFT)) & FMC_PFB0CR_B0ICE_MASK) +#define FMC_PFB0CR_B0DCE_MASK (0x10U) +#define FMC_PFB0CR_B0DCE_SHIFT (4U) +#define FMC_PFB0CR_B0DCE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0DCE_SHIFT)) & FMC_PFB0CR_B0DCE_MASK) +#define FMC_PFB0CR_CRC_MASK (0xE0U) +#define FMC_PFB0CR_CRC_SHIFT (5U) +#define FMC_PFB0CR_CRC(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_CRC_SHIFT)) & FMC_PFB0CR_CRC_MASK) +#define FMC_PFB0CR_B0MW_MASK (0x60000U) +#define FMC_PFB0CR_B0MW_SHIFT (17U) +#define FMC_PFB0CR_B0MW(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0MW_SHIFT)) & FMC_PFB0CR_B0MW_MASK) +#define FMC_PFB0CR_S_B_INV_MASK (0x80000U) +#define FMC_PFB0CR_S_B_INV_SHIFT (19U) +#define FMC_PFB0CR_S_B_INV(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_S_B_INV_SHIFT)) & FMC_PFB0CR_S_B_INV_MASK) +#define FMC_PFB0CR_CINV_WAY_MASK (0xF00000U) +#define FMC_PFB0CR_CINV_WAY_SHIFT (20U) +#define FMC_PFB0CR_CINV_WAY(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_CINV_WAY_SHIFT)) & FMC_PFB0CR_CINV_WAY_MASK) +#define FMC_PFB0CR_CLCK_WAY_MASK (0xF000000U) +#define FMC_PFB0CR_CLCK_WAY_SHIFT (24U) +#define FMC_PFB0CR_CLCK_WAY(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_CLCK_WAY_SHIFT)) & FMC_PFB0CR_CLCK_WAY_MASK) +#define FMC_PFB0CR_B0RWSC_MASK (0xF0000000U) +#define FMC_PFB0CR_B0RWSC_SHIFT (28U) +#define FMC_PFB0CR_B0RWSC(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0RWSC_SHIFT)) & FMC_PFB0CR_B0RWSC_MASK) + +/*! @name TAGVDW0S - Cache Tag Storage */ +#define FMC_TAGVDW0S_valid_MASK (0x1U) +#define FMC_TAGVDW0S_valid_SHIFT (0U) +#define FMC_TAGVDW0S_valid(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW0S_valid_SHIFT)) & FMC_TAGVDW0S_valid_MASK) +#define FMC_TAGVDW0S_cache_tag_MASK (0xFFFC0U) +#define FMC_TAGVDW0S_cache_tag_SHIFT (6U) +#define FMC_TAGVDW0S_cache_tag(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW0S_cache_tag_SHIFT)) & FMC_TAGVDW0S_cache_tag_MASK) + +/* The count of FMC_TAGVDW0S */ +#define FMC_TAGVDW0S_COUNT (4U) + +/*! @name TAGVDW1S - Cache Tag Storage */ +#define FMC_TAGVDW1S_valid_MASK (0x1U) +#define FMC_TAGVDW1S_valid_SHIFT (0U) +#define FMC_TAGVDW1S_valid(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW1S_valid_SHIFT)) & FMC_TAGVDW1S_valid_MASK) +#define FMC_TAGVDW1S_cache_tag_MASK (0xFFFC0U) +#define FMC_TAGVDW1S_cache_tag_SHIFT (6U) +#define FMC_TAGVDW1S_cache_tag(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW1S_cache_tag_SHIFT)) & FMC_TAGVDW1S_cache_tag_MASK) + +/* The count of FMC_TAGVDW1S */ +#define FMC_TAGVDW1S_COUNT (4U) + +/*! @name TAGVDW2S - Cache Tag Storage */ +#define FMC_TAGVDW2S_valid_MASK (0x1U) +#define FMC_TAGVDW2S_valid_SHIFT (0U) +#define FMC_TAGVDW2S_valid(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW2S_valid_SHIFT)) & FMC_TAGVDW2S_valid_MASK) +#define FMC_TAGVDW2S_cache_tag_MASK (0xFFFC0U) +#define FMC_TAGVDW2S_cache_tag_SHIFT (6U) +#define FMC_TAGVDW2S_cache_tag(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW2S_cache_tag_SHIFT)) & FMC_TAGVDW2S_cache_tag_MASK) + +/* The count of FMC_TAGVDW2S */ +#define FMC_TAGVDW2S_COUNT (4U) + +/*! @name TAGVDW3S - Cache Tag Storage */ +#define FMC_TAGVDW3S_valid_MASK (0x1U) +#define FMC_TAGVDW3S_valid_SHIFT (0U) +#define FMC_TAGVDW3S_valid(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW3S_valid_SHIFT)) & FMC_TAGVDW3S_valid_MASK) +#define FMC_TAGVDW3S_cache_tag_MASK (0xFFFC0U) +#define FMC_TAGVDW3S_cache_tag_SHIFT (6U) +#define FMC_TAGVDW3S_cache_tag(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW3S_cache_tag_SHIFT)) & FMC_TAGVDW3S_cache_tag_MASK) + +/* The count of FMC_TAGVDW3S */ +#define FMC_TAGVDW3S_COUNT (4U) + +/*! @name DATA_UM - Cache Data Storage (uppermost word) */ +#define FMC_DATA_UM_data_MASK (0xFFFFFFFFU) +#define FMC_DATA_UM_data_SHIFT (0U) +#define FMC_DATA_UM_data(x) (((uint32_t)(((uint32_t)(x)) << FMC_DATA_UM_data_SHIFT)) & FMC_DATA_UM_data_MASK) + +/* The count of FMC_DATA_UM */ +#define FMC_DATA_UM_COUNT (4U) + +/* The count of FMC_DATA_UM */ +#define FMC_DATA_UM_COUNT2 (4U) + +/*! @name DATA_MU - Cache Data Storage (mid-upper word) */ +#define FMC_DATA_MU_data_MASK (0xFFFFFFFFU) +#define FMC_DATA_MU_data_SHIFT (0U) +#define FMC_DATA_MU_data(x) (((uint32_t)(((uint32_t)(x)) << FMC_DATA_MU_data_SHIFT)) & FMC_DATA_MU_data_MASK) + +/* The count of FMC_DATA_MU */ +#define FMC_DATA_MU_COUNT (4U) + +/* The count of FMC_DATA_MU */ +#define FMC_DATA_MU_COUNT2 (4U) + +/*! @name DATA_ML - Cache Data Storage (mid-lower word) */ +#define FMC_DATA_ML_data_MASK (0xFFFFFFFFU) +#define FMC_DATA_ML_data_SHIFT (0U) +#define FMC_DATA_ML_data(x) (((uint32_t)(((uint32_t)(x)) << FMC_DATA_ML_data_SHIFT)) & FMC_DATA_ML_data_MASK) + +/* The count of FMC_DATA_ML */ +#define FMC_DATA_ML_COUNT (4U) + +/* The count of FMC_DATA_ML */ +#define FMC_DATA_ML_COUNT2 (4U) + +/*! @name DATA_LM - Cache Data Storage (lowermost word) */ +#define FMC_DATA_LM_data_MASK (0xFFFFFFFFU) +#define FMC_DATA_LM_data_SHIFT (0U) +#define FMC_DATA_LM_data(x) (((uint32_t)(((uint32_t)(x)) << FMC_DATA_LM_data_SHIFT)) & FMC_DATA_LM_data_MASK) + +/* The count of FMC_DATA_LM */ +#define FMC_DATA_LM_COUNT (4U) + +/* The count of FMC_DATA_LM */ +#define FMC_DATA_LM_COUNT2 (4U) + + +/*! + * @} + */ /* end of group FMC_Register_Masks */ + + +/* FMC - Peripheral instance base addresses */ +/** Peripheral FMC base address */ +#define FMC_BASE (0x4001F000u) +/** Peripheral FMC base pointer */ +#define FMC ((FMC_Type *)FMC_BASE) +/** Array initializer of FMC peripheral base addresses */ +#define FMC_BASE_ADDRS { FMC_BASE } +/** Array initializer of FMC peripheral base pointers */ +#define FMC_BASE_PTRS { FMC } + +/*! + * @} + */ /* end of group FMC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- FTFA Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FTFA_Peripheral_Access_Layer FTFA Peripheral Access Layer + * @{ + */ + +/** FTFA - Register Layout Typedef */ +typedef struct { + __IO uint8_t FSTAT; /**< Flash Status Register, offset: 0x0 */ + __IO uint8_t FCNFG; /**< Flash Configuration Register, offset: 0x1 */ + __I uint8_t FSEC; /**< Flash Security Register, offset: 0x2 */ + __I uint8_t FOPT; /**< Flash Option Register, offset: 0x3 */ + __IO uint8_t FCCOB3; /**< Flash Common Command Object Registers, offset: 0x4 */ + __IO uint8_t FCCOB2; /**< Flash Common Command Object Registers, offset: 0x5 */ + __IO uint8_t FCCOB1; /**< Flash Common Command Object Registers, offset: 0x6 */ + __IO uint8_t FCCOB0; /**< Flash Common Command Object Registers, offset: 0x7 */ + __IO uint8_t FCCOB7; /**< Flash Common Command Object Registers, offset: 0x8 */ + __IO uint8_t FCCOB6; /**< Flash Common Command Object Registers, offset: 0x9 */ + __IO uint8_t FCCOB5; /**< Flash Common Command Object Registers, offset: 0xA */ + __IO uint8_t FCCOB4; /**< Flash Common Command Object Registers, offset: 0xB */ + __IO uint8_t FCCOBB; /**< Flash Common Command Object Registers, offset: 0xC */ + __IO uint8_t FCCOBA; /**< Flash Common Command Object Registers, offset: 0xD */ + __IO uint8_t FCCOB9; /**< Flash Common Command Object Registers, offset: 0xE */ + __IO uint8_t FCCOB8; /**< Flash Common Command Object Registers, offset: 0xF */ + __IO uint8_t FPROT3; /**< Program Flash Protection Registers, offset: 0x10 */ + __IO uint8_t FPROT2; /**< Program Flash Protection Registers, offset: 0x11 */ + __IO uint8_t FPROT1; /**< Program Flash Protection Registers, offset: 0x12 */ + __IO uint8_t FPROT0; /**< Program Flash Protection Registers, offset: 0x13 */ + uint8_t RESERVED_0[4]; + __I uint8_t XACCH3; /**< Execute-only Access Registers, offset: 0x18 */ + __I uint8_t XACCH2; /**< Execute-only Access Registers, offset: 0x19 */ + __I uint8_t XACCH1; /**< Execute-only Access Registers, offset: 0x1A */ + __I uint8_t XACCH0; /**< Execute-only Access Registers, offset: 0x1B */ + __I uint8_t XACCL3; /**< Execute-only Access Registers, offset: 0x1C */ + __I uint8_t XACCL2; /**< Execute-only Access Registers, offset: 0x1D */ + __I uint8_t XACCL1; /**< Execute-only Access Registers, offset: 0x1E */ + __I uint8_t XACCL0; /**< Execute-only Access Registers, offset: 0x1F */ + __I uint8_t SACCH3; /**< Supervisor-only Access Registers, offset: 0x20 */ + __I uint8_t SACCH2; /**< Supervisor-only Access Registers, offset: 0x21 */ + __I uint8_t SACCH1; /**< Supervisor-only Access Registers, offset: 0x22 */ + __I uint8_t SACCH0; /**< Supervisor-only Access Registers, offset: 0x23 */ + __I uint8_t SACCL3; /**< Supervisor-only Access Registers, offset: 0x24 */ + __I uint8_t SACCL2; /**< Supervisor-only Access Registers, offset: 0x25 */ + __I uint8_t SACCL1; /**< Supervisor-only Access Registers, offset: 0x26 */ + __I uint8_t SACCL0; /**< Supervisor-only Access Registers, offset: 0x27 */ + __I uint8_t FACSS; /**< Flash Access Segment Size Register, offset: 0x28 */ + uint8_t RESERVED_1[2]; + __I uint8_t FACSN; /**< Flash Access Segment Number Register, offset: 0x2B */ +} FTFA_Type; + +/* ---------------------------------------------------------------------------- + -- FTFA Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FTFA_Register_Masks FTFA Register Masks + * @{ + */ + +/*! @name FSTAT - Flash Status Register */ +#define FTFA_FSTAT_MGSTAT0_MASK (0x1U) +#define FTFA_FSTAT_MGSTAT0_SHIFT (0U) +#define FTFA_FSTAT_MGSTAT0(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSTAT_MGSTAT0_SHIFT)) & FTFA_FSTAT_MGSTAT0_MASK) +#define FTFA_FSTAT_FPVIOL_MASK (0x10U) +#define FTFA_FSTAT_FPVIOL_SHIFT (4U) +#define FTFA_FSTAT_FPVIOL(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSTAT_FPVIOL_SHIFT)) & FTFA_FSTAT_FPVIOL_MASK) +#define FTFA_FSTAT_ACCERR_MASK (0x20U) +#define FTFA_FSTAT_ACCERR_SHIFT (5U) +#define FTFA_FSTAT_ACCERR(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSTAT_ACCERR_SHIFT)) & FTFA_FSTAT_ACCERR_MASK) +#define FTFA_FSTAT_RDCOLERR_MASK (0x40U) +#define FTFA_FSTAT_RDCOLERR_SHIFT (6U) +#define FTFA_FSTAT_RDCOLERR(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSTAT_RDCOLERR_SHIFT)) & FTFA_FSTAT_RDCOLERR_MASK) +#define FTFA_FSTAT_CCIF_MASK (0x80U) +#define FTFA_FSTAT_CCIF_SHIFT (7U) +#define FTFA_FSTAT_CCIF(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSTAT_CCIF_SHIFT)) & FTFA_FSTAT_CCIF_MASK) + +/*! @name FCNFG - Flash Configuration Register */ +#define FTFA_FCNFG_ERSSUSP_MASK (0x10U) +#define FTFA_FCNFG_ERSSUSP_SHIFT (4U) +#define FTFA_FCNFG_ERSSUSP(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCNFG_ERSSUSP_SHIFT)) & FTFA_FCNFG_ERSSUSP_MASK) +#define FTFA_FCNFG_ERSAREQ_MASK (0x20U) +#define FTFA_FCNFG_ERSAREQ_SHIFT (5U) +#define FTFA_FCNFG_ERSAREQ(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCNFG_ERSAREQ_SHIFT)) & FTFA_FCNFG_ERSAREQ_MASK) +#define FTFA_FCNFG_RDCOLLIE_MASK (0x40U) +#define FTFA_FCNFG_RDCOLLIE_SHIFT (6U) +#define FTFA_FCNFG_RDCOLLIE(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCNFG_RDCOLLIE_SHIFT)) & FTFA_FCNFG_RDCOLLIE_MASK) +#define FTFA_FCNFG_CCIE_MASK (0x80U) +#define FTFA_FCNFG_CCIE_SHIFT (7U) +#define FTFA_FCNFG_CCIE(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCNFG_CCIE_SHIFT)) & FTFA_FCNFG_CCIE_MASK) + +/*! @name FSEC - Flash Security Register */ +#define FTFA_FSEC_SEC_MASK (0x3U) +#define FTFA_FSEC_SEC_SHIFT (0U) +#define FTFA_FSEC_SEC(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSEC_SEC_SHIFT)) & FTFA_FSEC_SEC_MASK) +#define FTFA_FSEC_FSLACC_MASK (0xCU) +#define FTFA_FSEC_FSLACC_SHIFT (2U) +#define FTFA_FSEC_FSLACC(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSEC_FSLACC_SHIFT)) & FTFA_FSEC_FSLACC_MASK) +#define FTFA_FSEC_MEEN_MASK (0x30U) +#define FTFA_FSEC_MEEN_SHIFT (4U) +#define FTFA_FSEC_MEEN(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSEC_MEEN_SHIFT)) & FTFA_FSEC_MEEN_MASK) +#define FTFA_FSEC_KEYEN_MASK (0xC0U) +#define FTFA_FSEC_KEYEN_SHIFT (6U) +#define FTFA_FSEC_KEYEN(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSEC_KEYEN_SHIFT)) & FTFA_FSEC_KEYEN_MASK) + +/*! @name FOPT - Flash Option Register */ +#define FTFA_FOPT_OPT_MASK (0xFFU) +#define FTFA_FOPT_OPT_SHIFT (0U) +#define FTFA_FOPT_OPT(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FOPT_OPT_SHIFT)) & FTFA_FOPT_OPT_MASK) + +/*! @name FCCOB3 - Flash Common Command Object Registers */ +#define FTFA_FCCOB3_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB3_CCOBn_SHIFT (0U) +#define FTFA_FCCOB3_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB3_CCOBn_SHIFT)) & FTFA_FCCOB3_CCOBn_MASK) + +/*! @name FCCOB2 - Flash Common Command Object Registers */ +#define FTFA_FCCOB2_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB2_CCOBn_SHIFT (0U) +#define FTFA_FCCOB2_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB2_CCOBn_SHIFT)) & FTFA_FCCOB2_CCOBn_MASK) + +/*! @name FCCOB1 - Flash Common Command Object Registers */ +#define FTFA_FCCOB1_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB1_CCOBn_SHIFT (0U) +#define FTFA_FCCOB1_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB1_CCOBn_SHIFT)) & FTFA_FCCOB1_CCOBn_MASK) + +/*! @name FCCOB0 - Flash Common Command Object Registers */ +#define FTFA_FCCOB0_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB0_CCOBn_SHIFT (0U) +#define FTFA_FCCOB0_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB0_CCOBn_SHIFT)) & FTFA_FCCOB0_CCOBn_MASK) + +/*! @name FCCOB7 - Flash Common Command Object Registers */ +#define FTFA_FCCOB7_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB7_CCOBn_SHIFT (0U) +#define FTFA_FCCOB7_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB7_CCOBn_SHIFT)) & FTFA_FCCOB7_CCOBn_MASK) + +/*! @name FCCOB6 - Flash Common Command Object Registers */ +#define FTFA_FCCOB6_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB6_CCOBn_SHIFT (0U) +#define FTFA_FCCOB6_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB6_CCOBn_SHIFT)) & FTFA_FCCOB6_CCOBn_MASK) + +/*! @name FCCOB5 - Flash Common Command Object Registers */ +#define FTFA_FCCOB5_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB5_CCOBn_SHIFT (0U) +#define FTFA_FCCOB5_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB5_CCOBn_SHIFT)) & FTFA_FCCOB5_CCOBn_MASK) + +/*! @name FCCOB4 - Flash Common Command Object Registers */ +#define FTFA_FCCOB4_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB4_CCOBn_SHIFT (0U) +#define FTFA_FCCOB4_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB4_CCOBn_SHIFT)) & FTFA_FCCOB4_CCOBn_MASK) + +/*! @name FCCOBB - Flash Common Command Object Registers */ +#define FTFA_FCCOBB_CCOBn_MASK (0xFFU) +#define FTFA_FCCOBB_CCOBn_SHIFT (0U) +#define FTFA_FCCOBB_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOBB_CCOBn_SHIFT)) & FTFA_FCCOBB_CCOBn_MASK) + +/*! @name FCCOBA - Flash Common Command Object Registers */ +#define FTFA_FCCOBA_CCOBn_MASK (0xFFU) +#define FTFA_FCCOBA_CCOBn_SHIFT (0U) +#define FTFA_FCCOBA_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOBA_CCOBn_SHIFT)) & FTFA_FCCOBA_CCOBn_MASK) + +/*! @name FCCOB9 - Flash Common Command Object Registers */ +#define FTFA_FCCOB9_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB9_CCOBn_SHIFT (0U) +#define FTFA_FCCOB9_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB9_CCOBn_SHIFT)) & FTFA_FCCOB9_CCOBn_MASK) + +/*! @name FCCOB8 - Flash Common Command Object Registers */ +#define FTFA_FCCOB8_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB8_CCOBn_SHIFT (0U) +#define FTFA_FCCOB8_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB8_CCOBn_SHIFT)) & FTFA_FCCOB8_CCOBn_MASK) + +/*! @name FPROT3 - Program Flash Protection Registers */ +#define FTFA_FPROT3_PROT_MASK (0xFFU) +#define FTFA_FPROT3_PROT_SHIFT (0U) +#define FTFA_FPROT3_PROT(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FPROT3_PROT_SHIFT)) & FTFA_FPROT3_PROT_MASK) + +/*! @name FPROT2 - Program Flash Protection Registers */ +#define FTFA_FPROT2_PROT_MASK (0xFFU) +#define FTFA_FPROT2_PROT_SHIFT (0U) +#define FTFA_FPROT2_PROT(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FPROT2_PROT_SHIFT)) & FTFA_FPROT2_PROT_MASK) + +/*! @name FPROT1 - Program Flash Protection Registers */ +#define FTFA_FPROT1_PROT_MASK (0xFFU) +#define FTFA_FPROT1_PROT_SHIFT (0U) +#define FTFA_FPROT1_PROT(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FPROT1_PROT_SHIFT)) & FTFA_FPROT1_PROT_MASK) + +/*! @name FPROT0 - Program Flash Protection Registers */ +#define FTFA_FPROT0_PROT_MASK (0xFFU) +#define FTFA_FPROT0_PROT_SHIFT (0U) +#define FTFA_FPROT0_PROT(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FPROT0_PROT_SHIFT)) & FTFA_FPROT0_PROT_MASK) + +/*! @name XACCH3 - Execute-only Access Registers */ +#define FTFA_XACCH3_XA_MASK (0xFFU) +#define FTFA_XACCH3_XA_SHIFT (0U) +#define FTFA_XACCH3_XA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_XACCH3_XA_SHIFT)) & FTFA_XACCH3_XA_MASK) + +/*! @name XACCH2 - Execute-only Access Registers */ +#define FTFA_XACCH2_XA_MASK (0xFFU) +#define FTFA_XACCH2_XA_SHIFT (0U) +#define FTFA_XACCH2_XA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_XACCH2_XA_SHIFT)) & FTFA_XACCH2_XA_MASK) + +/*! @name XACCH1 - Execute-only Access Registers */ +#define FTFA_XACCH1_XA_MASK (0xFFU) +#define FTFA_XACCH1_XA_SHIFT (0U) +#define FTFA_XACCH1_XA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_XACCH1_XA_SHIFT)) & FTFA_XACCH1_XA_MASK) + +/*! @name XACCH0 - Execute-only Access Registers */ +#define FTFA_XACCH0_XA_MASK (0xFFU) +#define FTFA_XACCH0_XA_SHIFT (0U) +#define FTFA_XACCH0_XA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_XACCH0_XA_SHIFT)) & FTFA_XACCH0_XA_MASK) + +/*! @name XACCL3 - Execute-only Access Registers */ +#define FTFA_XACCL3_XA_MASK (0xFFU) +#define FTFA_XACCL3_XA_SHIFT (0U) +#define FTFA_XACCL3_XA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_XACCL3_XA_SHIFT)) & FTFA_XACCL3_XA_MASK) + +/*! @name XACCL2 - Execute-only Access Registers */ +#define FTFA_XACCL2_XA_MASK (0xFFU) +#define FTFA_XACCL2_XA_SHIFT (0U) +#define FTFA_XACCL2_XA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_XACCL2_XA_SHIFT)) & FTFA_XACCL2_XA_MASK) + +/*! @name XACCL1 - Execute-only Access Registers */ +#define FTFA_XACCL1_XA_MASK (0xFFU) +#define FTFA_XACCL1_XA_SHIFT (0U) +#define FTFA_XACCL1_XA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_XACCL1_XA_SHIFT)) & FTFA_XACCL1_XA_MASK) + +/*! @name XACCL0 - Execute-only Access Registers */ +#define FTFA_XACCL0_XA_MASK (0xFFU) +#define FTFA_XACCL0_XA_SHIFT (0U) +#define FTFA_XACCL0_XA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_XACCL0_XA_SHIFT)) & FTFA_XACCL0_XA_MASK) + +/*! @name SACCH3 - Supervisor-only Access Registers */ +#define FTFA_SACCH3_SA_MASK (0xFFU) +#define FTFA_SACCH3_SA_SHIFT (0U) +#define FTFA_SACCH3_SA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_SACCH3_SA_SHIFT)) & FTFA_SACCH3_SA_MASK) + +/*! @name SACCH2 - Supervisor-only Access Registers */ +#define FTFA_SACCH2_SA_MASK (0xFFU) +#define FTFA_SACCH2_SA_SHIFT (0U) +#define FTFA_SACCH2_SA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_SACCH2_SA_SHIFT)) & FTFA_SACCH2_SA_MASK) + +/*! @name SACCH1 - Supervisor-only Access Registers */ +#define FTFA_SACCH1_SA_MASK (0xFFU) +#define FTFA_SACCH1_SA_SHIFT (0U) +#define FTFA_SACCH1_SA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_SACCH1_SA_SHIFT)) & FTFA_SACCH1_SA_MASK) + +/*! @name SACCH0 - Supervisor-only Access Registers */ +#define FTFA_SACCH0_SA_MASK (0xFFU) +#define FTFA_SACCH0_SA_SHIFT (0U) +#define FTFA_SACCH0_SA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_SACCH0_SA_SHIFT)) & FTFA_SACCH0_SA_MASK) + +/*! @name SACCL3 - Supervisor-only Access Registers */ +#define FTFA_SACCL3_SA_MASK (0xFFU) +#define FTFA_SACCL3_SA_SHIFT (0U) +#define FTFA_SACCL3_SA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_SACCL3_SA_SHIFT)) & FTFA_SACCL3_SA_MASK) + +/*! @name SACCL2 - Supervisor-only Access Registers */ +#define FTFA_SACCL2_SA_MASK (0xFFU) +#define FTFA_SACCL2_SA_SHIFT (0U) +#define FTFA_SACCL2_SA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_SACCL2_SA_SHIFT)) & FTFA_SACCL2_SA_MASK) + +/*! @name SACCL1 - Supervisor-only Access Registers */ +#define FTFA_SACCL1_SA_MASK (0xFFU) +#define FTFA_SACCL1_SA_SHIFT (0U) +#define FTFA_SACCL1_SA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_SACCL1_SA_SHIFT)) & FTFA_SACCL1_SA_MASK) + +/*! @name SACCL0 - Supervisor-only Access Registers */ +#define FTFA_SACCL0_SA_MASK (0xFFU) +#define FTFA_SACCL0_SA_SHIFT (0U) +#define FTFA_SACCL0_SA(x) (((uint8_t)(((uint8_t)(x)) << FTFA_SACCL0_SA_SHIFT)) & FTFA_SACCL0_SA_MASK) + +/*! @name FACSS - Flash Access Segment Size Register */ +#define FTFA_FACSS_SGSIZE_MASK (0xFFU) +#define FTFA_FACSS_SGSIZE_SHIFT (0U) +#define FTFA_FACSS_SGSIZE(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FACSS_SGSIZE_SHIFT)) & FTFA_FACSS_SGSIZE_MASK) + +/*! @name FACSN - Flash Access Segment Number Register */ +#define FTFA_FACSN_NUMSG_MASK (0xFFU) +#define FTFA_FACSN_NUMSG_SHIFT (0U) +#define FTFA_FACSN_NUMSG(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FACSN_NUMSG_SHIFT)) & FTFA_FACSN_NUMSG_MASK) + + +/*! + * @} + */ /* end of group FTFA_Register_Masks */ + + +/* FTFA - Peripheral instance base addresses */ +/** Peripheral FTFA base address */ +#define FTFA_BASE (0x40020000u) +/** Peripheral FTFA base pointer */ +#define FTFA ((FTFA_Type *)FTFA_BASE) +/** Array initializer of FTFA peripheral base addresses */ +#define FTFA_BASE_ADDRS { FTFA_BASE } +/** Array initializer of FTFA peripheral base pointers */ +#define FTFA_BASE_PTRS { FTFA } +/** Interrupt vectors for the FTFA peripheral type */ +#define FTFA_COMMAND_COMPLETE_IRQS { FTFA_IRQn } +#define FTFA_READ_COLLISION_IRQS { Read_Collision_IRQn } + +/*! + * @} + */ /* end of group FTFA_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- FTM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FTM_Peripheral_Access_Layer FTM Peripheral Access Layer + * @{ + */ + +/** FTM - Register Layout Typedef */ +typedef struct { + __IO uint32_t SC; /**< Status And Control, offset: 0x0 */ + __IO uint32_t CNT; /**< Counter, offset: 0x4 */ + __IO uint32_t MOD; /**< Modulo, offset: 0x8 */ + struct { /* offset: 0xC, array step: 0x8 */ + __IO uint32_t CnSC; /**< Channel (n) Status And Control, array offset: 0xC, array step: 0x8 */ + __IO uint32_t CnV; /**< Channel (n) Value, array offset: 0x10, array step: 0x8 */ + } CONTROLS[8]; + __IO uint32_t CNTIN; /**< Counter Initial Value, offset: 0x4C */ + __IO uint32_t STATUS; /**< Capture And Compare Status, offset: 0x50 */ + __IO uint32_t MODE; /**< Features Mode Selection, offset: 0x54 */ + __IO uint32_t SYNC; /**< Synchronization, offset: 0x58 */ + __IO uint32_t OUTINIT; /**< Initial State For Channels Output, offset: 0x5C */ + __IO uint32_t OUTMASK; /**< Output Mask, offset: 0x60 */ + __IO uint32_t COMBINE; /**< Function For Linked Channels, offset: 0x64 */ + __IO uint32_t DEADTIME; /**< Deadtime Insertion Control, offset: 0x68 */ + __IO uint32_t EXTTRIG; /**< FTM External Trigger, offset: 0x6C */ + __IO uint32_t POL; /**< Channels Polarity, offset: 0x70 */ + __IO uint32_t FMS; /**< Fault Mode Status, offset: 0x74 */ + __IO uint32_t FILTER; /**< Input Capture Filter Control, offset: 0x78 */ + __IO uint32_t FLTCTRL; /**< Fault Control, offset: 0x7C */ + __IO uint32_t QDCTRL; /**< Quadrature Decoder Control And Status, offset: 0x80 */ + __IO uint32_t CONF; /**< Configuration, offset: 0x84 */ + __IO uint32_t FLTPOL; /**< FTM Fault Input Polarity, offset: 0x88 */ + __IO uint32_t SYNCONF; /**< Synchronization Configuration, offset: 0x8C */ + __IO uint32_t INVCTRL; /**< FTM Inverting Control, offset: 0x90 */ + __IO uint32_t SWOCTRL; /**< FTM Software Output Control, offset: 0x94 */ + __IO uint32_t PWMLOAD; /**< FTM PWM Load, offset: 0x98 */ +} FTM_Type; + +/* ---------------------------------------------------------------------------- + -- FTM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FTM_Register_Masks FTM Register Masks + * @{ + */ + +/*! @name SC - Status And Control */ +#define FTM_SC_PS_MASK (0x7U) +#define FTM_SC_PS_SHIFT (0U) +#define FTM_SC_PS(x) (((uint32_t)(((uint32_t)(x)) << FTM_SC_PS_SHIFT)) & FTM_SC_PS_MASK) +#define FTM_SC_CLKS_MASK (0x18U) +#define FTM_SC_CLKS_SHIFT (3U) +#define FTM_SC_CLKS(x) (((uint32_t)(((uint32_t)(x)) << FTM_SC_CLKS_SHIFT)) & FTM_SC_CLKS_MASK) +#define FTM_SC_CPWMS_MASK (0x20U) +#define FTM_SC_CPWMS_SHIFT (5U) +#define FTM_SC_CPWMS(x) (((uint32_t)(((uint32_t)(x)) << FTM_SC_CPWMS_SHIFT)) & FTM_SC_CPWMS_MASK) +#define FTM_SC_TOIE_MASK (0x40U) +#define FTM_SC_TOIE_SHIFT (6U) +#define FTM_SC_TOIE(x) (((uint32_t)(((uint32_t)(x)) << FTM_SC_TOIE_SHIFT)) & FTM_SC_TOIE_MASK) +#define FTM_SC_TOF_MASK (0x80U) +#define FTM_SC_TOF_SHIFT (7U) +#define FTM_SC_TOF(x) (((uint32_t)(((uint32_t)(x)) << FTM_SC_TOF_SHIFT)) & FTM_SC_TOF_MASK) + +/*! @name CNT - Counter */ +#define FTM_CNT_COUNT_MASK (0xFFFFU) +#define FTM_CNT_COUNT_SHIFT (0U) +#define FTM_CNT_COUNT(x) (((uint32_t)(((uint32_t)(x)) << FTM_CNT_COUNT_SHIFT)) & FTM_CNT_COUNT_MASK) + +/*! @name MOD - Modulo */ +#define FTM_MOD_MOD_MASK (0xFFFFU) +#define FTM_MOD_MOD_SHIFT (0U) +#define FTM_MOD_MOD(x) (((uint32_t)(((uint32_t)(x)) << FTM_MOD_MOD_SHIFT)) & FTM_MOD_MOD_MASK) + +/*! @name CnSC - Channel (n) Status And Control */ +#define FTM_CnSC_DMA_MASK (0x1U) +#define FTM_CnSC_DMA_SHIFT (0U) +#define FTM_CnSC_DMA(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_DMA_SHIFT)) & FTM_CnSC_DMA_MASK) +#define FTM_CnSC_ICRST_MASK (0x2U) +#define FTM_CnSC_ICRST_SHIFT (1U) +#define FTM_CnSC_ICRST(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_ICRST_SHIFT)) & FTM_CnSC_ICRST_MASK) +#define FTM_CnSC_ELSA_MASK (0x4U) +#define FTM_CnSC_ELSA_SHIFT (2U) +#define FTM_CnSC_ELSA(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_ELSA_SHIFT)) & FTM_CnSC_ELSA_MASK) +#define FTM_CnSC_ELSB_MASK (0x8U) +#define FTM_CnSC_ELSB_SHIFT (3U) +#define FTM_CnSC_ELSB(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_ELSB_SHIFT)) & FTM_CnSC_ELSB_MASK) +#define FTM_CnSC_MSA_MASK (0x10U) +#define FTM_CnSC_MSA_SHIFT (4U) +#define FTM_CnSC_MSA(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_MSA_SHIFT)) & FTM_CnSC_MSA_MASK) +#define FTM_CnSC_MSB_MASK (0x20U) +#define FTM_CnSC_MSB_SHIFT (5U) +#define FTM_CnSC_MSB(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_MSB_SHIFT)) & FTM_CnSC_MSB_MASK) +#define FTM_CnSC_CHIE_MASK (0x40U) +#define FTM_CnSC_CHIE_SHIFT (6U) +#define FTM_CnSC_CHIE(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_CHIE_SHIFT)) & FTM_CnSC_CHIE_MASK) +#define FTM_CnSC_CHF_MASK (0x80U) +#define FTM_CnSC_CHF_SHIFT (7U) +#define FTM_CnSC_CHF(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_CHF_SHIFT)) & FTM_CnSC_CHF_MASK) + +/* The count of FTM_CnSC */ +#define FTM_CnSC_COUNT (8U) + +/*! @name CnV - Channel (n) Value */ +#define FTM_CnV_VAL_MASK (0xFFFFU) +#define FTM_CnV_VAL_SHIFT (0U) +#define FTM_CnV_VAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnV_VAL_SHIFT)) & FTM_CnV_VAL_MASK) + +/* The count of FTM_CnV */ +#define FTM_CnV_COUNT (8U) + +/*! @name CNTIN - Counter Initial Value */ +#define FTM_CNTIN_INIT_MASK (0xFFFFU) +#define FTM_CNTIN_INIT_SHIFT (0U) +#define FTM_CNTIN_INIT(x) (((uint32_t)(((uint32_t)(x)) << FTM_CNTIN_INIT_SHIFT)) & FTM_CNTIN_INIT_MASK) + +/*! @name STATUS - Capture And Compare Status */ +#define FTM_STATUS_CH0F_MASK (0x1U) +#define FTM_STATUS_CH0F_SHIFT (0U) +#define FTM_STATUS_CH0F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH0F_SHIFT)) & FTM_STATUS_CH0F_MASK) +#define FTM_STATUS_CH1F_MASK (0x2U) +#define FTM_STATUS_CH1F_SHIFT (1U) +#define FTM_STATUS_CH1F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH1F_SHIFT)) & FTM_STATUS_CH1F_MASK) +#define FTM_STATUS_CH2F_MASK (0x4U) +#define FTM_STATUS_CH2F_SHIFT (2U) +#define FTM_STATUS_CH2F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH2F_SHIFT)) & FTM_STATUS_CH2F_MASK) +#define FTM_STATUS_CH3F_MASK (0x8U) +#define FTM_STATUS_CH3F_SHIFT (3U) +#define FTM_STATUS_CH3F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH3F_SHIFT)) & FTM_STATUS_CH3F_MASK) +#define FTM_STATUS_CH4F_MASK (0x10U) +#define FTM_STATUS_CH4F_SHIFT (4U) +#define FTM_STATUS_CH4F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH4F_SHIFT)) & FTM_STATUS_CH4F_MASK) +#define FTM_STATUS_CH5F_MASK (0x20U) +#define FTM_STATUS_CH5F_SHIFT (5U) +#define FTM_STATUS_CH5F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH5F_SHIFT)) & FTM_STATUS_CH5F_MASK) +#define FTM_STATUS_CH6F_MASK (0x40U) +#define FTM_STATUS_CH6F_SHIFT (6U) +#define FTM_STATUS_CH6F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH6F_SHIFT)) & FTM_STATUS_CH6F_MASK) +#define FTM_STATUS_CH7F_MASK (0x80U) +#define FTM_STATUS_CH7F_SHIFT (7U) +#define FTM_STATUS_CH7F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH7F_SHIFT)) & FTM_STATUS_CH7F_MASK) + +/*! @name MODE - Features Mode Selection */ +#define FTM_MODE_FTMEN_MASK (0x1U) +#define FTM_MODE_FTMEN_SHIFT (0U) +#define FTM_MODE_FTMEN(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_FTMEN_SHIFT)) & FTM_MODE_FTMEN_MASK) +#define FTM_MODE_INIT_MASK (0x2U) +#define FTM_MODE_INIT_SHIFT (1U) +#define FTM_MODE_INIT(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_INIT_SHIFT)) & FTM_MODE_INIT_MASK) +#define FTM_MODE_WPDIS_MASK (0x4U) +#define FTM_MODE_WPDIS_SHIFT (2U) +#define FTM_MODE_WPDIS(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_WPDIS_SHIFT)) & FTM_MODE_WPDIS_MASK) +#define FTM_MODE_PWMSYNC_MASK (0x8U) +#define FTM_MODE_PWMSYNC_SHIFT (3U) +#define FTM_MODE_PWMSYNC(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_PWMSYNC_SHIFT)) & FTM_MODE_PWMSYNC_MASK) +#define FTM_MODE_CAPTEST_MASK (0x10U) +#define FTM_MODE_CAPTEST_SHIFT (4U) +#define FTM_MODE_CAPTEST(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_CAPTEST_SHIFT)) & FTM_MODE_CAPTEST_MASK) +#define FTM_MODE_FAULTM_MASK (0x60U) +#define FTM_MODE_FAULTM_SHIFT (5U) +#define FTM_MODE_FAULTM(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_FAULTM_SHIFT)) & FTM_MODE_FAULTM_MASK) +#define FTM_MODE_FAULTIE_MASK (0x80U) +#define FTM_MODE_FAULTIE_SHIFT (7U) +#define FTM_MODE_FAULTIE(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_FAULTIE_SHIFT)) & FTM_MODE_FAULTIE_MASK) + +/*! @name SYNC - Synchronization */ +#define FTM_SYNC_CNTMIN_MASK (0x1U) +#define FTM_SYNC_CNTMIN_SHIFT (0U) +#define FTM_SYNC_CNTMIN(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_CNTMIN_SHIFT)) & FTM_SYNC_CNTMIN_MASK) +#define FTM_SYNC_CNTMAX_MASK (0x2U) +#define FTM_SYNC_CNTMAX_SHIFT (1U) +#define FTM_SYNC_CNTMAX(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_CNTMAX_SHIFT)) & FTM_SYNC_CNTMAX_MASK) +#define FTM_SYNC_REINIT_MASK (0x4U) +#define FTM_SYNC_REINIT_SHIFT (2U) +#define FTM_SYNC_REINIT(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_REINIT_SHIFT)) & FTM_SYNC_REINIT_MASK) +#define FTM_SYNC_SYNCHOM_MASK (0x8U) +#define FTM_SYNC_SYNCHOM_SHIFT (3U) +#define FTM_SYNC_SYNCHOM(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_SYNCHOM_SHIFT)) & FTM_SYNC_SYNCHOM_MASK) +#define FTM_SYNC_TRIG0_MASK (0x10U) +#define FTM_SYNC_TRIG0_SHIFT (4U) +#define FTM_SYNC_TRIG0(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_TRIG0_SHIFT)) & FTM_SYNC_TRIG0_MASK) +#define FTM_SYNC_TRIG1_MASK (0x20U) +#define FTM_SYNC_TRIG1_SHIFT (5U) +#define FTM_SYNC_TRIG1(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_TRIG1_SHIFT)) & FTM_SYNC_TRIG1_MASK) +#define FTM_SYNC_TRIG2_MASK (0x40U) +#define FTM_SYNC_TRIG2_SHIFT (6U) +#define FTM_SYNC_TRIG2(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_TRIG2_SHIFT)) & FTM_SYNC_TRIG2_MASK) +#define FTM_SYNC_SWSYNC_MASK (0x80U) +#define FTM_SYNC_SWSYNC_SHIFT (7U) +#define FTM_SYNC_SWSYNC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_SWSYNC_SHIFT)) & FTM_SYNC_SWSYNC_MASK) + +/*! @name OUTINIT - Initial State For Channels Output */ +#define FTM_OUTINIT_CH0OI_MASK (0x1U) +#define FTM_OUTINIT_CH0OI_SHIFT (0U) +#define FTM_OUTINIT_CH0OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH0OI_SHIFT)) & FTM_OUTINIT_CH0OI_MASK) +#define FTM_OUTINIT_CH1OI_MASK (0x2U) +#define FTM_OUTINIT_CH1OI_SHIFT (1U) +#define FTM_OUTINIT_CH1OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH1OI_SHIFT)) & FTM_OUTINIT_CH1OI_MASK) +#define FTM_OUTINIT_CH2OI_MASK (0x4U) +#define FTM_OUTINIT_CH2OI_SHIFT (2U) +#define FTM_OUTINIT_CH2OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH2OI_SHIFT)) & FTM_OUTINIT_CH2OI_MASK) +#define FTM_OUTINIT_CH3OI_MASK (0x8U) +#define FTM_OUTINIT_CH3OI_SHIFT (3U) +#define FTM_OUTINIT_CH3OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH3OI_SHIFT)) & FTM_OUTINIT_CH3OI_MASK) +#define FTM_OUTINIT_CH4OI_MASK (0x10U) +#define FTM_OUTINIT_CH4OI_SHIFT (4U) +#define FTM_OUTINIT_CH4OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH4OI_SHIFT)) & FTM_OUTINIT_CH4OI_MASK) +#define FTM_OUTINIT_CH5OI_MASK (0x20U) +#define FTM_OUTINIT_CH5OI_SHIFT (5U) +#define FTM_OUTINIT_CH5OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH5OI_SHIFT)) & FTM_OUTINIT_CH5OI_MASK) +#define FTM_OUTINIT_CH6OI_MASK (0x40U) +#define FTM_OUTINIT_CH6OI_SHIFT (6U) +#define FTM_OUTINIT_CH6OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH6OI_SHIFT)) & FTM_OUTINIT_CH6OI_MASK) +#define FTM_OUTINIT_CH7OI_MASK (0x80U) +#define FTM_OUTINIT_CH7OI_SHIFT (7U) +#define FTM_OUTINIT_CH7OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH7OI_SHIFT)) & FTM_OUTINIT_CH7OI_MASK) + +/*! @name OUTMASK - Output Mask */ +#define FTM_OUTMASK_CH0OM_MASK (0x1U) +#define FTM_OUTMASK_CH0OM_SHIFT (0U) +#define FTM_OUTMASK_CH0OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH0OM_SHIFT)) & FTM_OUTMASK_CH0OM_MASK) +#define FTM_OUTMASK_CH1OM_MASK (0x2U) +#define FTM_OUTMASK_CH1OM_SHIFT (1U) +#define FTM_OUTMASK_CH1OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH1OM_SHIFT)) & FTM_OUTMASK_CH1OM_MASK) +#define FTM_OUTMASK_CH2OM_MASK (0x4U) +#define FTM_OUTMASK_CH2OM_SHIFT (2U) +#define FTM_OUTMASK_CH2OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH2OM_SHIFT)) & FTM_OUTMASK_CH2OM_MASK) +#define FTM_OUTMASK_CH3OM_MASK (0x8U) +#define FTM_OUTMASK_CH3OM_SHIFT (3U) +#define FTM_OUTMASK_CH3OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH3OM_SHIFT)) & FTM_OUTMASK_CH3OM_MASK) +#define FTM_OUTMASK_CH4OM_MASK (0x10U) +#define FTM_OUTMASK_CH4OM_SHIFT (4U) +#define FTM_OUTMASK_CH4OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH4OM_SHIFT)) & FTM_OUTMASK_CH4OM_MASK) +#define FTM_OUTMASK_CH5OM_MASK (0x20U) +#define FTM_OUTMASK_CH5OM_SHIFT (5U) +#define FTM_OUTMASK_CH5OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH5OM_SHIFT)) & FTM_OUTMASK_CH5OM_MASK) +#define FTM_OUTMASK_CH6OM_MASK (0x40U) +#define FTM_OUTMASK_CH6OM_SHIFT (6U) +#define FTM_OUTMASK_CH6OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH6OM_SHIFT)) & FTM_OUTMASK_CH6OM_MASK) +#define FTM_OUTMASK_CH7OM_MASK (0x80U) +#define FTM_OUTMASK_CH7OM_SHIFT (7U) +#define FTM_OUTMASK_CH7OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH7OM_SHIFT)) & FTM_OUTMASK_CH7OM_MASK) + +/*! @name COMBINE - Function For Linked Channels */ +#define FTM_COMBINE_COMBINE0_MASK (0x1U) +#define FTM_COMBINE_COMBINE0_SHIFT (0U) +#define FTM_COMBINE_COMBINE0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMBINE0_SHIFT)) & FTM_COMBINE_COMBINE0_MASK) +#define FTM_COMBINE_COMP0_MASK (0x2U) +#define FTM_COMBINE_COMP0_SHIFT (1U) +#define FTM_COMBINE_COMP0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMP0_SHIFT)) & FTM_COMBINE_COMP0_MASK) +#define FTM_COMBINE_DECAPEN0_MASK (0x4U) +#define FTM_COMBINE_DECAPEN0_SHIFT (2U) +#define FTM_COMBINE_DECAPEN0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAPEN0_SHIFT)) & FTM_COMBINE_DECAPEN0_MASK) +#define FTM_COMBINE_DECAP0_MASK (0x8U) +#define FTM_COMBINE_DECAP0_SHIFT (3U) +#define FTM_COMBINE_DECAP0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAP0_SHIFT)) & FTM_COMBINE_DECAP0_MASK) +#define FTM_COMBINE_DTEN0_MASK (0x10U) +#define FTM_COMBINE_DTEN0_SHIFT (4U) +#define FTM_COMBINE_DTEN0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DTEN0_SHIFT)) & FTM_COMBINE_DTEN0_MASK) +#define FTM_COMBINE_SYNCEN0_MASK (0x20U) +#define FTM_COMBINE_SYNCEN0_SHIFT (5U) +#define FTM_COMBINE_SYNCEN0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_SYNCEN0_SHIFT)) & FTM_COMBINE_SYNCEN0_MASK) +#define FTM_COMBINE_FAULTEN0_MASK (0x40U) +#define FTM_COMBINE_FAULTEN0_SHIFT (6U) +#define FTM_COMBINE_FAULTEN0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_FAULTEN0_SHIFT)) & FTM_COMBINE_FAULTEN0_MASK) +#define FTM_COMBINE_COMBINE1_MASK (0x100U) +#define FTM_COMBINE_COMBINE1_SHIFT (8U) +#define FTM_COMBINE_COMBINE1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMBINE1_SHIFT)) & FTM_COMBINE_COMBINE1_MASK) +#define FTM_COMBINE_COMP1_MASK (0x200U) +#define FTM_COMBINE_COMP1_SHIFT (9U) +#define FTM_COMBINE_COMP1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMP1_SHIFT)) & FTM_COMBINE_COMP1_MASK) +#define FTM_COMBINE_DECAPEN1_MASK (0x400U) +#define FTM_COMBINE_DECAPEN1_SHIFT (10U) +#define FTM_COMBINE_DECAPEN1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAPEN1_SHIFT)) & FTM_COMBINE_DECAPEN1_MASK) +#define FTM_COMBINE_DECAP1_MASK (0x800U) +#define FTM_COMBINE_DECAP1_SHIFT (11U) +#define FTM_COMBINE_DECAP1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAP1_SHIFT)) & FTM_COMBINE_DECAP1_MASK) +#define FTM_COMBINE_DTEN1_MASK (0x1000U) +#define FTM_COMBINE_DTEN1_SHIFT (12U) +#define FTM_COMBINE_DTEN1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DTEN1_SHIFT)) & FTM_COMBINE_DTEN1_MASK) +#define FTM_COMBINE_SYNCEN1_MASK (0x2000U) +#define FTM_COMBINE_SYNCEN1_SHIFT (13U) +#define FTM_COMBINE_SYNCEN1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_SYNCEN1_SHIFT)) & FTM_COMBINE_SYNCEN1_MASK) +#define FTM_COMBINE_FAULTEN1_MASK (0x4000U) +#define FTM_COMBINE_FAULTEN1_SHIFT (14U) +#define FTM_COMBINE_FAULTEN1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_FAULTEN1_SHIFT)) & FTM_COMBINE_FAULTEN1_MASK) +#define FTM_COMBINE_COMBINE2_MASK (0x10000U) +#define FTM_COMBINE_COMBINE2_SHIFT (16U) +#define FTM_COMBINE_COMBINE2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMBINE2_SHIFT)) & FTM_COMBINE_COMBINE2_MASK) +#define FTM_COMBINE_COMP2_MASK (0x20000U) +#define FTM_COMBINE_COMP2_SHIFT (17U) +#define FTM_COMBINE_COMP2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMP2_SHIFT)) & FTM_COMBINE_COMP2_MASK) +#define FTM_COMBINE_DECAPEN2_MASK (0x40000U) +#define FTM_COMBINE_DECAPEN2_SHIFT (18U) +#define FTM_COMBINE_DECAPEN2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAPEN2_SHIFT)) & FTM_COMBINE_DECAPEN2_MASK) +#define FTM_COMBINE_DECAP2_MASK (0x80000U) +#define FTM_COMBINE_DECAP2_SHIFT (19U) +#define FTM_COMBINE_DECAP2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAP2_SHIFT)) & FTM_COMBINE_DECAP2_MASK) +#define FTM_COMBINE_DTEN2_MASK (0x100000U) +#define FTM_COMBINE_DTEN2_SHIFT (20U) +#define FTM_COMBINE_DTEN2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DTEN2_SHIFT)) & FTM_COMBINE_DTEN2_MASK) +#define FTM_COMBINE_SYNCEN2_MASK (0x200000U) +#define FTM_COMBINE_SYNCEN2_SHIFT (21U) +#define FTM_COMBINE_SYNCEN2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_SYNCEN2_SHIFT)) & FTM_COMBINE_SYNCEN2_MASK) +#define FTM_COMBINE_FAULTEN2_MASK (0x400000U) +#define FTM_COMBINE_FAULTEN2_SHIFT (22U) +#define FTM_COMBINE_FAULTEN2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_FAULTEN2_SHIFT)) & FTM_COMBINE_FAULTEN2_MASK) +#define FTM_COMBINE_COMBINE3_MASK (0x1000000U) +#define FTM_COMBINE_COMBINE3_SHIFT (24U) +#define FTM_COMBINE_COMBINE3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMBINE3_SHIFT)) & FTM_COMBINE_COMBINE3_MASK) +#define FTM_COMBINE_COMP3_MASK (0x2000000U) +#define FTM_COMBINE_COMP3_SHIFT (25U) +#define FTM_COMBINE_COMP3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMP3_SHIFT)) & FTM_COMBINE_COMP3_MASK) +#define FTM_COMBINE_DECAPEN3_MASK (0x4000000U) +#define FTM_COMBINE_DECAPEN3_SHIFT (26U) +#define FTM_COMBINE_DECAPEN3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAPEN3_SHIFT)) & FTM_COMBINE_DECAPEN3_MASK) +#define FTM_COMBINE_DECAP3_MASK (0x8000000U) +#define FTM_COMBINE_DECAP3_SHIFT (27U) +#define FTM_COMBINE_DECAP3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAP3_SHIFT)) & FTM_COMBINE_DECAP3_MASK) +#define FTM_COMBINE_DTEN3_MASK (0x10000000U) +#define FTM_COMBINE_DTEN3_SHIFT (28U) +#define FTM_COMBINE_DTEN3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DTEN3_SHIFT)) & FTM_COMBINE_DTEN3_MASK) +#define FTM_COMBINE_SYNCEN3_MASK (0x20000000U) +#define FTM_COMBINE_SYNCEN3_SHIFT (29U) +#define FTM_COMBINE_SYNCEN3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_SYNCEN3_SHIFT)) & FTM_COMBINE_SYNCEN3_MASK) +#define FTM_COMBINE_FAULTEN3_MASK (0x40000000U) +#define FTM_COMBINE_FAULTEN3_SHIFT (30U) +#define FTM_COMBINE_FAULTEN3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_FAULTEN3_SHIFT)) & FTM_COMBINE_FAULTEN3_MASK) + +/*! @name DEADTIME - Deadtime Insertion Control */ +#define FTM_DEADTIME_DTVAL_MASK (0x3FU) +#define FTM_DEADTIME_DTVAL_SHIFT (0U) +#define FTM_DEADTIME_DTVAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_DEADTIME_DTVAL_SHIFT)) & FTM_DEADTIME_DTVAL_MASK) +#define FTM_DEADTIME_DTPS_MASK (0xC0U) +#define FTM_DEADTIME_DTPS_SHIFT (6U) +#define FTM_DEADTIME_DTPS(x) (((uint32_t)(((uint32_t)(x)) << FTM_DEADTIME_DTPS_SHIFT)) & FTM_DEADTIME_DTPS_MASK) + +/*! @name EXTTRIG - FTM External Trigger */ +#define FTM_EXTTRIG_CH2TRIG_MASK (0x1U) +#define FTM_EXTTRIG_CH2TRIG_SHIFT (0U) +#define FTM_EXTTRIG_CH2TRIG(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_CH2TRIG_SHIFT)) & FTM_EXTTRIG_CH2TRIG_MASK) +#define FTM_EXTTRIG_CH3TRIG_MASK (0x2U) +#define FTM_EXTTRIG_CH3TRIG_SHIFT (1U) +#define FTM_EXTTRIG_CH3TRIG(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_CH3TRIG_SHIFT)) & FTM_EXTTRIG_CH3TRIG_MASK) +#define FTM_EXTTRIG_CH4TRIG_MASK (0x4U) +#define FTM_EXTTRIG_CH4TRIG_SHIFT (2U) +#define FTM_EXTTRIG_CH4TRIG(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_CH4TRIG_SHIFT)) & FTM_EXTTRIG_CH4TRIG_MASK) +#define FTM_EXTTRIG_CH5TRIG_MASK (0x8U) +#define FTM_EXTTRIG_CH5TRIG_SHIFT (3U) +#define FTM_EXTTRIG_CH5TRIG(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_CH5TRIG_SHIFT)) & FTM_EXTTRIG_CH5TRIG_MASK) +#define FTM_EXTTRIG_CH0TRIG_MASK (0x10U) +#define FTM_EXTTRIG_CH0TRIG_SHIFT (4U) +#define FTM_EXTTRIG_CH0TRIG(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_CH0TRIG_SHIFT)) & FTM_EXTTRIG_CH0TRIG_MASK) +#define FTM_EXTTRIG_CH1TRIG_MASK (0x20U) +#define FTM_EXTTRIG_CH1TRIG_SHIFT (5U) +#define FTM_EXTTRIG_CH1TRIG(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_CH1TRIG_SHIFT)) & FTM_EXTTRIG_CH1TRIG_MASK) +#define FTM_EXTTRIG_INITTRIGEN_MASK (0x40U) +#define FTM_EXTTRIG_INITTRIGEN_SHIFT (6U) +#define FTM_EXTTRIG_INITTRIGEN(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_INITTRIGEN_SHIFT)) & FTM_EXTTRIG_INITTRIGEN_MASK) +#define FTM_EXTTRIG_TRIGF_MASK (0x80U) +#define FTM_EXTTRIG_TRIGF_SHIFT (7U) +#define FTM_EXTTRIG_TRIGF(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_TRIGF_SHIFT)) & FTM_EXTTRIG_TRIGF_MASK) + +/*! @name POL - Channels Polarity */ +#define FTM_POL_POL0_MASK (0x1U) +#define FTM_POL_POL0_SHIFT (0U) +#define FTM_POL_POL0(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL0_SHIFT)) & FTM_POL_POL0_MASK) +#define FTM_POL_POL1_MASK (0x2U) +#define FTM_POL_POL1_SHIFT (1U) +#define FTM_POL_POL1(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL1_SHIFT)) & FTM_POL_POL1_MASK) +#define FTM_POL_POL2_MASK (0x4U) +#define FTM_POL_POL2_SHIFT (2U) +#define FTM_POL_POL2(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL2_SHIFT)) & FTM_POL_POL2_MASK) +#define FTM_POL_POL3_MASK (0x8U) +#define FTM_POL_POL3_SHIFT (3U) +#define FTM_POL_POL3(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL3_SHIFT)) & FTM_POL_POL3_MASK) +#define FTM_POL_POL4_MASK (0x10U) +#define FTM_POL_POL4_SHIFT (4U) +#define FTM_POL_POL4(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL4_SHIFT)) & FTM_POL_POL4_MASK) +#define FTM_POL_POL5_MASK (0x20U) +#define FTM_POL_POL5_SHIFT (5U) +#define FTM_POL_POL5(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL5_SHIFT)) & FTM_POL_POL5_MASK) +#define FTM_POL_POL6_MASK (0x40U) +#define FTM_POL_POL6_SHIFT (6U) +#define FTM_POL_POL6(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL6_SHIFT)) & FTM_POL_POL6_MASK) +#define FTM_POL_POL7_MASK (0x80U) +#define FTM_POL_POL7_SHIFT (7U) +#define FTM_POL_POL7(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL7_SHIFT)) & FTM_POL_POL7_MASK) + +/*! @name FMS - Fault Mode Status */ +#define FTM_FMS_FAULTF0_MASK (0x1U) +#define FTM_FMS_FAULTF0_SHIFT (0U) +#define FTM_FMS_FAULTF0(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_FAULTF0_SHIFT)) & FTM_FMS_FAULTF0_MASK) +#define FTM_FMS_FAULTF1_MASK (0x2U) +#define FTM_FMS_FAULTF1_SHIFT (1U) +#define FTM_FMS_FAULTF1(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_FAULTF1_SHIFT)) & FTM_FMS_FAULTF1_MASK) +#define FTM_FMS_FAULTF2_MASK (0x4U) +#define FTM_FMS_FAULTF2_SHIFT (2U) +#define FTM_FMS_FAULTF2(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_FAULTF2_SHIFT)) & FTM_FMS_FAULTF2_MASK) +#define FTM_FMS_FAULTF3_MASK (0x8U) +#define FTM_FMS_FAULTF3_SHIFT (3U) +#define FTM_FMS_FAULTF3(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_FAULTF3_SHIFT)) & FTM_FMS_FAULTF3_MASK) +#define FTM_FMS_FAULTIN_MASK (0x20U) +#define FTM_FMS_FAULTIN_SHIFT (5U) +#define FTM_FMS_FAULTIN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_FAULTIN_SHIFT)) & FTM_FMS_FAULTIN_MASK) +#define FTM_FMS_WPEN_MASK (0x40U) +#define FTM_FMS_WPEN_SHIFT (6U) +#define FTM_FMS_WPEN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_WPEN_SHIFT)) & FTM_FMS_WPEN_MASK) +#define FTM_FMS_FAULTF_MASK (0x80U) +#define FTM_FMS_FAULTF_SHIFT (7U) +#define FTM_FMS_FAULTF(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_FAULTF_SHIFT)) & FTM_FMS_FAULTF_MASK) + +/*! @name FILTER - Input Capture Filter Control */ +#define FTM_FILTER_CH0FVAL_MASK (0xFU) +#define FTM_FILTER_CH0FVAL_SHIFT (0U) +#define FTM_FILTER_CH0FVAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FILTER_CH0FVAL_SHIFT)) & FTM_FILTER_CH0FVAL_MASK) +#define FTM_FILTER_CH1FVAL_MASK (0xF0U) +#define FTM_FILTER_CH1FVAL_SHIFT (4U) +#define FTM_FILTER_CH1FVAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FILTER_CH1FVAL_SHIFT)) & FTM_FILTER_CH1FVAL_MASK) +#define FTM_FILTER_CH2FVAL_MASK (0xF00U) +#define FTM_FILTER_CH2FVAL_SHIFT (8U) +#define FTM_FILTER_CH2FVAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FILTER_CH2FVAL_SHIFT)) & FTM_FILTER_CH2FVAL_MASK) +#define FTM_FILTER_CH3FVAL_MASK (0xF000U) +#define FTM_FILTER_CH3FVAL_SHIFT (12U) +#define FTM_FILTER_CH3FVAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FILTER_CH3FVAL_SHIFT)) & FTM_FILTER_CH3FVAL_MASK) + +/*! @name FLTCTRL - Fault Control */ +#define FTM_FLTCTRL_FAULT0EN_MASK (0x1U) +#define FTM_FLTCTRL_FAULT0EN_SHIFT (0U) +#define FTM_FLTCTRL_FAULT0EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FAULT0EN_SHIFT)) & FTM_FLTCTRL_FAULT0EN_MASK) +#define FTM_FLTCTRL_FAULT1EN_MASK (0x2U) +#define FTM_FLTCTRL_FAULT1EN_SHIFT (1U) +#define FTM_FLTCTRL_FAULT1EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FAULT1EN_SHIFT)) & FTM_FLTCTRL_FAULT1EN_MASK) +#define FTM_FLTCTRL_FAULT2EN_MASK (0x4U) +#define FTM_FLTCTRL_FAULT2EN_SHIFT (2U) +#define FTM_FLTCTRL_FAULT2EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FAULT2EN_SHIFT)) & FTM_FLTCTRL_FAULT2EN_MASK) +#define FTM_FLTCTRL_FAULT3EN_MASK (0x8U) +#define FTM_FLTCTRL_FAULT3EN_SHIFT (3U) +#define FTM_FLTCTRL_FAULT3EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FAULT3EN_SHIFT)) & FTM_FLTCTRL_FAULT3EN_MASK) +#define FTM_FLTCTRL_FFLTR0EN_MASK (0x10U) +#define FTM_FLTCTRL_FFLTR0EN_SHIFT (4U) +#define FTM_FLTCTRL_FFLTR0EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FFLTR0EN_SHIFT)) & FTM_FLTCTRL_FFLTR0EN_MASK) +#define FTM_FLTCTRL_FFLTR1EN_MASK (0x20U) +#define FTM_FLTCTRL_FFLTR1EN_SHIFT (5U) +#define FTM_FLTCTRL_FFLTR1EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FFLTR1EN_SHIFT)) & FTM_FLTCTRL_FFLTR1EN_MASK) +#define FTM_FLTCTRL_FFLTR2EN_MASK (0x40U) +#define FTM_FLTCTRL_FFLTR2EN_SHIFT (6U) +#define FTM_FLTCTRL_FFLTR2EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FFLTR2EN_SHIFT)) & FTM_FLTCTRL_FFLTR2EN_MASK) +#define FTM_FLTCTRL_FFLTR3EN_MASK (0x80U) +#define FTM_FLTCTRL_FFLTR3EN_SHIFT (7U) +#define FTM_FLTCTRL_FFLTR3EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FFLTR3EN_SHIFT)) & FTM_FLTCTRL_FFLTR3EN_MASK) +#define FTM_FLTCTRL_FFVAL_MASK (0xF00U) +#define FTM_FLTCTRL_FFVAL_SHIFT (8U) +#define FTM_FLTCTRL_FFVAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FFVAL_SHIFT)) & FTM_FLTCTRL_FFVAL_MASK) + +/*! @name QDCTRL - Quadrature Decoder Control And Status */ +#define FTM_QDCTRL_QUADEN_MASK (0x1U) +#define FTM_QDCTRL_QUADEN_SHIFT (0U) +#define FTM_QDCTRL_QUADEN(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_QUADEN_SHIFT)) & FTM_QDCTRL_QUADEN_MASK) +#define FTM_QDCTRL_TOFDIR_MASK (0x2U) +#define FTM_QDCTRL_TOFDIR_SHIFT (1U) +#define FTM_QDCTRL_TOFDIR(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_TOFDIR_SHIFT)) & FTM_QDCTRL_TOFDIR_MASK) +#define FTM_QDCTRL_QUADIR_MASK (0x4U) +#define FTM_QDCTRL_QUADIR_SHIFT (2U) +#define FTM_QDCTRL_QUADIR(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_QUADIR_SHIFT)) & FTM_QDCTRL_QUADIR_MASK) +#define FTM_QDCTRL_QUADMODE_MASK (0x8U) +#define FTM_QDCTRL_QUADMODE_SHIFT (3U) +#define FTM_QDCTRL_QUADMODE(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_QUADMODE_SHIFT)) & FTM_QDCTRL_QUADMODE_MASK) +#define FTM_QDCTRL_PHBPOL_MASK (0x10U) +#define FTM_QDCTRL_PHBPOL_SHIFT (4U) +#define FTM_QDCTRL_PHBPOL(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_PHBPOL_SHIFT)) & FTM_QDCTRL_PHBPOL_MASK) +#define FTM_QDCTRL_PHAPOL_MASK (0x20U) +#define FTM_QDCTRL_PHAPOL_SHIFT (5U) +#define FTM_QDCTRL_PHAPOL(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_PHAPOL_SHIFT)) & FTM_QDCTRL_PHAPOL_MASK) +#define FTM_QDCTRL_PHBFLTREN_MASK (0x40U) +#define FTM_QDCTRL_PHBFLTREN_SHIFT (6U) +#define FTM_QDCTRL_PHBFLTREN(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_PHBFLTREN_SHIFT)) & FTM_QDCTRL_PHBFLTREN_MASK) +#define FTM_QDCTRL_PHAFLTREN_MASK (0x80U) +#define FTM_QDCTRL_PHAFLTREN_SHIFT (7U) +#define FTM_QDCTRL_PHAFLTREN(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_PHAFLTREN_SHIFT)) & FTM_QDCTRL_PHAFLTREN_MASK) + +/*! @name CONF - Configuration */ +#define FTM_CONF_NUMTOF_MASK (0x1FU) +#define FTM_CONF_NUMTOF_SHIFT (0U) +#define FTM_CONF_NUMTOF(x) (((uint32_t)(((uint32_t)(x)) << FTM_CONF_NUMTOF_SHIFT)) & FTM_CONF_NUMTOF_MASK) +#define FTM_CONF_BDMMODE_MASK (0xC0U) +#define FTM_CONF_BDMMODE_SHIFT (6U) +#define FTM_CONF_BDMMODE(x) (((uint32_t)(((uint32_t)(x)) << FTM_CONF_BDMMODE_SHIFT)) & FTM_CONF_BDMMODE_MASK) +#define FTM_CONF_GTBEEN_MASK (0x200U) +#define FTM_CONF_GTBEEN_SHIFT (9U) +#define FTM_CONF_GTBEEN(x) (((uint32_t)(((uint32_t)(x)) << FTM_CONF_GTBEEN_SHIFT)) & FTM_CONF_GTBEEN_MASK) +#define FTM_CONF_GTBEOUT_MASK (0x400U) +#define FTM_CONF_GTBEOUT_SHIFT (10U) +#define FTM_CONF_GTBEOUT(x) (((uint32_t)(((uint32_t)(x)) << FTM_CONF_GTBEOUT_SHIFT)) & FTM_CONF_GTBEOUT_MASK) + +/*! @name FLTPOL - FTM Fault Input Polarity */ +#define FTM_FLTPOL_FLT0POL_MASK (0x1U) +#define FTM_FLTPOL_FLT0POL_SHIFT (0U) +#define FTM_FLTPOL_FLT0POL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTPOL_FLT0POL_SHIFT)) & FTM_FLTPOL_FLT0POL_MASK) +#define FTM_FLTPOL_FLT1POL_MASK (0x2U) +#define FTM_FLTPOL_FLT1POL_SHIFT (1U) +#define FTM_FLTPOL_FLT1POL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTPOL_FLT1POL_SHIFT)) & FTM_FLTPOL_FLT1POL_MASK) +#define FTM_FLTPOL_FLT2POL_MASK (0x4U) +#define FTM_FLTPOL_FLT2POL_SHIFT (2U) +#define FTM_FLTPOL_FLT2POL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTPOL_FLT2POL_SHIFT)) & FTM_FLTPOL_FLT2POL_MASK) +#define FTM_FLTPOL_FLT3POL_MASK (0x8U) +#define FTM_FLTPOL_FLT3POL_SHIFT (3U) +#define FTM_FLTPOL_FLT3POL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTPOL_FLT3POL_SHIFT)) & FTM_FLTPOL_FLT3POL_MASK) + +/*! @name SYNCONF - Synchronization Configuration */ +#define FTM_SYNCONF_HWTRIGMODE_MASK (0x1U) +#define FTM_SYNCONF_HWTRIGMODE_SHIFT (0U) +#define FTM_SYNCONF_HWTRIGMODE(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_HWTRIGMODE_SHIFT)) & FTM_SYNCONF_HWTRIGMODE_MASK) +#define FTM_SYNCONF_CNTINC_MASK (0x4U) +#define FTM_SYNCONF_CNTINC_SHIFT (2U) +#define FTM_SYNCONF_CNTINC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_CNTINC_SHIFT)) & FTM_SYNCONF_CNTINC_MASK) +#define FTM_SYNCONF_INVC_MASK (0x10U) +#define FTM_SYNCONF_INVC_SHIFT (4U) +#define FTM_SYNCONF_INVC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_INVC_SHIFT)) & FTM_SYNCONF_INVC_MASK) +#define FTM_SYNCONF_SWOC_MASK (0x20U) +#define FTM_SYNCONF_SWOC_SHIFT (5U) +#define FTM_SYNCONF_SWOC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SWOC_SHIFT)) & FTM_SYNCONF_SWOC_MASK) +#define FTM_SYNCONF_SYNCMODE_MASK (0x80U) +#define FTM_SYNCONF_SYNCMODE_SHIFT (7U) +#define FTM_SYNCONF_SYNCMODE(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SYNCMODE_SHIFT)) & FTM_SYNCONF_SYNCMODE_MASK) +#define FTM_SYNCONF_SWRSTCNT_MASK (0x100U) +#define FTM_SYNCONF_SWRSTCNT_SHIFT (8U) +#define FTM_SYNCONF_SWRSTCNT(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SWRSTCNT_SHIFT)) & FTM_SYNCONF_SWRSTCNT_MASK) +#define FTM_SYNCONF_SWWRBUF_MASK (0x200U) +#define FTM_SYNCONF_SWWRBUF_SHIFT (9U) +#define FTM_SYNCONF_SWWRBUF(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SWWRBUF_SHIFT)) & FTM_SYNCONF_SWWRBUF_MASK) +#define FTM_SYNCONF_SWOM_MASK (0x400U) +#define FTM_SYNCONF_SWOM_SHIFT (10U) +#define FTM_SYNCONF_SWOM(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SWOM_SHIFT)) & FTM_SYNCONF_SWOM_MASK) +#define FTM_SYNCONF_SWINVC_MASK (0x800U) +#define FTM_SYNCONF_SWINVC_SHIFT (11U) +#define FTM_SYNCONF_SWINVC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SWINVC_SHIFT)) & FTM_SYNCONF_SWINVC_MASK) +#define FTM_SYNCONF_SWSOC_MASK (0x1000U) +#define FTM_SYNCONF_SWSOC_SHIFT (12U) +#define FTM_SYNCONF_SWSOC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SWSOC_SHIFT)) & FTM_SYNCONF_SWSOC_MASK) +#define FTM_SYNCONF_HWRSTCNT_MASK (0x10000U) +#define FTM_SYNCONF_HWRSTCNT_SHIFT (16U) +#define FTM_SYNCONF_HWRSTCNT(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_HWRSTCNT_SHIFT)) & FTM_SYNCONF_HWRSTCNT_MASK) +#define FTM_SYNCONF_HWWRBUF_MASK (0x20000U) +#define FTM_SYNCONF_HWWRBUF_SHIFT (17U) +#define FTM_SYNCONF_HWWRBUF(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_HWWRBUF_SHIFT)) & FTM_SYNCONF_HWWRBUF_MASK) +#define FTM_SYNCONF_HWOM_MASK (0x40000U) +#define FTM_SYNCONF_HWOM_SHIFT (18U) +#define FTM_SYNCONF_HWOM(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_HWOM_SHIFT)) & FTM_SYNCONF_HWOM_MASK) +#define FTM_SYNCONF_HWINVC_MASK (0x80000U) +#define FTM_SYNCONF_HWINVC_SHIFT (19U) +#define FTM_SYNCONF_HWINVC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_HWINVC_SHIFT)) & FTM_SYNCONF_HWINVC_MASK) +#define FTM_SYNCONF_HWSOC_MASK (0x100000U) +#define FTM_SYNCONF_HWSOC_SHIFT (20U) +#define FTM_SYNCONF_HWSOC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_HWSOC_SHIFT)) & FTM_SYNCONF_HWSOC_MASK) + +/*! @name INVCTRL - FTM Inverting Control */ +#define FTM_INVCTRL_INV0EN_MASK (0x1U) +#define FTM_INVCTRL_INV0EN_SHIFT (0U) +#define FTM_INVCTRL_INV0EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_INVCTRL_INV0EN_SHIFT)) & FTM_INVCTRL_INV0EN_MASK) +#define FTM_INVCTRL_INV1EN_MASK (0x2U) +#define FTM_INVCTRL_INV1EN_SHIFT (1U) +#define FTM_INVCTRL_INV1EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_INVCTRL_INV1EN_SHIFT)) & FTM_INVCTRL_INV1EN_MASK) +#define FTM_INVCTRL_INV2EN_MASK (0x4U) +#define FTM_INVCTRL_INV2EN_SHIFT (2U) +#define FTM_INVCTRL_INV2EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_INVCTRL_INV2EN_SHIFT)) & FTM_INVCTRL_INV2EN_MASK) +#define FTM_INVCTRL_INV3EN_MASK (0x8U) +#define FTM_INVCTRL_INV3EN_SHIFT (3U) +#define FTM_INVCTRL_INV3EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_INVCTRL_INV3EN_SHIFT)) & FTM_INVCTRL_INV3EN_MASK) + +/*! @name SWOCTRL - FTM Software Output Control */ +#define FTM_SWOCTRL_CH0OC_MASK (0x1U) +#define FTM_SWOCTRL_CH0OC_SHIFT (0U) +#define FTM_SWOCTRL_CH0OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH0OC_SHIFT)) & FTM_SWOCTRL_CH0OC_MASK) +#define FTM_SWOCTRL_CH1OC_MASK (0x2U) +#define FTM_SWOCTRL_CH1OC_SHIFT (1U) +#define FTM_SWOCTRL_CH1OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH1OC_SHIFT)) & FTM_SWOCTRL_CH1OC_MASK) +#define FTM_SWOCTRL_CH2OC_MASK (0x4U) +#define FTM_SWOCTRL_CH2OC_SHIFT (2U) +#define FTM_SWOCTRL_CH2OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH2OC_SHIFT)) & FTM_SWOCTRL_CH2OC_MASK) +#define FTM_SWOCTRL_CH3OC_MASK (0x8U) +#define FTM_SWOCTRL_CH3OC_SHIFT (3U) +#define FTM_SWOCTRL_CH3OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH3OC_SHIFT)) & FTM_SWOCTRL_CH3OC_MASK) +#define FTM_SWOCTRL_CH4OC_MASK (0x10U) +#define FTM_SWOCTRL_CH4OC_SHIFT (4U) +#define FTM_SWOCTRL_CH4OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH4OC_SHIFT)) & FTM_SWOCTRL_CH4OC_MASK) +#define FTM_SWOCTRL_CH5OC_MASK (0x20U) +#define FTM_SWOCTRL_CH5OC_SHIFT (5U) +#define FTM_SWOCTRL_CH5OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH5OC_SHIFT)) & FTM_SWOCTRL_CH5OC_MASK) +#define FTM_SWOCTRL_CH6OC_MASK (0x40U) +#define FTM_SWOCTRL_CH6OC_SHIFT (6U) +#define FTM_SWOCTRL_CH6OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH6OC_SHIFT)) & FTM_SWOCTRL_CH6OC_MASK) +#define FTM_SWOCTRL_CH7OC_MASK (0x80U) +#define FTM_SWOCTRL_CH7OC_SHIFT (7U) +#define FTM_SWOCTRL_CH7OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH7OC_SHIFT)) & FTM_SWOCTRL_CH7OC_MASK) +#define FTM_SWOCTRL_CH0OCV_MASK (0x100U) +#define FTM_SWOCTRL_CH0OCV_SHIFT (8U) +#define FTM_SWOCTRL_CH0OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH0OCV_SHIFT)) & FTM_SWOCTRL_CH0OCV_MASK) +#define FTM_SWOCTRL_CH1OCV_MASK (0x200U) +#define FTM_SWOCTRL_CH1OCV_SHIFT (9U) +#define FTM_SWOCTRL_CH1OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH1OCV_SHIFT)) & FTM_SWOCTRL_CH1OCV_MASK) +#define FTM_SWOCTRL_CH2OCV_MASK (0x400U) +#define FTM_SWOCTRL_CH2OCV_SHIFT (10U) +#define FTM_SWOCTRL_CH2OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH2OCV_SHIFT)) & FTM_SWOCTRL_CH2OCV_MASK) +#define FTM_SWOCTRL_CH3OCV_MASK (0x800U) +#define FTM_SWOCTRL_CH3OCV_SHIFT (11U) +#define FTM_SWOCTRL_CH3OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH3OCV_SHIFT)) & FTM_SWOCTRL_CH3OCV_MASK) +#define FTM_SWOCTRL_CH4OCV_MASK (0x1000U) +#define FTM_SWOCTRL_CH4OCV_SHIFT (12U) +#define FTM_SWOCTRL_CH4OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH4OCV_SHIFT)) & FTM_SWOCTRL_CH4OCV_MASK) +#define FTM_SWOCTRL_CH5OCV_MASK (0x2000U) +#define FTM_SWOCTRL_CH5OCV_SHIFT (13U) +#define FTM_SWOCTRL_CH5OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH5OCV_SHIFT)) & FTM_SWOCTRL_CH5OCV_MASK) +#define FTM_SWOCTRL_CH6OCV_MASK (0x4000U) +#define FTM_SWOCTRL_CH6OCV_SHIFT (14U) +#define FTM_SWOCTRL_CH6OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH6OCV_SHIFT)) & FTM_SWOCTRL_CH6OCV_MASK) +#define FTM_SWOCTRL_CH7OCV_MASK (0x8000U) +#define FTM_SWOCTRL_CH7OCV_SHIFT (15U) +#define FTM_SWOCTRL_CH7OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH7OCV_SHIFT)) & FTM_SWOCTRL_CH7OCV_MASK) + +/*! @name PWMLOAD - FTM PWM Load */ +#define FTM_PWMLOAD_CH0SEL_MASK (0x1U) +#define FTM_PWMLOAD_CH0SEL_SHIFT (0U) +#define FTM_PWMLOAD_CH0SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH0SEL_SHIFT)) & FTM_PWMLOAD_CH0SEL_MASK) +#define FTM_PWMLOAD_CH1SEL_MASK (0x2U) +#define FTM_PWMLOAD_CH1SEL_SHIFT (1U) +#define FTM_PWMLOAD_CH1SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH1SEL_SHIFT)) & FTM_PWMLOAD_CH1SEL_MASK) +#define FTM_PWMLOAD_CH2SEL_MASK (0x4U) +#define FTM_PWMLOAD_CH2SEL_SHIFT (2U) +#define FTM_PWMLOAD_CH2SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH2SEL_SHIFT)) & FTM_PWMLOAD_CH2SEL_MASK) +#define FTM_PWMLOAD_CH3SEL_MASK (0x8U) +#define FTM_PWMLOAD_CH3SEL_SHIFT (3U) +#define FTM_PWMLOAD_CH3SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH3SEL_SHIFT)) & FTM_PWMLOAD_CH3SEL_MASK) +#define FTM_PWMLOAD_CH4SEL_MASK (0x10U) +#define FTM_PWMLOAD_CH4SEL_SHIFT (4U) +#define FTM_PWMLOAD_CH4SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH4SEL_SHIFT)) & FTM_PWMLOAD_CH4SEL_MASK) +#define FTM_PWMLOAD_CH5SEL_MASK (0x20U) +#define FTM_PWMLOAD_CH5SEL_SHIFT (5U) +#define FTM_PWMLOAD_CH5SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH5SEL_SHIFT)) & FTM_PWMLOAD_CH5SEL_MASK) +#define FTM_PWMLOAD_CH6SEL_MASK (0x40U) +#define FTM_PWMLOAD_CH6SEL_SHIFT (6U) +#define FTM_PWMLOAD_CH6SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH6SEL_SHIFT)) & FTM_PWMLOAD_CH6SEL_MASK) +#define FTM_PWMLOAD_CH7SEL_MASK (0x80U) +#define FTM_PWMLOAD_CH7SEL_SHIFT (7U) +#define FTM_PWMLOAD_CH7SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH7SEL_SHIFT)) & FTM_PWMLOAD_CH7SEL_MASK) +#define FTM_PWMLOAD_LDOK_MASK (0x200U) +#define FTM_PWMLOAD_LDOK_SHIFT (9U) +#define FTM_PWMLOAD_LDOK(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_LDOK_SHIFT)) & FTM_PWMLOAD_LDOK_MASK) + + +/*! + * @} + */ /* end of group FTM_Register_Masks */ + + +/* FTM - Peripheral instance base addresses */ +/** Peripheral FTM0 base address */ +#define FTM0_BASE (0x40038000u) +/** Peripheral FTM0 base pointer */ +#define FTM0 ((FTM_Type *)FTM0_BASE) +/** Peripheral FTM1 base address */ +#define FTM1_BASE (0x40039000u) +/** Peripheral FTM1 base pointer */ +#define FTM1 ((FTM_Type *)FTM1_BASE) +/** Peripheral FTM2 base address */ +#define FTM2_BASE (0x4003A000u) +/** Peripheral FTM2 base pointer */ +#define FTM2 ((FTM_Type *)FTM2_BASE) +/** Peripheral FTM3 base address */ +#define FTM3_BASE (0x400B9000u) +/** Peripheral FTM3 base pointer */ +#define FTM3 ((FTM_Type *)FTM3_BASE) +/** Array initializer of FTM peripheral base addresses */ +#define FTM_BASE_ADDRS { FTM0_BASE, FTM1_BASE, FTM2_BASE, FTM3_BASE } +/** Array initializer of FTM peripheral base pointers */ +#define FTM_BASE_PTRS { FTM0, FTM1, FTM2, FTM3 } +/** Interrupt vectors for the FTM peripheral type */ +#define FTM_IRQS { FTM0_IRQn, FTM1_IRQn, FTM2_IRQn, FTM3_IRQn } + +/*! + * @} + */ /* end of group FTM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- GPIO Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GPIO_Peripheral_Access_Layer GPIO Peripheral Access Layer + * @{ + */ + +/** GPIO - Register Layout Typedef */ +typedef struct { + __IO uint32_t PDOR; /**< Port Data Output Register, offset: 0x0 */ + __O uint32_t PSOR; /**< Port Set Output Register, offset: 0x4 */ + __O uint32_t PCOR; /**< Port Clear Output Register, offset: 0x8 */ + __O uint32_t PTOR; /**< Port Toggle Output Register, offset: 0xC */ + __I uint32_t PDIR; /**< Port Data Input Register, offset: 0x10 */ + __IO uint32_t PDDR; /**< Port Data Direction Register, offset: 0x14 */ +} GPIO_Type; + +/* ---------------------------------------------------------------------------- + -- GPIO Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GPIO_Register_Masks GPIO Register Masks + * @{ + */ + +/*! @name PDOR - Port Data Output Register */ +#define GPIO_PDOR_PDO_MASK (0xFFFFFFFFU) +#define GPIO_PDOR_PDO_SHIFT (0U) +#define GPIO_PDOR_PDO(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PDOR_PDO_SHIFT)) & GPIO_PDOR_PDO_MASK) + +/*! @name PSOR - Port Set Output Register */ +#define GPIO_PSOR_PTSO_MASK (0xFFFFFFFFU) +#define GPIO_PSOR_PTSO_SHIFT (0U) +#define GPIO_PSOR_PTSO(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PSOR_PTSO_SHIFT)) & GPIO_PSOR_PTSO_MASK) + +/*! @name PCOR - Port Clear Output Register */ +#define GPIO_PCOR_PTCO_MASK (0xFFFFFFFFU) +#define GPIO_PCOR_PTCO_SHIFT (0U) +#define GPIO_PCOR_PTCO(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PCOR_PTCO_SHIFT)) & GPIO_PCOR_PTCO_MASK) + +/*! @name PTOR - Port Toggle Output Register */ +#define GPIO_PTOR_PTTO_MASK (0xFFFFFFFFU) +#define GPIO_PTOR_PTTO_SHIFT (0U) +#define GPIO_PTOR_PTTO(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PTOR_PTTO_SHIFT)) & GPIO_PTOR_PTTO_MASK) + +/*! @name PDIR - Port Data Input Register */ +#define GPIO_PDIR_PDI_MASK (0xFFFFFFFFU) +#define GPIO_PDIR_PDI_SHIFT (0U) +#define GPIO_PDIR_PDI(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PDIR_PDI_SHIFT)) & GPIO_PDIR_PDI_MASK) + +/*! @name PDDR - Port Data Direction Register */ +#define GPIO_PDDR_PDD_MASK (0xFFFFFFFFU) +#define GPIO_PDDR_PDD_SHIFT (0U) +#define GPIO_PDDR_PDD(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PDDR_PDD_SHIFT)) & GPIO_PDDR_PDD_MASK) + + +/*! + * @} + */ /* end of group GPIO_Register_Masks */ + + +/* GPIO - Peripheral instance base addresses */ +/** Peripheral GPIOA base address */ +#define GPIOA_BASE (0x400FF000u) +/** Peripheral GPIOA base pointer */ +#define GPIOA ((GPIO_Type *)GPIOA_BASE) +/** Peripheral GPIOB base address */ +#define GPIOB_BASE (0x400FF040u) +/** Peripheral GPIOB base pointer */ +#define GPIOB ((GPIO_Type *)GPIOB_BASE) +/** Peripheral GPIOC base address */ +#define GPIOC_BASE (0x400FF080u) +/** Peripheral GPIOC base pointer */ +#define GPIOC ((GPIO_Type *)GPIOC_BASE) +/** Peripheral GPIOD base address */ +#define GPIOD_BASE (0x400FF0C0u) +/** Peripheral GPIOD base pointer */ +#define GPIOD ((GPIO_Type *)GPIOD_BASE) +/** Peripheral GPIOE base address */ +#define GPIOE_BASE (0x400FF100u) +/** Peripheral GPIOE base pointer */ +#define GPIOE ((GPIO_Type *)GPIOE_BASE) +/** Array initializer of GPIO peripheral base addresses */ +#define GPIO_BASE_ADDRS { GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, GPIOD_BASE, GPIOE_BASE } +/** Array initializer of GPIO peripheral base pointers */ +#define GPIO_BASE_PTRS { GPIOA, GPIOB, GPIOC, GPIOD, GPIOE } + +/*! + * @} + */ /* end of group GPIO_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- I2C Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2C_Peripheral_Access_Layer I2C Peripheral Access Layer + * @{ + */ + +/** I2C - Register Layout Typedef */ +typedef struct { + __IO uint8_t A1; /**< I2C Address Register 1, offset: 0x0 */ + __IO uint8_t F; /**< I2C Frequency Divider register, offset: 0x1 */ + __IO uint8_t C1; /**< I2C Control Register 1, offset: 0x2 */ + __IO uint8_t S; /**< I2C Status register, offset: 0x3 */ + __IO uint8_t D; /**< I2C Data I/O register, offset: 0x4 */ + __IO uint8_t C2; /**< I2C Control Register 2, offset: 0x5 */ + __IO uint8_t FLT; /**< I2C Programmable Input Glitch Filter Register, offset: 0x6 */ + __IO uint8_t RA; /**< I2C Range Address register, offset: 0x7 */ + __IO uint8_t SMB; /**< I2C SMBus Control and Status register, offset: 0x8 */ + __IO uint8_t A2; /**< I2C Address Register 2, offset: 0x9 */ + __IO uint8_t SLTH; /**< I2C SCL Low Timeout Register High, offset: 0xA */ + __IO uint8_t SLTL; /**< I2C SCL Low Timeout Register Low, offset: 0xB */ + __IO uint8_t S2; /**< I2C Status register 2, offset: 0xC */ +} I2C_Type; + +/* ---------------------------------------------------------------------------- + -- I2C Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2C_Register_Masks I2C Register Masks + * @{ + */ + +/*! @name A1 - I2C Address Register 1 */ +#define I2C_A1_AD_MASK (0xFEU) +#define I2C_A1_AD_SHIFT (1U) +#define I2C_A1_AD(x) (((uint8_t)(((uint8_t)(x)) << I2C_A1_AD_SHIFT)) & I2C_A1_AD_MASK) + +/*! @name F - I2C Frequency Divider register */ +#define I2C_F_ICR_MASK (0x3FU) +#define I2C_F_ICR_SHIFT (0U) +#define I2C_F_ICR(x) (((uint8_t)(((uint8_t)(x)) << I2C_F_ICR_SHIFT)) & I2C_F_ICR_MASK) +#define I2C_F_MULT_MASK (0xC0U) +#define I2C_F_MULT_SHIFT (6U) +#define I2C_F_MULT(x) (((uint8_t)(((uint8_t)(x)) << I2C_F_MULT_SHIFT)) & I2C_F_MULT_MASK) + +/*! @name C1 - I2C Control Register 1 */ +#define I2C_C1_DMAEN_MASK (0x1U) +#define I2C_C1_DMAEN_SHIFT (0U) +#define I2C_C1_DMAEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_DMAEN_SHIFT)) & I2C_C1_DMAEN_MASK) +#define I2C_C1_WUEN_MASK (0x2U) +#define I2C_C1_WUEN_SHIFT (1U) +#define I2C_C1_WUEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_WUEN_SHIFT)) & I2C_C1_WUEN_MASK) +#define I2C_C1_RSTA_MASK (0x4U) +#define I2C_C1_RSTA_SHIFT (2U) +#define I2C_C1_RSTA(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_RSTA_SHIFT)) & I2C_C1_RSTA_MASK) +#define I2C_C1_TXAK_MASK (0x8U) +#define I2C_C1_TXAK_SHIFT (3U) +#define I2C_C1_TXAK(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_TXAK_SHIFT)) & I2C_C1_TXAK_MASK) +#define I2C_C1_TX_MASK (0x10U) +#define I2C_C1_TX_SHIFT (4U) +#define I2C_C1_TX(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_TX_SHIFT)) & I2C_C1_TX_MASK) +#define I2C_C1_MST_MASK (0x20U) +#define I2C_C1_MST_SHIFT (5U) +#define I2C_C1_MST(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_MST_SHIFT)) & I2C_C1_MST_MASK) +#define I2C_C1_IICIE_MASK (0x40U) +#define I2C_C1_IICIE_SHIFT (6U) +#define I2C_C1_IICIE(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_IICIE_SHIFT)) & I2C_C1_IICIE_MASK) +#define I2C_C1_IICEN_MASK (0x80U) +#define I2C_C1_IICEN_SHIFT (7U) +#define I2C_C1_IICEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_IICEN_SHIFT)) & I2C_C1_IICEN_MASK) + +/*! @name S - I2C Status register */ +#define I2C_S_RXAK_MASK (0x1U) +#define I2C_S_RXAK_SHIFT (0U) +#define I2C_S_RXAK(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_RXAK_SHIFT)) & I2C_S_RXAK_MASK) +#define I2C_S_IICIF_MASK (0x2U) +#define I2C_S_IICIF_SHIFT (1U) +#define I2C_S_IICIF(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_IICIF_SHIFT)) & I2C_S_IICIF_MASK) +#define I2C_S_SRW_MASK (0x4U) +#define I2C_S_SRW_SHIFT (2U) +#define I2C_S_SRW(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_SRW_SHIFT)) & I2C_S_SRW_MASK) +#define I2C_S_RAM_MASK (0x8U) +#define I2C_S_RAM_SHIFT (3U) +#define I2C_S_RAM(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_RAM_SHIFT)) & I2C_S_RAM_MASK) +#define I2C_S_ARBL_MASK (0x10U) +#define I2C_S_ARBL_SHIFT (4U) +#define I2C_S_ARBL(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_ARBL_SHIFT)) & I2C_S_ARBL_MASK) +#define I2C_S_BUSY_MASK (0x20U) +#define I2C_S_BUSY_SHIFT (5U) +#define I2C_S_BUSY(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_BUSY_SHIFT)) & I2C_S_BUSY_MASK) +#define I2C_S_IAAS_MASK (0x40U) +#define I2C_S_IAAS_SHIFT (6U) +#define I2C_S_IAAS(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_IAAS_SHIFT)) & I2C_S_IAAS_MASK) +#define I2C_S_TCF_MASK (0x80U) +#define I2C_S_TCF_SHIFT (7U) +#define I2C_S_TCF(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_TCF_SHIFT)) & I2C_S_TCF_MASK) + +/*! @name D - I2C Data I/O register */ +#define I2C_D_DATA_MASK (0xFFU) +#define I2C_D_DATA_SHIFT (0U) +#define I2C_D_DATA(x) (((uint8_t)(((uint8_t)(x)) << I2C_D_DATA_SHIFT)) & I2C_D_DATA_MASK) + +/*! @name C2 - I2C Control Register 2 */ +#define I2C_C2_AD_MASK (0x7U) +#define I2C_C2_AD_SHIFT (0U) +#define I2C_C2_AD(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_AD_SHIFT)) & I2C_C2_AD_MASK) +#define I2C_C2_RMEN_MASK (0x8U) +#define I2C_C2_RMEN_SHIFT (3U) +#define I2C_C2_RMEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_RMEN_SHIFT)) & I2C_C2_RMEN_MASK) +#define I2C_C2_SBRC_MASK (0x10U) +#define I2C_C2_SBRC_SHIFT (4U) +#define I2C_C2_SBRC(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_SBRC_SHIFT)) & I2C_C2_SBRC_MASK) +#define I2C_C2_HDRS_MASK (0x20U) +#define I2C_C2_HDRS_SHIFT (5U) +#define I2C_C2_HDRS(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_HDRS_SHIFT)) & I2C_C2_HDRS_MASK) +#define I2C_C2_ADEXT_MASK (0x40U) +#define I2C_C2_ADEXT_SHIFT (6U) +#define I2C_C2_ADEXT(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_ADEXT_SHIFT)) & I2C_C2_ADEXT_MASK) +#define I2C_C2_GCAEN_MASK (0x80U) +#define I2C_C2_GCAEN_SHIFT (7U) +#define I2C_C2_GCAEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_GCAEN_SHIFT)) & I2C_C2_GCAEN_MASK) + +/*! @name FLT - I2C Programmable Input Glitch Filter Register */ +#define I2C_FLT_FLT_MASK (0xFU) +#define I2C_FLT_FLT_SHIFT (0U) +#define I2C_FLT_FLT(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_FLT_SHIFT)) & I2C_FLT_FLT_MASK) +#define I2C_FLT_STARTF_MASK (0x10U) +#define I2C_FLT_STARTF_SHIFT (4U) +#define I2C_FLT_STARTF(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_STARTF_SHIFT)) & I2C_FLT_STARTF_MASK) +#define I2C_FLT_SSIE_MASK (0x20U) +#define I2C_FLT_SSIE_SHIFT (5U) +#define I2C_FLT_SSIE(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_SSIE_SHIFT)) & I2C_FLT_SSIE_MASK) +#define I2C_FLT_STOPF_MASK (0x40U) +#define I2C_FLT_STOPF_SHIFT (6U) +#define I2C_FLT_STOPF(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_STOPF_SHIFT)) & I2C_FLT_STOPF_MASK) +#define I2C_FLT_SHEN_MASK (0x80U) +#define I2C_FLT_SHEN_SHIFT (7U) +#define I2C_FLT_SHEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_SHEN_SHIFT)) & I2C_FLT_SHEN_MASK) + +/*! @name RA - I2C Range Address register */ +#define I2C_RA_RAD_MASK (0xFEU) +#define I2C_RA_RAD_SHIFT (1U) +#define I2C_RA_RAD(x) (((uint8_t)(((uint8_t)(x)) << I2C_RA_RAD_SHIFT)) & I2C_RA_RAD_MASK) + +/*! @name SMB - I2C SMBus Control and Status register */ +#define I2C_SMB_SHTF2IE_MASK (0x1U) +#define I2C_SMB_SHTF2IE_SHIFT (0U) +#define I2C_SMB_SHTF2IE(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SHTF2IE_SHIFT)) & I2C_SMB_SHTF2IE_MASK) +#define I2C_SMB_SHTF2_MASK (0x2U) +#define I2C_SMB_SHTF2_SHIFT (1U) +#define I2C_SMB_SHTF2(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SHTF2_SHIFT)) & I2C_SMB_SHTF2_MASK) +#define I2C_SMB_SHTF1_MASK (0x4U) +#define I2C_SMB_SHTF1_SHIFT (2U) +#define I2C_SMB_SHTF1(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SHTF1_SHIFT)) & I2C_SMB_SHTF1_MASK) +#define I2C_SMB_SLTF_MASK (0x8U) +#define I2C_SMB_SLTF_SHIFT (3U) +#define I2C_SMB_SLTF(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SLTF_SHIFT)) & I2C_SMB_SLTF_MASK) +#define I2C_SMB_TCKSEL_MASK (0x10U) +#define I2C_SMB_TCKSEL_SHIFT (4U) +#define I2C_SMB_TCKSEL(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_TCKSEL_SHIFT)) & I2C_SMB_TCKSEL_MASK) +#define I2C_SMB_SIICAEN_MASK (0x20U) +#define I2C_SMB_SIICAEN_SHIFT (5U) +#define I2C_SMB_SIICAEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SIICAEN_SHIFT)) & I2C_SMB_SIICAEN_MASK) +#define I2C_SMB_ALERTEN_MASK (0x40U) +#define I2C_SMB_ALERTEN_SHIFT (6U) +#define I2C_SMB_ALERTEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_ALERTEN_SHIFT)) & I2C_SMB_ALERTEN_MASK) +#define I2C_SMB_FACK_MASK (0x80U) +#define I2C_SMB_FACK_SHIFT (7U) +#define I2C_SMB_FACK(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_FACK_SHIFT)) & I2C_SMB_FACK_MASK) + +/*! @name A2 - I2C Address Register 2 */ +#define I2C_A2_SAD_MASK (0xFEU) +#define I2C_A2_SAD_SHIFT (1U) +#define I2C_A2_SAD(x) (((uint8_t)(((uint8_t)(x)) << I2C_A2_SAD_SHIFT)) & I2C_A2_SAD_MASK) + +/*! @name SLTH - I2C SCL Low Timeout Register High */ +#define I2C_SLTH_SSLT_MASK (0xFFU) +#define I2C_SLTH_SSLT_SHIFT (0U) +#define I2C_SLTH_SSLT(x) (((uint8_t)(((uint8_t)(x)) << I2C_SLTH_SSLT_SHIFT)) & I2C_SLTH_SSLT_MASK) + +/*! @name SLTL - I2C SCL Low Timeout Register Low */ +#define I2C_SLTL_SSLT_MASK (0xFFU) +#define I2C_SLTL_SSLT_SHIFT (0U) +#define I2C_SLTL_SSLT(x) (((uint8_t)(((uint8_t)(x)) << I2C_SLTL_SSLT_SHIFT)) & I2C_SLTL_SSLT_MASK) + +/*! @name S2 - I2C Status register 2 */ +#define I2C_S2_EMPTY_MASK (0x1U) +#define I2C_S2_EMPTY_SHIFT (0U) +#define I2C_S2_EMPTY(x) (((uint8_t)(((uint8_t)(x)) << I2C_S2_EMPTY_SHIFT)) & I2C_S2_EMPTY_MASK) +#define I2C_S2_ERROR_MASK (0x2U) +#define I2C_S2_ERROR_SHIFT (1U) +#define I2C_S2_ERROR(x) (((uint8_t)(((uint8_t)(x)) << I2C_S2_ERROR_SHIFT)) & I2C_S2_ERROR_MASK) + + +/*! + * @} + */ /* end of group I2C_Register_Masks */ + + +/* I2C - Peripheral instance base addresses */ +/** Peripheral I2C0 base address */ +#define I2C0_BASE (0x40066000u) +/** Peripheral I2C0 base pointer */ +#define I2C0 ((I2C_Type *)I2C0_BASE) +/** Peripheral I2C1 base address */ +#define I2C1_BASE (0x40067000u) +/** Peripheral I2C1 base pointer */ +#define I2C1 ((I2C_Type *)I2C1_BASE) +/** Peripheral I2C2 base address */ +#define I2C2_BASE (0x400E6000u) +/** Peripheral I2C2 base pointer */ +#define I2C2 ((I2C_Type *)I2C2_BASE) +/** Peripheral I2C3 base address */ +#define I2C3_BASE (0x400E7000u) +/** Peripheral I2C3 base pointer */ +#define I2C3 ((I2C_Type *)I2C3_BASE) +/** Array initializer of I2C peripheral base addresses */ +#define I2C_BASE_ADDRS { I2C0_BASE, I2C1_BASE, I2C2_BASE, I2C3_BASE } +/** Array initializer of I2C peripheral base pointers */ +#define I2C_BASE_PTRS { I2C0, I2C1, I2C2, I2C3 } +/** Interrupt vectors for the I2C peripheral type */ +#define I2C_IRQS { I2C0_IRQn, I2C1_IRQn, I2C2_IRQn, I2C3_IRQn } + +/*! + * @} + */ /* end of group I2C_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- I2S Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2S_Peripheral_Access_Layer I2S Peripheral Access Layer + * @{ + */ + +/** I2S - Register Layout Typedef */ +typedef struct { + __IO uint32_t TCSR; /**< SAI Transmit Control Register, offset: 0x0 */ + __IO uint32_t TCR1; /**< SAI Transmit Configuration 1 Register, offset: 0x4 */ + __IO uint32_t TCR2; /**< SAI Transmit Configuration 2 Register, offset: 0x8 */ + __IO uint32_t TCR3; /**< SAI Transmit Configuration 3 Register, offset: 0xC */ + __IO uint32_t TCR4; /**< SAI Transmit Configuration 4 Register, offset: 0x10 */ + __IO uint32_t TCR5; /**< SAI Transmit Configuration 5 Register, offset: 0x14 */ + uint8_t RESERVED_0[8]; + __O uint32_t TDR[2]; /**< SAI Transmit Data Register, array offset: 0x20, array step: 0x4 */ + uint8_t RESERVED_1[24]; + __I uint32_t TFR[2]; /**< SAI Transmit FIFO Register, array offset: 0x40, array step: 0x4 */ + uint8_t RESERVED_2[24]; + __IO uint32_t TMR; /**< SAI Transmit Mask Register, offset: 0x60 */ + uint8_t RESERVED_3[28]; + __IO uint32_t RCSR; /**< SAI Receive Control Register, offset: 0x80 */ + __IO uint32_t RCR1; /**< SAI Receive Configuration 1 Register, offset: 0x84 */ + __IO uint32_t RCR2; /**< SAI Receive Configuration 2 Register, offset: 0x88 */ + __IO uint32_t RCR3; /**< SAI Receive Configuration 3 Register, offset: 0x8C */ + __IO uint32_t RCR4; /**< SAI Receive Configuration 4 Register, offset: 0x90 */ + __IO uint32_t RCR5; /**< SAI Receive Configuration 5 Register, offset: 0x94 */ + uint8_t RESERVED_4[8]; + __I uint32_t RDR[2]; /**< SAI Receive Data Register, array offset: 0xA0, array step: 0x4 */ + uint8_t RESERVED_5[24]; + __I uint32_t RFR[2]; /**< SAI Receive FIFO Register, array offset: 0xC0, array step: 0x4 */ + uint8_t RESERVED_6[24]; + __IO uint32_t RMR; /**< SAI Receive Mask Register, offset: 0xE0 */ + uint8_t RESERVED_7[28]; + __IO uint32_t MCR; /**< SAI MCLK Control Register, offset: 0x100 */ + __IO uint32_t MDR; /**< SAI MCLK Divide Register, offset: 0x104 */ +} I2S_Type; + +/* ---------------------------------------------------------------------------- + -- I2S Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2S_Register_Masks I2S Register Masks + * @{ + */ + +/*! @name TCSR - SAI Transmit Control Register */ +#define I2S_TCSR_FRDE_MASK (0x1U) +#define I2S_TCSR_FRDE_SHIFT (0U) +#define I2S_TCSR_FRDE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FRDE_SHIFT)) & I2S_TCSR_FRDE_MASK) +#define I2S_TCSR_FWDE_MASK (0x2U) +#define I2S_TCSR_FWDE_SHIFT (1U) +#define I2S_TCSR_FWDE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FWDE_SHIFT)) & I2S_TCSR_FWDE_MASK) +#define I2S_TCSR_FRIE_MASK (0x100U) +#define I2S_TCSR_FRIE_SHIFT (8U) +#define I2S_TCSR_FRIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FRIE_SHIFT)) & I2S_TCSR_FRIE_MASK) +#define I2S_TCSR_FWIE_MASK (0x200U) +#define I2S_TCSR_FWIE_SHIFT (9U) +#define I2S_TCSR_FWIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FWIE_SHIFT)) & I2S_TCSR_FWIE_MASK) +#define I2S_TCSR_FEIE_MASK (0x400U) +#define I2S_TCSR_FEIE_SHIFT (10U) +#define I2S_TCSR_FEIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FEIE_SHIFT)) & I2S_TCSR_FEIE_MASK) +#define I2S_TCSR_SEIE_MASK (0x800U) +#define I2S_TCSR_SEIE_SHIFT (11U) +#define I2S_TCSR_SEIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_SEIE_SHIFT)) & I2S_TCSR_SEIE_MASK) +#define I2S_TCSR_WSIE_MASK (0x1000U) +#define I2S_TCSR_WSIE_SHIFT (12U) +#define I2S_TCSR_WSIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_WSIE_SHIFT)) & I2S_TCSR_WSIE_MASK) +#define I2S_TCSR_FRF_MASK (0x10000U) +#define I2S_TCSR_FRF_SHIFT (16U) +#define I2S_TCSR_FRF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FRF_SHIFT)) & I2S_TCSR_FRF_MASK) +#define I2S_TCSR_FWF_MASK (0x20000U) +#define I2S_TCSR_FWF_SHIFT (17U) +#define I2S_TCSR_FWF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FWF_SHIFT)) & I2S_TCSR_FWF_MASK) +#define I2S_TCSR_FEF_MASK (0x40000U) +#define I2S_TCSR_FEF_SHIFT (18U) +#define I2S_TCSR_FEF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FEF_SHIFT)) & I2S_TCSR_FEF_MASK) +#define I2S_TCSR_SEF_MASK (0x80000U) +#define I2S_TCSR_SEF_SHIFT (19U) +#define I2S_TCSR_SEF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_SEF_SHIFT)) & I2S_TCSR_SEF_MASK) +#define I2S_TCSR_WSF_MASK (0x100000U) +#define I2S_TCSR_WSF_SHIFT (20U) +#define I2S_TCSR_WSF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_WSF_SHIFT)) & I2S_TCSR_WSF_MASK) +#define I2S_TCSR_SR_MASK (0x1000000U) +#define I2S_TCSR_SR_SHIFT (24U) +#define I2S_TCSR_SR(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_SR_SHIFT)) & I2S_TCSR_SR_MASK) +#define I2S_TCSR_FR_MASK (0x2000000U) +#define I2S_TCSR_FR_SHIFT (25U) +#define I2S_TCSR_FR(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FR_SHIFT)) & I2S_TCSR_FR_MASK) +#define I2S_TCSR_BCE_MASK (0x10000000U) +#define I2S_TCSR_BCE_SHIFT (28U) +#define I2S_TCSR_BCE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_BCE_SHIFT)) & I2S_TCSR_BCE_MASK) +#define I2S_TCSR_DBGE_MASK (0x20000000U) +#define I2S_TCSR_DBGE_SHIFT (29U) +#define I2S_TCSR_DBGE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_DBGE_SHIFT)) & I2S_TCSR_DBGE_MASK) +#define I2S_TCSR_STOPE_MASK (0x40000000U) +#define I2S_TCSR_STOPE_SHIFT (30U) +#define I2S_TCSR_STOPE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_STOPE_SHIFT)) & I2S_TCSR_STOPE_MASK) +#define I2S_TCSR_TE_MASK (0x80000000U) +#define I2S_TCSR_TE_SHIFT (31U) +#define I2S_TCSR_TE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_TE_SHIFT)) & I2S_TCSR_TE_MASK) + +/*! @name TCR1 - SAI Transmit Configuration 1 Register */ +#define I2S_TCR1_TFW_MASK (0x7U) +#define I2S_TCR1_TFW_SHIFT (0U) +#define I2S_TCR1_TFW(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR1_TFW_SHIFT)) & I2S_TCR1_TFW_MASK) + +/*! @name TCR2 - SAI Transmit Configuration 2 Register */ +#define I2S_TCR2_DIV_MASK (0xFFU) +#define I2S_TCR2_DIV_SHIFT (0U) +#define I2S_TCR2_DIV(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_DIV_SHIFT)) & I2S_TCR2_DIV_MASK) +#define I2S_TCR2_BCD_MASK (0x1000000U) +#define I2S_TCR2_BCD_SHIFT (24U) +#define I2S_TCR2_BCD(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_BCD_SHIFT)) & I2S_TCR2_BCD_MASK) +#define I2S_TCR2_BCP_MASK (0x2000000U) +#define I2S_TCR2_BCP_SHIFT (25U) +#define I2S_TCR2_BCP(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_BCP_SHIFT)) & I2S_TCR2_BCP_MASK) +#define I2S_TCR2_MSEL_MASK (0xC000000U) +#define I2S_TCR2_MSEL_SHIFT (26U) +#define I2S_TCR2_MSEL(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_MSEL_SHIFT)) & I2S_TCR2_MSEL_MASK) +#define I2S_TCR2_BCI_MASK (0x10000000U) +#define I2S_TCR2_BCI_SHIFT (28U) +#define I2S_TCR2_BCI(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_BCI_SHIFT)) & I2S_TCR2_BCI_MASK) +#define I2S_TCR2_BCS_MASK (0x20000000U) +#define I2S_TCR2_BCS_SHIFT (29U) +#define I2S_TCR2_BCS(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_BCS_SHIFT)) & I2S_TCR2_BCS_MASK) +#define I2S_TCR2_SYNC_MASK (0xC0000000U) +#define I2S_TCR2_SYNC_SHIFT (30U) +#define I2S_TCR2_SYNC(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_SYNC_SHIFT)) & I2S_TCR2_SYNC_MASK) + +/*! @name TCR3 - SAI Transmit Configuration 3 Register */ +#define I2S_TCR3_WDFL_MASK (0x1FU) +#define I2S_TCR3_WDFL_SHIFT (0U) +#define I2S_TCR3_WDFL(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR3_WDFL_SHIFT)) & I2S_TCR3_WDFL_MASK) +#define I2S_TCR3_TCE_MASK (0x30000U) +#define I2S_TCR3_TCE_SHIFT (16U) +#define I2S_TCR3_TCE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR3_TCE_SHIFT)) & I2S_TCR3_TCE_MASK) +#define I2S_TCR3_CFR_MASK (0x3000000U) +#define I2S_TCR3_CFR_SHIFT (24U) +#define I2S_TCR3_CFR(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR3_CFR_SHIFT)) & I2S_TCR3_CFR_MASK) + +/*! @name TCR4 - SAI Transmit Configuration 4 Register */ +#define I2S_TCR4_FSD_MASK (0x1U) +#define I2S_TCR4_FSD_SHIFT (0U) +#define I2S_TCR4_FSD(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FSD_SHIFT)) & I2S_TCR4_FSD_MASK) +#define I2S_TCR4_FSP_MASK (0x2U) +#define I2S_TCR4_FSP_SHIFT (1U) +#define I2S_TCR4_FSP(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FSP_SHIFT)) & I2S_TCR4_FSP_MASK) +#define I2S_TCR4_ONDEM_MASK (0x4U) +#define I2S_TCR4_ONDEM_SHIFT (2U) +#define I2S_TCR4_ONDEM(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_ONDEM_SHIFT)) & I2S_TCR4_ONDEM_MASK) +#define I2S_TCR4_FSE_MASK (0x8U) +#define I2S_TCR4_FSE_SHIFT (3U) +#define I2S_TCR4_FSE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FSE_SHIFT)) & I2S_TCR4_FSE_MASK) +#define I2S_TCR4_MF_MASK (0x10U) +#define I2S_TCR4_MF_SHIFT (4U) +#define I2S_TCR4_MF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_MF_SHIFT)) & I2S_TCR4_MF_MASK) +#define I2S_TCR4_SYWD_MASK (0x1F00U) +#define I2S_TCR4_SYWD_SHIFT (8U) +#define I2S_TCR4_SYWD(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_SYWD_SHIFT)) & I2S_TCR4_SYWD_MASK) +#define I2S_TCR4_FRSZ_MASK (0x1F0000U) +#define I2S_TCR4_FRSZ_SHIFT (16U) +#define I2S_TCR4_FRSZ(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FRSZ_SHIFT)) & I2S_TCR4_FRSZ_MASK) +#define I2S_TCR4_FPACK_MASK (0x3000000U) +#define I2S_TCR4_FPACK_SHIFT (24U) +#define I2S_TCR4_FPACK(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FPACK_SHIFT)) & I2S_TCR4_FPACK_MASK) +#define I2S_TCR4_FCOMB_MASK (0xC000000U) +#define I2S_TCR4_FCOMB_SHIFT (26U) +#define I2S_TCR4_FCOMB(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FCOMB_SHIFT)) & I2S_TCR4_FCOMB_MASK) +#define I2S_TCR4_FCONT_MASK (0x10000000U) +#define I2S_TCR4_FCONT_SHIFT (28U) +#define I2S_TCR4_FCONT(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FCONT_SHIFT)) & I2S_TCR4_FCONT_MASK) + +/*! @name TCR5 - SAI Transmit Configuration 5 Register */ +#define I2S_TCR5_FBT_MASK (0x1F00U) +#define I2S_TCR5_FBT_SHIFT (8U) +#define I2S_TCR5_FBT(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR5_FBT_SHIFT)) & I2S_TCR5_FBT_MASK) +#define I2S_TCR5_W0W_MASK (0x1F0000U) +#define I2S_TCR5_W0W_SHIFT (16U) +#define I2S_TCR5_W0W(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR5_W0W_SHIFT)) & I2S_TCR5_W0W_MASK) +#define I2S_TCR5_WNW_MASK (0x1F000000U) +#define I2S_TCR5_WNW_SHIFT (24U) +#define I2S_TCR5_WNW(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR5_WNW_SHIFT)) & I2S_TCR5_WNW_MASK) + +/*! @name TDR - SAI Transmit Data Register */ +#define I2S_TDR_TDR_MASK (0xFFFFFFFFU) +#define I2S_TDR_TDR_SHIFT (0U) +#define I2S_TDR_TDR(x) (((uint32_t)(((uint32_t)(x)) << I2S_TDR_TDR_SHIFT)) & I2S_TDR_TDR_MASK) + +/* The count of I2S_TDR */ +#define I2S_TDR_COUNT (2U) + +/*! @name TFR - SAI Transmit FIFO Register */ +#define I2S_TFR_RFP_MASK (0xFU) +#define I2S_TFR_RFP_SHIFT (0U) +#define I2S_TFR_RFP(x) (((uint32_t)(((uint32_t)(x)) << I2S_TFR_RFP_SHIFT)) & I2S_TFR_RFP_MASK) +#define I2S_TFR_WFP_MASK (0xF0000U) +#define I2S_TFR_WFP_SHIFT (16U) +#define I2S_TFR_WFP(x) (((uint32_t)(((uint32_t)(x)) << I2S_TFR_WFP_SHIFT)) & I2S_TFR_WFP_MASK) +#define I2S_TFR_WCP_MASK (0x80000000U) +#define I2S_TFR_WCP_SHIFT (31U) +#define I2S_TFR_WCP(x) (((uint32_t)(((uint32_t)(x)) << I2S_TFR_WCP_SHIFT)) & I2S_TFR_WCP_MASK) + +/* The count of I2S_TFR */ +#define I2S_TFR_COUNT (2U) + +/*! @name TMR - SAI Transmit Mask Register */ +#define I2S_TMR_TWM_MASK (0xFFFFFFFFU) +#define I2S_TMR_TWM_SHIFT (0U) +#define I2S_TMR_TWM(x) (((uint32_t)(((uint32_t)(x)) << I2S_TMR_TWM_SHIFT)) & I2S_TMR_TWM_MASK) + +/*! @name RCSR - SAI Receive Control Register */ +#define I2S_RCSR_FRDE_MASK (0x1U) +#define I2S_RCSR_FRDE_SHIFT (0U) +#define I2S_RCSR_FRDE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FRDE_SHIFT)) & I2S_RCSR_FRDE_MASK) +#define I2S_RCSR_FWDE_MASK (0x2U) +#define I2S_RCSR_FWDE_SHIFT (1U) +#define I2S_RCSR_FWDE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FWDE_SHIFT)) & I2S_RCSR_FWDE_MASK) +#define I2S_RCSR_FRIE_MASK (0x100U) +#define I2S_RCSR_FRIE_SHIFT (8U) +#define I2S_RCSR_FRIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FRIE_SHIFT)) & I2S_RCSR_FRIE_MASK) +#define I2S_RCSR_FWIE_MASK (0x200U) +#define I2S_RCSR_FWIE_SHIFT (9U) +#define I2S_RCSR_FWIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FWIE_SHIFT)) & I2S_RCSR_FWIE_MASK) +#define I2S_RCSR_FEIE_MASK (0x400U) +#define I2S_RCSR_FEIE_SHIFT (10U) +#define I2S_RCSR_FEIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FEIE_SHIFT)) & I2S_RCSR_FEIE_MASK) +#define I2S_RCSR_SEIE_MASK (0x800U) +#define I2S_RCSR_SEIE_SHIFT (11U) +#define I2S_RCSR_SEIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_SEIE_SHIFT)) & I2S_RCSR_SEIE_MASK) +#define I2S_RCSR_WSIE_MASK (0x1000U) +#define I2S_RCSR_WSIE_SHIFT (12U) +#define I2S_RCSR_WSIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_WSIE_SHIFT)) & I2S_RCSR_WSIE_MASK) +#define I2S_RCSR_FRF_MASK (0x10000U) +#define I2S_RCSR_FRF_SHIFT (16U) +#define I2S_RCSR_FRF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FRF_SHIFT)) & I2S_RCSR_FRF_MASK) +#define I2S_RCSR_FWF_MASK (0x20000U) +#define I2S_RCSR_FWF_SHIFT (17U) +#define I2S_RCSR_FWF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FWF_SHIFT)) & I2S_RCSR_FWF_MASK) +#define I2S_RCSR_FEF_MASK (0x40000U) +#define I2S_RCSR_FEF_SHIFT (18U) +#define I2S_RCSR_FEF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FEF_SHIFT)) & I2S_RCSR_FEF_MASK) +#define I2S_RCSR_SEF_MASK (0x80000U) +#define I2S_RCSR_SEF_SHIFT (19U) +#define I2S_RCSR_SEF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_SEF_SHIFT)) & I2S_RCSR_SEF_MASK) +#define I2S_RCSR_WSF_MASK (0x100000U) +#define I2S_RCSR_WSF_SHIFT (20U) +#define I2S_RCSR_WSF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_WSF_SHIFT)) & I2S_RCSR_WSF_MASK) +#define I2S_RCSR_SR_MASK (0x1000000U) +#define I2S_RCSR_SR_SHIFT (24U) +#define I2S_RCSR_SR(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_SR_SHIFT)) & I2S_RCSR_SR_MASK) +#define I2S_RCSR_FR_MASK (0x2000000U) +#define I2S_RCSR_FR_SHIFT (25U) +#define I2S_RCSR_FR(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FR_SHIFT)) & I2S_RCSR_FR_MASK) +#define I2S_RCSR_BCE_MASK (0x10000000U) +#define I2S_RCSR_BCE_SHIFT (28U) +#define I2S_RCSR_BCE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_BCE_SHIFT)) & I2S_RCSR_BCE_MASK) +#define I2S_RCSR_DBGE_MASK (0x20000000U) +#define I2S_RCSR_DBGE_SHIFT (29U) +#define I2S_RCSR_DBGE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_DBGE_SHIFT)) & I2S_RCSR_DBGE_MASK) +#define I2S_RCSR_STOPE_MASK (0x40000000U) +#define I2S_RCSR_STOPE_SHIFT (30U) +#define I2S_RCSR_STOPE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_STOPE_SHIFT)) & I2S_RCSR_STOPE_MASK) +#define I2S_RCSR_RE_MASK (0x80000000U) +#define I2S_RCSR_RE_SHIFT (31U) +#define I2S_RCSR_RE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_RE_SHIFT)) & I2S_RCSR_RE_MASK) + +/*! @name RCR1 - SAI Receive Configuration 1 Register */ +#define I2S_RCR1_RFW_MASK (0x7U) +#define I2S_RCR1_RFW_SHIFT (0U) +#define I2S_RCR1_RFW(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR1_RFW_SHIFT)) & I2S_RCR1_RFW_MASK) + +/*! @name RCR2 - SAI Receive Configuration 2 Register */ +#define I2S_RCR2_DIV_MASK (0xFFU) +#define I2S_RCR2_DIV_SHIFT (0U) +#define I2S_RCR2_DIV(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_DIV_SHIFT)) & I2S_RCR2_DIV_MASK) +#define I2S_RCR2_BCD_MASK (0x1000000U) +#define I2S_RCR2_BCD_SHIFT (24U) +#define I2S_RCR2_BCD(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_BCD_SHIFT)) & I2S_RCR2_BCD_MASK) +#define I2S_RCR2_BCP_MASK (0x2000000U) +#define I2S_RCR2_BCP_SHIFT (25U) +#define I2S_RCR2_BCP(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_BCP_SHIFT)) & I2S_RCR2_BCP_MASK) +#define I2S_RCR2_MSEL_MASK (0xC000000U) +#define I2S_RCR2_MSEL_SHIFT (26U) +#define I2S_RCR2_MSEL(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_MSEL_SHIFT)) & I2S_RCR2_MSEL_MASK) +#define I2S_RCR2_BCI_MASK (0x10000000U) +#define I2S_RCR2_BCI_SHIFT (28U) +#define I2S_RCR2_BCI(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_BCI_SHIFT)) & I2S_RCR2_BCI_MASK) +#define I2S_RCR2_BCS_MASK (0x20000000U) +#define I2S_RCR2_BCS_SHIFT (29U) +#define I2S_RCR2_BCS(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_BCS_SHIFT)) & I2S_RCR2_BCS_MASK) +#define I2S_RCR2_SYNC_MASK (0xC0000000U) +#define I2S_RCR2_SYNC_SHIFT (30U) +#define I2S_RCR2_SYNC(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_SYNC_SHIFT)) & I2S_RCR2_SYNC_MASK) + +/*! @name RCR3 - SAI Receive Configuration 3 Register */ +#define I2S_RCR3_WDFL_MASK (0x1FU) +#define I2S_RCR3_WDFL_SHIFT (0U) +#define I2S_RCR3_WDFL(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR3_WDFL_SHIFT)) & I2S_RCR3_WDFL_MASK) +#define I2S_RCR3_RCE_MASK (0x30000U) +#define I2S_RCR3_RCE_SHIFT (16U) +#define I2S_RCR3_RCE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR3_RCE_SHIFT)) & I2S_RCR3_RCE_MASK) +#define I2S_RCR3_CFR_MASK (0x3000000U) +#define I2S_RCR3_CFR_SHIFT (24U) +#define I2S_RCR3_CFR(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR3_CFR_SHIFT)) & I2S_RCR3_CFR_MASK) + +/*! @name RCR4 - SAI Receive Configuration 4 Register */ +#define I2S_RCR4_FSD_MASK (0x1U) +#define I2S_RCR4_FSD_SHIFT (0U) +#define I2S_RCR4_FSD(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FSD_SHIFT)) & I2S_RCR4_FSD_MASK) +#define I2S_RCR4_FSP_MASK (0x2U) +#define I2S_RCR4_FSP_SHIFT (1U) +#define I2S_RCR4_FSP(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FSP_SHIFT)) & I2S_RCR4_FSP_MASK) +#define I2S_RCR4_ONDEM_MASK (0x4U) +#define I2S_RCR4_ONDEM_SHIFT (2U) +#define I2S_RCR4_ONDEM(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_ONDEM_SHIFT)) & I2S_RCR4_ONDEM_MASK) +#define I2S_RCR4_FSE_MASK (0x8U) +#define I2S_RCR4_FSE_SHIFT (3U) +#define I2S_RCR4_FSE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FSE_SHIFT)) & I2S_RCR4_FSE_MASK) +#define I2S_RCR4_MF_MASK (0x10U) +#define I2S_RCR4_MF_SHIFT (4U) +#define I2S_RCR4_MF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_MF_SHIFT)) & I2S_RCR4_MF_MASK) +#define I2S_RCR4_SYWD_MASK (0x1F00U) +#define I2S_RCR4_SYWD_SHIFT (8U) +#define I2S_RCR4_SYWD(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_SYWD_SHIFT)) & I2S_RCR4_SYWD_MASK) +#define I2S_RCR4_FRSZ_MASK (0x1F0000U) +#define I2S_RCR4_FRSZ_SHIFT (16U) +#define I2S_RCR4_FRSZ(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FRSZ_SHIFT)) & I2S_RCR4_FRSZ_MASK) +#define I2S_RCR4_FPACK_MASK (0x3000000U) +#define I2S_RCR4_FPACK_SHIFT (24U) +#define I2S_RCR4_FPACK(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FPACK_SHIFT)) & I2S_RCR4_FPACK_MASK) +#define I2S_RCR4_FCOMB_MASK (0xC000000U) +#define I2S_RCR4_FCOMB_SHIFT (26U) +#define I2S_RCR4_FCOMB(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FCOMB_SHIFT)) & I2S_RCR4_FCOMB_MASK) +#define I2S_RCR4_FCONT_MASK (0x10000000U) +#define I2S_RCR4_FCONT_SHIFT (28U) +#define I2S_RCR4_FCONT(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FCONT_SHIFT)) & I2S_RCR4_FCONT_MASK) + +/*! @name RCR5 - SAI Receive Configuration 5 Register */ +#define I2S_RCR5_FBT_MASK (0x1F00U) +#define I2S_RCR5_FBT_SHIFT (8U) +#define I2S_RCR5_FBT(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR5_FBT_SHIFT)) & I2S_RCR5_FBT_MASK) +#define I2S_RCR5_W0W_MASK (0x1F0000U) +#define I2S_RCR5_W0W_SHIFT (16U) +#define I2S_RCR5_W0W(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR5_W0W_SHIFT)) & I2S_RCR5_W0W_MASK) +#define I2S_RCR5_WNW_MASK (0x1F000000U) +#define I2S_RCR5_WNW_SHIFT (24U) +#define I2S_RCR5_WNW(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR5_WNW_SHIFT)) & I2S_RCR5_WNW_MASK) + +/*! @name RDR - SAI Receive Data Register */ +#define I2S_RDR_RDR_MASK (0xFFFFFFFFU) +#define I2S_RDR_RDR_SHIFT (0U) +#define I2S_RDR_RDR(x) (((uint32_t)(((uint32_t)(x)) << I2S_RDR_RDR_SHIFT)) & I2S_RDR_RDR_MASK) + +/* The count of I2S_RDR */ +#define I2S_RDR_COUNT (2U) + +/*! @name RFR - SAI Receive FIFO Register */ +#define I2S_RFR_RFP_MASK (0xFU) +#define I2S_RFR_RFP_SHIFT (0U) +#define I2S_RFR_RFP(x) (((uint32_t)(((uint32_t)(x)) << I2S_RFR_RFP_SHIFT)) & I2S_RFR_RFP_MASK) +#define I2S_RFR_RCP_MASK (0x8000U) +#define I2S_RFR_RCP_SHIFT (15U) +#define I2S_RFR_RCP(x) (((uint32_t)(((uint32_t)(x)) << I2S_RFR_RCP_SHIFT)) & I2S_RFR_RCP_MASK) +#define I2S_RFR_WFP_MASK (0xF0000U) +#define I2S_RFR_WFP_SHIFT (16U) +#define I2S_RFR_WFP(x) (((uint32_t)(((uint32_t)(x)) << I2S_RFR_WFP_SHIFT)) & I2S_RFR_WFP_MASK) + +/* The count of I2S_RFR */ +#define I2S_RFR_COUNT (2U) + +/*! @name RMR - SAI Receive Mask Register */ +#define I2S_RMR_RWM_MASK (0xFFFFFFFFU) +#define I2S_RMR_RWM_SHIFT (0U) +#define I2S_RMR_RWM(x) (((uint32_t)(((uint32_t)(x)) << I2S_RMR_RWM_SHIFT)) & I2S_RMR_RWM_MASK) + +/*! @name MCR - SAI MCLK Control Register */ +#define I2S_MCR_MICS_MASK (0x3000000U) +#define I2S_MCR_MICS_SHIFT (24U) +#define I2S_MCR_MICS(x) (((uint32_t)(((uint32_t)(x)) << I2S_MCR_MICS_SHIFT)) & I2S_MCR_MICS_MASK) +#define I2S_MCR_MOE_MASK (0x40000000U) +#define I2S_MCR_MOE_SHIFT (30U) +#define I2S_MCR_MOE(x) (((uint32_t)(((uint32_t)(x)) << I2S_MCR_MOE_SHIFT)) & I2S_MCR_MOE_MASK) +#define I2S_MCR_DUF_MASK (0x80000000U) +#define I2S_MCR_DUF_SHIFT (31U) +#define I2S_MCR_DUF(x) (((uint32_t)(((uint32_t)(x)) << I2S_MCR_DUF_SHIFT)) & I2S_MCR_DUF_MASK) + +/*! @name MDR - SAI MCLK Divide Register */ +#define I2S_MDR_DIVIDE_MASK (0xFFFU) +#define I2S_MDR_DIVIDE_SHIFT (0U) +#define I2S_MDR_DIVIDE(x) (((uint32_t)(((uint32_t)(x)) << I2S_MDR_DIVIDE_SHIFT)) & I2S_MDR_DIVIDE_MASK) +#define I2S_MDR_FRACT_MASK (0xFF000U) +#define I2S_MDR_FRACT_SHIFT (12U) +#define I2S_MDR_FRACT(x) (((uint32_t)(((uint32_t)(x)) << I2S_MDR_FRACT_SHIFT)) & I2S_MDR_FRACT_MASK) + + +/*! + * @} + */ /* end of group I2S_Register_Masks */ + + +/* I2S - Peripheral instance base addresses */ +/** Peripheral I2S0 base address */ +#define I2S0_BASE (0x4002F000u) +/** Peripheral I2S0 base pointer */ +#define I2S0 ((I2S_Type *)I2S0_BASE) +/** Array initializer of I2S peripheral base addresses */ +#define I2S_BASE_ADDRS { I2S0_BASE } +/** Array initializer of I2S peripheral base pointers */ +#define I2S_BASE_PTRS { I2S0 } +/** Interrupt vectors for the I2S peripheral type */ +#define I2S_RX_IRQS { I2S0_Rx_IRQn } +#define I2S_TX_IRQS { I2S0_Tx_IRQn } + +/*! + * @} + */ /* end of group I2S_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- LLWU Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LLWU_Peripheral_Access_Layer LLWU Peripheral Access Layer + * @{ + */ + +/** LLWU - Register Layout Typedef */ +typedef struct { + __IO uint8_t PE1; /**< LLWU Pin Enable 1 register, offset: 0x0 */ + __IO uint8_t PE2; /**< LLWU Pin Enable 2 register, offset: 0x1 */ + __IO uint8_t PE3; /**< LLWU Pin Enable 3 register, offset: 0x2 */ + __IO uint8_t PE4; /**< LLWU Pin Enable 4 register, offset: 0x3 */ + __IO uint8_t PE5; /**< LLWU Pin Enable 5 register, offset: 0x4 */ + __IO uint8_t PE6; /**< LLWU Pin Enable 6 register, offset: 0x5 */ + __IO uint8_t PE7; /**< LLWU Pin Enable 7 register, offset: 0x6 */ + __IO uint8_t PE8; /**< LLWU Pin Enable 8 register, offset: 0x7 */ + __IO uint8_t ME; /**< LLWU Module Enable register, offset: 0x8 */ + __IO uint8_t PF1; /**< LLWU Pin Flag 1 register, offset: 0x9 */ + __IO uint8_t PF2; /**< LLWU Pin Flag 2 register, offset: 0xA */ + __IO uint8_t PF3; /**< LLWU Pin Flag 3 register, offset: 0xB */ + __IO uint8_t PF4; /**< LLWU Pin Flag 4 register, offset: 0xC */ + __I uint8_t MF5; /**< LLWU Module Flag 5 register, offset: 0xD */ + __IO uint8_t FILT1; /**< LLWU Pin Filter 1 register, offset: 0xE */ + __IO uint8_t FILT2; /**< LLWU Pin Filter 2 register, offset: 0xF */ + __IO uint8_t FILT3; /**< LLWU Pin Filter 3 register, offset: 0x10 */ + __IO uint8_t FILT4; /**< LLWU Pin Filter 4 register, offset: 0x11 */ +} LLWU_Type; + +/* ---------------------------------------------------------------------------- + -- LLWU Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LLWU_Register_Masks LLWU Register Masks + * @{ + */ + +/*! @name PE1 - LLWU Pin Enable 1 register */ +#define LLWU_PE1_WUPE0_MASK (0x3U) +#define LLWU_PE1_WUPE0_SHIFT (0U) +#define LLWU_PE1_WUPE0(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE1_WUPE0_SHIFT)) & LLWU_PE1_WUPE0_MASK) +#define LLWU_PE1_WUPE1_MASK (0xCU) +#define LLWU_PE1_WUPE1_SHIFT (2U) +#define LLWU_PE1_WUPE1(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE1_WUPE1_SHIFT)) & LLWU_PE1_WUPE1_MASK) +#define LLWU_PE1_WUPE2_MASK (0x30U) +#define LLWU_PE1_WUPE2_SHIFT (4U) +#define LLWU_PE1_WUPE2(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE1_WUPE2_SHIFT)) & LLWU_PE1_WUPE2_MASK) +#define LLWU_PE1_WUPE3_MASK (0xC0U) +#define LLWU_PE1_WUPE3_SHIFT (6U) +#define LLWU_PE1_WUPE3(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE1_WUPE3_SHIFT)) & LLWU_PE1_WUPE3_MASK) + +/*! @name PE2 - LLWU Pin Enable 2 register */ +#define LLWU_PE2_WUPE4_MASK (0x3U) +#define LLWU_PE2_WUPE4_SHIFT (0U) +#define LLWU_PE2_WUPE4(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE2_WUPE4_SHIFT)) & LLWU_PE2_WUPE4_MASK) +#define LLWU_PE2_WUPE5_MASK (0xCU) +#define LLWU_PE2_WUPE5_SHIFT (2U) +#define LLWU_PE2_WUPE5(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE2_WUPE5_SHIFT)) & LLWU_PE2_WUPE5_MASK) +#define LLWU_PE2_WUPE6_MASK (0x30U) +#define LLWU_PE2_WUPE6_SHIFT (4U) +#define LLWU_PE2_WUPE6(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE2_WUPE6_SHIFT)) & LLWU_PE2_WUPE6_MASK) +#define LLWU_PE2_WUPE7_MASK (0xC0U) +#define LLWU_PE2_WUPE7_SHIFT (6U) +#define LLWU_PE2_WUPE7(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE2_WUPE7_SHIFT)) & LLWU_PE2_WUPE7_MASK) + +/*! @name PE3 - LLWU Pin Enable 3 register */ +#define LLWU_PE3_WUPE8_MASK (0x3U) +#define LLWU_PE3_WUPE8_SHIFT (0U) +#define LLWU_PE3_WUPE8(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE3_WUPE8_SHIFT)) & LLWU_PE3_WUPE8_MASK) +#define LLWU_PE3_WUPE9_MASK (0xCU) +#define LLWU_PE3_WUPE9_SHIFT (2U) +#define LLWU_PE3_WUPE9(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE3_WUPE9_SHIFT)) & LLWU_PE3_WUPE9_MASK) +#define LLWU_PE3_WUPE10_MASK (0x30U) +#define LLWU_PE3_WUPE10_SHIFT (4U) +#define LLWU_PE3_WUPE10(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE3_WUPE10_SHIFT)) & LLWU_PE3_WUPE10_MASK) +#define LLWU_PE3_WUPE11_MASK (0xC0U) +#define LLWU_PE3_WUPE11_SHIFT (6U) +#define LLWU_PE3_WUPE11(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE3_WUPE11_SHIFT)) & LLWU_PE3_WUPE11_MASK) + +/*! @name PE4 - LLWU Pin Enable 4 register */ +#define LLWU_PE4_WUPE12_MASK (0x3U) +#define LLWU_PE4_WUPE12_SHIFT (0U) +#define LLWU_PE4_WUPE12(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE4_WUPE12_SHIFT)) & LLWU_PE4_WUPE12_MASK) +#define LLWU_PE4_WUPE13_MASK (0xCU) +#define LLWU_PE4_WUPE13_SHIFT (2U) +#define LLWU_PE4_WUPE13(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE4_WUPE13_SHIFT)) & LLWU_PE4_WUPE13_MASK) +#define LLWU_PE4_WUPE14_MASK (0x30U) +#define LLWU_PE4_WUPE14_SHIFT (4U) +#define LLWU_PE4_WUPE14(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE4_WUPE14_SHIFT)) & LLWU_PE4_WUPE14_MASK) +#define LLWU_PE4_WUPE15_MASK (0xC0U) +#define LLWU_PE4_WUPE15_SHIFT (6U) +#define LLWU_PE4_WUPE15(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE4_WUPE15_SHIFT)) & LLWU_PE4_WUPE15_MASK) + +/*! @name PE5 - LLWU Pin Enable 5 register */ +#define LLWU_PE5_WUPE16_MASK (0x3U) +#define LLWU_PE5_WUPE16_SHIFT (0U) +#define LLWU_PE5_WUPE16(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE5_WUPE16_SHIFT)) & LLWU_PE5_WUPE16_MASK) +#define LLWU_PE5_WUPE17_MASK (0xCU) +#define LLWU_PE5_WUPE17_SHIFT (2U) +#define LLWU_PE5_WUPE17(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE5_WUPE17_SHIFT)) & LLWU_PE5_WUPE17_MASK) +#define LLWU_PE5_WUPE18_MASK (0x30U) +#define LLWU_PE5_WUPE18_SHIFT (4U) +#define LLWU_PE5_WUPE18(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE5_WUPE18_SHIFT)) & LLWU_PE5_WUPE18_MASK) +#define LLWU_PE5_WUPE19_MASK (0xC0U) +#define LLWU_PE5_WUPE19_SHIFT (6U) +#define LLWU_PE5_WUPE19(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE5_WUPE19_SHIFT)) & LLWU_PE5_WUPE19_MASK) + +/*! @name PE6 - LLWU Pin Enable 6 register */ +#define LLWU_PE6_WUPE20_MASK (0x3U) +#define LLWU_PE6_WUPE20_SHIFT (0U) +#define LLWU_PE6_WUPE20(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE6_WUPE20_SHIFT)) & LLWU_PE6_WUPE20_MASK) +#define LLWU_PE6_WUPE21_MASK (0xCU) +#define LLWU_PE6_WUPE21_SHIFT (2U) +#define LLWU_PE6_WUPE21(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE6_WUPE21_SHIFT)) & LLWU_PE6_WUPE21_MASK) +#define LLWU_PE6_WUPE22_MASK (0x30U) +#define LLWU_PE6_WUPE22_SHIFT (4U) +#define LLWU_PE6_WUPE22(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE6_WUPE22_SHIFT)) & LLWU_PE6_WUPE22_MASK) +#define LLWU_PE6_WUPE23_MASK (0xC0U) +#define LLWU_PE6_WUPE23_SHIFT (6U) +#define LLWU_PE6_WUPE23(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE6_WUPE23_SHIFT)) & LLWU_PE6_WUPE23_MASK) + +/*! @name PE7 - LLWU Pin Enable 7 register */ +#define LLWU_PE7_WUPE24_MASK (0x3U) +#define LLWU_PE7_WUPE24_SHIFT (0U) +#define LLWU_PE7_WUPE24(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE7_WUPE24_SHIFT)) & LLWU_PE7_WUPE24_MASK) +#define LLWU_PE7_WUPE25_MASK (0xCU) +#define LLWU_PE7_WUPE25_SHIFT (2U) +#define LLWU_PE7_WUPE25(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE7_WUPE25_SHIFT)) & LLWU_PE7_WUPE25_MASK) +#define LLWU_PE7_WUPE26_MASK (0x30U) +#define LLWU_PE7_WUPE26_SHIFT (4U) +#define LLWU_PE7_WUPE26(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE7_WUPE26_SHIFT)) & LLWU_PE7_WUPE26_MASK) +#define LLWU_PE7_WUPE27_MASK (0xC0U) +#define LLWU_PE7_WUPE27_SHIFT (6U) +#define LLWU_PE7_WUPE27(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE7_WUPE27_SHIFT)) & LLWU_PE7_WUPE27_MASK) + +/*! @name PE8 - LLWU Pin Enable 8 register */ +#define LLWU_PE8_WUPE28_MASK (0x3U) +#define LLWU_PE8_WUPE28_SHIFT (0U) +#define LLWU_PE8_WUPE28(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE8_WUPE28_SHIFT)) & LLWU_PE8_WUPE28_MASK) +#define LLWU_PE8_WUPE29_MASK (0xCU) +#define LLWU_PE8_WUPE29_SHIFT (2U) +#define LLWU_PE8_WUPE29(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE8_WUPE29_SHIFT)) & LLWU_PE8_WUPE29_MASK) +#define LLWU_PE8_WUPE30_MASK (0x30U) +#define LLWU_PE8_WUPE30_SHIFT (4U) +#define LLWU_PE8_WUPE30(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE8_WUPE30_SHIFT)) & LLWU_PE8_WUPE30_MASK) +#define LLWU_PE8_WUPE31_MASK (0xC0U) +#define LLWU_PE8_WUPE31_SHIFT (6U) +#define LLWU_PE8_WUPE31(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE8_WUPE31_SHIFT)) & LLWU_PE8_WUPE31_MASK) + +/*! @name ME - LLWU Module Enable register */ +#define LLWU_ME_WUME0_MASK (0x1U) +#define LLWU_ME_WUME0_SHIFT (0U) +#define LLWU_ME_WUME0(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME0_SHIFT)) & LLWU_ME_WUME0_MASK) +#define LLWU_ME_WUME1_MASK (0x2U) +#define LLWU_ME_WUME1_SHIFT (1U) +#define LLWU_ME_WUME1(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME1_SHIFT)) & LLWU_ME_WUME1_MASK) +#define LLWU_ME_WUME2_MASK (0x4U) +#define LLWU_ME_WUME2_SHIFT (2U) +#define LLWU_ME_WUME2(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME2_SHIFT)) & LLWU_ME_WUME2_MASK) +#define LLWU_ME_WUME3_MASK (0x8U) +#define LLWU_ME_WUME3_SHIFT (3U) +#define LLWU_ME_WUME3(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME3_SHIFT)) & LLWU_ME_WUME3_MASK) +#define LLWU_ME_WUME4_MASK (0x10U) +#define LLWU_ME_WUME4_SHIFT (4U) +#define LLWU_ME_WUME4(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME4_SHIFT)) & LLWU_ME_WUME4_MASK) +#define LLWU_ME_WUME5_MASK (0x20U) +#define LLWU_ME_WUME5_SHIFT (5U) +#define LLWU_ME_WUME5(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME5_SHIFT)) & LLWU_ME_WUME5_MASK) +#define LLWU_ME_WUME6_MASK (0x40U) +#define LLWU_ME_WUME6_SHIFT (6U) +#define LLWU_ME_WUME6(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME6_SHIFT)) & LLWU_ME_WUME6_MASK) +#define LLWU_ME_WUME7_MASK (0x80U) +#define LLWU_ME_WUME7_SHIFT (7U) +#define LLWU_ME_WUME7(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME7_SHIFT)) & LLWU_ME_WUME7_MASK) + +/*! @name PF1 - LLWU Pin Flag 1 register */ +#define LLWU_PF1_WUF0_MASK (0x1U) +#define LLWU_PF1_WUF0_SHIFT (0U) +#define LLWU_PF1_WUF0(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF1_WUF0_SHIFT)) & LLWU_PF1_WUF0_MASK) +#define LLWU_PF1_WUF1_MASK (0x2U) +#define LLWU_PF1_WUF1_SHIFT (1U) +#define LLWU_PF1_WUF1(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF1_WUF1_SHIFT)) & LLWU_PF1_WUF1_MASK) +#define LLWU_PF1_WUF2_MASK (0x4U) +#define LLWU_PF1_WUF2_SHIFT (2U) +#define LLWU_PF1_WUF2(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF1_WUF2_SHIFT)) & LLWU_PF1_WUF2_MASK) +#define LLWU_PF1_WUF3_MASK (0x8U) +#define LLWU_PF1_WUF3_SHIFT (3U) +#define LLWU_PF1_WUF3(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF1_WUF3_SHIFT)) & LLWU_PF1_WUF3_MASK) +#define LLWU_PF1_WUF4_MASK (0x10U) +#define LLWU_PF1_WUF4_SHIFT (4U) +#define LLWU_PF1_WUF4(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF1_WUF4_SHIFT)) & LLWU_PF1_WUF4_MASK) +#define LLWU_PF1_WUF5_MASK (0x20U) +#define LLWU_PF1_WUF5_SHIFT (5U) +#define LLWU_PF1_WUF5(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF1_WUF5_SHIFT)) & LLWU_PF1_WUF5_MASK) +#define LLWU_PF1_WUF6_MASK (0x40U) +#define LLWU_PF1_WUF6_SHIFT (6U) +#define LLWU_PF1_WUF6(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF1_WUF6_SHIFT)) & LLWU_PF1_WUF6_MASK) +#define LLWU_PF1_WUF7_MASK (0x80U) +#define LLWU_PF1_WUF7_SHIFT (7U) +#define LLWU_PF1_WUF7(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF1_WUF7_SHIFT)) & LLWU_PF1_WUF7_MASK) + +/*! @name PF2 - LLWU Pin Flag 2 register */ +#define LLWU_PF2_WUF8_MASK (0x1U) +#define LLWU_PF2_WUF8_SHIFT (0U) +#define LLWU_PF2_WUF8(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF2_WUF8_SHIFT)) & LLWU_PF2_WUF8_MASK) +#define LLWU_PF2_WUF9_MASK (0x2U) +#define LLWU_PF2_WUF9_SHIFT (1U) +#define LLWU_PF2_WUF9(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF2_WUF9_SHIFT)) & LLWU_PF2_WUF9_MASK) +#define LLWU_PF2_WUF10_MASK (0x4U) +#define LLWU_PF2_WUF10_SHIFT (2U) +#define LLWU_PF2_WUF10(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF2_WUF10_SHIFT)) & LLWU_PF2_WUF10_MASK) +#define LLWU_PF2_WUF11_MASK (0x8U) +#define LLWU_PF2_WUF11_SHIFT (3U) +#define LLWU_PF2_WUF11(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF2_WUF11_SHIFT)) & LLWU_PF2_WUF11_MASK) +#define LLWU_PF2_WUF12_MASK (0x10U) +#define LLWU_PF2_WUF12_SHIFT (4U) +#define LLWU_PF2_WUF12(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF2_WUF12_SHIFT)) & LLWU_PF2_WUF12_MASK) +#define LLWU_PF2_WUF13_MASK (0x20U) +#define LLWU_PF2_WUF13_SHIFT (5U) +#define LLWU_PF2_WUF13(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF2_WUF13_SHIFT)) & LLWU_PF2_WUF13_MASK) +#define LLWU_PF2_WUF14_MASK (0x40U) +#define LLWU_PF2_WUF14_SHIFT (6U) +#define LLWU_PF2_WUF14(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF2_WUF14_SHIFT)) & LLWU_PF2_WUF14_MASK) +#define LLWU_PF2_WUF15_MASK (0x80U) +#define LLWU_PF2_WUF15_SHIFT (7U) +#define LLWU_PF2_WUF15(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF2_WUF15_SHIFT)) & LLWU_PF2_WUF15_MASK) + +/*! @name PF3 - LLWU Pin Flag 3 register */ +#define LLWU_PF3_WUF16_MASK (0x1U) +#define LLWU_PF3_WUF16_SHIFT (0U) +#define LLWU_PF3_WUF16(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF3_WUF16_SHIFT)) & LLWU_PF3_WUF16_MASK) +#define LLWU_PF3_WUF17_MASK (0x2U) +#define LLWU_PF3_WUF17_SHIFT (1U) +#define LLWU_PF3_WUF17(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF3_WUF17_SHIFT)) & LLWU_PF3_WUF17_MASK) +#define LLWU_PF3_WUF18_MASK (0x4U) +#define LLWU_PF3_WUF18_SHIFT (2U) +#define LLWU_PF3_WUF18(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF3_WUF18_SHIFT)) & LLWU_PF3_WUF18_MASK) +#define LLWU_PF3_WUF19_MASK (0x8U) +#define LLWU_PF3_WUF19_SHIFT (3U) +#define LLWU_PF3_WUF19(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF3_WUF19_SHIFT)) & LLWU_PF3_WUF19_MASK) +#define LLWU_PF3_WUF20_MASK (0x10U) +#define LLWU_PF3_WUF20_SHIFT (4U) +#define LLWU_PF3_WUF20(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF3_WUF20_SHIFT)) & LLWU_PF3_WUF20_MASK) +#define LLWU_PF3_WUF21_MASK (0x20U) +#define LLWU_PF3_WUF21_SHIFT (5U) +#define LLWU_PF3_WUF21(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF3_WUF21_SHIFT)) & LLWU_PF3_WUF21_MASK) +#define LLWU_PF3_WUF22_MASK (0x40U) +#define LLWU_PF3_WUF22_SHIFT (6U) +#define LLWU_PF3_WUF22(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF3_WUF22_SHIFT)) & LLWU_PF3_WUF22_MASK) +#define LLWU_PF3_WUF23_MASK (0x80U) +#define LLWU_PF3_WUF23_SHIFT (7U) +#define LLWU_PF3_WUF23(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF3_WUF23_SHIFT)) & LLWU_PF3_WUF23_MASK) + +/*! @name PF4 - LLWU Pin Flag 4 register */ +#define LLWU_PF4_WUF24_MASK (0x1U) +#define LLWU_PF4_WUF24_SHIFT (0U) +#define LLWU_PF4_WUF24(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF4_WUF24_SHIFT)) & LLWU_PF4_WUF24_MASK) +#define LLWU_PF4_WUF25_MASK (0x2U) +#define LLWU_PF4_WUF25_SHIFT (1U) +#define LLWU_PF4_WUF25(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF4_WUF25_SHIFT)) & LLWU_PF4_WUF25_MASK) +#define LLWU_PF4_WUF26_MASK (0x4U) +#define LLWU_PF4_WUF26_SHIFT (2U) +#define LLWU_PF4_WUF26(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF4_WUF26_SHIFT)) & LLWU_PF4_WUF26_MASK) +#define LLWU_PF4_WUF27_MASK (0x8U) +#define LLWU_PF4_WUF27_SHIFT (3U) +#define LLWU_PF4_WUF27(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF4_WUF27_SHIFT)) & LLWU_PF4_WUF27_MASK) +#define LLWU_PF4_WUF28_MASK (0x10U) +#define LLWU_PF4_WUF28_SHIFT (4U) +#define LLWU_PF4_WUF28(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF4_WUF28_SHIFT)) & LLWU_PF4_WUF28_MASK) +#define LLWU_PF4_WUF29_MASK (0x20U) +#define LLWU_PF4_WUF29_SHIFT (5U) +#define LLWU_PF4_WUF29(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF4_WUF29_SHIFT)) & LLWU_PF4_WUF29_MASK) +#define LLWU_PF4_WUF30_MASK (0x40U) +#define LLWU_PF4_WUF30_SHIFT (6U) +#define LLWU_PF4_WUF30(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF4_WUF30_SHIFT)) & LLWU_PF4_WUF30_MASK) +#define LLWU_PF4_WUF31_MASK (0x80U) +#define LLWU_PF4_WUF31_SHIFT (7U) +#define LLWU_PF4_WUF31(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PF4_WUF31_SHIFT)) & LLWU_PF4_WUF31_MASK) + +/*! @name MF5 - LLWU Module Flag 5 register */ +#define LLWU_MF5_MWUF0_MASK (0x1U) +#define LLWU_MF5_MWUF0_SHIFT (0U) +#define LLWU_MF5_MWUF0(x) (((uint8_t)(((uint8_t)(x)) << LLWU_MF5_MWUF0_SHIFT)) & LLWU_MF5_MWUF0_MASK) +#define LLWU_MF5_MWUF1_MASK (0x2U) +#define LLWU_MF5_MWUF1_SHIFT (1U) +#define LLWU_MF5_MWUF1(x) (((uint8_t)(((uint8_t)(x)) << LLWU_MF5_MWUF1_SHIFT)) & LLWU_MF5_MWUF1_MASK) +#define LLWU_MF5_MWUF2_MASK (0x4U) +#define LLWU_MF5_MWUF2_SHIFT (2U) +#define LLWU_MF5_MWUF2(x) (((uint8_t)(((uint8_t)(x)) << LLWU_MF5_MWUF2_SHIFT)) & LLWU_MF5_MWUF2_MASK) +#define LLWU_MF5_MWUF3_MASK (0x8U) +#define LLWU_MF5_MWUF3_SHIFT (3U) +#define LLWU_MF5_MWUF3(x) (((uint8_t)(((uint8_t)(x)) << LLWU_MF5_MWUF3_SHIFT)) & LLWU_MF5_MWUF3_MASK) +#define LLWU_MF5_MWUF4_MASK (0x10U) +#define LLWU_MF5_MWUF4_SHIFT (4U) +#define LLWU_MF5_MWUF4(x) (((uint8_t)(((uint8_t)(x)) << LLWU_MF5_MWUF4_SHIFT)) & LLWU_MF5_MWUF4_MASK) +#define LLWU_MF5_MWUF5_MASK (0x20U) +#define LLWU_MF5_MWUF5_SHIFT (5U) +#define LLWU_MF5_MWUF5(x) (((uint8_t)(((uint8_t)(x)) << LLWU_MF5_MWUF5_SHIFT)) & LLWU_MF5_MWUF5_MASK) +#define LLWU_MF5_MWUF6_MASK (0x40U) +#define LLWU_MF5_MWUF6_SHIFT (6U) +#define LLWU_MF5_MWUF6(x) (((uint8_t)(((uint8_t)(x)) << LLWU_MF5_MWUF6_SHIFT)) & LLWU_MF5_MWUF6_MASK) +#define LLWU_MF5_MWUF7_MASK (0x80U) +#define LLWU_MF5_MWUF7_SHIFT (7U) +#define LLWU_MF5_MWUF7(x) (((uint8_t)(((uint8_t)(x)) << LLWU_MF5_MWUF7_SHIFT)) & LLWU_MF5_MWUF7_MASK) + +/*! @name FILT1 - LLWU Pin Filter 1 register */ +#define LLWU_FILT1_FILTSEL_MASK (0x1FU) +#define LLWU_FILT1_FILTSEL_SHIFT (0U) +#define LLWU_FILT1_FILTSEL(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT1_FILTSEL_SHIFT)) & LLWU_FILT1_FILTSEL_MASK) +#define LLWU_FILT1_FILTE_MASK (0x60U) +#define LLWU_FILT1_FILTE_SHIFT (5U) +#define LLWU_FILT1_FILTE(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT1_FILTE_SHIFT)) & LLWU_FILT1_FILTE_MASK) +#define LLWU_FILT1_FILTF_MASK (0x80U) +#define LLWU_FILT1_FILTF_SHIFT (7U) +#define LLWU_FILT1_FILTF(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT1_FILTF_SHIFT)) & LLWU_FILT1_FILTF_MASK) + +/*! @name FILT2 - LLWU Pin Filter 2 register */ +#define LLWU_FILT2_FILTSEL_MASK (0x1FU) +#define LLWU_FILT2_FILTSEL_SHIFT (0U) +#define LLWU_FILT2_FILTSEL(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT2_FILTSEL_SHIFT)) & LLWU_FILT2_FILTSEL_MASK) +#define LLWU_FILT2_FILTE_MASK (0x60U) +#define LLWU_FILT2_FILTE_SHIFT (5U) +#define LLWU_FILT2_FILTE(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT2_FILTE_SHIFT)) & LLWU_FILT2_FILTE_MASK) +#define LLWU_FILT2_FILTF_MASK (0x80U) +#define LLWU_FILT2_FILTF_SHIFT (7U) +#define LLWU_FILT2_FILTF(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT2_FILTF_SHIFT)) & LLWU_FILT2_FILTF_MASK) + +/*! @name FILT3 - LLWU Pin Filter 3 register */ +#define LLWU_FILT3_FILTSEL_MASK (0x1FU) +#define LLWU_FILT3_FILTSEL_SHIFT (0U) +#define LLWU_FILT3_FILTSEL(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT3_FILTSEL_SHIFT)) & LLWU_FILT3_FILTSEL_MASK) +#define LLWU_FILT3_FILTE_MASK (0x60U) +#define LLWU_FILT3_FILTE_SHIFT (5U) +#define LLWU_FILT3_FILTE(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT3_FILTE_SHIFT)) & LLWU_FILT3_FILTE_MASK) +#define LLWU_FILT3_FILTF_MASK (0x80U) +#define LLWU_FILT3_FILTF_SHIFT (7U) +#define LLWU_FILT3_FILTF(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT3_FILTF_SHIFT)) & LLWU_FILT3_FILTF_MASK) + +/*! @name FILT4 - LLWU Pin Filter 4 register */ +#define LLWU_FILT4_FILTSEL_MASK (0x1FU) +#define LLWU_FILT4_FILTSEL_SHIFT (0U) +#define LLWU_FILT4_FILTSEL(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT4_FILTSEL_SHIFT)) & LLWU_FILT4_FILTSEL_MASK) +#define LLWU_FILT4_FILTE_MASK (0x60U) +#define LLWU_FILT4_FILTE_SHIFT (5U) +#define LLWU_FILT4_FILTE(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT4_FILTE_SHIFT)) & LLWU_FILT4_FILTE_MASK) +#define LLWU_FILT4_FILTF_MASK (0x80U) +#define LLWU_FILT4_FILTF_SHIFT (7U) +#define LLWU_FILT4_FILTF(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT4_FILTF_SHIFT)) & LLWU_FILT4_FILTF_MASK) + + +/*! + * @} + */ /* end of group LLWU_Register_Masks */ + + +/* LLWU - Peripheral instance base addresses */ +/** Peripheral LLWU base address */ +#define LLWU_BASE (0x4007C000u) +/** Peripheral LLWU base pointer */ +#define LLWU ((LLWU_Type *)LLWU_BASE) +/** Array initializer of LLWU peripheral base addresses */ +#define LLWU_BASE_ADDRS { LLWU_BASE } +/** Array initializer of LLWU peripheral base pointers */ +#define LLWU_BASE_PTRS { LLWU } +/** Interrupt vectors for the LLWU peripheral type */ +#define LLWU_IRQS { LLWU_IRQn } + +/*! + * @} + */ /* end of group LLWU_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- LMEM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LMEM_Peripheral_Access_Layer LMEM Peripheral Access Layer + * @{ + */ + +/** LMEM - Register Layout Typedef */ +typedef struct { + __IO uint32_t PCCCR; /**< Cache control register, offset: 0x0 */ + __IO uint32_t PCCLCR; /**< Cache line control register, offset: 0x4 */ + __IO uint32_t PCCSAR; /**< Cache search address register, offset: 0x8 */ + __IO uint32_t PCCCVR; /**< Cache read/write value register, offset: 0xC */ + uint8_t RESERVED_0[16]; + __IO uint32_t PCCRMR; /**< Cache regions mode register, offset: 0x20 */ + uint8_t RESERVED_1[2012]; + __IO uint32_t PSCCR; /**< Cache control register, offset: 0x800 */ + __IO uint32_t PSCLCR; /**< Cache line control register, offset: 0x804 */ + __IO uint32_t PSCSAR; /**< Cache search address register, offset: 0x808 */ + __IO uint32_t PSCCVR; /**< Cache read/write value register, offset: 0x80C */ + uint8_t RESERVED_2[16]; + __IO uint32_t PSCRMR; /**< Cache regions mode register, offset: 0x820 */ +} LMEM_Type; + +/* ---------------------------------------------------------------------------- + -- LMEM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LMEM_Register_Masks LMEM Register Masks + * @{ + */ + +/*! @name PCCCR - Cache control register */ +#define LMEM_PCCCR_ENCACHE_MASK (0x1U) +#define LMEM_PCCCR_ENCACHE_SHIFT (0U) +#define LMEM_PCCCR_ENCACHE(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCCR_ENCACHE_SHIFT)) & LMEM_PCCCR_ENCACHE_MASK) +#define LMEM_PCCCR_ENWRBUF_MASK (0x2U) +#define LMEM_PCCCR_ENWRBUF_SHIFT (1U) +#define LMEM_PCCCR_ENWRBUF(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCCR_ENWRBUF_SHIFT)) & LMEM_PCCCR_ENWRBUF_MASK) +#define LMEM_PCCCR_PCCR2_MASK (0x4U) +#define LMEM_PCCCR_PCCR2_SHIFT (2U) +#define LMEM_PCCCR_PCCR2(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCCR_PCCR2_SHIFT)) & LMEM_PCCCR_PCCR2_MASK) +#define LMEM_PCCCR_PCCR3_MASK (0x8U) +#define LMEM_PCCCR_PCCR3_SHIFT (3U) +#define LMEM_PCCCR_PCCR3(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCCR_PCCR3_SHIFT)) & LMEM_PCCCR_PCCR3_MASK) +#define LMEM_PCCCR_INVW0_MASK (0x1000000U) +#define LMEM_PCCCR_INVW0_SHIFT (24U) +#define LMEM_PCCCR_INVW0(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCCR_INVW0_SHIFT)) & LMEM_PCCCR_INVW0_MASK) +#define LMEM_PCCCR_PUSHW0_MASK (0x2000000U) +#define LMEM_PCCCR_PUSHW0_SHIFT (25U) +#define LMEM_PCCCR_PUSHW0(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCCR_PUSHW0_SHIFT)) & LMEM_PCCCR_PUSHW0_MASK) +#define LMEM_PCCCR_INVW1_MASK (0x4000000U) +#define LMEM_PCCCR_INVW1_SHIFT (26U) +#define LMEM_PCCCR_INVW1(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCCR_INVW1_SHIFT)) & LMEM_PCCCR_INVW1_MASK) +#define LMEM_PCCCR_PUSHW1_MASK (0x8000000U) +#define LMEM_PCCCR_PUSHW1_SHIFT (27U) +#define LMEM_PCCCR_PUSHW1(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCCR_PUSHW1_SHIFT)) & LMEM_PCCCR_PUSHW1_MASK) +#define LMEM_PCCCR_GO_MASK (0x80000000U) +#define LMEM_PCCCR_GO_SHIFT (31U) +#define LMEM_PCCCR_GO(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCCR_GO_SHIFT)) & LMEM_PCCCR_GO_MASK) + +/*! @name PCCLCR - Cache line control register */ +#define LMEM_PCCLCR_LGO_MASK (0x1U) +#define LMEM_PCCLCR_LGO_SHIFT (0U) +#define LMEM_PCCLCR_LGO(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCLCR_LGO_SHIFT)) & LMEM_PCCLCR_LGO_MASK) +#define LMEM_PCCLCR_CACHEADDR_MASK (0xFFCU) +#define LMEM_PCCLCR_CACHEADDR_SHIFT (2U) +#define LMEM_PCCLCR_CACHEADDR(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCLCR_CACHEADDR_SHIFT)) & LMEM_PCCLCR_CACHEADDR_MASK) +#define LMEM_PCCLCR_WSEL_MASK (0x4000U) +#define LMEM_PCCLCR_WSEL_SHIFT (14U) +#define LMEM_PCCLCR_WSEL(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCLCR_WSEL_SHIFT)) & LMEM_PCCLCR_WSEL_MASK) +#define LMEM_PCCLCR_TDSEL_MASK (0x10000U) +#define LMEM_PCCLCR_TDSEL_SHIFT (16U) +#define LMEM_PCCLCR_TDSEL(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCLCR_TDSEL_SHIFT)) & LMEM_PCCLCR_TDSEL_MASK) +#define LMEM_PCCLCR_LCIVB_MASK (0x100000U) +#define LMEM_PCCLCR_LCIVB_SHIFT (20U) +#define LMEM_PCCLCR_LCIVB(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCLCR_LCIVB_SHIFT)) & LMEM_PCCLCR_LCIVB_MASK) +#define LMEM_PCCLCR_LCIMB_MASK (0x200000U) +#define LMEM_PCCLCR_LCIMB_SHIFT (21U) +#define LMEM_PCCLCR_LCIMB(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCLCR_LCIMB_SHIFT)) & LMEM_PCCLCR_LCIMB_MASK) +#define LMEM_PCCLCR_LCWAY_MASK (0x400000U) +#define LMEM_PCCLCR_LCWAY_SHIFT (22U) +#define LMEM_PCCLCR_LCWAY(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCLCR_LCWAY_SHIFT)) & LMEM_PCCLCR_LCWAY_MASK) +#define LMEM_PCCLCR_LCMD_MASK (0x3000000U) +#define LMEM_PCCLCR_LCMD_SHIFT (24U) +#define LMEM_PCCLCR_LCMD(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCLCR_LCMD_SHIFT)) & LMEM_PCCLCR_LCMD_MASK) +#define LMEM_PCCLCR_LADSEL_MASK (0x4000000U) +#define LMEM_PCCLCR_LADSEL_SHIFT (26U) +#define LMEM_PCCLCR_LADSEL(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCLCR_LADSEL_SHIFT)) & LMEM_PCCLCR_LADSEL_MASK) +#define LMEM_PCCLCR_LACC_MASK (0x8000000U) +#define LMEM_PCCLCR_LACC_SHIFT (27U) +#define LMEM_PCCLCR_LACC(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCLCR_LACC_SHIFT)) & LMEM_PCCLCR_LACC_MASK) + +/*! @name PCCSAR - Cache search address register */ +#define LMEM_PCCSAR_LGO_MASK (0x1U) +#define LMEM_PCCSAR_LGO_SHIFT (0U) +#define LMEM_PCCSAR_LGO(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCSAR_LGO_SHIFT)) & LMEM_PCCSAR_LGO_MASK) +#define LMEM_PCCSAR_PHYADDR_MASK (0xFFFFFFFCU) +#define LMEM_PCCSAR_PHYADDR_SHIFT (2U) +#define LMEM_PCCSAR_PHYADDR(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCSAR_PHYADDR_SHIFT)) & LMEM_PCCSAR_PHYADDR_MASK) + +/*! @name PCCCVR - Cache read/write value register */ +#define LMEM_PCCCVR_DATA_MASK (0xFFFFFFFFU) +#define LMEM_PCCCVR_DATA_SHIFT (0U) +#define LMEM_PCCCVR_DATA(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCCVR_DATA_SHIFT)) & LMEM_PCCCVR_DATA_MASK) + +/*! @name PCCRMR - Cache regions mode register */ +#define LMEM_PCCRMR_R15_MASK (0x3U) +#define LMEM_PCCRMR_R15_SHIFT (0U) +#define LMEM_PCCRMR_R15(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R15_SHIFT)) & LMEM_PCCRMR_R15_MASK) +#define LMEM_PCCRMR_R14_MASK (0xCU) +#define LMEM_PCCRMR_R14_SHIFT (2U) +#define LMEM_PCCRMR_R14(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R14_SHIFT)) & LMEM_PCCRMR_R14_MASK) +#define LMEM_PCCRMR_R13_MASK (0x30U) +#define LMEM_PCCRMR_R13_SHIFT (4U) +#define LMEM_PCCRMR_R13(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R13_SHIFT)) & LMEM_PCCRMR_R13_MASK) +#define LMEM_PCCRMR_R12_MASK (0xC0U) +#define LMEM_PCCRMR_R12_SHIFT (6U) +#define LMEM_PCCRMR_R12(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R12_SHIFT)) & LMEM_PCCRMR_R12_MASK) +#define LMEM_PCCRMR_R11_MASK (0x300U) +#define LMEM_PCCRMR_R11_SHIFT (8U) +#define LMEM_PCCRMR_R11(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R11_SHIFT)) & LMEM_PCCRMR_R11_MASK) +#define LMEM_PCCRMR_R10_MASK (0xC00U) +#define LMEM_PCCRMR_R10_SHIFT (10U) +#define LMEM_PCCRMR_R10(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R10_SHIFT)) & LMEM_PCCRMR_R10_MASK) +#define LMEM_PCCRMR_R9_MASK (0x3000U) +#define LMEM_PCCRMR_R9_SHIFT (12U) +#define LMEM_PCCRMR_R9(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R9_SHIFT)) & LMEM_PCCRMR_R9_MASK) +#define LMEM_PCCRMR_R8_MASK (0xC000U) +#define LMEM_PCCRMR_R8_SHIFT (14U) +#define LMEM_PCCRMR_R8(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R8_SHIFT)) & LMEM_PCCRMR_R8_MASK) +#define LMEM_PCCRMR_R7_MASK (0x30000U) +#define LMEM_PCCRMR_R7_SHIFT (16U) +#define LMEM_PCCRMR_R7(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R7_SHIFT)) & LMEM_PCCRMR_R7_MASK) +#define LMEM_PCCRMR_R6_MASK (0xC0000U) +#define LMEM_PCCRMR_R6_SHIFT (18U) +#define LMEM_PCCRMR_R6(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R6_SHIFT)) & LMEM_PCCRMR_R6_MASK) +#define LMEM_PCCRMR_R5_MASK (0x300000U) +#define LMEM_PCCRMR_R5_SHIFT (20U) +#define LMEM_PCCRMR_R5(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R5_SHIFT)) & LMEM_PCCRMR_R5_MASK) +#define LMEM_PCCRMR_R4_MASK (0xC00000U) +#define LMEM_PCCRMR_R4_SHIFT (22U) +#define LMEM_PCCRMR_R4(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R4_SHIFT)) & LMEM_PCCRMR_R4_MASK) +#define LMEM_PCCRMR_R3_MASK (0x3000000U) +#define LMEM_PCCRMR_R3_SHIFT (24U) +#define LMEM_PCCRMR_R3(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R3_SHIFT)) & LMEM_PCCRMR_R3_MASK) +#define LMEM_PCCRMR_R2_MASK (0xC000000U) +#define LMEM_PCCRMR_R2_SHIFT (26U) +#define LMEM_PCCRMR_R2(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R2_SHIFT)) & LMEM_PCCRMR_R2_MASK) +#define LMEM_PCCRMR_R1_MASK (0x30000000U) +#define LMEM_PCCRMR_R1_SHIFT (28U) +#define LMEM_PCCRMR_R1(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R1_SHIFT)) & LMEM_PCCRMR_R1_MASK) +#define LMEM_PCCRMR_R0_MASK (0xC0000000U) +#define LMEM_PCCRMR_R0_SHIFT (30U) +#define LMEM_PCCRMR_R0(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PCCRMR_R0_SHIFT)) & LMEM_PCCRMR_R0_MASK) + +/*! @name PSCCR - Cache control register */ +#define LMEM_PSCCR_ENCACHE_MASK (0x1U) +#define LMEM_PSCCR_ENCACHE_SHIFT (0U) +#define LMEM_PSCCR_ENCACHE(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCCR_ENCACHE_SHIFT)) & LMEM_PSCCR_ENCACHE_MASK) +#define LMEM_PSCCR_ENWRBUF_MASK (0x2U) +#define LMEM_PSCCR_ENWRBUF_SHIFT (1U) +#define LMEM_PSCCR_ENWRBUF(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCCR_ENWRBUF_SHIFT)) & LMEM_PSCCR_ENWRBUF_MASK) +#define LMEM_PSCCR_INVW0_MASK (0x1000000U) +#define LMEM_PSCCR_INVW0_SHIFT (24U) +#define LMEM_PSCCR_INVW0(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCCR_INVW0_SHIFT)) & LMEM_PSCCR_INVW0_MASK) +#define LMEM_PSCCR_PUSHW0_MASK (0x2000000U) +#define LMEM_PSCCR_PUSHW0_SHIFT (25U) +#define LMEM_PSCCR_PUSHW0(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCCR_PUSHW0_SHIFT)) & LMEM_PSCCR_PUSHW0_MASK) +#define LMEM_PSCCR_INVW1_MASK (0x4000000U) +#define LMEM_PSCCR_INVW1_SHIFT (26U) +#define LMEM_PSCCR_INVW1(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCCR_INVW1_SHIFT)) & LMEM_PSCCR_INVW1_MASK) +#define LMEM_PSCCR_PUSHW1_MASK (0x8000000U) +#define LMEM_PSCCR_PUSHW1_SHIFT (27U) +#define LMEM_PSCCR_PUSHW1(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCCR_PUSHW1_SHIFT)) & LMEM_PSCCR_PUSHW1_MASK) +#define LMEM_PSCCR_GO_MASK (0x80000000U) +#define LMEM_PSCCR_GO_SHIFT (31U) +#define LMEM_PSCCR_GO(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCCR_GO_SHIFT)) & LMEM_PSCCR_GO_MASK) + +/*! @name PSCLCR - Cache line control register */ +#define LMEM_PSCLCR_LGO_MASK (0x1U) +#define LMEM_PSCLCR_LGO_SHIFT (0U) +#define LMEM_PSCLCR_LGO(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCLCR_LGO_SHIFT)) & LMEM_PSCLCR_LGO_MASK) +#define LMEM_PSCLCR_CACHEADDR_MASK (0xFFCU) +#define LMEM_PSCLCR_CACHEADDR_SHIFT (2U) +#define LMEM_PSCLCR_CACHEADDR(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCLCR_CACHEADDR_SHIFT)) & LMEM_PSCLCR_CACHEADDR_MASK) +#define LMEM_PSCLCR_WSEL_MASK (0x4000U) +#define LMEM_PSCLCR_WSEL_SHIFT (14U) +#define LMEM_PSCLCR_WSEL(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCLCR_WSEL_SHIFT)) & LMEM_PSCLCR_WSEL_MASK) +#define LMEM_PSCLCR_TDSEL_MASK (0x10000U) +#define LMEM_PSCLCR_TDSEL_SHIFT (16U) +#define LMEM_PSCLCR_TDSEL(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCLCR_TDSEL_SHIFT)) & LMEM_PSCLCR_TDSEL_MASK) +#define LMEM_PSCLCR_LCIVB_MASK (0x100000U) +#define LMEM_PSCLCR_LCIVB_SHIFT (20U) +#define LMEM_PSCLCR_LCIVB(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCLCR_LCIVB_SHIFT)) & LMEM_PSCLCR_LCIVB_MASK) +#define LMEM_PSCLCR_LCIMB_MASK (0x200000U) +#define LMEM_PSCLCR_LCIMB_SHIFT (21U) +#define LMEM_PSCLCR_LCIMB(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCLCR_LCIMB_SHIFT)) & LMEM_PSCLCR_LCIMB_MASK) +#define LMEM_PSCLCR_LCWAY_MASK (0x400000U) +#define LMEM_PSCLCR_LCWAY_SHIFT (22U) +#define LMEM_PSCLCR_LCWAY(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCLCR_LCWAY_SHIFT)) & LMEM_PSCLCR_LCWAY_MASK) +#define LMEM_PSCLCR_LCMD_MASK (0x3000000U) +#define LMEM_PSCLCR_LCMD_SHIFT (24U) +#define LMEM_PSCLCR_LCMD(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCLCR_LCMD_SHIFT)) & LMEM_PSCLCR_LCMD_MASK) +#define LMEM_PSCLCR_LADSEL_MASK (0x4000000U) +#define LMEM_PSCLCR_LADSEL_SHIFT (26U) +#define LMEM_PSCLCR_LADSEL(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCLCR_LADSEL_SHIFT)) & LMEM_PSCLCR_LADSEL_MASK) +#define LMEM_PSCLCR_LACC_MASK (0x8000000U) +#define LMEM_PSCLCR_LACC_SHIFT (27U) +#define LMEM_PSCLCR_LACC(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCLCR_LACC_SHIFT)) & LMEM_PSCLCR_LACC_MASK) + +/*! @name PSCSAR - Cache search address register */ +#define LMEM_PSCSAR_LGO_MASK (0x1U) +#define LMEM_PSCSAR_LGO_SHIFT (0U) +#define LMEM_PSCSAR_LGO(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCSAR_LGO_SHIFT)) & LMEM_PSCSAR_LGO_MASK) +#define LMEM_PSCSAR_PHYADDR_MASK (0xFFFFFFFCU) +#define LMEM_PSCSAR_PHYADDR_SHIFT (2U) +#define LMEM_PSCSAR_PHYADDR(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCSAR_PHYADDR_SHIFT)) & LMEM_PSCSAR_PHYADDR_MASK) + +/*! @name PSCCVR - Cache read/write value register */ +#define LMEM_PSCCVR_DATA_MASK (0xFFFFFFFFU) +#define LMEM_PSCCVR_DATA_SHIFT (0U) +#define LMEM_PSCCVR_DATA(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCCVR_DATA_SHIFT)) & LMEM_PSCCVR_DATA_MASK) + +/*! @name PSCRMR - Cache regions mode register */ +#define LMEM_PSCRMR_R15_MASK (0x3U) +#define LMEM_PSCRMR_R15_SHIFT (0U) +#define LMEM_PSCRMR_R15(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R15_SHIFT)) & LMEM_PSCRMR_R15_MASK) +#define LMEM_PSCRMR_R14_MASK (0xCU) +#define LMEM_PSCRMR_R14_SHIFT (2U) +#define LMEM_PSCRMR_R14(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R14_SHIFT)) & LMEM_PSCRMR_R14_MASK) +#define LMEM_PSCRMR_R13_MASK (0x30U) +#define LMEM_PSCRMR_R13_SHIFT (4U) +#define LMEM_PSCRMR_R13(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R13_SHIFT)) & LMEM_PSCRMR_R13_MASK) +#define LMEM_PSCRMR_R12_MASK (0xC0U) +#define LMEM_PSCRMR_R12_SHIFT (6U) +#define LMEM_PSCRMR_R12(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R12_SHIFT)) & LMEM_PSCRMR_R12_MASK) +#define LMEM_PSCRMR_R11_MASK (0x300U) +#define LMEM_PSCRMR_R11_SHIFT (8U) +#define LMEM_PSCRMR_R11(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R11_SHIFT)) & LMEM_PSCRMR_R11_MASK) +#define LMEM_PSCRMR_R10_MASK (0xC00U) +#define LMEM_PSCRMR_R10_SHIFT (10U) +#define LMEM_PSCRMR_R10(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R10_SHIFT)) & LMEM_PSCRMR_R10_MASK) +#define LMEM_PSCRMR_R9_MASK (0x3000U) +#define LMEM_PSCRMR_R9_SHIFT (12U) +#define LMEM_PSCRMR_R9(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R9_SHIFT)) & LMEM_PSCRMR_R9_MASK) +#define LMEM_PSCRMR_R8_MASK (0xC000U) +#define LMEM_PSCRMR_R8_SHIFT (14U) +#define LMEM_PSCRMR_R8(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R8_SHIFT)) & LMEM_PSCRMR_R8_MASK) +#define LMEM_PSCRMR_R7_MASK (0x30000U) +#define LMEM_PSCRMR_R7_SHIFT (16U) +#define LMEM_PSCRMR_R7(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R7_SHIFT)) & LMEM_PSCRMR_R7_MASK) +#define LMEM_PSCRMR_R6_MASK (0xC0000U) +#define LMEM_PSCRMR_R6_SHIFT (18U) +#define LMEM_PSCRMR_R6(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R6_SHIFT)) & LMEM_PSCRMR_R6_MASK) +#define LMEM_PSCRMR_R5_MASK (0x300000U) +#define LMEM_PSCRMR_R5_SHIFT (20U) +#define LMEM_PSCRMR_R5(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R5_SHIFT)) & LMEM_PSCRMR_R5_MASK) +#define LMEM_PSCRMR_R4_MASK (0xC00000U) +#define LMEM_PSCRMR_R4_SHIFT (22U) +#define LMEM_PSCRMR_R4(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R4_SHIFT)) & LMEM_PSCRMR_R4_MASK) +#define LMEM_PSCRMR_R3_MASK (0x3000000U) +#define LMEM_PSCRMR_R3_SHIFT (24U) +#define LMEM_PSCRMR_R3(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R3_SHIFT)) & LMEM_PSCRMR_R3_MASK) +#define LMEM_PSCRMR_R2_MASK (0xC000000U) +#define LMEM_PSCRMR_R2_SHIFT (26U) +#define LMEM_PSCRMR_R2(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R2_SHIFT)) & LMEM_PSCRMR_R2_MASK) +#define LMEM_PSCRMR_R1_MASK (0x30000000U) +#define LMEM_PSCRMR_R1_SHIFT (28U) +#define LMEM_PSCRMR_R1(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R1_SHIFT)) & LMEM_PSCRMR_R1_MASK) +#define LMEM_PSCRMR_R0_MASK (0xC0000000U) +#define LMEM_PSCRMR_R0_SHIFT (30U) +#define LMEM_PSCRMR_R0(x) (((uint32_t)(((uint32_t)(x)) << LMEM_PSCRMR_R0_SHIFT)) & LMEM_PSCRMR_R0_MASK) + + +/*! + * @} + */ /* end of group LMEM_Register_Masks */ + + +/* LMEM - Peripheral instance base addresses */ +/** Peripheral LMEM base address */ +#define LMEM_BASE (0xE0082000u) +/** Peripheral LMEM base pointer */ +#define LMEM ((LMEM_Type *)LMEM_BASE) +/** Array initializer of LMEM peripheral base addresses */ +#define LMEM_BASE_ADDRS { LMEM_BASE } +/** Array initializer of LMEM peripheral base pointers */ +#define LMEM_BASE_PTRS { LMEM } + +/*! + * @} + */ /* end of group LMEM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- LPTMR Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LPTMR_Peripheral_Access_Layer LPTMR Peripheral Access Layer + * @{ + */ + +/** LPTMR - Register Layout Typedef */ +typedef struct { + __IO uint32_t CSR; /**< Low Power Timer Control Status Register, offset: 0x0 */ + __IO uint32_t PSR; /**< Low Power Timer Prescale Register, offset: 0x4 */ + __IO uint32_t CMR; /**< Low Power Timer Compare Register, offset: 0x8 */ + __IO uint32_t CNR; /**< Low Power Timer Counter Register, offset: 0xC */ +} LPTMR_Type; + +/* ---------------------------------------------------------------------------- + -- LPTMR Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LPTMR_Register_Masks LPTMR Register Masks + * @{ + */ + +/*! @name CSR - Low Power Timer Control Status Register */ +#define LPTMR_CSR_TEN_MASK (0x1U) +#define LPTMR_CSR_TEN_SHIFT (0U) +#define LPTMR_CSR_TEN(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TEN_SHIFT)) & LPTMR_CSR_TEN_MASK) +#define LPTMR_CSR_TMS_MASK (0x2U) +#define LPTMR_CSR_TMS_SHIFT (1U) +#define LPTMR_CSR_TMS(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TMS_SHIFT)) & LPTMR_CSR_TMS_MASK) +#define LPTMR_CSR_TFC_MASK (0x4U) +#define LPTMR_CSR_TFC_SHIFT (2U) +#define LPTMR_CSR_TFC(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TFC_SHIFT)) & LPTMR_CSR_TFC_MASK) +#define LPTMR_CSR_TPP_MASK (0x8U) +#define LPTMR_CSR_TPP_SHIFT (3U) +#define LPTMR_CSR_TPP(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TPP_SHIFT)) & LPTMR_CSR_TPP_MASK) +#define LPTMR_CSR_TPS_MASK (0x30U) +#define LPTMR_CSR_TPS_SHIFT (4U) +#define LPTMR_CSR_TPS(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TPS_SHIFT)) & LPTMR_CSR_TPS_MASK) +#define LPTMR_CSR_TIE_MASK (0x40U) +#define LPTMR_CSR_TIE_SHIFT (6U) +#define LPTMR_CSR_TIE(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TIE_SHIFT)) & LPTMR_CSR_TIE_MASK) +#define LPTMR_CSR_TCF_MASK (0x80U) +#define LPTMR_CSR_TCF_SHIFT (7U) +#define LPTMR_CSR_TCF(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TCF_SHIFT)) & LPTMR_CSR_TCF_MASK) + +/*! @name PSR - Low Power Timer Prescale Register */ +#define LPTMR_PSR_PCS_MASK (0x3U) +#define LPTMR_PSR_PCS_SHIFT (0U) +#define LPTMR_PSR_PCS(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_PSR_PCS_SHIFT)) & LPTMR_PSR_PCS_MASK) +#define LPTMR_PSR_PBYP_MASK (0x4U) +#define LPTMR_PSR_PBYP_SHIFT (2U) +#define LPTMR_PSR_PBYP(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_PSR_PBYP_SHIFT)) & LPTMR_PSR_PBYP_MASK) +#define LPTMR_PSR_PRESCALE_MASK (0x78U) +#define LPTMR_PSR_PRESCALE_SHIFT (3U) +#define LPTMR_PSR_PRESCALE(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_PSR_PRESCALE_SHIFT)) & LPTMR_PSR_PRESCALE_MASK) + +/*! @name CMR - Low Power Timer Compare Register */ +#define LPTMR_CMR_COMPARE_MASK (0xFFFFU) +#define LPTMR_CMR_COMPARE_SHIFT (0U) +#define LPTMR_CMR_COMPARE(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CMR_COMPARE_SHIFT)) & LPTMR_CMR_COMPARE_MASK) + +/*! @name CNR - Low Power Timer Counter Register */ +#define LPTMR_CNR_COUNTER_MASK (0xFFFFU) +#define LPTMR_CNR_COUNTER_SHIFT (0U) +#define LPTMR_CNR_COUNTER(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CNR_COUNTER_SHIFT)) & LPTMR_CNR_COUNTER_MASK) + + +/*! + * @} + */ /* end of group LPTMR_Register_Masks */ + + +/* LPTMR - Peripheral instance base addresses */ +/** Peripheral LPTMR0 base address */ +#define LPTMR0_BASE (0x40040000u) +/** Peripheral LPTMR0 base pointer */ +#define LPTMR0 ((LPTMR_Type *)LPTMR0_BASE) +/** Peripheral LPTMR1 base address */ +#define LPTMR1_BASE (0x40044000u) +/** Peripheral LPTMR1 base pointer */ +#define LPTMR1 ((LPTMR_Type *)LPTMR1_BASE) +/** Array initializer of LPTMR peripheral base addresses */ +#define LPTMR_BASE_ADDRS { LPTMR0_BASE, LPTMR1_BASE } +/** Array initializer of LPTMR peripheral base pointers */ +#define LPTMR_BASE_PTRS { LPTMR0, LPTMR1 } +/** Interrupt vectors for the LPTMR peripheral type */ +#define LPTMR_IRQS { LPTMR0_LPTMR1_IRQn, LPTMR0_LPTMR1_IRQn } + +/*! + * @} + */ /* end of group LPTMR_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- LPUART Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LPUART_Peripheral_Access_Layer LPUART Peripheral Access Layer + * @{ + */ + +/** LPUART - Register Layout Typedef */ +typedef struct { + __IO uint32_t BAUD; /**< LPUART Baud Rate Register, offset: 0x0 */ + __IO uint32_t STAT; /**< LPUART Status Register, offset: 0x4 */ + __IO uint32_t CTRL; /**< LPUART Control Register, offset: 0x8 */ + __IO uint32_t DATA; /**< LPUART Data Register, offset: 0xC */ + __IO uint32_t MATCH; /**< LPUART Match Address Register, offset: 0x10 */ + __IO uint32_t MODIR; /**< LPUART Modem IrDA Register, offset: 0x14 */ + __IO uint32_t FIFO; /**< LPUART FIFO Register, offset: 0x18 */ + __IO uint32_t WATER; /**< LPUART Watermark Register, offset: 0x1C */ +} LPUART_Type; + +/* ---------------------------------------------------------------------------- + -- LPUART Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LPUART_Register_Masks LPUART Register Masks + * @{ + */ + +/*! @name BAUD - LPUART Baud Rate Register */ +#define LPUART_BAUD_SBR_MASK (0x1FFFU) +#define LPUART_BAUD_SBR_SHIFT (0U) +#define LPUART_BAUD_SBR(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_SBR_SHIFT)) & LPUART_BAUD_SBR_MASK) +#define LPUART_BAUD_SBNS_MASK (0x2000U) +#define LPUART_BAUD_SBNS_SHIFT (13U) +#define LPUART_BAUD_SBNS(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_SBNS_SHIFT)) & LPUART_BAUD_SBNS_MASK) +#define LPUART_BAUD_RXEDGIE_MASK (0x4000U) +#define LPUART_BAUD_RXEDGIE_SHIFT (14U) +#define LPUART_BAUD_RXEDGIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_RXEDGIE_SHIFT)) & LPUART_BAUD_RXEDGIE_MASK) +#define LPUART_BAUD_LBKDIE_MASK (0x8000U) +#define LPUART_BAUD_LBKDIE_SHIFT (15U) +#define LPUART_BAUD_LBKDIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_LBKDIE_SHIFT)) & LPUART_BAUD_LBKDIE_MASK) +#define LPUART_BAUD_RESYNCDIS_MASK (0x10000U) +#define LPUART_BAUD_RESYNCDIS_SHIFT (16U) +#define LPUART_BAUD_RESYNCDIS(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_RESYNCDIS_SHIFT)) & LPUART_BAUD_RESYNCDIS_MASK) +#define LPUART_BAUD_BOTHEDGE_MASK (0x20000U) +#define LPUART_BAUD_BOTHEDGE_SHIFT (17U) +#define LPUART_BAUD_BOTHEDGE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_BOTHEDGE_SHIFT)) & LPUART_BAUD_BOTHEDGE_MASK) +#define LPUART_BAUD_MATCFG_MASK (0xC0000U) +#define LPUART_BAUD_MATCFG_SHIFT (18U) +#define LPUART_BAUD_MATCFG(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_MATCFG_SHIFT)) & LPUART_BAUD_MATCFG_MASK) +#define LPUART_BAUD_RDMAE_MASK (0x200000U) +#define LPUART_BAUD_RDMAE_SHIFT (21U) +#define LPUART_BAUD_RDMAE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_RDMAE_SHIFT)) & LPUART_BAUD_RDMAE_MASK) +#define LPUART_BAUD_TDMAE_MASK (0x800000U) +#define LPUART_BAUD_TDMAE_SHIFT (23U) +#define LPUART_BAUD_TDMAE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_TDMAE_SHIFT)) & LPUART_BAUD_TDMAE_MASK) +#define LPUART_BAUD_OSR_MASK (0x1F000000U) +#define LPUART_BAUD_OSR_SHIFT (24U) +#define LPUART_BAUD_OSR(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_OSR_SHIFT)) & LPUART_BAUD_OSR_MASK) +#define LPUART_BAUD_M10_MASK (0x20000000U) +#define LPUART_BAUD_M10_SHIFT (29U) +#define LPUART_BAUD_M10(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_M10_SHIFT)) & LPUART_BAUD_M10_MASK) +#define LPUART_BAUD_MAEN2_MASK (0x40000000U) +#define LPUART_BAUD_MAEN2_SHIFT (30U) +#define LPUART_BAUD_MAEN2(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_MAEN2_SHIFT)) & LPUART_BAUD_MAEN2_MASK) +#define LPUART_BAUD_MAEN1_MASK (0x80000000U) +#define LPUART_BAUD_MAEN1_SHIFT (31U) +#define LPUART_BAUD_MAEN1(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_MAEN1_SHIFT)) & LPUART_BAUD_MAEN1_MASK) + +/*! @name STAT - LPUART Status Register */ +#define LPUART_STAT_MA2F_MASK (0x4000U) +#define LPUART_STAT_MA2F_SHIFT (14U) +#define LPUART_STAT_MA2F(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_MA2F_SHIFT)) & LPUART_STAT_MA2F_MASK) +#define LPUART_STAT_MA1F_MASK (0x8000U) +#define LPUART_STAT_MA1F_SHIFT (15U) +#define LPUART_STAT_MA1F(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_MA1F_SHIFT)) & LPUART_STAT_MA1F_MASK) +#define LPUART_STAT_PF_MASK (0x10000U) +#define LPUART_STAT_PF_SHIFT (16U) +#define LPUART_STAT_PF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_PF_SHIFT)) & LPUART_STAT_PF_MASK) +#define LPUART_STAT_FE_MASK (0x20000U) +#define LPUART_STAT_FE_SHIFT (17U) +#define LPUART_STAT_FE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_FE_SHIFT)) & LPUART_STAT_FE_MASK) +#define LPUART_STAT_NF_MASK (0x40000U) +#define LPUART_STAT_NF_SHIFT (18U) +#define LPUART_STAT_NF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_NF_SHIFT)) & LPUART_STAT_NF_MASK) +#define LPUART_STAT_OR_MASK (0x80000U) +#define LPUART_STAT_OR_SHIFT (19U) +#define LPUART_STAT_OR(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_OR_SHIFT)) & LPUART_STAT_OR_MASK) +#define LPUART_STAT_IDLE_MASK (0x100000U) +#define LPUART_STAT_IDLE_SHIFT (20U) +#define LPUART_STAT_IDLE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_IDLE_SHIFT)) & LPUART_STAT_IDLE_MASK) +#define LPUART_STAT_RDRF_MASK (0x200000U) +#define LPUART_STAT_RDRF_SHIFT (21U) +#define LPUART_STAT_RDRF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_RDRF_SHIFT)) & LPUART_STAT_RDRF_MASK) +#define LPUART_STAT_TC_MASK (0x400000U) +#define LPUART_STAT_TC_SHIFT (22U) +#define LPUART_STAT_TC(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_TC_SHIFT)) & LPUART_STAT_TC_MASK) +#define LPUART_STAT_TDRE_MASK (0x800000U) +#define LPUART_STAT_TDRE_SHIFT (23U) +#define LPUART_STAT_TDRE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_TDRE_SHIFT)) & LPUART_STAT_TDRE_MASK) +#define LPUART_STAT_RAF_MASK (0x1000000U) +#define LPUART_STAT_RAF_SHIFT (24U) +#define LPUART_STAT_RAF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_RAF_SHIFT)) & LPUART_STAT_RAF_MASK) +#define LPUART_STAT_LBKDE_MASK (0x2000000U) +#define LPUART_STAT_LBKDE_SHIFT (25U) +#define LPUART_STAT_LBKDE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_LBKDE_SHIFT)) & LPUART_STAT_LBKDE_MASK) +#define LPUART_STAT_BRK13_MASK (0x4000000U) +#define LPUART_STAT_BRK13_SHIFT (26U) +#define LPUART_STAT_BRK13(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_BRK13_SHIFT)) & LPUART_STAT_BRK13_MASK) +#define LPUART_STAT_RWUID_MASK (0x8000000U) +#define LPUART_STAT_RWUID_SHIFT (27U) +#define LPUART_STAT_RWUID(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_RWUID_SHIFT)) & LPUART_STAT_RWUID_MASK) +#define LPUART_STAT_RXINV_MASK (0x10000000U) +#define LPUART_STAT_RXINV_SHIFT (28U) +#define LPUART_STAT_RXINV(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_RXINV_SHIFT)) & LPUART_STAT_RXINV_MASK) +#define LPUART_STAT_MSBF_MASK (0x20000000U) +#define LPUART_STAT_MSBF_SHIFT (29U) +#define LPUART_STAT_MSBF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_MSBF_SHIFT)) & LPUART_STAT_MSBF_MASK) +#define LPUART_STAT_RXEDGIF_MASK (0x40000000U) +#define LPUART_STAT_RXEDGIF_SHIFT (30U) +#define LPUART_STAT_RXEDGIF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_RXEDGIF_SHIFT)) & LPUART_STAT_RXEDGIF_MASK) +#define LPUART_STAT_LBKDIF_MASK (0x80000000U) +#define LPUART_STAT_LBKDIF_SHIFT (31U) +#define LPUART_STAT_LBKDIF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_LBKDIF_SHIFT)) & LPUART_STAT_LBKDIF_MASK) + +/*! @name CTRL - LPUART Control Register */ +#define LPUART_CTRL_PT_MASK (0x1U) +#define LPUART_CTRL_PT_SHIFT (0U) +#define LPUART_CTRL_PT(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_PT_SHIFT)) & LPUART_CTRL_PT_MASK) +#define LPUART_CTRL_PE_MASK (0x2U) +#define LPUART_CTRL_PE_SHIFT (1U) +#define LPUART_CTRL_PE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_PE_SHIFT)) & LPUART_CTRL_PE_MASK) +#define LPUART_CTRL_ILT_MASK (0x4U) +#define LPUART_CTRL_ILT_SHIFT (2U) +#define LPUART_CTRL_ILT(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_ILT_SHIFT)) & LPUART_CTRL_ILT_MASK) +#define LPUART_CTRL_WAKE_MASK (0x8U) +#define LPUART_CTRL_WAKE_SHIFT (3U) +#define LPUART_CTRL_WAKE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_WAKE_SHIFT)) & LPUART_CTRL_WAKE_MASK) +#define LPUART_CTRL_M_MASK (0x10U) +#define LPUART_CTRL_M_SHIFT (4U) +#define LPUART_CTRL_M(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_M_SHIFT)) & LPUART_CTRL_M_MASK) +#define LPUART_CTRL_RSRC_MASK (0x20U) +#define LPUART_CTRL_RSRC_SHIFT (5U) +#define LPUART_CTRL_RSRC(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_RSRC_SHIFT)) & LPUART_CTRL_RSRC_MASK) +#define LPUART_CTRL_DOZEEN_MASK (0x40U) +#define LPUART_CTRL_DOZEEN_SHIFT (6U) +#define LPUART_CTRL_DOZEEN(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_DOZEEN_SHIFT)) & LPUART_CTRL_DOZEEN_MASK) +#define LPUART_CTRL_LOOPS_MASK (0x80U) +#define LPUART_CTRL_LOOPS_SHIFT (7U) +#define LPUART_CTRL_LOOPS(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_LOOPS_SHIFT)) & LPUART_CTRL_LOOPS_MASK) +#define LPUART_CTRL_IDLECFG_MASK (0x700U) +#define LPUART_CTRL_IDLECFG_SHIFT (8U) +#define LPUART_CTRL_IDLECFG(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_IDLECFG_SHIFT)) & LPUART_CTRL_IDLECFG_MASK) +#define LPUART_CTRL_MA2IE_MASK (0x4000U) +#define LPUART_CTRL_MA2IE_SHIFT (14U) +#define LPUART_CTRL_MA2IE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_MA2IE_SHIFT)) & LPUART_CTRL_MA2IE_MASK) +#define LPUART_CTRL_MA1IE_MASK (0x8000U) +#define LPUART_CTRL_MA1IE_SHIFT (15U) +#define LPUART_CTRL_MA1IE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_MA1IE_SHIFT)) & LPUART_CTRL_MA1IE_MASK) +#define LPUART_CTRL_SBK_MASK (0x10000U) +#define LPUART_CTRL_SBK_SHIFT (16U) +#define LPUART_CTRL_SBK(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_SBK_SHIFT)) & LPUART_CTRL_SBK_MASK) +#define LPUART_CTRL_RWU_MASK (0x20000U) +#define LPUART_CTRL_RWU_SHIFT (17U) +#define LPUART_CTRL_RWU(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_RWU_SHIFT)) & LPUART_CTRL_RWU_MASK) +#define LPUART_CTRL_RE_MASK (0x40000U) +#define LPUART_CTRL_RE_SHIFT (18U) +#define LPUART_CTRL_RE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_RE_SHIFT)) & LPUART_CTRL_RE_MASK) +#define LPUART_CTRL_TE_MASK (0x80000U) +#define LPUART_CTRL_TE_SHIFT (19U) +#define LPUART_CTRL_TE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_TE_SHIFT)) & LPUART_CTRL_TE_MASK) +#define LPUART_CTRL_ILIE_MASK (0x100000U) +#define LPUART_CTRL_ILIE_SHIFT (20U) +#define LPUART_CTRL_ILIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_ILIE_SHIFT)) & LPUART_CTRL_ILIE_MASK) +#define LPUART_CTRL_RIE_MASK (0x200000U) +#define LPUART_CTRL_RIE_SHIFT (21U) +#define LPUART_CTRL_RIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_RIE_SHIFT)) & LPUART_CTRL_RIE_MASK) +#define LPUART_CTRL_TCIE_MASK (0x400000U) +#define LPUART_CTRL_TCIE_SHIFT (22U) +#define LPUART_CTRL_TCIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_TCIE_SHIFT)) & LPUART_CTRL_TCIE_MASK) +#define LPUART_CTRL_TIE_MASK (0x800000U) +#define LPUART_CTRL_TIE_SHIFT (23U) +#define LPUART_CTRL_TIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_TIE_SHIFT)) & LPUART_CTRL_TIE_MASK) +#define LPUART_CTRL_PEIE_MASK (0x1000000U) +#define LPUART_CTRL_PEIE_SHIFT (24U) +#define LPUART_CTRL_PEIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_PEIE_SHIFT)) & LPUART_CTRL_PEIE_MASK) +#define LPUART_CTRL_FEIE_MASK (0x2000000U) +#define LPUART_CTRL_FEIE_SHIFT (25U) +#define LPUART_CTRL_FEIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_FEIE_SHIFT)) & LPUART_CTRL_FEIE_MASK) +#define LPUART_CTRL_NEIE_MASK (0x4000000U) +#define LPUART_CTRL_NEIE_SHIFT (26U) +#define LPUART_CTRL_NEIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_NEIE_SHIFT)) & LPUART_CTRL_NEIE_MASK) +#define LPUART_CTRL_ORIE_MASK (0x8000000U) +#define LPUART_CTRL_ORIE_SHIFT (27U) +#define LPUART_CTRL_ORIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_ORIE_SHIFT)) & LPUART_CTRL_ORIE_MASK) +#define LPUART_CTRL_TXINV_MASK (0x10000000U) +#define LPUART_CTRL_TXINV_SHIFT (28U) +#define LPUART_CTRL_TXINV(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_TXINV_SHIFT)) & LPUART_CTRL_TXINV_MASK) +#define LPUART_CTRL_TXDIR_MASK (0x20000000U) +#define LPUART_CTRL_TXDIR_SHIFT (29U) +#define LPUART_CTRL_TXDIR(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_TXDIR_SHIFT)) & LPUART_CTRL_TXDIR_MASK) +#define LPUART_CTRL_R9T8_MASK (0x40000000U) +#define LPUART_CTRL_R9T8_SHIFT (30U) +#define LPUART_CTRL_R9T8(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_R9T8_SHIFT)) & LPUART_CTRL_R9T8_MASK) +#define LPUART_CTRL_R8T9_MASK (0x80000000U) +#define LPUART_CTRL_R8T9_SHIFT (31U) +#define LPUART_CTRL_R8T9(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_R8T9_SHIFT)) & LPUART_CTRL_R8T9_MASK) + +/*! @name DATA - LPUART Data Register */ +#define LPUART_DATA_R0T0_MASK (0x1U) +#define LPUART_DATA_R0T0_SHIFT (0U) +#define LPUART_DATA_R0T0(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R0T0_SHIFT)) & LPUART_DATA_R0T0_MASK) +#define LPUART_DATA_R1T1_MASK (0x2U) +#define LPUART_DATA_R1T1_SHIFT (1U) +#define LPUART_DATA_R1T1(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R1T1_SHIFT)) & LPUART_DATA_R1T1_MASK) +#define LPUART_DATA_R2T2_MASK (0x4U) +#define LPUART_DATA_R2T2_SHIFT (2U) +#define LPUART_DATA_R2T2(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R2T2_SHIFT)) & LPUART_DATA_R2T2_MASK) +#define LPUART_DATA_R3T3_MASK (0x8U) +#define LPUART_DATA_R3T3_SHIFT (3U) +#define LPUART_DATA_R3T3(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R3T3_SHIFT)) & LPUART_DATA_R3T3_MASK) +#define LPUART_DATA_R4T4_MASK (0x10U) +#define LPUART_DATA_R4T4_SHIFT (4U) +#define LPUART_DATA_R4T4(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R4T4_SHIFT)) & LPUART_DATA_R4T4_MASK) +#define LPUART_DATA_R5T5_MASK (0x20U) +#define LPUART_DATA_R5T5_SHIFT (5U) +#define LPUART_DATA_R5T5(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R5T5_SHIFT)) & LPUART_DATA_R5T5_MASK) +#define LPUART_DATA_R6T6_MASK (0x40U) +#define LPUART_DATA_R6T6_SHIFT (6U) +#define LPUART_DATA_R6T6(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R6T6_SHIFT)) & LPUART_DATA_R6T6_MASK) +#define LPUART_DATA_R7T7_MASK (0x80U) +#define LPUART_DATA_R7T7_SHIFT (7U) +#define LPUART_DATA_R7T7(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R7T7_SHIFT)) & LPUART_DATA_R7T7_MASK) +#define LPUART_DATA_R8T8_MASK (0x100U) +#define LPUART_DATA_R8T8_SHIFT (8U) +#define LPUART_DATA_R8T8(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R8T8_SHIFT)) & LPUART_DATA_R8T8_MASK) +#define LPUART_DATA_R9T9_MASK (0x200U) +#define LPUART_DATA_R9T9_SHIFT (9U) +#define LPUART_DATA_R9T9(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R9T9_SHIFT)) & LPUART_DATA_R9T9_MASK) +#define LPUART_DATA_IDLINE_MASK (0x800U) +#define LPUART_DATA_IDLINE_SHIFT (11U) +#define LPUART_DATA_IDLINE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_IDLINE_SHIFT)) & LPUART_DATA_IDLINE_MASK) +#define LPUART_DATA_RXEMPT_MASK (0x1000U) +#define LPUART_DATA_RXEMPT_SHIFT (12U) +#define LPUART_DATA_RXEMPT(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_RXEMPT_SHIFT)) & LPUART_DATA_RXEMPT_MASK) +#define LPUART_DATA_FRETSC_MASK (0x2000U) +#define LPUART_DATA_FRETSC_SHIFT (13U) +#define LPUART_DATA_FRETSC(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_FRETSC_SHIFT)) & LPUART_DATA_FRETSC_MASK) +#define LPUART_DATA_PARITYE_MASK (0x4000U) +#define LPUART_DATA_PARITYE_SHIFT (14U) +#define LPUART_DATA_PARITYE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_PARITYE_SHIFT)) & LPUART_DATA_PARITYE_MASK) +#define LPUART_DATA_NOISY_MASK (0x8000U) +#define LPUART_DATA_NOISY_SHIFT (15U) +#define LPUART_DATA_NOISY(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_NOISY_SHIFT)) & LPUART_DATA_NOISY_MASK) + +/*! @name MATCH - LPUART Match Address Register */ +#define LPUART_MATCH_MA1_MASK (0x3FFU) +#define LPUART_MATCH_MA1_SHIFT (0U) +#define LPUART_MATCH_MA1(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MATCH_MA1_SHIFT)) & LPUART_MATCH_MA1_MASK) +#define LPUART_MATCH_MA2_MASK (0x3FF0000U) +#define LPUART_MATCH_MA2_SHIFT (16U) +#define LPUART_MATCH_MA2(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MATCH_MA2_SHIFT)) & LPUART_MATCH_MA2_MASK) + +/*! @name MODIR - LPUART Modem IrDA Register */ +#define LPUART_MODIR_TXCTSE_MASK (0x1U) +#define LPUART_MODIR_TXCTSE_SHIFT (0U) +#define LPUART_MODIR_TXCTSE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MODIR_TXCTSE_SHIFT)) & LPUART_MODIR_TXCTSE_MASK) +#define LPUART_MODIR_TXRTSE_MASK (0x2U) +#define LPUART_MODIR_TXRTSE_SHIFT (1U) +#define LPUART_MODIR_TXRTSE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MODIR_TXRTSE_SHIFT)) & LPUART_MODIR_TXRTSE_MASK) +#define LPUART_MODIR_TXRTSPOL_MASK (0x4U) +#define LPUART_MODIR_TXRTSPOL_SHIFT (2U) +#define LPUART_MODIR_TXRTSPOL(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MODIR_TXRTSPOL_SHIFT)) & LPUART_MODIR_TXRTSPOL_MASK) +#define LPUART_MODIR_RXRTSE_MASK (0x8U) +#define LPUART_MODIR_RXRTSE_SHIFT (3U) +#define LPUART_MODIR_RXRTSE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MODIR_RXRTSE_SHIFT)) & LPUART_MODIR_RXRTSE_MASK) +#define LPUART_MODIR_TXCTSC_MASK (0x10U) +#define LPUART_MODIR_TXCTSC_SHIFT (4U) +#define LPUART_MODIR_TXCTSC(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MODIR_TXCTSC_SHIFT)) & LPUART_MODIR_TXCTSC_MASK) +#define LPUART_MODIR_TXCTSSRC_MASK (0x20U) +#define LPUART_MODIR_TXCTSSRC_SHIFT (5U) +#define LPUART_MODIR_TXCTSSRC(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MODIR_TXCTSSRC_SHIFT)) & LPUART_MODIR_TXCTSSRC_MASK) +#define LPUART_MODIR_RTSWATER_MASK (0xFF00U) +#define LPUART_MODIR_RTSWATER_SHIFT (8U) +#define LPUART_MODIR_RTSWATER(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MODIR_RTSWATER_SHIFT)) & LPUART_MODIR_RTSWATER_MASK) +#define LPUART_MODIR_TNP_MASK (0x30000U) +#define LPUART_MODIR_TNP_SHIFT (16U) +#define LPUART_MODIR_TNP(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MODIR_TNP_SHIFT)) & LPUART_MODIR_TNP_MASK) +#define LPUART_MODIR_IREN_MASK (0x40000U) +#define LPUART_MODIR_IREN_SHIFT (18U) +#define LPUART_MODIR_IREN(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MODIR_IREN_SHIFT)) & LPUART_MODIR_IREN_MASK) + +/*! @name FIFO - LPUART FIFO Register */ +#define LPUART_FIFO_RXFIFOSIZE_MASK (0x7U) +#define LPUART_FIFO_RXFIFOSIZE_SHIFT (0U) +#define LPUART_FIFO_RXFIFOSIZE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_RXFIFOSIZE_SHIFT)) & LPUART_FIFO_RXFIFOSIZE_MASK) +#define LPUART_FIFO_RXFE_MASK (0x8U) +#define LPUART_FIFO_RXFE_SHIFT (3U) +#define LPUART_FIFO_RXFE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_RXFE_SHIFT)) & LPUART_FIFO_RXFE_MASK) +#define LPUART_FIFO_TXFIFOSIZE_MASK (0x70U) +#define LPUART_FIFO_TXFIFOSIZE_SHIFT (4U) +#define LPUART_FIFO_TXFIFOSIZE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_TXFIFOSIZE_SHIFT)) & LPUART_FIFO_TXFIFOSIZE_MASK) +#define LPUART_FIFO_TXFE_MASK (0x80U) +#define LPUART_FIFO_TXFE_SHIFT (7U) +#define LPUART_FIFO_TXFE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_TXFE_SHIFT)) & LPUART_FIFO_TXFE_MASK) +#define LPUART_FIFO_RXUFE_MASK (0x100U) +#define LPUART_FIFO_RXUFE_SHIFT (8U) +#define LPUART_FIFO_RXUFE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_RXUFE_SHIFT)) & LPUART_FIFO_RXUFE_MASK) +#define LPUART_FIFO_TXOFE_MASK (0x200U) +#define LPUART_FIFO_TXOFE_SHIFT (9U) +#define LPUART_FIFO_TXOFE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_TXOFE_SHIFT)) & LPUART_FIFO_TXOFE_MASK) +#define LPUART_FIFO_RXIDEN_MASK (0x1C00U) +#define LPUART_FIFO_RXIDEN_SHIFT (10U) +#define LPUART_FIFO_RXIDEN(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_RXIDEN_SHIFT)) & LPUART_FIFO_RXIDEN_MASK) +#define LPUART_FIFO_RXFLUSH_MASK (0x4000U) +#define LPUART_FIFO_RXFLUSH_SHIFT (14U) +#define LPUART_FIFO_RXFLUSH(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_RXFLUSH_SHIFT)) & LPUART_FIFO_RXFLUSH_MASK) +#define LPUART_FIFO_TXFLUSH_MASK (0x8000U) +#define LPUART_FIFO_TXFLUSH_SHIFT (15U) +#define LPUART_FIFO_TXFLUSH(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_TXFLUSH_SHIFT)) & LPUART_FIFO_TXFLUSH_MASK) +#define LPUART_FIFO_RXUF_MASK (0x10000U) +#define LPUART_FIFO_RXUF_SHIFT (16U) +#define LPUART_FIFO_RXUF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_RXUF_SHIFT)) & LPUART_FIFO_RXUF_MASK) +#define LPUART_FIFO_TXOF_MASK (0x20000U) +#define LPUART_FIFO_TXOF_SHIFT (17U) +#define LPUART_FIFO_TXOF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_TXOF_SHIFT)) & LPUART_FIFO_TXOF_MASK) +#define LPUART_FIFO_RXEMPT_MASK (0x400000U) +#define LPUART_FIFO_RXEMPT_SHIFT (22U) +#define LPUART_FIFO_RXEMPT(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_RXEMPT_SHIFT)) & LPUART_FIFO_RXEMPT_MASK) +#define LPUART_FIFO_TXEMPT_MASK (0x800000U) +#define LPUART_FIFO_TXEMPT_SHIFT (23U) +#define LPUART_FIFO_TXEMPT(x) (((uint32_t)(((uint32_t)(x)) << LPUART_FIFO_TXEMPT_SHIFT)) & LPUART_FIFO_TXEMPT_MASK) + +/*! @name WATER - LPUART Watermark Register */ +#define LPUART_WATER_TXWATER_MASK (0xFFU) +#define LPUART_WATER_TXWATER_SHIFT (0U) +#define LPUART_WATER_TXWATER(x) (((uint32_t)(((uint32_t)(x)) << LPUART_WATER_TXWATER_SHIFT)) & LPUART_WATER_TXWATER_MASK) +#define LPUART_WATER_TXCOUNT_MASK (0xFF00U) +#define LPUART_WATER_TXCOUNT_SHIFT (8U) +#define LPUART_WATER_TXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << LPUART_WATER_TXCOUNT_SHIFT)) & LPUART_WATER_TXCOUNT_MASK) +#define LPUART_WATER_RXWATER_MASK (0xFF0000U) +#define LPUART_WATER_RXWATER_SHIFT (16U) +#define LPUART_WATER_RXWATER(x) (((uint32_t)(((uint32_t)(x)) << LPUART_WATER_RXWATER_SHIFT)) & LPUART_WATER_RXWATER_MASK) +#define LPUART_WATER_RXCOUNT_MASK (0xFF000000U) +#define LPUART_WATER_RXCOUNT_SHIFT (24U) +#define LPUART_WATER_RXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << LPUART_WATER_RXCOUNT_SHIFT)) & LPUART_WATER_RXCOUNT_MASK) + + +/*! + * @} + */ /* end of group LPUART_Register_Masks */ + + +/* LPUART - Peripheral instance base addresses */ +/** Peripheral LPUART0 base address */ +#define LPUART0_BASE (0x400C4000u) +/** Peripheral LPUART0 base pointer */ +#define LPUART0 ((LPUART_Type *)LPUART0_BASE) +/** Peripheral LPUART1 base address */ +#define LPUART1_BASE (0x400C5000u) +/** Peripheral LPUART1 base pointer */ +#define LPUART1 ((LPUART_Type *)LPUART1_BASE) +/** Peripheral LPUART2 base address */ +#define LPUART2_BASE (0x400C6000u) +/** Peripheral LPUART2 base pointer */ +#define LPUART2 ((LPUART_Type *)LPUART2_BASE) +/** Peripheral LPUART3 base address */ +#define LPUART3_BASE (0x400C7000u) +/** Peripheral LPUART3 base pointer */ +#define LPUART3 ((LPUART_Type *)LPUART3_BASE) +/** Peripheral LPUART4 base address */ +#define LPUART4_BASE (0x400D6000u) +/** Peripheral LPUART4 base pointer */ +#define LPUART4 ((LPUART_Type *)LPUART4_BASE) +/** Array initializer of LPUART peripheral base addresses */ +#define LPUART_BASE_ADDRS { LPUART0_BASE, LPUART1_BASE, LPUART2_BASE, LPUART3_BASE, LPUART4_BASE } +/** Array initializer of LPUART peripheral base pointers */ +#define LPUART_BASE_PTRS { LPUART0, LPUART1, LPUART2, LPUART3, LPUART4 } +/** Interrupt vectors for the LPUART peripheral type */ +#define LPUART_RX_TX_IRQS { LPUART0_IRQn, LPUART1_IRQn, LPUART2_IRQn, LPUART3_IRQn, LPUART4_IRQn } +#define LPUART_ERR_IRQS { LPUART0_IRQn, LPUART1_IRQn, LPUART2_IRQn, LPUART3_IRQn, LPUART4_IRQn } + +/*! + * @} + */ /* end of group LPUART_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- LTC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LTC_Peripheral_Access_Layer LTC Peripheral Access Layer + * @{ + */ + +/** LTC - Register Layout Typedef */ +typedef struct { + union { /* offset: 0x0 */ + __IO uint32_t MD; /**< LTC Mode Register (non-PKHA/non-RNG use), offset: 0x0 */ + __IO uint32_t MDPK; /**< LTC Mode Register (PublicKey), offset: 0x0 */ + }; + uint8_t RESERVED_0[4]; + __IO uint32_t KS; /**< LTC Key Size Register, offset: 0x8 */ + uint8_t RESERVED_1[4]; + __IO uint32_t DS; /**< LTC Data Size Register, offset: 0x10 */ + uint8_t RESERVED_2[4]; + __IO uint32_t ICVS; /**< LTC ICV Size Register, offset: 0x18 */ + uint8_t RESERVED_3[20]; + __IO uint32_t COM; /**< LTC Command Register, offset: 0x30 */ + __IO uint32_t CTL; /**< LTC Control Register, offset: 0x34 */ + uint8_t RESERVED_4[8]; + __IO uint32_t CW; /**< LTC Clear Written Register, offset: 0x40 */ + uint8_t RESERVED_5[4]; + __IO uint32_t STA; /**< LTC Status Register, offset: 0x48 */ + __I uint32_t ESTA; /**< LTC Error Status Register, offset: 0x4C */ + uint8_t RESERVED_6[8]; + __IO uint32_t AADSZ; /**< LTC AAD Size Register, offset: 0x58 */ + uint8_t RESERVED_7[4]; + __IO uint32_t IVSZ; /**< LTC IV Size Register, offset: 0x60 */ + uint8_t RESERVED_8[4]; + __O uint32_t DPAMS; /**< LTC DPA Mask Seed Register, offset: 0x68 */ + uint8_t RESERVED_9[20]; + __IO uint32_t PKASZ; /**< LTC PKHA A Size Register, offset: 0x80 */ + uint8_t RESERVED_10[4]; + __IO uint32_t PKBSZ; /**< LTC PKHA B Size Register, offset: 0x88 */ + uint8_t RESERVED_11[4]; + __IO uint32_t PKNSZ; /**< LTC PKHA N Size Register, offset: 0x90 */ + uint8_t RESERVED_12[4]; + __IO uint32_t PKESZ; /**< LTC PKHA E Size Register, offset: 0x98 */ + uint8_t RESERVED_13[100]; + __IO uint32_t CTX[16]; /**< LTC Context Register, array offset: 0x100, array step: 0x4 */ + uint8_t RESERVED_14[192]; + __IO uint32_t KEY[8]; /**< LTC Key Registers, array offset: 0x200, array step: 0x4 */ + uint8_t RESERVED_15[720]; + __I uint32_t VID1; /**< LTC Version ID Register, offset: 0x4F0 */ + uint8_t RESERVED_16[4]; + __I uint32_t CHAVID; /**< LTC CHA Version ID Register, offset: 0x4F8 */ + uint8_t RESERVED_17[708]; + __I uint32_t FIFOSTA; /**< LTC FIFO Status Register, offset: 0x7C0 */ + uint8_t RESERVED_18[28]; + __O uint32_t IFIFO; /**< LTC Input Data FIFO, offset: 0x7E0 */ + uint8_t RESERVED_19[12]; + __I uint32_t OFIFO; /**< LTC Output Data FIFO, offset: 0x7F0 */ + uint8_t RESERVED_20[12]; + union { /* offset: 0x800 */ + __IO uint32_t PKA[64]; /**< LTC PKHA A 0 Register..LTC PKHA A 63 Register, array offset: 0x800, array step: 0x4 */ + struct { /* offset: 0x800 */ + __IO uint32_t PKA0[16]; /**< LTC PKHA A0 0 Register..LTC PKHA A0 15 Register, array offset: 0x800, array step: 0x4 */ + __IO uint32_t PKA1[16]; /**< LTC PKHA A1 0 Register..LTC PKHA A1 15 Register, array offset: 0x840, array step: 0x4 */ + __IO uint32_t PKA2[16]; /**< LTC PKHA A2 0 Register..LTC PKHA A2 15 Register, array offset: 0x880, array step: 0x4 */ + __IO uint32_t PKA3[16]; /**< LTC PKHA A3 0 Register..LTC PKHA A3 15 Register, array offset: 0x8C0, array step: 0x4 */ + } PKA_SHORT; + }; + uint8_t RESERVED_21[256]; + union { /* offset: 0xA00 */ + __IO uint32_t PKB[64]; /**< LTC PKHA B 0 Register..LTC PKHA B 63 Register, array offset: 0xA00, array step: 0x4 */ + struct { /* offset: 0xA00 */ + __IO uint32_t PKB0[16]; /**< LTC PKHA B0 0 Register..LTC PKHA B0 15 Register, array offset: 0xA00, array step: 0x4 */ + __IO uint32_t PKB1[16]; /**< LTC PKHA B1 0 Register..LTC PKHA B1 15 Register, array offset: 0xA40, array step: 0x4 */ + __IO uint32_t PKB2[16]; /**< LTC PKHA B2 0 Register..LTC PKHA B2 15 Register, array offset: 0xA80, array step: 0x4 */ + __IO uint32_t PKB3[16]; /**< LTC PKHA B3 0 Register..LTC PKHA B3 15 Register, array offset: 0xAC0, array step: 0x4 */ + } PKB_SHORT; + }; + uint8_t RESERVED_22[256]; + union { /* offset: 0xC00 */ + __IO uint32_t PKN[64]; /**< LTC PKHA N 0 Register..LTC PKHA N 63 Register, array offset: 0xC00, array step: 0x4 */ + struct { /* offset: 0xC00 */ + __IO uint32_t PKN0[16]; /**< LTC PKHA N0 0 Register..LTC PKHA N0 15 Register, array offset: 0xC00, array step: 0x4 */ + __IO uint32_t PKN1[16]; /**< LTC PKHA N1 0 Register..LTC PKHA N1 15 Register, array offset: 0xC40, array step: 0x4 */ + __IO uint32_t PKN2[16]; /**< LTC PKHA N2 0 Register..LTC PKHA N2 15 Register, array offset: 0xC80, array step: 0x4 */ + __IO uint32_t PKN3[16]; /**< LTC PKHA N3 0 Register..LTC PKHA N3 15 Register, array offset: 0xCC0, array step: 0x4 */ + } PKN_SHORT; + }; + uint8_t RESERVED_23[256]; + union { /* offset: 0xE00 */ + __IO uint32_t PKE[64]; /**< LTC PKHA E 0 Register..LTC PKHA E 63 Register, array offset: 0xE00, array step: 0x4 */ + struct { /* offset: 0xE00 */ + __IO uint32_t PKE0[16]; /**< LTC PKHA E0 0 Register..LTC PKHA E0 15 Register, array offset: 0xE00, array step: 0x4 */ + __IO uint32_t PKE1[16]; /**< LTC PKHA E1 0 Register..LTC PKHA E1 15 Register, array offset: 0xE40, array step: 0x4 */ + __IO uint32_t PKE2[16]; /**< LTC PKHA E2 0 Register..LTC PKHA E2 15 Register, array offset: 0xE80, array step: 0x4 */ + __IO uint32_t PKE3[16]; /**< LTC PKHA E3 0 Register..LTC PKHA E3 15 Register, array offset: 0xEC0, array step: 0x4 */ + } PKE_SHORT; + }; +} LTC_Type; + +/* ---------------------------------------------------------------------------- + -- LTC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LTC_Register_Masks LTC Register Masks + * @{ + */ + +/*! @name MD - LTC Mode Register (non-PKHA/non-RNG use) */ +#define LTC_MD_ENC_MASK (0x1U) +#define LTC_MD_ENC_SHIFT (0U) +#define LTC_MD_ENC(x) (((uint32_t)(((uint32_t)(x)) << LTC_MD_ENC_SHIFT)) & LTC_MD_ENC_MASK) +#define LTC_MD_ICV_TEST_MASK (0x2U) +#define LTC_MD_ICV_TEST_SHIFT (1U) +#define LTC_MD_ICV_TEST(x) (((uint32_t)(((uint32_t)(x)) << LTC_MD_ICV_TEST_SHIFT)) & LTC_MD_ICV_TEST_MASK) +#define LTC_MD_AS_MASK (0xCU) +#define LTC_MD_AS_SHIFT (2U) +#define LTC_MD_AS(x) (((uint32_t)(((uint32_t)(x)) << LTC_MD_AS_SHIFT)) & LTC_MD_AS_MASK) +#define LTC_MD_AAI_MASK (0x1FF0U) +#define LTC_MD_AAI_SHIFT (4U) +#define LTC_MD_AAI(x) (((uint32_t)(((uint32_t)(x)) << LTC_MD_AAI_SHIFT)) & LTC_MD_AAI_MASK) +#define LTC_MD_ALG_MASK (0xFF0000U) +#define LTC_MD_ALG_SHIFT (16U) +#define LTC_MD_ALG(x) (((uint32_t)(((uint32_t)(x)) << LTC_MD_ALG_SHIFT)) & LTC_MD_ALG_MASK) + +/*! @name MDPK - LTC Mode Register (PublicKey) */ +#define LTC_MDPK_PKHA_MODE_LS_MASK (0xFFFU) +#define LTC_MDPK_PKHA_MODE_LS_SHIFT (0U) +#define LTC_MDPK_PKHA_MODE_LS(x) (((uint32_t)(((uint32_t)(x)) << LTC_MDPK_PKHA_MODE_LS_SHIFT)) & LTC_MDPK_PKHA_MODE_LS_MASK) +#define LTC_MDPK_PKHA_MODE_MS_MASK (0xF0000U) +#define LTC_MDPK_PKHA_MODE_MS_SHIFT (16U) +#define LTC_MDPK_PKHA_MODE_MS(x) (((uint32_t)(((uint32_t)(x)) << LTC_MDPK_PKHA_MODE_MS_SHIFT)) & LTC_MDPK_PKHA_MODE_MS_MASK) +#define LTC_MDPK_ALG_MASK (0xF00000U) +#define LTC_MDPK_ALG_SHIFT (20U) +#define LTC_MDPK_ALG(x) (((uint32_t)(((uint32_t)(x)) << LTC_MDPK_ALG_SHIFT)) & LTC_MDPK_ALG_MASK) + +/*! @name KS - LTC Key Size Register */ +#define LTC_KS_KS_MASK (0x3FU) +#define LTC_KS_KS_SHIFT (0U) +#define LTC_KS_KS(x) (((uint32_t)(((uint32_t)(x)) << LTC_KS_KS_SHIFT)) & LTC_KS_KS_MASK) + +/*! @name DS - LTC Data Size Register */ +#define LTC_DS_DS_MASK (0xFFFU) +#define LTC_DS_DS_SHIFT (0U) +#define LTC_DS_DS(x) (((uint32_t)(((uint32_t)(x)) << LTC_DS_DS_SHIFT)) & LTC_DS_DS_MASK) + +/*! @name ICVS - LTC ICV Size Register */ +#define LTC_ICVS_ICVS_MASK (0x1FU) +#define LTC_ICVS_ICVS_SHIFT (0U) +#define LTC_ICVS_ICVS(x) (((uint32_t)(((uint32_t)(x)) << LTC_ICVS_ICVS_SHIFT)) & LTC_ICVS_ICVS_MASK) + +/*! @name COM - LTC Command Register */ +#define LTC_COM_ALL_MASK (0x1U) +#define LTC_COM_ALL_SHIFT (0U) +#define LTC_COM_ALL(x) (((uint32_t)(((uint32_t)(x)) << LTC_COM_ALL_SHIFT)) & LTC_COM_ALL_MASK) +#define LTC_COM_AES_MASK (0x2U) +#define LTC_COM_AES_SHIFT (1U) +#define LTC_COM_AES(x) (((uint32_t)(((uint32_t)(x)) << LTC_COM_AES_SHIFT)) & LTC_COM_AES_MASK) +#define LTC_COM_DES_MASK (0x4U) +#define LTC_COM_DES_SHIFT (2U) +#define LTC_COM_DES(x) (((uint32_t)(((uint32_t)(x)) << LTC_COM_DES_SHIFT)) & LTC_COM_DES_MASK) +#define LTC_COM_PK_MASK (0x40U) +#define LTC_COM_PK_SHIFT (6U) +#define LTC_COM_PK(x) (((uint32_t)(((uint32_t)(x)) << LTC_COM_PK_SHIFT)) & LTC_COM_PK_MASK) + +/*! @name CTL - LTC Control Register */ +#define LTC_CTL_IM_MASK (0x1U) +#define LTC_CTL_IM_SHIFT (0U) +#define LTC_CTL_IM(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_IM_SHIFT)) & LTC_CTL_IM_MASK) +#define LTC_CTL_PDE_MASK (0x10U) +#define LTC_CTL_PDE_SHIFT (4U) +#define LTC_CTL_PDE(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_PDE_SHIFT)) & LTC_CTL_PDE_MASK) +#define LTC_CTL_IFE_MASK (0x100U) +#define LTC_CTL_IFE_SHIFT (8U) +#define LTC_CTL_IFE(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_IFE_SHIFT)) & LTC_CTL_IFE_MASK) +#define LTC_CTL_IFR_MASK (0x200U) +#define LTC_CTL_IFR_SHIFT (9U) +#define LTC_CTL_IFR(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_IFR_SHIFT)) & LTC_CTL_IFR_MASK) +#define LTC_CTL_OFE_MASK (0x1000U) +#define LTC_CTL_OFE_SHIFT (12U) +#define LTC_CTL_OFE(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_OFE_SHIFT)) & LTC_CTL_OFE_MASK) +#define LTC_CTL_OFR_MASK (0x2000U) +#define LTC_CTL_OFR_SHIFT (13U) +#define LTC_CTL_OFR(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_OFR_SHIFT)) & LTC_CTL_OFR_MASK) +#define LTC_CTL_IFS_MASK (0x10000U) +#define LTC_CTL_IFS_SHIFT (16U) +#define LTC_CTL_IFS(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_IFS_SHIFT)) & LTC_CTL_IFS_MASK) +#define LTC_CTL_OFS_MASK (0x20000U) +#define LTC_CTL_OFS_SHIFT (17U) +#define LTC_CTL_OFS(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_OFS_SHIFT)) & LTC_CTL_OFS_MASK) +#define LTC_CTL_KIS_MASK (0x100000U) +#define LTC_CTL_KIS_SHIFT (20U) +#define LTC_CTL_KIS(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_KIS_SHIFT)) & LTC_CTL_KIS_MASK) +#define LTC_CTL_KOS_MASK (0x200000U) +#define LTC_CTL_KOS_SHIFT (21U) +#define LTC_CTL_KOS(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_KOS_SHIFT)) & LTC_CTL_KOS_MASK) +#define LTC_CTL_CIS_MASK (0x400000U) +#define LTC_CTL_CIS_SHIFT (22U) +#define LTC_CTL_CIS(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_CIS_SHIFT)) & LTC_CTL_CIS_MASK) +#define LTC_CTL_COS_MASK (0x800000U) +#define LTC_CTL_COS_SHIFT (23U) +#define LTC_CTL_COS(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_COS_SHIFT)) & LTC_CTL_COS_MASK) +#define LTC_CTL_KAL_MASK (0x80000000U) +#define LTC_CTL_KAL_SHIFT (31U) +#define LTC_CTL_KAL(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTL_KAL_SHIFT)) & LTC_CTL_KAL_MASK) + +/*! @name CW - LTC Clear Written Register */ +#define LTC_CW_CM_MASK (0x1U) +#define LTC_CW_CM_SHIFT (0U) +#define LTC_CW_CM(x) (((uint32_t)(((uint32_t)(x)) << LTC_CW_CM_SHIFT)) & LTC_CW_CM_MASK) +#define LTC_CW_CDS_MASK (0x4U) +#define LTC_CW_CDS_SHIFT (2U) +#define LTC_CW_CDS(x) (((uint32_t)(((uint32_t)(x)) << LTC_CW_CDS_SHIFT)) & LTC_CW_CDS_MASK) +#define LTC_CW_CICV_MASK (0x8U) +#define LTC_CW_CICV_SHIFT (3U) +#define LTC_CW_CICV(x) (((uint32_t)(((uint32_t)(x)) << LTC_CW_CICV_SHIFT)) & LTC_CW_CICV_MASK) +#define LTC_CW_CCR_MASK (0x20U) +#define LTC_CW_CCR_SHIFT (5U) +#define LTC_CW_CCR(x) (((uint32_t)(((uint32_t)(x)) << LTC_CW_CCR_SHIFT)) & LTC_CW_CCR_MASK) +#define LTC_CW_CKR_MASK (0x40U) +#define LTC_CW_CKR_SHIFT (6U) +#define LTC_CW_CKR(x) (((uint32_t)(((uint32_t)(x)) << LTC_CW_CKR_SHIFT)) & LTC_CW_CKR_MASK) +#define LTC_CW_CPKA_MASK (0x1000U) +#define LTC_CW_CPKA_SHIFT (12U) +#define LTC_CW_CPKA(x) (((uint32_t)(((uint32_t)(x)) << LTC_CW_CPKA_SHIFT)) & LTC_CW_CPKA_MASK) +#define LTC_CW_CPKB_MASK (0x2000U) +#define LTC_CW_CPKB_SHIFT (13U) +#define LTC_CW_CPKB(x) (((uint32_t)(((uint32_t)(x)) << LTC_CW_CPKB_SHIFT)) & LTC_CW_CPKB_MASK) +#define LTC_CW_CPKN_MASK (0x4000U) +#define LTC_CW_CPKN_SHIFT (14U) +#define LTC_CW_CPKN(x) (((uint32_t)(((uint32_t)(x)) << LTC_CW_CPKN_SHIFT)) & LTC_CW_CPKN_MASK) +#define LTC_CW_CPKE_MASK (0x8000U) +#define LTC_CW_CPKE_SHIFT (15U) +#define LTC_CW_CPKE(x) (((uint32_t)(((uint32_t)(x)) << LTC_CW_CPKE_SHIFT)) & LTC_CW_CPKE_MASK) +#define LTC_CW_COF_MASK (0x40000000U) +#define LTC_CW_COF_SHIFT (30U) +#define LTC_CW_COF(x) (((uint32_t)(((uint32_t)(x)) << LTC_CW_COF_SHIFT)) & LTC_CW_COF_MASK) +#define LTC_CW_CIF_MASK (0x80000000U) +#define LTC_CW_CIF_SHIFT (31U) +#define LTC_CW_CIF(x) (((uint32_t)(((uint32_t)(x)) << LTC_CW_CIF_SHIFT)) & LTC_CW_CIF_MASK) + +/*! @name STA - LTC Status Register */ +#define LTC_STA_AB_MASK (0x2U) +#define LTC_STA_AB_SHIFT (1U) +#define LTC_STA_AB(x) (((uint32_t)(((uint32_t)(x)) << LTC_STA_AB_SHIFT)) & LTC_STA_AB_MASK) +#define LTC_STA_DB_MASK (0x4U) +#define LTC_STA_DB_SHIFT (2U) +#define LTC_STA_DB(x) (((uint32_t)(((uint32_t)(x)) << LTC_STA_DB_SHIFT)) & LTC_STA_DB_MASK) +#define LTC_STA_PB_MASK (0x40U) +#define LTC_STA_PB_SHIFT (6U) +#define LTC_STA_PB(x) (((uint32_t)(((uint32_t)(x)) << LTC_STA_PB_SHIFT)) & LTC_STA_PB_MASK) +#define LTC_STA_DI_MASK (0x10000U) +#define LTC_STA_DI_SHIFT (16U) +#define LTC_STA_DI(x) (((uint32_t)(((uint32_t)(x)) << LTC_STA_DI_SHIFT)) & LTC_STA_DI_MASK) +#define LTC_STA_EI_MASK (0x100000U) +#define LTC_STA_EI_SHIFT (20U) +#define LTC_STA_EI(x) (((uint32_t)(((uint32_t)(x)) << LTC_STA_EI_SHIFT)) & LTC_STA_EI_MASK) +#define LTC_STA_PKP_MASK (0x10000000U) +#define LTC_STA_PKP_SHIFT (28U) +#define LTC_STA_PKP(x) (((uint32_t)(((uint32_t)(x)) << LTC_STA_PKP_SHIFT)) & LTC_STA_PKP_MASK) +#define LTC_STA_PKO_MASK (0x20000000U) +#define LTC_STA_PKO_SHIFT (29U) +#define LTC_STA_PKO(x) (((uint32_t)(((uint32_t)(x)) << LTC_STA_PKO_SHIFT)) & LTC_STA_PKO_MASK) +#define LTC_STA_PKZ_MASK (0x40000000U) +#define LTC_STA_PKZ_SHIFT (30U) +#define LTC_STA_PKZ(x) (((uint32_t)(((uint32_t)(x)) << LTC_STA_PKZ_SHIFT)) & LTC_STA_PKZ_MASK) + +/*! @name ESTA - LTC Error Status Register */ +#define LTC_ESTA_ERRID1_MASK (0xFU) +#define LTC_ESTA_ERRID1_SHIFT (0U) +#define LTC_ESTA_ERRID1(x) (((uint32_t)(((uint32_t)(x)) << LTC_ESTA_ERRID1_SHIFT)) & LTC_ESTA_ERRID1_MASK) +#define LTC_ESTA_CL1_MASK (0xF00U) +#define LTC_ESTA_CL1_SHIFT (8U) +#define LTC_ESTA_CL1(x) (((uint32_t)(((uint32_t)(x)) << LTC_ESTA_CL1_SHIFT)) & LTC_ESTA_CL1_MASK) + +/*! @name AADSZ - LTC AAD Size Register */ +#define LTC_AADSZ_AADSZ_MASK (0xFU) +#define LTC_AADSZ_AADSZ_SHIFT (0U) +#define LTC_AADSZ_AADSZ(x) (((uint32_t)(((uint32_t)(x)) << LTC_AADSZ_AADSZ_SHIFT)) & LTC_AADSZ_AADSZ_MASK) +#define LTC_AADSZ_AL_MASK (0x80000000U) +#define LTC_AADSZ_AL_SHIFT (31U) +#define LTC_AADSZ_AL(x) (((uint32_t)(((uint32_t)(x)) << LTC_AADSZ_AL_SHIFT)) & LTC_AADSZ_AL_MASK) + +/*! @name IVSZ - LTC IV Size Register */ +#define LTC_IVSZ_IVSZ_MASK (0xFU) +#define LTC_IVSZ_IVSZ_SHIFT (0U) +#define LTC_IVSZ_IVSZ(x) (((uint32_t)(((uint32_t)(x)) << LTC_IVSZ_IVSZ_SHIFT)) & LTC_IVSZ_IVSZ_MASK) +#define LTC_IVSZ_IL_MASK (0x80000000U) +#define LTC_IVSZ_IL_SHIFT (31U) +#define LTC_IVSZ_IL(x) (((uint32_t)(((uint32_t)(x)) << LTC_IVSZ_IL_SHIFT)) & LTC_IVSZ_IL_MASK) + +/*! @name DPAMS - LTC DPA Mask Seed Register */ +#define LTC_DPAMS_DPAMS_MASK (0xFFFFFFFFU) +#define LTC_DPAMS_DPAMS_SHIFT (0U) +#define LTC_DPAMS_DPAMS(x) (((uint32_t)(((uint32_t)(x)) << LTC_DPAMS_DPAMS_SHIFT)) & LTC_DPAMS_DPAMS_MASK) + +/*! @name PKASZ - LTC PKHA A Size Register */ +#define LTC_PKASZ_PKASZ_MASK (0x1FFU) +#define LTC_PKASZ_PKASZ_SHIFT (0U) +#define LTC_PKASZ_PKASZ(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKASZ_PKASZ_SHIFT)) & LTC_PKASZ_PKASZ_MASK) + +/*! @name PKBSZ - LTC PKHA B Size Register */ +#define LTC_PKBSZ_PKBSZ_MASK (0x1FFU) +#define LTC_PKBSZ_PKBSZ_SHIFT (0U) +#define LTC_PKBSZ_PKBSZ(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKBSZ_PKBSZ_SHIFT)) & LTC_PKBSZ_PKBSZ_MASK) + +/*! @name PKNSZ - LTC PKHA N Size Register */ +#define LTC_PKNSZ_PKNSZ_MASK (0x1FFU) +#define LTC_PKNSZ_PKNSZ_SHIFT (0U) +#define LTC_PKNSZ_PKNSZ(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKNSZ_PKNSZ_SHIFT)) & LTC_PKNSZ_PKNSZ_MASK) + +/*! @name PKESZ - LTC PKHA E Size Register */ +#define LTC_PKESZ_PKESZ_MASK (0x1FFU) +#define LTC_PKESZ_PKESZ_SHIFT (0U) +#define LTC_PKESZ_PKESZ(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKESZ_PKESZ_SHIFT)) & LTC_PKESZ_PKESZ_MASK) + +/*! @name CTX - LTC Context Register */ +#define LTC_CTX_CTX_MASK (0xFFFFFFFFU) +#define LTC_CTX_CTX_SHIFT (0U) +#define LTC_CTX_CTX(x) (((uint32_t)(((uint32_t)(x)) << LTC_CTX_CTX_SHIFT)) & LTC_CTX_CTX_MASK) + +/* The count of LTC_CTX */ +#define LTC_CTX_COUNT (16U) + +/*! @name KEY - LTC Key Registers */ +#define LTC_KEY_KEY_MASK (0xFFFFFFFFU) +#define LTC_KEY_KEY_SHIFT (0U) +#define LTC_KEY_KEY(x) (((uint32_t)(((uint32_t)(x)) << LTC_KEY_KEY_SHIFT)) & LTC_KEY_KEY_MASK) + +/* The count of LTC_KEY */ +#define LTC_KEY_COUNT (8U) + +/*! @name VID1 - LTC Version ID Register */ +#define LTC_VID1_MIN_REV_MASK (0xFFU) +#define LTC_VID1_MIN_REV_SHIFT (0U) +#define LTC_VID1_MIN_REV(x) (((uint32_t)(((uint32_t)(x)) << LTC_VID1_MIN_REV_SHIFT)) & LTC_VID1_MIN_REV_MASK) +#define LTC_VID1_MAJ_REV_MASK (0xFF00U) +#define LTC_VID1_MAJ_REV_SHIFT (8U) +#define LTC_VID1_MAJ_REV(x) (((uint32_t)(((uint32_t)(x)) << LTC_VID1_MAJ_REV_SHIFT)) & LTC_VID1_MAJ_REV_MASK) +#define LTC_VID1_IP_ID_MASK (0xFFFF0000U) +#define LTC_VID1_IP_ID_SHIFT (16U) +#define LTC_VID1_IP_ID(x) (((uint32_t)(((uint32_t)(x)) << LTC_VID1_IP_ID_SHIFT)) & LTC_VID1_IP_ID_MASK) + +/*! @name CHAVID - LTC CHA Version ID Register */ +#define LTC_CHAVID_AESREV_MASK (0xFU) +#define LTC_CHAVID_AESREV_SHIFT (0U) +#define LTC_CHAVID_AESREV(x) (((uint32_t)(((uint32_t)(x)) << LTC_CHAVID_AESREV_SHIFT)) & LTC_CHAVID_AESREV_MASK) +#define LTC_CHAVID_AESVID_MASK (0xF0U) +#define LTC_CHAVID_AESVID_SHIFT (4U) +#define LTC_CHAVID_AESVID(x) (((uint32_t)(((uint32_t)(x)) << LTC_CHAVID_AESVID_SHIFT)) & LTC_CHAVID_AESVID_MASK) +#define LTC_CHAVID_DESREV_MASK (0xF00U) +#define LTC_CHAVID_DESREV_SHIFT (8U) +#define LTC_CHAVID_DESREV(x) (((uint32_t)(((uint32_t)(x)) << LTC_CHAVID_DESREV_SHIFT)) & LTC_CHAVID_DESREV_MASK) +#define LTC_CHAVID_DESVID_MASK (0xF000U) +#define LTC_CHAVID_DESVID_SHIFT (12U) +#define LTC_CHAVID_DESVID(x) (((uint32_t)(((uint32_t)(x)) << LTC_CHAVID_DESVID_SHIFT)) & LTC_CHAVID_DESVID_MASK) +#define LTC_CHAVID_PKHAREV_MASK (0xF0000U) +#define LTC_CHAVID_PKHAREV_SHIFT (16U) +#define LTC_CHAVID_PKHAREV(x) (((uint32_t)(((uint32_t)(x)) << LTC_CHAVID_PKHAREV_SHIFT)) & LTC_CHAVID_PKHAREV_MASK) +#define LTC_CHAVID_PKHAVID_MASK (0xF00000U) +#define LTC_CHAVID_PKHAVID_SHIFT (20U) +#define LTC_CHAVID_PKHAVID(x) (((uint32_t)(((uint32_t)(x)) << LTC_CHAVID_PKHAVID_SHIFT)) & LTC_CHAVID_PKHAVID_MASK) + +/*! @name FIFOSTA - LTC FIFO Status Register */ +#define LTC_FIFOSTA_IFL_MASK (0x7FU) +#define LTC_FIFOSTA_IFL_SHIFT (0U) +#define LTC_FIFOSTA_IFL(x) (((uint32_t)(((uint32_t)(x)) << LTC_FIFOSTA_IFL_SHIFT)) & LTC_FIFOSTA_IFL_MASK) +#define LTC_FIFOSTA_IFF_MASK (0x8000U) +#define LTC_FIFOSTA_IFF_SHIFT (15U) +#define LTC_FIFOSTA_IFF(x) (((uint32_t)(((uint32_t)(x)) << LTC_FIFOSTA_IFF_SHIFT)) & LTC_FIFOSTA_IFF_MASK) +#define LTC_FIFOSTA_OFL_MASK (0x7F0000U) +#define LTC_FIFOSTA_OFL_SHIFT (16U) +#define LTC_FIFOSTA_OFL(x) (((uint32_t)(((uint32_t)(x)) << LTC_FIFOSTA_OFL_SHIFT)) & LTC_FIFOSTA_OFL_MASK) +#define LTC_FIFOSTA_OFF_MASK (0x80000000U) +#define LTC_FIFOSTA_OFF_SHIFT (31U) +#define LTC_FIFOSTA_OFF(x) (((uint32_t)(((uint32_t)(x)) << LTC_FIFOSTA_OFF_SHIFT)) & LTC_FIFOSTA_OFF_MASK) + +/*! @name IFIFO - LTC Input Data FIFO */ +#define LTC_IFIFO_IFIFO_MASK (0xFFFFFFFFU) +#define LTC_IFIFO_IFIFO_SHIFT (0U) +#define LTC_IFIFO_IFIFO(x) (((uint32_t)(((uint32_t)(x)) << LTC_IFIFO_IFIFO_SHIFT)) & LTC_IFIFO_IFIFO_MASK) + +/*! @name OFIFO - LTC Output Data FIFO */ +#define LTC_OFIFO_OFIFO_MASK (0xFFFFFFFFU) +#define LTC_OFIFO_OFIFO_SHIFT (0U) +#define LTC_OFIFO_OFIFO(x) (((uint32_t)(((uint32_t)(x)) << LTC_OFIFO_OFIFO_SHIFT)) & LTC_OFIFO_OFIFO_MASK) + +/* The count of LTC_PKA */ +#define LTC_PKA_COUNT (64U) + +/*! @name PKA0 - LTC PKHA A0 0 Register..LTC PKHA A0 15 Register */ +#define LTC_PKA0_PKHA_A0_MASK (0xFFFFFFFFU) +#define LTC_PKA0_PKHA_A0_SHIFT (0U) +#define LTC_PKA0_PKHA_A0(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKA0_PKHA_A0_SHIFT)) & LTC_PKA0_PKHA_A0_MASK) + +/* The count of LTC_PKA0 */ +#define LTC_PKA0_COUNT (16U) + +/*! @name PKA1 - LTC PKHA A1 0 Register..LTC PKHA A1 15 Register */ +#define LTC_PKA1_PKHA_A1_MASK (0xFFFFFFFFU) +#define LTC_PKA1_PKHA_A1_SHIFT (0U) +#define LTC_PKA1_PKHA_A1(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKA1_PKHA_A1_SHIFT)) & LTC_PKA1_PKHA_A1_MASK) + +/* The count of LTC_PKA1 */ +#define LTC_PKA1_COUNT (16U) + +/*! @name PKA2 - LTC PKHA A2 0 Register..LTC PKHA A2 15 Register */ +#define LTC_PKA2_PKHA_A2_MASK (0xFFFFFFFFU) +#define LTC_PKA2_PKHA_A2_SHIFT (0U) +#define LTC_PKA2_PKHA_A2(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKA2_PKHA_A2_SHIFT)) & LTC_PKA2_PKHA_A2_MASK) + +/* The count of LTC_PKA2 */ +#define LTC_PKA2_COUNT (16U) + +/*! @name PKA3 - LTC PKHA A3 0 Register..LTC PKHA A3 15 Register */ +#define LTC_PKA3_PKHA_A3_MASK (0xFFFFFFFFU) +#define LTC_PKA3_PKHA_A3_SHIFT (0U) +#define LTC_PKA3_PKHA_A3(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKA3_PKHA_A3_SHIFT)) & LTC_PKA3_PKHA_A3_MASK) + +/* The count of LTC_PKA3 */ +#define LTC_PKA3_COUNT (16U) + +/* The count of LTC_PKB */ +#define LTC_PKB_COUNT (64U) + +/*! @name PKB0 - LTC PKHA B0 0 Register..LTC PKHA B0 15 Register */ +#define LTC_PKB0_PKHA_B0_MASK (0xFFFFFFFFU) +#define LTC_PKB0_PKHA_B0_SHIFT (0U) +#define LTC_PKB0_PKHA_B0(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKB0_PKHA_B0_SHIFT)) & LTC_PKB0_PKHA_B0_MASK) + +/* The count of LTC_PKB0 */ +#define LTC_PKB0_COUNT (16U) + +/*! @name PKB1 - LTC PKHA B1 0 Register..LTC PKHA B1 15 Register */ +#define LTC_PKB1_PKHA_B1_MASK (0xFFFFFFFFU) +#define LTC_PKB1_PKHA_B1_SHIFT (0U) +#define LTC_PKB1_PKHA_B1(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKB1_PKHA_B1_SHIFT)) & LTC_PKB1_PKHA_B1_MASK) + +/* The count of LTC_PKB1 */ +#define LTC_PKB1_COUNT (16U) + +/*! @name PKB2 - LTC PKHA B2 0 Register..LTC PKHA B2 15 Register */ +#define LTC_PKB2_PKHA_B2_MASK (0xFFFFFFFFU) +#define LTC_PKB2_PKHA_B2_SHIFT (0U) +#define LTC_PKB2_PKHA_B2(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKB2_PKHA_B2_SHIFT)) & LTC_PKB2_PKHA_B2_MASK) + +/* The count of LTC_PKB2 */ +#define LTC_PKB2_COUNT (16U) + +/*! @name PKB3 - LTC PKHA B3 0 Register..LTC PKHA B3 15 Register */ +#define LTC_PKB3_PKHA_B3_MASK (0xFFFFFFFFU) +#define LTC_PKB3_PKHA_B3_SHIFT (0U) +#define LTC_PKB3_PKHA_B3(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKB3_PKHA_B3_SHIFT)) & LTC_PKB3_PKHA_B3_MASK) + +/* The count of LTC_PKB3 */ +#define LTC_PKB3_COUNT (16U) + +/* The count of LTC_PKN */ +#define LTC_PKN_COUNT (64U) + +/*! @name PKN0 - LTC PKHA N0 0 Register..LTC PKHA N0 15 Register */ +#define LTC_PKN0_PKHA_N0_MASK (0xFFFFFFFFU) +#define LTC_PKN0_PKHA_N0_SHIFT (0U) +#define LTC_PKN0_PKHA_N0(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKN0_PKHA_N0_SHIFT)) & LTC_PKN0_PKHA_N0_MASK) + +/* The count of LTC_PKN0 */ +#define LTC_PKN0_COUNT (16U) + +/*! @name PKN1 - LTC PKHA N1 0 Register..LTC PKHA N1 15 Register */ +#define LTC_PKN1_PKHA_N1_MASK (0xFFFFFFFFU) +#define LTC_PKN1_PKHA_N1_SHIFT (0U) +#define LTC_PKN1_PKHA_N1(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKN1_PKHA_N1_SHIFT)) & LTC_PKN1_PKHA_N1_MASK) + +/* The count of LTC_PKN1 */ +#define LTC_PKN1_COUNT (16U) + +/*! @name PKN2 - LTC PKHA N2 0 Register..LTC PKHA N2 15 Register */ +#define LTC_PKN2_PKHA_N2_MASK (0xFFFFFFFFU) +#define LTC_PKN2_PKHA_N2_SHIFT (0U) +#define LTC_PKN2_PKHA_N2(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKN2_PKHA_N2_SHIFT)) & LTC_PKN2_PKHA_N2_MASK) + +/* The count of LTC_PKN2 */ +#define LTC_PKN2_COUNT (16U) + +/*! @name PKN3 - LTC PKHA N3 0 Register..LTC PKHA N3 15 Register */ +#define LTC_PKN3_PKHA_N3_MASK (0xFFFFFFFFU) +#define LTC_PKN3_PKHA_N3_SHIFT (0U) +#define LTC_PKN3_PKHA_N3(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKN3_PKHA_N3_SHIFT)) & LTC_PKN3_PKHA_N3_MASK) + +/* The count of LTC_PKN3 */ +#define LTC_PKN3_COUNT (16U) + +/* The count of LTC_PKE */ +#define LTC_PKE_COUNT (64U) + +/*! @name PKE0 - LTC PKHA E0 0 Register..LTC PKHA E0 15 Register */ +#define LTC_PKE0_PKHA_E0_MASK (0xFFFFFFFFU) +#define LTC_PKE0_PKHA_E0_SHIFT (0U) +#define LTC_PKE0_PKHA_E0(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKE0_PKHA_E0_SHIFT)) & LTC_PKE0_PKHA_E0_MASK) + +/* The count of LTC_PKE0 */ +#define LTC_PKE0_COUNT (16U) + +/*! @name PKE1 - LTC PKHA E1 0 Register..LTC PKHA E1 15 Register */ +#define LTC_PKE1_PKHA_E1_MASK (0xFFFFFFFFU) +#define LTC_PKE1_PKHA_E1_SHIFT (0U) +#define LTC_PKE1_PKHA_E1(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKE1_PKHA_E1_SHIFT)) & LTC_PKE1_PKHA_E1_MASK) + +/* The count of LTC_PKE1 */ +#define LTC_PKE1_COUNT (16U) + +/*! @name PKE2 - LTC PKHA E2 0 Register..LTC PKHA E2 15 Register */ +#define LTC_PKE2_PKHA_E2_MASK (0xFFFFFFFFU) +#define LTC_PKE2_PKHA_E2_SHIFT (0U) +#define LTC_PKE2_PKHA_E2(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKE2_PKHA_E2_SHIFT)) & LTC_PKE2_PKHA_E2_MASK) + +/* The count of LTC_PKE2 */ +#define LTC_PKE2_COUNT (16U) + +/*! @name PKE3 - LTC PKHA E3 0 Register..LTC PKHA E3 15 Register */ +#define LTC_PKE3_PKHA_E3_MASK (0xFFFFFFFFU) +#define LTC_PKE3_PKHA_E3_SHIFT (0U) +#define LTC_PKE3_PKHA_E3(x) (((uint32_t)(((uint32_t)(x)) << LTC_PKE3_PKHA_E3_SHIFT)) & LTC_PKE3_PKHA_E3_MASK) + +/* The count of LTC_PKE3 */ +#define LTC_PKE3_COUNT (16U) + + +/*! + * @} + */ /* end of group LTC_Register_Masks */ + + +/* LTC - Peripheral instance base addresses */ +/** Peripheral LTC0 base address */ +#define LTC0_BASE (0x400D1000u) +/** Peripheral LTC0 base pointer */ +#define LTC0 ((LTC_Type *)LTC0_BASE) +/** Array initializer of LTC peripheral base addresses */ +#define LTC_BASE_ADDRS { LTC0_BASE } +/** Array initializer of LTC peripheral base pointers */ +#define LTC_BASE_PTRS { LTC0 } +/** Interrupt vectors for the LTC peripheral type */ +#define LTC_IRQS { LTC0_IRQn } + +/*! + * @} + */ /* end of group LTC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MCG Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MCG_Peripheral_Access_Layer MCG Peripheral Access Layer + * @{ + */ + +/** MCG - Register Layout Typedef */ +typedef struct { + __IO uint8_t C1; /**< MCG Control 1 Register, offset: 0x0 */ + __IO uint8_t C2; /**< MCG Control 2 Register, offset: 0x1 */ + __IO uint8_t C3; /**< MCG Control 3 Register, offset: 0x2 */ + __IO uint8_t C4; /**< MCG Control 4 Register, offset: 0x3 */ + __IO uint8_t C5; /**< MCG Control 5 Register, offset: 0x4 */ + __IO uint8_t C6; /**< MCG Control 6 Register, offset: 0x5 */ + __IO uint8_t S; /**< MCG Status Register, offset: 0x6 */ + uint8_t RESERVED_0[1]; + __IO uint8_t SC; /**< MCG Status and Control Register, offset: 0x8 */ + uint8_t RESERVED_1[1]; + __IO uint8_t ATCVH; /**< MCG Auto Trim Compare Value High Register, offset: 0xA */ + __IO uint8_t ATCVL; /**< MCG Auto Trim Compare Value Low Register, offset: 0xB */ + __IO uint8_t C7; /**< MCG Control 7 Register, offset: 0xC */ + __IO uint8_t C8; /**< MCG Control 8 Register, offset: 0xD */ +} MCG_Type; + +/* ---------------------------------------------------------------------------- + -- MCG Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MCG_Register_Masks MCG Register Masks + * @{ + */ + +/*! @name C1 - MCG Control 1 Register */ +#define MCG_C1_IREFSTEN_MASK (0x1U) +#define MCG_C1_IREFSTEN_SHIFT (0U) +#define MCG_C1_IREFSTEN(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_IREFSTEN_SHIFT)) & MCG_C1_IREFSTEN_MASK) +#define MCG_C1_IRCLKEN_MASK (0x2U) +#define MCG_C1_IRCLKEN_SHIFT (1U) +#define MCG_C1_IRCLKEN(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_IRCLKEN_SHIFT)) & MCG_C1_IRCLKEN_MASK) +#define MCG_C1_IREFS_MASK (0x4U) +#define MCG_C1_IREFS_SHIFT (2U) +#define MCG_C1_IREFS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_IREFS_SHIFT)) & MCG_C1_IREFS_MASK) +#define MCG_C1_FRDIV_MASK (0x38U) +#define MCG_C1_FRDIV_SHIFT (3U) +#define MCG_C1_FRDIV(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_FRDIV_SHIFT)) & MCG_C1_FRDIV_MASK) +#define MCG_C1_CLKS_MASK (0xC0U) +#define MCG_C1_CLKS_SHIFT (6U) +#define MCG_C1_CLKS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_CLKS_SHIFT)) & MCG_C1_CLKS_MASK) + +/*! @name C2 - MCG Control 2 Register */ +#define MCG_C2_IRCS_MASK (0x1U) +#define MCG_C2_IRCS_SHIFT (0U) +#define MCG_C2_IRCS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_IRCS_SHIFT)) & MCG_C2_IRCS_MASK) +#define MCG_C2_LP_MASK (0x2U) +#define MCG_C2_LP_SHIFT (1U) +#define MCG_C2_LP(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_LP_SHIFT)) & MCG_C2_LP_MASK) +#define MCG_C2_EREFS_MASK (0x4U) +#define MCG_C2_EREFS_SHIFT (2U) +#define MCG_C2_EREFS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_EREFS_SHIFT)) & MCG_C2_EREFS_MASK) +#define MCG_C2_HGO_MASK (0x8U) +#define MCG_C2_HGO_SHIFT (3U) +#define MCG_C2_HGO(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_HGO_SHIFT)) & MCG_C2_HGO_MASK) +#define MCG_C2_RANGE_MASK (0x30U) +#define MCG_C2_RANGE_SHIFT (4U) +#define MCG_C2_RANGE(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_RANGE_SHIFT)) & MCG_C2_RANGE_MASK) +#define MCG_C2_FCFTRIM_MASK (0x40U) +#define MCG_C2_FCFTRIM_SHIFT (6U) +#define MCG_C2_FCFTRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_FCFTRIM_SHIFT)) & MCG_C2_FCFTRIM_MASK) +#define MCG_C2_LOCRE0_MASK (0x80U) +#define MCG_C2_LOCRE0_SHIFT (7U) +#define MCG_C2_LOCRE0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_LOCRE0_SHIFT)) & MCG_C2_LOCRE0_MASK) + +/*! @name C3 - MCG Control 3 Register */ +#define MCG_C3_SCTRIM_MASK (0xFFU) +#define MCG_C3_SCTRIM_SHIFT (0U) +#define MCG_C3_SCTRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_C3_SCTRIM_SHIFT)) & MCG_C3_SCTRIM_MASK) + +/*! @name C4 - MCG Control 4 Register */ +#define MCG_C4_SCFTRIM_MASK (0x1U) +#define MCG_C4_SCFTRIM_SHIFT (0U) +#define MCG_C4_SCFTRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_C4_SCFTRIM_SHIFT)) & MCG_C4_SCFTRIM_MASK) +#define MCG_C4_FCTRIM_MASK (0x1EU) +#define MCG_C4_FCTRIM_SHIFT (1U) +#define MCG_C4_FCTRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_C4_FCTRIM_SHIFT)) & MCG_C4_FCTRIM_MASK) +#define MCG_C4_DRST_DRS_MASK (0x60U) +#define MCG_C4_DRST_DRS_SHIFT (5U) +#define MCG_C4_DRST_DRS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C4_DRST_DRS_SHIFT)) & MCG_C4_DRST_DRS_MASK) +#define MCG_C4_DMX32_MASK (0x80U) +#define MCG_C4_DMX32_SHIFT (7U) +#define MCG_C4_DMX32(x) (((uint8_t)(((uint8_t)(x)) << MCG_C4_DMX32_SHIFT)) & MCG_C4_DMX32_MASK) + +/*! @name C5 - MCG Control 5 Register */ +#define MCG_C5_PRDIV_MASK (0x7U) +#define MCG_C5_PRDIV_SHIFT (0U) +#define MCG_C5_PRDIV(x) (((uint8_t)(((uint8_t)(x)) << MCG_C5_PRDIV_SHIFT)) & MCG_C5_PRDIV_MASK) +#define MCG_C5_PLLSTEN_MASK (0x20U) +#define MCG_C5_PLLSTEN_SHIFT (5U) +#define MCG_C5_PLLSTEN(x) (((uint8_t)(((uint8_t)(x)) << MCG_C5_PLLSTEN_SHIFT)) & MCG_C5_PLLSTEN_MASK) +#define MCG_C5_PLLCLKEN_MASK (0x40U) +#define MCG_C5_PLLCLKEN_SHIFT (6U) +#define MCG_C5_PLLCLKEN(x) (((uint8_t)(((uint8_t)(x)) << MCG_C5_PLLCLKEN_SHIFT)) & MCG_C5_PLLCLKEN_MASK) + +/*! @name C6 - MCG Control 6 Register */ +#define MCG_C6_VDIV_MASK (0x1FU) +#define MCG_C6_VDIV_SHIFT (0U) +#define MCG_C6_VDIV(x) (((uint8_t)(((uint8_t)(x)) << MCG_C6_VDIV_SHIFT)) & MCG_C6_VDIV_MASK) +#define MCG_C6_CME0_MASK (0x20U) +#define MCG_C6_CME0_SHIFT (5U) +#define MCG_C6_CME0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C6_CME0_SHIFT)) & MCG_C6_CME0_MASK) +#define MCG_C6_PLLS_MASK (0x40U) +#define MCG_C6_PLLS_SHIFT (6U) +#define MCG_C6_PLLS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C6_PLLS_SHIFT)) & MCG_C6_PLLS_MASK) +#define MCG_C6_LOLIE0_MASK (0x80U) +#define MCG_C6_LOLIE0_SHIFT (7U) +#define MCG_C6_LOLIE0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C6_LOLIE0_SHIFT)) & MCG_C6_LOLIE0_MASK) + +/*! @name S - MCG Status Register */ +#define MCG_S_IRCST_MASK (0x1U) +#define MCG_S_IRCST_SHIFT (0U) +#define MCG_S_IRCST(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_IRCST_SHIFT)) & MCG_S_IRCST_MASK) +#define MCG_S_OSCINIT0_MASK (0x2U) +#define MCG_S_OSCINIT0_SHIFT (1U) +#define MCG_S_OSCINIT0(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_OSCINIT0_SHIFT)) & MCG_S_OSCINIT0_MASK) +#define MCG_S_CLKST_MASK (0xCU) +#define MCG_S_CLKST_SHIFT (2U) +#define MCG_S_CLKST(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_CLKST_SHIFT)) & MCG_S_CLKST_MASK) +#define MCG_S_IREFST_MASK (0x10U) +#define MCG_S_IREFST_SHIFT (4U) +#define MCG_S_IREFST(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_IREFST_SHIFT)) & MCG_S_IREFST_MASK) +#define MCG_S_PLLST_MASK (0x20U) +#define MCG_S_PLLST_SHIFT (5U) +#define MCG_S_PLLST(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_PLLST_SHIFT)) & MCG_S_PLLST_MASK) +#define MCG_S_LOCK0_MASK (0x40U) +#define MCG_S_LOCK0_SHIFT (6U) +#define MCG_S_LOCK0(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_LOCK0_SHIFT)) & MCG_S_LOCK0_MASK) +#define MCG_S_LOLS0_MASK (0x80U) +#define MCG_S_LOLS0_SHIFT (7U) +#define MCG_S_LOLS0(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_LOLS0_SHIFT)) & MCG_S_LOLS0_MASK) + +/*! @name SC - MCG Status and Control Register */ +#define MCG_SC_LOCS0_MASK (0x1U) +#define MCG_SC_LOCS0_SHIFT (0U) +#define MCG_SC_LOCS0(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_LOCS0_SHIFT)) & MCG_SC_LOCS0_MASK) +#define MCG_SC_FCRDIV_MASK (0xEU) +#define MCG_SC_FCRDIV_SHIFT (1U) +#define MCG_SC_FCRDIV(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_FCRDIV_SHIFT)) & MCG_SC_FCRDIV_MASK) +#define MCG_SC_FLTPRSRV_MASK (0x10U) +#define MCG_SC_FLTPRSRV_SHIFT (4U) +#define MCG_SC_FLTPRSRV(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_FLTPRSRV_SHIFT)) & MCG_SC_FLTPRSRV_MASK) +#define MCG_SC_ATMF_MASK (0x20U) +#define MCG_SC_ATMF_SHIFT (5U) +#define MCG_SC_ATMF(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_ATMF_SHIFT)) & MCG_SC_ATMF_MASK) +#define MCG_SC_ATMS_MASK (0x40U) +#define MCG_SC_ATMS_SHIFT (6U) +#define MCG_SC_ATMS(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_ATMS_SHIFT)) & MCG_SC_ATMS_MASK) +#define MCG_SC_ATME_MASK (0x80U) +#define MCG_SC_ATME_SHIFT (7U) +#define MCG_SC_ATME(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_ATME_SHIFT)) & MCG_SC_ATME_MASK) + +/*! @name ATCVH - MCG Auto Trim Compare Value High Register */ +#define MCG_ATCVH_ATCVH_MASK (0xFFU) +#define MCG_ATCVH_ATCVH_SHIFT (0U) +#define MCG_ATCVH_ATCVH(x) (((uint8_t)(((uint8_t)(x)) << MCG_ATCVH_ATCVH_SHIFT)) & MCG_ATCVH_ATCVH_MASK) + +/*! @name ATCVL - MCG Auto Trim Compare Value Low Register */ +#define MCG_ATCVL_ATCVL_MASK (0xFFU) +#define MCG_ATCVL_ATCVL_SHIFT (0U) +#define MCG_ATCVL_ATCVL(x) (((uint8_t)(((uint8_t)(x)) << MCG_ATCVL_ATCVL_SHIFT)) & MCG_ATCVL_ATCVL_MASK) + +/*! @name C7 - MCG Control 7 Register */ +#define MCG_C7_OSCSEL_MASK (0x3U) +#define MCG_C7_OSCSEL_SHIFT (0U) +#define MCG_C7_OSCSEL(x) (((uint8_t)(((uint8_t)(x)) << MCG_C7_OSCSEL_SHIFT)) & MCG_C7_OSCSEL_MASK) + +/*! @name C8 - MCG Control 8 Register */ +#define MCG_C8_LOCS1_MASK (0x1U) +#define MCG_C8_LOCS1_SHIFT (0U) +#define MCG_C8_LOCS1(x) (((uint8_t)(((uint8_t)(x)) << MCG_C8_LOCS1_SHIFT)) & MCG_C8_LOCS1_MASK) +#define MCG_C8_CME1_MASK (0x20U) +#define MCG_C8_CME1_SHIFT (5U) +#define MCG_C8_CME1(x) (((uint8_t)(((uint8_t)(x)) << MCG_C8_CME1_SHIFT)) & MCG_C8_CME1_MASK) +#define MCG_C8_LOLRE_MASK (0x40U) +#define MCG_C8_LOLRE_SHIFT (6U) +#define MCG_C8_LOLRE(x) (((uint8_t)(((uint8_t)(x)) << MCG_C8_LOLRE_SHIFT)) & MCG_C8_LOLRE_MASK) +#define MCG_C8_LOCRE1_MASK (0x80U) +#define MCG_C8_LOCRE1_SHIFT (7U) +#define MCG_C8_LOCRE1(x) (((uint8_t)(((uint8_t)(x)) << MCG_C8_LOCRE1_SHIFT)) & MCG_C8_LOCRE1_MASK) + + +/*! + * @} + */ /* end of group MCG_Register_Masks */ + + +/* MCG - Peripheral instance base addresses */ +/** Peripheral MCG base address */ +#define MCG_BASE (0x40064000u) +/** Peripheral MCG base pointer */ +#define MCG ((MCG_Type *)MCG_BASE) +/** Array initializer of MCG peripheral base addresses */ +#define MCG_BASE_ADDRS { MCG_BASE } +/** Array initializer of MCG peripheral base pointers */ +#define MCG_BASE_PTRS { MCG } +/** Interrupt vectors for the MCG peripheral type */ +#define MCG_IRQS { MCG_IRQn } +/* MCG C5[PLLCLKEN0] backward compatibility */ +#define MCG_C5_PLLCLKEN0_MASK (MCG_C5_PLLCLKEN_MASK) +#define MCG_C5_PLLCLKEN0_SHIFT (MCG_C5_PLLCLKEN_SHIFT) +#define MCG_C5_PLLCLKEN0_WIDTH (MCG_C5_PLLCLKEN_WIDTH) +#define MCG_C5_PLLCLKEN0(x) (MCG_C5_PLLCLKEN(x)) + +/* MCG C5[PLLSTEN0] backward compatibility */ +#define MCG_C5_PLLSTEN0_MASK (MCG_C5_PLLSTEN_MASK) +#define MCG_C5_PLLSTEN0_SHIFT (MCG_C5_PLLSTEN_SHIFT) +#define MCG_C5_PLLSTEN0_WIDTH (MCG_C5_PLLSTEN_WIDTH) +#define MCG_C5_PLLSTEN0(x) (MCG_C5_PLLSTEN(x)) + +/* MCG C5[PRDIV0] backward compatibility */ +#define MCG_C5_PRDIV0_MASK (MCG_C5_PRDIV_MASK) +#define MCG_C5_PRDIV0_SHIFT (MCG_C5_PRDIV_SHIFT) +#define MCG_C5_PRDIV0_WIDTH (MCG_C5_PRDIV_WIDTH) +#define MCG_C5_PRDIV0(x) (MCG_C5_PRDIV(x)) + +/* MCG C6[VDIV0] backward compatibility */ +#define MCG_C6_VDIV0_MASK (MCG_C6_VDIV_MASK) +#define MCG_C6_VDIV0_SHIFT (MCG_C6_VDIV_SHIFT) +#define MCG_C6_VDIV0_WIDTH (MCG_C6_VDIV_WIDTH) +#define MCG_C6_VDIV0(x) (MCG_C6_VDIV(x)) + + +/*! + * @} + */ /* end of group MCG_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MCM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MCM_Peripheral_Access_Layer MCM Peripheral Access Layer + * @{ + */ + +/** MCM - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[8]; + __I uint16_t PLASC; /**< Crossbar Switch (AXBS) Slave Configuration, offset: 0x8 */ + __I uint16_t PLAMC; /**< Crossbar Switch (AXBS) Master Configuration, offset: 0xA */ + __IO uint32_t CR; /**< Control Register, offset: 0xC */ + __IO uint32_t ISCR; /**< Interrupt Status Register, offset: 0x10 */ + uint8_t RESERVED_1[12]; + __I uint32_t FADR; /**< Fault address register, offset: 0x20 */ + __I uint32_t FATR; /**< Fault attributes register, offset: 0x24 */ + __I uint32_t FDR; /**< Fault data register, offset: 0x28 */ + uint8_t RESERVED_2[4]; + __IO uint32_t PID; /**< Process ID register, offset: 0x30 */ + uint8_t RESERVED_3[12]; + __IO uint32_t CPO; /**< Compute Operation Control Register, offset: 0x40 */ +} MCM_Type; + +/* ---------------------------------------------------------------------------- + -- MCM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MCM_Register_Masks MCM Register Masks + * @{ + */ + +/*! @name PLASC - Crossbar Switch (AXBS) Slave Configuration */ +#define MCM_PLASC_ASC_MASK (0xFFU) +#define MCM_PLASC_ASC_SHIFT (0U) +#define MCM_PLASC_ASC(x) (((uint16_t)(((uint16_t)(x)) << MCM_PLASC_ASC_SHIFT)) & MCM_PLASC_ASC_MASK) + +/*! @name PLAMC - Crossbar Switch (AXBS) Master Configuration */ +#define MCM_PLAMC_AMC_MASK (0xFFU) +#define MCM_PLAMC_AMC_SHIFT (0U) +#define MCM_PLAMC_AMC(x) (((uint16_t)(((uint16_t)(x)) << MCM_PLAMC_AMC_SHIFT)) & MCM_PLAMC_AMC_MASK) + +/*! @name CR - Control Register */ +#define MCM_CR_SRAMUAP_MASK (0x3000000U) +#define MCM_CR_SRAMUAP_SHIFT (24U) +#define MCM_CR_SRAMUAP(x) (((uint32_t)(((uint32_t)(x)) << MCM_CR_SRAMUAP_SHIFT)) & MCM_CR_SRAMUAP_MASK) +#define MCM_CR_SRAMUWP_MASK (0x4000000U) +#define MCM_CR_SRAMUWP_SHIFT (26U) +#define MCM_CR_SRAMUWP(x) (((uint32_t)(((uint32_t)(x)) << MCM_CR_SRAMUWP_SHIFT)) & MCM_CR_SRAMUWP_MASK) +#define MCM_CR_SRAMLAP_MASK (0x30000000U) +#define MCM_CR_SRAMLAP_SHIFT (28U) +#define MCM_CR_SRAMLAP(x) (((uint32_t)(((uint32_t)(x)) << MCM_CR_SRAMLAP_SHIFT)) & MCM_CR_SRAMLAP_MASK) +#define MCM_CR_SRAMLWP_MASK (0x40000000U) +#define MCM_CR_SRAMLWP_SHIFT (30U) +#define MCM_CR_SRAMLWP(x) (((uint32_t)(((uint32_t)(x)) << MCM_CR_SRAMLWP_SHIFT)) & MCM_CR_SRAMLWP_MASK) + +/*! @name ISCR - Interrupt Status Register */ +#define MCM_ISCR_FIOC_MASK (0x100U) +#define MCM_ISCR_FIOC_SHIFT (8U) +#define MCM_ISCR_FIOC(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FIOC_SHIFT)) & MCM_ISCR_FIOC_MASK) +#define MCM_ISCR_FDZC_MASK (0x200U) +#define MCM_ISCR_FDZC_SHIFT (9U) +#define MCM_ISCR_FDZC(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FDZC_SHIFT)) & MCM_ISCR_FDZC_MASK) +#define MCM_ISCR_FOFC_MASK (0x400U) +#define MCM_ISCR_FOFC_SHIFT (10U) +#define MCM_ISCR_FOFC(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FOFC_SHIFT)) & MCM_ISCR_FOFC_MASK) +#define MCM_ISCR_FUFC_MASK (0x800U) +#define MCM_ISCR_FUFC_SHIFT (11U) +#define MCM_ISCR_FUFC(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FUFC_SHIFT)) & MCM_ISCR_FUFC_MASK) +#define MCM_ISCR_FIXC_MASK (0x1000U) +#define MCM_ISCR_FIXC_SHIFT (12U) +#define MCM_ISCR_FIXC(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FIXC_SHIFT)) & MCM_ISCR_FIXC_MASK) +#define MCM_ISCR_FIDC_MASK (0x8000U) +#define MCM_ISCR_FIDC_SHIFT (15U) +#define MCM_ISCR_FIDC(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FIDC_SHIFT)) & MCM_ISCR_FIDC_MASK) +#define MCM_ISCR_FIOCE_MASK (0x1000000U) +#define MCM_ISCR_FIOCE_SHIFT (24U) +#define MCM_ISCR_FIOCE(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FIOCE_SHIFT)) & MCM_ISCR_FIOCE_MASK) +#define MCM_ISCR_FDZCE_MASK (0x2000000U) +#define MCM_ISCR_FDZCE_SHIFT (25U) +#define MCM_ISCR_FDZCE(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FDZCE_SHIFT)) & MCM_ISCR_FDZCE_MASK) +#define MCM_ISCR_FOFCE_MASK (0x4000000U) +#define MCM_ISCR_FOFCE_SHIFT (26U) +#define MCM_ISCR_FOFCE(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FOFCE_SHIFT)) & MCM_ISCR_FOFCE_MASK) +#define MCM_ISCR_FUFCE_MASK (0x8000000U) +#define MCM_ISCR_FUFCE_SHIFT (27U) +#define MCM_ISCR_FUFCE(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FUFCE_SHIFT)) & MCM_ISCR_FUFCE_MASK) +#define MCM_ISCR_FIXCE_MASK (0x10000000U) +#define MCM_ISCR_FIXCE_SHIFT (28U) +#define MCM_ISCR_FIXCE(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FIXCE_SHIFT)) & MCM_ISCR_FIXCE_MASK) +#define MCM_ISCR_FIDCE_MASK (0x80000000U) +#define MCM_ISCR_FIDCE_SHIFT (31U) +#define MCM_ISCR_FIDCE(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FIDCE_SHIFT)) & MCM_ISCR_FIDCE_MASK) + +/*! @name FADR - Fault address register */ +#define MCM_FADR_ADDRESS_MASK (0xFFFFFFFFU) +#define MCM_FADR_ADDRESS_SHIFT (0U) +#define MCM_FADR_ADDRESS(x) (((uint32_t)(((uint32_t)(x)) << MCM_FADR_ADDRESS_SHIFT)) & MCM_FADR_ADDRESS_MASK) + +/*! @name FATR - Fault attributes register */ +#define MCM_FATR_BEDA_MASK (0x1U) +#define MCM_FATR_BEDA_SHIFT (0U) +#define MCM_FATR_BEDA(x) (((uint32_t)(((uint32_t)(x)) << MCM_FATR_BEDA_SHIFT)) & MCM_FATR_BEDA_MASK) +#define MCM_FATR_BEMD_MASK (0x2U) +#define MCM_FATR_BEMD_SHIFT (1U) +#define MCM_FATR_BEMD(x) (((uint32_t)(((uint32_t)(x)) << MCM_FATR_BEMD_SHIFT)) & MCM_FATR_BEMD_MASK) +#define MCM_FATR_BESZ_MASK (0x30U) +#define MCM_FATR_BESZ_SHIFT (4U) +#define MCM_FATR_BESZ(x) (((uint32_t)(((uint32_t)(x)) << MCM_FATR_BESZ_SHIFT)) & MCM_FATR_BESZ_MASK) +#define MCM_FATR_BEWT_MASK (0x80U) +#define MCM_FATR_BEWT_SHIFT (7U) +#define MCM_FATR_BEWT(x) (((uint32_t)(((uint32_t)(x)) << MCM_FATR_BEWT_SHIFT)) & MCM_FATR_BEWT_MASK) +#define MCM_FATR_BEMN_MASK (0xF00U) +#define MCM_FATR_BEMN_SHIFT (8U) +#define MCM_FATR_BEMN(x) (((uint32_t)(((uint32_t)(x)) << MCM_FATR_BEMN_SHIFT)) & MCM_FATR_BEMN_MASK) +#define MCM_FATR_BEOVR_MASK (0x80000000U) +#define MCM_FATR_BEOVR_SHIFT (31U) +#define MCM_FATR_BEOVR(x) (((uint32_t)(((uint32_t)(x)) << MCM_FATR_BEOVR_SHIFT)) & MCM_FATR_BEOVR_MASK) + +/*! @name FDR - Fault data register */ +#define MCM_FDR_DATA_MASK (0xFFFFFFFFU) +#define MCM_FDR_DATA_SHIFT (0U) +#define MCM_FDR_DATA(x) (((uint32_t)(((uint32_t)(x)) << MCM_FDR_DATA_SHIFT)) & MCM_FDR_DATA_MASK) + +/*! @name PID - Process ID register */ +#define MCM_PID_PID_MASK (0xFFU) +#define MCM_PID_PID_SHIFT (0U) +#define MCM_PID_PID(x) (((uint32_t)(((uint32_t)(x)) << MCM_PID_PID_SHIFT)) & MCM_PID_PID_MASK) + +/*! @name CPO - Compute Operation Control Register */ +#define MCM_CPO_CPOREQ_MASK (0x1U) +#define MCM_CPO_CPOREQ_SHIFT (0U) +#define MCM_CPO_CPOREQ(x) (((uint32_t)(((uint32_t)(x)) << MCM_CPO_CPOREQ_SHIFT)) & MCM_CPO_CPOREQ_MASK) +#define MCM_CPO_CPOACK_MASK (0x2U) +#define MCM_CPO_CPOACK_SHIFT (1U) +#define MCM_CPO_CPOACK(x) (((uint32_t)(((uint32_t)(x)) << MCM_CPO_CPOACK_SHIFT)) & MCM_CPO_CPOACK_MASK) +#define MCM_CPO_CPOWOI_MASK (0x4U) +#define MCM_CPO_CPOWOI_SHIFT (2U) +#define MCM_CPO_CPOWOI(x) (((uint32_t)(((uint32_t)(x)) << MCM_CPO_CPOWOI_SHIFT)) & MCM_CPO_CPOWOI_MASK) + + +/*! + * @} + */ /* end of group MCM_Register_Masks */ + + +/* MCM - Peripheral instance base addresses */ +/** Peripheral MCM base address */ +#define MCM_BASE (0xE0080000u) +/** Peripheral MCM base pointer */ +#define MCM ((MCM_Type *)MCM_BASE) +/** Array initializer of MCM peripheral base addresses */ +#define MCM_BASE_ADDRS { MCM_BASE } +/** Array initializer of MCM peripheral base pointers */ +#define MCM_BASE_PTRS { MCM } +/** Interrupt vectors for the MCM peripheral type */ +#define MCM_IRQS { MCM_IRQn } + +/*! + * @} + */ /* end of group MCM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MPU Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MPU_Peripheral_Access_Layer MPU Peripheral Access Layer + * @{ + */ + +/** MPU - Register Layout Typedef */ +typedef struct { + __IO uint32_t CESR; /**< Control/Error Status Register, offset: 0x0 */ + uint8_t RESERVED_0[12]; + struct { /* offset: 0x10, array step: 0x8 */ + __I uint32_t EAR; /**< Error Address Register, slave port n, array offset: 0x10, array step: 0x8 */ + __I uint32_t EDR; /**< Error Detail Register, slave port n, array offset: 0x14, array step: 0x8 */ + } SP[5]; + uint8_t RESERVED_1[968]; + __IO uint32_t WORD[12][4]; /**< Region Descriptor n, Word 0..Region Descriptor n, Word 3, array offset: 0x400, array step: index*0x10, index2*0x4 */ + uint8_t RESERVED_2[832]; + __IO uint32_t RGDAAC[12]; /**< Region Descriptor Alternate Access Control n, array offset: 0x800, array step: 0x4 */ +} MPU_Type; + +/* ---------------------------------------------------------------------------- + -- MPU Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MPU_Register_Masks MPU Register Masks + * @{ + */ + +/*! @name CESR - Control/Error Status Register */ +#define MPU_CESR_VLD_MASK (0x1U) +#define MPU_CESR_VLD_SHIFT (0U) +#define MPU_CESR_VLD(x) (((uint32_t)(((uint32_t)(x)) << MPU_CESR_VLD_SHIFT)) & MPU_CESR_VLD_MASK) +#define MPU_CESR_NRGD_MASK (0xF00U) +#define MPU_CESR_NRGD_SHIFT (8U) +#define MPU_CESR_NRGD(x) (((uint32_t)(((uint32_t)(x)) << MPU_CESR_NRGD_SHIFT)) & MPU_CESR_NRGD_MASK) +#define MPU_CESR_NSP_MASK (0xF000U) +#define MPU_CESR_NSP_SHIFT (12U) +#define MPU_CESR_NSP(x) (((uint32_t)(((uint32_t)(x)) << MPU_CESR_NSP_SHIFT)) & MPU_CESR_NSP_MASK) +#define MPU_CESR_HRL_MASK (0xF0000U) +#define MPU_CESR_HRL_SHIFT (16U) +#define MPU_CESR_HRL(x) (((uint32_t)(((uint32_t)(x)) << MPU_CESR_HRL_SHIFT)) & MPU_CESR_HRL_MASK) +#define MPU_CESR_SPERR_MASK (0xF8000000U) +#define MPU_CESR_SPERR_SHIFT (27U) +#define MPU_CESR_SPERR(x) (((uint32_t)(((uint32_t)(x)) << MPU_CESR_SPERR_SHIFT)) & MPU_CESR_SPERR_MASK) + +/*! @name EAR - Error Address Register, slave port n */ +#define MPU_EAR_EADDR_MASK (0xFFFFFFFFU) +#define MPU_EAR_EADDR_SHIFT (0U) +#define MPU_EAR_EADDR(x) (((uint32_t)(((uint32_t)(x)) << MPU_EAR_EADDR_SHIFT)) & MPU_EAR_EADDR_MASK) + +/* The count of MPU_EAR */ +#define MPU_EAR_COUNT (5U) + +/*! @name EDR - Error Detail Register, slave port n */ +#define MPU_EDR_ERW_MASK (0x1U) +#define MPU_EDR_ERW_SHIFT (0U) +#define MPU_EDR_ERW(x) (((uint32_t)(((uint32_t)(x)) << MPU_EDR_ERW_SHIFT)) & MPU_EDR_ERW_MASK) +#define MPU_EDR_EATTR_MASK (0xEU) +#define MPU_EDR_EATTR_SHIFT (1U) +#define MPU_EDR_EATTR(x) (((uint32_t)(((uint32_t)(x)) << MPU_EDR_EATTR_SHIFT)) & MPU_EDR_EATTR_MASK) +#define MPU_EDR_EMN_MASK (0xF0U) +#define MPU_EDR_EMN_SHIFT (4U) +#define MPU_EDR_EMN(x) (((uint32_t)(((uint32_t)(x)) << MPU_EDR_EMN_SHIFT)) & MPU_EDR_EMN_MASK) +#define MPU_EDR_EPID_MASK (0xFF00U) +#define MPU_EDR_EPID_SHIFT (8U) +#define MPU_EDR_EPID(x) (((uint32_t)(((uint32_t)(x)) << MPU_EDR_EPID_SHIFT)) & MPU_EDR_EPID_MASK) +#define MPU_EDR_EACD_MASK (0xFFFF0000U) +#define MPU_EDR_EACD_SHIFT (16U) +#define MPU_EDR_EACD(x) (((uint32_t)(((uint32_t)(x)) << MPU_EDR_EACD_SHIFT)) & MPU_EDR_EACD_MASK) + +/* The count of MPU_EDR */ +#define MPU_EDR_COUNT (5U) + +/*! @name WORD - Region Descriptor n, Word 0..Region Descriptor n, Word 3 */ +#define MPU_WORD_VLD_MASK (0x1U) +#define MPU_WORD_VLD_SHIFT (0U) +#define MPU_WORD_VLD(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_VLD_SHIFT)) & MPU_WORD_VLD_MASK) +#define MPU_WORD_M0UM_MASK (0x7U) +#define MPU_WORD_M0UM_SHIFT (0U) +#define MPU_WORD_M0UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M0UM_SHIFT)) & MPU_WORD_M0UM_MASK) +#define MPU_WORD_M0SM_MASK (0x18U) +#define MPU_WORD_M0SM_SHIFT (3U) +#define MPU_WORD_M0SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M0SM_SHIFT)) & MPU_WORD_M0SM_MASK) +#define MPU_WORD_M0PE_MASK (0x20U) +#define MPU_WORD_M0PE_SHIFT (5U) +#define MPU_WORD_M0PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M0PE_SHIFT)) & MPU_WORD_M0PE_MASK) +#define MPU_WORD_ENDADDR_MASK (0xFFFFFFE0U) +#define MPU_WORD_ENDADDR_SHIFT (5U) +#define MPU_WORD_ENDADDR(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_ENDADDR_SHIFT)) & MPU_WORD_ENDADDR_MASK) +#define MPU_WORD_SRTADDR_MASK (0xFFFFFFE0U) +#define MPU_WORD_SRTADDR_SHIFT (5U) +#define MPU_WORD_SRTADDR(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_SRTADDR_SHIFT)) & MPU_WORD_SRTADDR_MASK) +#define MPU_WORD_M1UM_MASK (0x1C0U) +#define MPU_WORD_M1UM_SHIFT (6U) +#define MPU_WORD_M1UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M1UM_SHIFT)) & MPU_WORD_M1UM_MASK) +#define MPU_WORD_M1SM_MASK (0x600U) +#define MPU_WORD_M1SM_SHIFT (9U) +#define MPU_WORD_M1SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M1SM_SHIFT)) & MPU_WORD_M1SM_MASK) +#define MPU_WORD_M1PE_MASK (0x800U) +#define MPU_WORD_M1PE_SHIFT (11U) +#define MPU_WORD_M1PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M1PE_SHIFT)) & MPU_WORD_M1PE_MASK) +#define MPU_WORD_M2UM_MASK (0x7000U) +#define MPU_WORD_M2UM_SHIFT (12U) +#define MPU_WORD_M2UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M2UM_SHIFT)) & MPU_WORD_M2UM_MASK) +#define MPU_WORD_M2SM_MASK (0x18000U) +#define MPU_WORD_M2SM_SHIFT (15U) +#define MPU_WORD_M2SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M2SM_SHIFT)) & MPU_WORD_M2SM_MASK) +#define MPU_WORD_PIDMASK_MASK (0xFF0000U) +#define MPU_WORD_PIDMASK_SHIFT (16U) +#define MPU_WORD_PIDMASK(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_PIDMASK_SHIFT)) & MPU_WORD_PIDMASK_MASK) +#define MPU_WORD_M2PE_MASK (0x20000U) +#define MPU_WORD_M2PE_SHIFT (17U) +#define MPU_WORD_M2PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M2PE_SHIFT)) & MPU_WORD_M2PE_MASK) +#define MPU_WORD_M3UM_MASK (0x1C0000U) +#define MPU_WORD_M3UM_SHIFT (18U) +#define MPU_WORD_M3UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M3UM_SHIFT)) & MPU_WORD_M3UM_MASK) +#define MPU_WORD_M3SM_MASK (0x600000U) +#define MPU_WORD_M3SM_SHIFT (21U) +#define MPU_WORD_M3SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M3SM_SHIFT)) & MPU_WORD_M3SM_MASK) +#define MPU_WORD_M3PE_MASK (0x800000U) +#define MPU_WORD_M3PE_SHIFT (23U) +#define MPU_WORD_M3PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M3PE_SHIFT)) & MPU_WORD_M3PE_MASK) +#define MPU_WORD_PID_MASK (0xFF000000U) +#define MPU_WORD_PID_SHIFT (24U) +#define MPU_WORD_PID(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_PID_SHIFT)) & MPU_WORD_PID_MASK) +#define MPU_WORD_M4WE_MASK (0x1000000U) +#define MPU_WORD_M4WE_SHIFT (24U) +#define MPU_WORD_M4WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M4WE_SHIFT)) & MPU_WORD_M4WE_MASK) +#define MPU_WORD_M4RE_MASK (0x2000000U) +#define MPU_WORD_M4RE_SHIFT (25U) +#define MPU_WORD_M4RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M4RE_SHIFT)) & MPU_WORD_M4RE_MASK) +#define MPU_WORD_M5WE_MASK (0x4000000U) +#define MPU_WORD_M5WE_SHIFT (26U) +#define MPU_WORD_M5WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M5WE_SHIFT)) & MPU_WORD_M5WE_MASK) +#define MPU_WORD_M5RE_MASK (0x8000000U) +#define MPU_WORD_M5RE_SHIFT (27U) +#define MPU_WORD_M5RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M5RE_SHIFT)) & MPU_WORD_M5RE_MASK) +#define MPU_WORD_M6WE_MASK (0x10000000U) +#define MPU_WORD_M6WE_SHIFT (28U) +#define MPU_WORD_M6WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M6WE_SHIFT)) & MPU_WORD_M6WE_MASK) +#define MPU_WORD_M6RE_MASK (0x20000000U) +#define MPU_WORD_M6RE_SHIFT (29U) +#define MPU_WORD_M6RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M6RE_SHIFT)) & MPU_WORD_M6RE_MASK) +#define MPU_WORD_M7WE_MASK (0x40000000U) +#define MPU_WORD_M7WE_SHIFT (30U) +#define MPU_WORD_M7WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M7WE_SHIFT)) & MPU_WORD_M7WE_MASK) +#define MPU_WORD_M7RE_MASK (0x80000000U) +#define MPU_WORD_M7RE_SHIFT (31U) +#define MPU_WORD_M7RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M7RE_SHIFT)) & MPU_WORD_M7RE_MASK) + +/* The count of MPU_WORD */ +#define MPU_WORD_COUNT (12U) + +/* The count of MPU_WORD */ +#define MPU_WORD_COUNT2 (4U) + +/*! @name RGDAAC - Region Descriptor Alternate Access Control n */ +#define MPU_RGDAAC_M0UM_MASK (0x7U) +#define MPU_RGDAAC_M0UM_SHIFT (0U) +#define MPU_RGDAAC_M0UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M0UM_SHIFT)) & MPU_RGDAAC_M0UM_MASK) +#define MPU_RGDAAC_M0SM_MASK (0x18U) +#define MPU_RGDAAC_M0SM_SHIFT (3U) +#define MPU_RGDAAC_M0SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M0SM_SHIFT)) & MPU_RGDAAC_M0SM_MASK) +#define MPU_RGDAAC_M0PE_MASK (0x20U) +#define MPU_RGDAAC_M0PE_SHIFT (5U) +#define MPU_RGDAAC_M0PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M0PE_SHIFT)) & MPU_RGDAAC_M0PE_MASK) +#define MPU_RGDAAC_M1UM_MASK (0x1C0U) +#define MPU_RGDAAC_M1UM_SHIFT (6U) +#define MPU_RGDAAC_M1UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M1UM_SHIFT)) & MPU_RGDAAC_M1UM_MASK) +#define MPU_RGDAAC_M1SM_MASK (0x600U) +#define MPU_RGDAAC_M1SM_SHIFT (9U) +#define MPU_RGDAAC_M1SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M1SM_SHIFT)) & MPU_RGDAAC_M1SM_MASK) +#define MPU_RGDAAC_M1PE_MASK (0x800U) +#define MPU_RGDAAC_M1PE_SHIFT (11U) +#define MPU_RGDAAC_M1PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M1PE_SHIFT)) & MPU_RGDAAC_M1PE_MASK) +#define MPU_RGDAAC_M2UM_MASK (0x7000U) +#define MPU_RGDAAC_M2UM_SHIFT (12U) +#define MPU_RGDAAC_M2UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M2UM_SHIFT)) & MPU_RGDAAC_M2UM_MASK) +#define MPU_RGDAAC_M2SM_MASK (0x18000U) +#define MPU_RGDAAC_M2SM_SHIFT (15U) +#define MPU_RGDAAC_M2SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M2SM_SHIFT)) & MPU_RGDAAC_M2SM_MASK) +#define MPU_RGDAAC_M2PE_MASK (0x20000U) +#define MPU_RGDAAC_M2PE_SHIFT (17U) +#define MPU_RGDAAC_M2PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M2PE_SHIFT)) & MPU_RGDAAC_M2PE_MASK) +#define MPU_RGDAAC_M3UM_MASK (0x1C0000U) +#define MPU_RGDAAC_M3UM_SHIFT (18U) +#define MPU_RGDAAC_M3UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M3UM_SHIFT)) & MPU_RGDAAC_M3UM_MASK) +#define MPU_RGDAAC_M3SM_MASK (0x600000U) +#define MPU_RGDAAC_M3SM_SHIFT (21U) +#define MPU_RGDAAC_M3SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M3SM_SHIFT)) & MPU_RGDAAC_M3SM_MASK) +#define MPU_RGDAAC_M3PE_MASK (0x800000U) +#define MPU_RGDAAC_M3PE_SHIFT (23U) +#define MPU_RGDAAC_M3PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M3PE_SHIFT)) & MPU_RGDAAC_M3PE_MASK) +#define MPU_RGDAAC_M4WE_MASK (0x1000000U) +#define MPU_RGDAAC_M4WE_SHIFT (24U) +#define MPU_RGDAAC_M4WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M4WE_SHIFT)) & MPU_RGDAAC_M4WE_MASK) +#define MPU_RGDAAC_M4RE_MASK (0x2000000U) +#define MPU_RGDAAC_M4RE_SHIFT (25U) +#define MPU_RGDAAC_M4RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M4RE_SHIFT)) & MPU_RGDAAC_M4RE_MASK) +#define MPU_RGDAAC_M5WE_MASK (0x4000000U) +#define MPU_RGDAAC_M5WE_SHIFT (26U) +#define MPU_RGDAAC_M5WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M5WE_SHIFT)) & MPU_RGDAAC_M5WE_MASK) +#define MPU_RGDAAC_M5RE_MASK (0x8000000U) +#define MPU_RGDAAC_M5RE_SHIFT (27U) +#define MPU_RGDAAC_M5RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M5RE_SHIFT)) & MPU_RGDAAC_M5RE_MASK) +#define MPU_RGDAAC_M6WE_MASK (0x10000000U) +#define MPU_RGDAAC_M6WE_SHIFT (28U) +#define MPU_RGDAAC_M6WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M6WE_SHIFT)) & MPU_RGDAAC_M6WE_MASK) +#define MPU_RGDAAC_M6RE_MASK (0x20000000U) +#define MPU_RGDAAC_M6RE_SHIFT (29U) +#define MPU_RGDAAC_M6RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M6RE_SHIFT)) & MPU_RGDAAC_M6RE_MASK) +#define MPU_RGDAAC_M7WE_MASK (0x40000000U) +#define MPU_RGDAAC_M7WE_SHIFT (30U) +#define MPU_RGDAAC_M7WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M7WE_SHIFT)) & MPU_RGDAAC_M7WE_MASK) +#define MPU_RGDAAC_M7RE_MASK (0x80000000U) +#define MPU_RGDAAC_M7RE_SHIFT (31U) +#define MPU_RGDAAC_M7RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M7RE_SHIFT)) & MPU_RGDAAC_M7RE_MASK) + +/* The count of MPU_RGDAAC */ +#define MPU_RGDAAC_COUNT (12U) + + +/*! + * @} + */ /* end of group MPU_Register_Masks */ + + +/* MPU - Peripheral instance base addresses */ +/** Peripheral MPU base address */ +#define MPU_BASE (0x4000D000u) +/** Peripheral MPU base pointer */ +#define MPU ((MPU_Type *)MPU_BASE) +/** Array initializer of MPU peripheral base addresses */ +#define MPU_BASE_ADDRS { MPU_BASE } +/** Array initializer of MPU peripheral base pointers */ +#define MPU_BASE_PTRS { MPU } + +/*! + * @} + */ /* end of group MPU_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- NV Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup NV_Peripheral_Access_Layer NV Peripheral Access Layer + * @{ + */ + +/** NV - Register Layout Typedef */ +typedef struct { + __I uint8_t BACKKEY3; /**< Backdoor Comparison Key 3., offset: 0x0 */ + __I uint8_t BACKKEY2; /**< Backdoor Comparison Key 2., offset: 0x1 */ + __I uint8_t BACKKEY1; /**< Backdoor Comparison Key 1., offset: 0x2 */ + __I uint8_t BACKKEY0; /**< Backdoor Comparison Key 0., offset: 0x3 */ + __I uint8_t BACKKEY7; /**< Backdoor Comparison Key 7., offset: 0x4 */ + __I uint8_t BACKKEY6; /**< Backdoor Comparison Key 6., offset: 0x5 */ + __I uint8_t BACKKEY5; /**< Backdoor Comparison Key 5., offset: 0x6 */ + __I uint8_t BACKKEY4; /**< Backdoor Comparison Key 4., offset: 0x7 */ + __I uint8_t FPROT3; /**< Non-volatile P-Flash Protection 1 - Low Register, offset: 0x8 */ + __I uint8_t FPROT2; /**< Non-volatile P-Flash Protection 1 - High Register, offset: 0x9 */ + __I uint8_t FPROT1; /**< Non-volatile P-Flash Protection 0 - Low Register, offset: 0xA */ + __I uint8_t FPROT0; /**< Non-volatile P-Flash Protection 0 - High Register, offset: 0xB */ + __I uint8_t FSEC; /**< Non-volatile Flash Security Register, offset: 0xC */ + __I uint8_t FOPT; /**< Non-volatile Flash Option Register, offset: 0xD */ +} NV_Type; + +/* ---------------------------------------------------------------------------- + -- NV Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup NV_Register_Masks NV Register Masks + * @{ + */ + +/*! @name BACKKEY3 - Backdoor Comparison Key 3. */ +#define NV_BACKKEY3_KEY_MASK (0xFFU) +#define NV_BACKKEY3_KEY_SHIFT (0U) +#define NV_BACKKEY3_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY3_KEY_SHIFT)) & NV_BACKKEY3_KEY_MASK) + +/*! @name BACKKEY2 - Backdoor Comparison Key 2. */ +#define NV_BACKKEY2_KEY_MASK (0xFFU) +#define NV_BACKKEY2_KEY_SHIFT (0U) +#define NV_BACKKEY2_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY2_KEY_SHIFT)) & NV_BACKKEY2_KEY_MASK) + +/*! @name BACKKEY1 - Backdoor Comparison Key 1. */ +#define NV_BACKKEY1_KEY_MASK (0xFFU) +#define NV_BACKKEY1_KEY_SHIFT (0U) +#define NV_BACKKEY1_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY1_KEY_SHIFT)) & NV_BACKKEY1_KEY_MASK) + +/*! @name BACKKEY0 - Backdoor Comparison Key 0. */ +#define NV_BACKKEY0_KEY_MASK (0xFFU) +#define NV_BACKKEY0_KEY_SHIFT (0U) +#define NV_BACKKEY0_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY0_KEY_SHIFT)) & NV_BACKKEY0_KEY_MASK) + +/*! @name BACKKEY7 - Backdoor Comparison Key 7. */ +#define NV_BACKKEY7_KEY_MASK (0xFFU) +#define NV_BACKKEY7_KEY_SHIFT (0U) +#define NV_BACKKEY7_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY7_KEY_SHIFT)) & NV_BACKKEY7_KEY_MASK) + +/*! @name BACKKEY6 - Backdoor Comparison Key 6. */ +#define NV_BACKKEY6_KEY_MASK (0xFFU) +#define NV_BACKKEY6_KEY_SHIFT (0U) +#define NV_BACKKEY6_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY6_KEY_SHIFT)) & NV_BACKKEY6_KEY_MASK) + +/*! @name BACKKEY5 - Backdoor Comparison Key 5. */ +#define NV_BACKKEY5_KEY_MASK (0xFFU) +#define NV_BACKKEY5_KEY_SHIFT (0U) +#define NV_BACKKEY5_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY5_KEY_SHIFT)) & NV_BACKKEY5_KEY_MASK) + +/*! @name BACKKEY4 - Backdoor Comparison Key 4. */ +#define NV_BACKKEY4_KEY_MASK (0xFFU) +#define NV_BACKKEY4_KEY_SHIFT (0U) +#define NV_BACKKEY4_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY4_KEY_SHIFT)) & NV_BACKKEY4_KEY_MASK) + +/*! @name FPROT3 - Non-volatile P-Flash Protection 1 - Low Register */ +#define NV_FPROT3_PROT_MASK (0xFFU) +#define NV_FPROT3_PROT_SHIFT (0U) +#define NV_FPROT3_PROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FPROT3_PROT_SHIFT)) & NV_FPROT3_PROT_MASK) + +/*! @name FPROT2 - Non-volatile P-Flash Protection 1 - High Register */ +#define NV_FPROT2_PROT_MASK (0xFFU) +#define NV_FPROT2_PROT_SHIFT (0U) +#define NV_FPROT2_PROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FPROT2_PROT_SHIFT)) & NV_FPROT2_PROT_MASK) + +/*! @name FPROT1 - Non-volatile P-Flash Protection 0 - Low Register */ +#define NV_FPROT1_PROT_MASK (0xFFU) +#define NV_FPROT1_PROT_SHIFT (0U) +#define NV_FPROT1_PROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FPROT1_PROT_SHIFT)) & NV_FPROT1_PROT_MASK) + +/*! @name FPROT0 - Non-volatile P-Flash Protection 0 - High Register */ +#define NV_FPROT0_PROT_MASK (0xFFU) +#define NV_FPROT0_PROT_SHIFT (0U) +#define NV_FPROT0_PROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FPROT0_PROT_SHIFT)) & NV_FPROT0_PROT_MASK) + +/*! @name FSEC - Non-volatile Flash Security Register */ +#define NV_FSEC_SEC_MASK (0x3U) +#define NV_FSEC_SEC_SHIFT (0U) +#define NV_FSEC_SEC(x) (((uint8_t)(((uint8_t)(x)) << NV_FSEC_SEC_SHIFT)) & NV_FSEC_SEC_MASK) +#define NV_FSEC_FSLACC_MASK (0xCU) +#define NV_FSEC_FSLACC_SHIFT (2U) +#define NV_FSEC_FSLACC(x) (((uint8_t)(((uint8_t)(x)) << NV_FSEC_FSLACC_SHIFT)) & NV_FSEC_FSLACC_MASK) +#define NV_FSEC_MEEN_MASK (0x30U) +#define NV_FSEC_MEEN_SHIFT (4U) +#define NV_FSEC_MEEN(x) (((uint8_t)(((uint8_t)(x)) << NV_FSEC_MEEN_SHIFT)) & NV_FSEC_MEEN_MASK) +#define NV_FSEC_KEYEN_MASK (0xC0U) +#define NV_FSEC_KEYEN_SHIFT (6U) +#define NV_FSEC_KEYEN(x) (((uint8_t)(((uint8_t)(x)) << NV_FSEC_KEYEN_SHIFT)) & NV_FSEC_KEYEN_MASK) + +/*! @name FOPT - Non-volatile Flash Option Register */ +#define NV_FOPT_LPBOOT_MASK (0x1U) +#define NV_FOPT_LPBOOT_SHIFT (0U) +#define NV_FOPT_LPBOOT(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_LPBOOT_SHIFT)) & NV_FOPT_LPBOOT_MASK) +#define NV_FOPT_BOOTPIN_OPT_MASK (0x2U) +#define NV_FOPT_BOOTPIN_OPT_SHIFT (1U) +#define NV_FOPT_BOOTPIN_OPT(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_BOOTPIN_OPT_SHIFT)) & NV_FOPT_BOOTPIN_OPT_MASK) +#define NV_FOPT_NMI_DIS_MASK (0x4U) +#define NV_FOPT_NMI_DIS_SHIFT (2U) +#define NV_FOPT_NMI_DIS(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_NMI_DIS_SHIFT)) & NV_FOPT_NMI_DIS_MASK) +#define NV_FOPT_FAST_INIT_MASK (0x20U) +#define NV_FOPT_FAST_INIT_SHIFT (5U) +#define NV_FOPT_FAST_INIT(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_FAST_INIT_SHIFT)) & NV_FOPT_FAST_INIT_MASK) +#define NV_FOPT_BOOTSRC_SEL_MASK (0xC0U) +#define NV_FOPT_BOOTSRC_SEL_SHIFT (6U) +#define NV_FOPT_BOOTSRC_SEL(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_BOOTSRC_SEL_SHIFT)) & NV_FOPT_BOOTSRC_SEL_MASK) + + +/*! + * @} + */ /* end of group NV_Register_Masks */ + + +/* NV - Peripheral instance base addresses */ +/** Peripheral FTFA_FlashConfig base address */ +#define FTFA_FlashConfig_BASE (0x400u) +/** Peripheral FTFA_FlashConfig base pointer */ +#define FTFA_FlashConfig ((NV_Type *)FTFA_FlashConfig_BASE) +/** Array initializer of NV peripheral base addresses */ +#define NV_BASE_ADDRS { FTFA_FlashConfig_BASE } +/** Array initializer of NV peripheral base pointers */ +#define NV_BASE_PTRS { FTFA_FlashConfig } + +/*! + * @} + */ /* end of group NV_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- OSC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup OSC_Peripheral_Access_Layer OSC Peripheral Access Layer + * @{ + */ + +/** OSC - Register Layout Typedef */ +typedef struct { + __IO uint8_t CR; /**< OSC Control Register, offset: 0x0 */ + uint8_t RESERVED_0[1]; + __IO uint8_t DIV; /**< OSC_DIV, offset: 0x2 */ +} OSC_Type; + +/* ---------------------------------------------------------------------------- + -- OSC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup OSC_Register_Masks OSC Register Masks + * @{ + */ + +/*! @name CR - OSC Control Register */ +#define OSC_CR_SC16P_MASK (0x1U) +#define OSC_CR_SC16P_SHIFT (0U) +#define OSC_CR_SC16P(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_SC16P_SHIFT)) & OSC_CR_SC16P_MASK) +#define OSC_CR_SC8P_MASK (0x2U) +#define OSC_CR_SC8P_SHIFT (1U) +#define OSC_CR_SC8P(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_SC8P_SHIFT)) & OSC_CR_SC8P_MASK) +#define OSC_CR_SC4P_MASK (0x4U) +#define OSC_CR_SC4P_SHIFT (2U) +#define OSC_CR_SC4P(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_SC4P_SHIFT)) & OSC_CR_SC4P_MASK) +#define OSC_CR_SC2P_MASK (0x8U) +#define OSC_CR_SC2P_SHIFT (3U) +#define OSC_CR_SC2P(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_SC2P_SHIFT)) & OSC_CR_SC2P_MASK) +#define OSC_CR_EREFSTEN_MASK (0x20U) +#define OSC_CR_EREFSTEN_SHIFT (5U) +#define OSC_CR_EREFSTEN(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_EREFSTEN_SHIFT)) & OSC_CR_EREFSTEN_MASK) +#define OSC_CR_ERCLKEN_MASK (0x80U) +#define OSC_CR_ERCLKEN_SHIFT (7U) +#define OSC_CR_ERCLKEN(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_ERCLKEN_SHIFT)) & OSC_CR_ERCLKEN_MASK) + +/*! @name DIV - OSC_DIV */ +#define OSC_DIV_ERPS_MASK (0xC0U) +#define OSC_DIV_ERPS_SHIFT (6U) +#define OSC_DIV_ERPS(x) (((uint8_t)(((uint8_t)(x)) << OSC_DIV_ERPS_SHIFT)) & OSC_DIV_ERPS_MASK) + + +/*! + * @} + */ /* end of group OSC_Register_Masks */ + + +/* OSC - Peripheral instance base addresses */ +/** Peripheral OSC base address */ +#define OSC_BASE (0x40065000u) +/** Peripheral OSC base pointer */ +#define OSC ((OSC_Type *)OSC_BASE) +/** Array initializer of OSC peripheral base addresses */ +#define OSC_BASE_ADDRS { OSC_BASE } +/** Array initializer of OSC peripheral base pointers */ +#define OSC_BASE_PTRS { OSC } + +/*! + * @} + */ /* end of group OSC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- OTFAD Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup OTFAD_Peripheral_Access_Layer OTFAD Peripheral Access Layer + * @{ + */ + +/** OTFAD - Register Layout Typedef */ +typedef struct { + __IO uint32_t CR; /**< Control Register, offset: 0x0 */ + __I uint32_t SR; /**< Status Register, offset: 0x4 */ + __IO uint32_t CRC; /**< Cyclic Redundancy Check Register, offset: 0x8 */ + uint8_t RESERVED_0[244]; + struct { /* offset: 0x100, array step: 0x40 */ + __IO uint32_t CTX_KEY[4]; /**< AES Key Word0..AES Key Word3, array offset: 0x100, array step: index*0x40, index2*0x4 */ + __IO uint32_t CTX_CTR[2]; /**< AES Counter Word0..AES Counter Word1, array offset: 0x110, array step: index*0x40, index2*0x4 */ + __IO uint32_t CTX_RGD[2]; /**< AES Region Descriptor Word0..AES Region Descriptor Word1, array offset: 0x118, array step: index*0x40, index2*0x4 */ + uint8_t RESERVED_0[32]; + } CTX[4]; +} OTFAD_Type; + +/* ---------------------------------------------------------------------------- + -- OTFAD Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup OTFAD_Register_Masks OTFAD Register Masks + * @{ + */ + +/*! @name CR - Control Register */ +#define OTFAD_CR_FSVM_MASK (0x4U) +#define OTFAD_CR_FSVM_SHIFT (2U) +#define OTFAD_CR_FSVM(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CR_FSVM_SHIFT)) & OTFAD_CR_FSVM_MASK) +#define OTFAD_CR_FLDM_MASK (0x8U) +#define OTFAD_CR_FLDM_SHIFT (3U) +#define OTFAD_CR_FLDM(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CR_FLDM_SHIFT)) & OTFAD_CR_FLDM_MASK) +#define OTFAD_CR_RRAE_MASK (0x80U) +#define OTFAD_CR_RRAE_SHIFT (7U) +#define OTFAD_CR_RRAE(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CR_RRAE_SHIFT)) & OTFAD_CR_RRAE_MASK) +#define OTFAD_CR_CCTX_MASK (0x30000U) +#define OTFAD_CR_CCTX_SHIFT (16U) +#define OTFAD_CR_CCTX(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CR_CCTX_SHIFT)) & OTFAD_CR_CCTX_MASK) +#define OTFAD_CR_CRCE_MASK (0x100000U) +#define OTFAD_CR_CRCE_SHIFT (20U) +#define OTFAD_CR_CRCE(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CR_CRCE_SHIFT)) & OTFAD_CR_CRCE_MASK) +#define OTFAD_CR_CRCI_MASK (0x200000U) +#define OTFAD_CR_CRCI_SHIFT (21U) +#define OTFAD_CR_CRCI(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CR_CRCI_SHIFT)) & OTFAD_CR_CRCI_MASK) +#define OTFAD_CR_GE_MASK (0x80000000U) +#define OTFAD_CR_GE_SHIFT (31U) +#define OTFAD_CR_GE(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CR_GE_SHIFT)) & OTFAD_CR_GE_MASK) + +/*! @name SR - Status Register */ +#define OTFAD_SR_MDPCP_MASK (0x2U) +#define OTFAD_SR_MDPCP_SHIFT (1U) +#define OTFAD_SR_MDPCP(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_SR_MDPCP_SHIFT)) & OTFAD_SR_MDPCP_MASK) +#define OTFAD_SR_MODE_MASK (0xCU) +#define OTFAD_SR_MODE_SHIFT (2U) +#define OTFAD_SR_MODE(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_SR_MODE_SHIFT)) & OTFAD_SR_MODE_MASK) +#define OTFAD_SR_NCTX_MASK (0xF0U) +#define OTFAD_SR_NCTX_SHIFT (4U) +#define OTFAD_SR_NCTX(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_SR_NCTX_SHIFT)) & OTFAD_SR_NCTX_MASK) +#define OTFAD_SR_HRL_MASK (0xF000000U) +#define OTFAD_SR_HRL_SHIFT (24U) +#define OTFAD_SR_HRL(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_SR_HRL_SHIFT)) & OTFAD_SR_HRL_MASK) +#define OTFAD_SR_RRAM_MASK (0x10000000U) +#define OTFAD_SR_RRAM_SHIFT (28U) +#define OTFAD_SR_RRAM(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_SR_RRAM_SHIFT)) & OTFAD_SR_RRAM_MASK) +#define OTFAD_SR_GEM_MASK (0x20000000U) +#define OTFAD_SR_GEM_SHIFT (29U) +#define OTFAD_SR_GEM(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_SR_GEM_SHIFT)) & OTFAD_SR_GEM_MASK) + +/*! @name CRC - Cyclic Redundancy Check Register */ +#define OTFAD_CRC_CRCD_MASK (0xFFFFFFFFU) +#define OTFAD_CRC_CRCD_SHIFT (0U) +#define OTFAD_CRC_CRCD(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CRC_CRCD_SHIFT)) & OTFAD_CRC_CRCD_MASK) + +/*! @name CTX_KEY - AES Key Word0..AES Key Word3 */ +#define OTFAD_CTX_KEY_W0KEY_MASK (0xFFFFFFFFU) +#define OTFAD_CTX_KEY_W0KEY_SHIFT (0U) +#define OTFAD_CTX_KEY_W0KEY(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CTX_KEY_W0KEY_SHIFT)) & OTFAD_CTX_KEY_W0KEY_MASK) +#define OTFAD_CTX_KEY_W1KEY_MASK (0xFFFFFFFFU) +#define OTFAD_CTX_KEY_W1KEY_SHIFT (0U) +#define OTFAD_CTX_KEY_W1KEY(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CTX_KEY_W1KEY_SHIFT)) & OTFAD_CTX_KEY_W1KEY_MASK) +#define OTFAD_CTX_KEY_W2KEY_MASK (0xFFFFFFFFU) +#define OTFAD_CTX_KEY_W2KEY_SHIFT (0U) +#define OTFAD_CTX_KEY_W2KEY(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CTX_KEY_W2KEY_SHIFT)) & OTFAD_CTX_KEY_W2KEY_MASK) +#define OTFAD_CTX_KEY_W3KEY_MASK (0xFFFFFFFFU) +#define OTFAD_CTX_KEY_W3KEY_SHIFT (0U) +#define OTFAD_CTX_KEY_W3KEY(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CTX_KEY_W3KEY_SHIFT)) & OTFAD_CTX_KEY_W3KEY_MASK) + +/* The count of OTFAD_CTX_KEY */ +#define OTFAD_CTX_KEY_COUNT (4U) + +/* The count of OTFAD_CTX_KEY */ +#define OTFAD_CTX_KEY_COUNT2 (4U) + +/*! @name CTX_CTR - AES Counter Word0..AES Counter Word1 */ +#define OTFAD_CTX_CTR_W0CTR_MASK (0xFFFFFFFFU) +#define OTFAD_CTX_CTR_W0CTR_SHIFT (0U) +#define OTFAD_CTX_CTR_W0CTR(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CTX_CTR_W0CTR_SHIFT)) & OTFAD_CTX_CTR_W0CTR_MASK) +#define OTFAD_CTX_CTR_W1CTR_MASK (0xFFFFFFFFU) +#define OTFAD_CTX_CTR_W1CTR_SHIFT (0U) +#define OTFAD_CTX_CTR_W1CTR(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CTX_CTR_W1CTR_SHIFT)) & OTFAD_CTX_CTR_W1CTR_MASK) + +/* The count of OTFAD_CTX_CTR */ +#define OTFAD_CTX_CTR_COUNT (4U) + +/* The count of OTFAD_CTX_CTR */ +#define OTFAD_CTX_CTR_COUNT2 (2U) + +/*! @name CTX_RGD - AES Region Descriptor Word0..AES Region Descriptor Word1 */ +#define OTFAD_CTX_RGD_VLD_MASK (0x1U) +#define OTFAD_CTX_RGD_VLD_SHIFT (0U) +#define OTFAD_CTX_RGD_VLD(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CTX_RGD_VLD_SHIFT)) & OTFAD_CTX_RGD_VLD_MASK) +#define OTFAD_CTX_RGD_ADE_MASK (0x2U) +#define OTFAD_CTX_RGD_ADE_SHIFT (1U) +#define OTFAD_CTX_RGD_ADE(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CTX_RGD_ADE_SHIFT)) & OTFAD_CTX_RGD_ADE_MASK) +#define OTFAD_CTX_RGD_RO_MASK (0x4U) +#define OTFAD_CTX_RGD_RO_SHIFT (2U) +#define OTFAD_CTX_RGD_RO(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CTX_RGD_RO_SHIFT)) & OTFAD_CTX_RGD_RO_MASK) +#define OTFAD_CTX_RGD_ENDADDR_MASK (0xFFFFFC00U) +#define OTFAD_CTX_RGD_ENDADDR_SHIFT (10U) +#define OTFAD_CTX_RGD_ENDADDR(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CTX_RGD_ENDADDR_SHIFT)) & OTFAD_CTX_RGD_ENDADDR_MASK) +#define OTFAD_CTX_RGD_SRTADDR_MASK (0xFFFFFC00U) +#define OTFAD_CTX_RGD_SRTADDR_SHIFT (10U) +#define OTFAD_CTX_RGD_SRTADDR(x) (((uint32_t)(((uint32_t)(x)) << OTFAD_CTX_RGD_SRTADDR_SHIFT)) & OTFAD_CTX_RGD_SRTADDR_MASK) + +/* The count of OTFAD_CTX_RGD */ +#define OTFAD_CTX_RGD_COUNT (4U) + +/* The count of OTFAD_CTX_RGD */ +#define OTFAD_CTX_RGD_COUNT2 (2U) + + +/*! + * @} + */ /* end of group OTFAD_Register_Masks */ + + +/* OTFAD - Peripheral instance base addresses */ +/** Peripheral OTFAD base address */ +#define OTFAD_BASE (0x400DAC00u) +/** Peripheral OTFAD base pointer */ +#define OTFAD ((OTFAD_Type *)OTFAD_BASE) +/** Array initializer of OTFAD peripheral base addresses */ +#define OTFAD_BASE_ADDRS { OTFAD_BASE } +/** Array initializer of OTFAD peripheral base pointers */ +#define OTFAD_BASE_PTRS { OTFAD } + +/*! + * @} + */ /* end of group OTFAD_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PDB Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PDB_Peripheral_Access_Layer PDB Peripheral Access Layer + * @{ + */ + +/** PDB - Register Layout Typedef */ +typedef struct { + __IO uint32_t SC; /**< Status and Control register, offset: 0x0 */ + __IO uint32_t MOD; /**< Modulus register, offset: 0x4 */ + __I uint32_t CNT; /**< Counter register, offset: 0x8 */ + __IO uint32_t IDLY; /**< Interrupt Delay register, offset: 0xC */ + struct { /* offset: 0x10, array step: 0x10 */ + __IO uint32_t C1; /**< Channel n Control register 1, array offset: 0x10, array step: 0x10 */ + __IO uint32_t S; /**< Channel n Status register, array offset: 0x14, array step: 0x10 */ + __IO uint32_t DLY[2]; /**< Channel n Delay 0 register..Channel n Delay 1 register, array offset: 0x18, array step: index*0x10, index2*0x4 */ + } CH[1]; + uint8_t RESERVED_0[304]; + struct { /* offset: 0x150, array step: 0x8 */ + __IO uint32_t INTC; /**< DAC Interval Trigger n Control register, array offset: 0x150, array step: 0x8 */ + __IO uint32_t INT; /**< DAC Interval n register, array offset: 0x154, array step: 0x8 */ + } DAC[1]; + uint8_t RESERVED_1[56]; + __IO uint32_t POEN; /**< Pulse-Out n Enable register, offset: 0x190 */ + __IO uint32_t PODLY[2]; /**< Pulse-Out n Delay register, array offset: 0x194, array step: 0x4 */ +} PDB_Type; + +/* ---------------------------------------------------------------------------- + -- PDB Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PDB_Register_Masks PDB Register Masks + * @{ + */ + +/*! @name SC - Status and Control register */ +#define PDB_SC_LDOK_MASK (0x1U) +#define PDB_SC_LDOK_SHIFT (0U) +#define PDB_SC_LDOK(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_LDOK_SHIFT)) & PDB_SC_LDOK_MASK) +#define PDB_SC_CONT_MASK (0x2U) +#define PDB_SC_CONT_SHIFT (1U) +#define PDB_SC_CONT(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_CONT_SHIFT)) & PDB_SC_CONT_MASK) +#define PDB_SC_MULT_MASK (0xCU) +#define PDB_SC_MULT_SHIFT (2U) +#define PDB_SC_MULT(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_MULT_SHIFT)) & PDB_SC_MULT_MASK) +#define PDB_SC_PDBIE_MASK (0x20U) +#define PDB_SC_PDBIE_SHIFT (5U) +#define PDB_SC_PDBIE(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_PDBIE_SHIFT)) & PDB_SC_PDBIE_MASK) +#define PDB_SC_PDBIF_MASK (0x40U) +#define PDB_SC_PDBIF_SHIFT (6U) +#define PDB_SC_PDBIF(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_PDBIF_SHIFT)) & PDB_SC_PDBIF_MASK) +#define PDB_SC_PDBEN_MASK (0x80U) +#define PDB_SC_PDBEN_SHIFT (7U) +#define PDB_SC_PDBEN(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_PDBEN_SHIFT)) & PDB_SC_PDBEN_MASK) +#define PDB_SC_TRGSEL_MASK (0xF00U) +#define PDB_SC_TRGSEL_SHIFT (8U) +#define PDB_SC_TRGSEL(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_TRGSEL_SHIFT)) & PDB_SC_TRGSEL_MASK) +#define PDB_SC_PRESCALER_MASK (0x7000U) +#define PDB_SC_PRESCALER_SHIFT (12U) +#define PDB_SC_PRESCALER(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_PRESCALER_SHIFT)) & PDB_SC_PRESCALER_MASK) +#define PDB_SC_DMAEN_MASK (0x8000U) +#define PDB_SC_DMAEN_SHIFT (15U) +#define PDB_SC_DMAEN(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_DMAEN_SHIFT)) & PDB_SC_DMAEN_MASK) +#define PDB_SC_SWTRIG_MASK (0x10000U) +#define PDB_SC_SWTRIG_SHIFT (16U) +#define PDB_SC_SWTRIG(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_SWTRIG_SHIFT)) & PDB_SC_SWTRIG_MASK) +#define PDB_SC_PDBEIE_MASK (0x20000U) +#define PDB_SC_PDBEIE_SHIFT (17U) +#define PDB_SC_PDBEIE(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_PDBEIE_SHIFT)) & PDB_SC_PDBEIE_MASK) +#define PDB_SC_LDMOD_MASK (0xC0000U) +#define PDB_SC_LDMOD_SHIFT (18U) +#define PDB_SC_LDMOD(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_LDMOD_SHIFT)) & PDB_SC_LDMOD_MASK) + +/*! @name MOD - Modulus register */ +#define PDB_MOD_MOD_MASK (0xFFFFU) +#define PDB_MOD_MOD_SHIFT (0U) +#define PDB_MOD_MOD(x) (((uint32_t)(((uint32_t)(x)) << PDB_MOD_MOD_SHIFT)) & PDB_MOD_MOD_MASK) + +/*! @name CNT - Counter register */ +#define PDB_CNT_CNT_MASK (0xFFFFU) +#define PDB_CNT_CNT_SHIFT (0U) +#define PDB_CNT_CNT(x) (((uint32_t)(((uint32_t)(x)) << PDB_CNT_CNT_SHIFT)) & PDB_CNT_CNT_MASK) + +/*! @name IDLY - Interrupt Delay register */ +#define PDB_IDLY_IDLY_MASK (0xFFFFU) +#define PDB_IDLY_IDLY_SHIFT (0U) +#define PDB_IDLY_IDLY(x) (((uint32_t)(((uint32_t)(x)) << PDB_IDLY_IDLY_SHIFT)) & PDB_IDLY_IDLY_MASK) + +/*! @name C1 - Channel n Control register 1 */ +#define PDB_C1_EN_MASK (0xFFU) +#define PDB_C1_EN_SHIFT (0U) +#define PDB_C1_EN(x) (((uint32_t)(((uint32_t)(x)) << PDB_C1_EN_SHIFT)) & PDB_C1_EN_MASK) +#define PDB_C1_TOS_MASK (0xFF00U) +#define PDB_C1_TOS_SHIFT (8U) +#define PDB_C1_TOS(x) (((uint32_t)(((uint32_t)(x)) << PDB_C1_TOS_SHIFT)) & PDB_C1_TOS_MASK) +#define PDB_C1_BB_MASK (0xFF0000U) +#define PDB_C1_BB_SHIFT (16U) +#define PDB_C1_BB(x) (((uint32_t)(((uint32_t)(x)) << PDB_C1_BB_SHIFT)) & PDB_C1_BB_MASK) + +/* The count of PDB_C1 */ +#define PDB_C1_COUNT (1U) + +/*! @name S - Channel n Status register */ +#define PDB_S_ERR_MASK (0xFFU) +#define PDB_S_ERR_SHIFT (0U) +#define PDB_S_ERR(x) (((uint32_t)(((uint32_t)(x)) << PDB_S_ERR_SHIFT)) & PDB_S_ERR_MASK) +#define PDB_S_CF_MASK (0xFF0000U) +#define PDB_S_CF_SHIFT (16U) +#define PDB_S_CF(x) (((uint32_t)(((uint32_t)(x)) << PDB_S_CF_SHIFT)) & PDB_S_CF_MASK) + +/* The count of PDB_S */ +#define PDB_S_COUNT (1U) + +/*! @name DLY - Channel n Delay 0 register..Channel n Delay 1 register */ +#define PDB_DLY_DLY_MASK (0xFFFFU) +#define PDB_DLY_DLY_SHIFT (0U) +#define PDB_DLY_DLY(x) (((uint32_t)(((uint32_t)(x)) << PDB_DLY_DLY_SHIFT)) & PDB_DLY_DLY_MASK) + +/* The count of PDB_DLY */ +#define PDB_DLY_COUNT (1U) + +/* The count of PDB_DLY */ +#define PDB_DLY_COUNT2 (2U) + +/*! @name INTC - DAC Interval Trigger n Control register */ +#define PDB_INTC_TOE_MASK (0x1U) +#define PDB_INTC_TOE_SHIFT (0U) +#define PDB_INTC_TOE(x) (((uint32_t)(((uint32_t)(x)) << PDB_INTC_TOE_SHIFT)) & PDB_INTC_TOE_MASK) +#define PDB_INTC_EXT_MASK (0x2U) +#define PDB_INTC_EXT_SHIFT (1U) +#define PDB_INTC_EXT(x) (((uint32_t)(((uint32_t)(x)) << PDB_INTC_EXT_SHIFT)) & PDB_INTC_EXT_MASK) + +/* The count of PDB_INTC */ +#define PDB_INTC_COUNT (1U) + +/*! @name INT - DAC Interval n register */ +#define PDB_INT_INT_MASK (0xFFFFU) +#define PDB_INT_INT_SHIFT (0U) +#define PDB_INT_INT(x) (((uint32_t)(((uint32_t)(x)) << PDB_INT_INT_SHIFT)) & PDB_INT_INT_MASK) + +/* The count of PDB_INT */ +#define PDB_INT_COUNT (1U) + +/*! @name POEN - Pulse-Out n Enable register */ +#define PDB_POEN_POEN_MASK (0xFFU) +#define PDB_POEN_POEN_SHIFT (0U) +#define PDB_POEN_POEN(x) (((uint32_t)(((uint32_t)(x)) << PDB_POEN_POEN_SHIFT)) & PDB_POEN_POEN_MASK) + +/*! @name PODLY - Pulse-Out n Delay register */ +#define PDB_PODLY_DLY2_MASK (0xFFFFU) +#define PDB_PODLY_DLY2_SHIFT (0U) +#define PDB_PODLY_DLY2(x) (((uint32_t)(((uint32_t)(x)) << PDB_PODLY_DLY2_SHIFT)) & PDB_PODLY_DLY2_MASK) +#define PDB_PODLY_DLY1_MASK (0xFFFF0000U) +#define PDB_PODLY_DLY1_SHIFT (16U) +#define PDB_PODLY_DLY1(x) (((uint32_t)(((uint32_t)(x)) << PDB_PODLY_DLY1_SHIFT)) & PDB_PODLY_DLY1_MASK) + +/* The count of PDB_PODLY */ +#define PDB_PODLY_COUNT (2U) + + +/*! + * @} + */ /* end of group PDB_Register_Masks */ + + +/* PDB - Peripheral instance base addresses */ +/** Peripheral PDB0 base address */ +#define PDB0_BASE (0x40036000u) +/** Peripheral PDB0 base pointer */ +#define PDB0 ((PDB_Type *)PDB0_BASE) +/** Array initializer of PDB peripheral base addresses */ +#define PDB_BASE_ADDRS { PDB0_BASE } +/** Array initializer of PDB peripheral base pointers */ +#define PDB_BASE_PTRS { PDB0 } +/** Interrupt vectors for the PDB peripheral type */ +#define PDB_IRQS { PDB0_IRQn } + +/*! + * @} + */ /* end of group PDB_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PIT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PIT_Peripheral_Access_Layer PIT Peripheral Access Layer + * @{ + */ + +/** PIT - Register Layout Typedef */ +typedef struct { + __IO uint32_t MCR; /**< PIT Module Control Register, offset: 0x0 */ + uint8_t RESERVED_0[252]; + struct { /* offset: 0x100, array step: 0x10 */ + __IO uint32_t LDVAL; /**< Timer Load Value Register, array offset: 0x100, array step: 0x10 */ + __I uint32_t CVAL; /**< Current Timer Value Register, array offset: 0x104, array step: 0x10 */ + __IO uint32_t TCTRL; /**< Timer Control Register, array offset: 0x108, array step: 0x10 */ + __IO uint32_t TFLG; /**< Timer Flag Register, array offset: 0x10C, array step: 0x10 */ + } CHANNEL[4]; +} PIT_Type; + +/* ---------------------------------------------------------------------------- + -- PIT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PIT_Register_Masks PIT Register Masks + * @{ + */ + +/*! @name MCR - PIT Module Control Register */ +#define PIT_MCR_FRZ_MASK (0x1U) +#define PIT_MCR_FRZ_SHIFT (0U) +#define PIT_MCR_FRZ(x) (((uint32_t)(((uint32_t)(x)) << PIT_MCR_FRZ_SHIFT)) & PIT_MCR_FRZ_MASK) +#define PIT_MCR_MDIS_MASK (0x2U) +#define PIT_MCR_MDIS_SHIFT (1U) +#define PIT_MCR_MDIS(x) (((uint32_t)(((uint32_t)(x)) << PIT_MCR_MDIS_SHIFT)) & PIT_MCR_MDIS_MASK) + +/*! @name LDVAL - Timer Load Value Register */ +#define PIT_LDVAL_TSV_MASK (0xFFFFFFFFU) +#define PIT_LDVAL_TSV_SHIFT (0U) +#define PIT_LDVAL_TSV(x) (((uint32_t)(((uint32_t)(x)) << PIT_LDVAL_TSV_SHIFT)) & PIT_LDVAL_TSV_MASK) + +/* The count of PIT_LDVAL */ +#define PIT_LDVAL_COUNT (4U) + +/*! @name CVAL - Current Timer Value Register */ +#define PIT_CVAL_TVL_MASK (0xFFFFFFFFU) +#define PIT_CVAL_TVL_SHIFT (0U) +#define PIT_CVAL_TVL(x) (((uint32_t)(((uint32_t)(x)) << PIT_CVAL_TVL_SHIFT)) & PIT_CVAL_TVL_MASK) + +/* The count of PIT_CVAL */ +#define PIT_CVAL_COUNT (4U) + +/*! @name TCTRL - Timer Control Register */ +#define PIT_TCTRL_TEN_MASK (0x1U) +#define PIT_TCTRL_TEN_SHIFT (0U) +#define PIT_TCTRL_TEN(x) (((uint32_t)(((uint32_t)(x)) << PIT_TCTRL_TEN_SHIFT)) & PIT_TCTRL_TEN_MASK) +#define PIT_TCTRL_TIE_MASK (0x2U) +#define PIT_TCTRL_TIE_SHIFT (1U) +#define PIT_TCTRL_TIE(x) (((uint32_t)(((uint32_t)(x)) << PIT_TCTRL_TIE_SHIFT)) & PIT_TCTRL_TIE_MASK) +#define PIT_TCTRL_CHN_MASK (0x4U) +#define PIT_TCTRL_CHN_SHIFT (2U) +#define PIT_TCTRL_CHN(x) (((uint32_t)(((uint32_t)(x)) << PIT_TCTRL_CHN_SHIFT)) & PIT_TCTRL_CHN_MASK) + +/* The count of PIT_TCTRL */ +#define PIT_TCTRL_COUNT (4U) + +/*! @name TFLG - Timer Flag Register */ +#define PIT_TFLG_TIF_MASK (0x1U) +#define PIT_TFLG_TIF_SHIFT (0U) +#define PIT_TFLG_TIF(x) (((uint32_t)(((uint32_t)(x)) << PIT_TFLG_TIF_SHIFT)) & PIT_TFLG_TIF_MASK) + +/* The count of PIT_TFLG */ +#define PIT_TFLG_COUNT (4U) + + +/*! + * @} + */ /* end of group PIT_Register_Masks */ + + +/* PIT - Peripheral instance base addresses */ +/** Peripheral PIT0 base address */ +#define PIT0_BASE (0x40037000u) +/** Peripheral PIT0 base pointer */ +#define PIT0 ((PIT_Type *)PIT0_BASE) +/** Array initializer of PIT peripheral base addresses */ +#define PIT_BASE_ADDRS { PIT0_BASE } +/** Array initializer of PIT peripheral base pointers */ +#define PIT_BASE_PTRS { PIT0 } +/** Interrupt vectors for the PIT peripheral type */ +#define PIT_IRQS { PIT0CH0_IRQn, PIT0CH1_IRQn, PIT0CH2_IRQn, PIT0CH3_IRQn } + +/*! + * @} + */ /* end of group PIT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PMC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PMC_Peripheral_Access_Layer PMC Peripheral Access Layer + * @{ + */ + +/** PMC - Register Layout Typedef */ +typedef struct { + __IO uint8_t LVDSC1; /**< Low Voltage Detect Status And Control 1 register, offset: 0x0 */ + __IO uint8_t LVDSC2; /**< Low Voltage Detect Status And Control 2 register, offset: 0x1 */ + __IO uint8_t REGSC; /**< Regulator Status And Control register, offset: 0x2 */ + uint8_t RESERVED_0[8]; + __IO uint8_t HVDSC1; /**< High Voltage Detect Status And Control 1 register, offset: 0xB */ +} PMC_Type; + +/* ---------------------------------------------------------------------------- + -- PMC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PMC_Register_Masks PMC Register Masks + * @{ + */ + +/*! @name LVDSC1 - Low Voltage Detect Status And Control 1 register */ +#define PMC_LVDSC1_LVDV_MASK (0x3U) +#define PMC_LVDSC1_LVDV_SHIFT (0U) +#define PMC_LVDSC1_LVDV(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDV_SHIFT)) & PMC_LVDSC1_LVDV_MASK) +#define PMC_LVDSC1_LVDRE_MASK (0x10U) +#define PMC_LVDSC1_LVDRE_SHIFT (4U) +#define PMC_LVDSC1_LVDRE(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDRE_SHIFT)) & PMC_LVDSC1_LVDRE_MASK) +#define PMC_LVDSC1_LVDIE_MASK (0x20U) +#define PMC_LVDSC1_LVDIE_SHIFT (5U) +#define PMC_LVDSC1_LVDIE(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDIE_SHIFT)) & PMC_LVDSC1_LVDIE_MASK) +#define PMC_LVDSC1_LVDACK_MASK (0x40U) +#define PMC_LVDSC1_LVDACK_SHIFT (6U) +#define PMC_LVDSC1_LVDACK(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDACK_SHIFT)) & PMC_LVDSC1_LVDACK_MASK) +#define PMC_LVDSC1_LVDF_MASK (0x80U) +#define PMC_LVDSC1_LVDF_SHIFT (7U) +#define PMC_LVDSC1_LVDF(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDF_SHIFT)) & PMC_LVDSC1_LVDF_MASK) + +/*! @name LVDSC2 - Low Voltage Detect Status And Control 2 register */ +#define PMC_LVDSC2_LVWV_MASK (0x3U) +#define PMC_LVDSC2_LVWV_SHIFT (0U) +#define PMC_LVDSC2_LVWV(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC2_LVWV_SHIFT)) & PMC_LVDSC2_LVWV_MASK) +#define PMC_LVDSC2_LVWIE_MASK (0x20U) +#define PMC_LVDSC2_LVWIE_SHIFT (5U) +#define PMC_LVDSC2_LVWIE(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC2_LVWIE_SHIFT)) & PMC_LVDSC2_LVWIE_MASK) +#define PMC_LVDSC2_LVWACK_MASK (0x40U) +#define PMC_LVDSC2_LVWACK_SHIFT (6U) +#define PMC_LVDSC2_LVWACK(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC2_LVWACK_SHIFT)) & PMC_LVDSC2_LVWACK_MASK) +#define PMC_LVDSC2_LVWF_MASK (0x80U) +#define PMC_LVDSC2_LVWF_SHIFT (7U) +#define PMC_LVDSC2_LVWF(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC2_LVWF_SHIFT)) & PMC_LVDSC2_LVWF_MASK) + +/*! @name REGSC - Regulator Status And Control register */ +#define PMC_REGSC_BGBE_MASK (0x1U) +#define PMC_REGSC_BGBE_SHIFT (0U) +#define PMC_REGSC_BGBE(x) (((uint8_t)(((uint8_t)(x)) << PMC_REGSC_BGBE_SHIFT)) & PMC_REGSC_BGBE_MASK) +#define PMC_REGSC_REGONS_MASK (0x4U) +#define PMC_REGSC_REGONS_SHIFT (2U) +#define PMC_REGSC_REGONS(x) (((uint8_t)(((uint8_t)(x)) << PMC_REGSC_REGONS_SHIFT)) & PMC_REGSC_REGONS_MASK) +#define PMC_REGSC_ACKISO_MASK (0x8U) +#define PMC_REGSC_ACKISO_SHIFT (3U) +#define PMC_REGSC_ACKISO(x) (((uint8_t)(((uint8_t)(x)) << PMC_REGSC_ACKISO_SHIFT)) & PMC_REGSC_ACKISO_MASK) +#define PMC_REGSC_BGEN_MASK (0x10U) +#define PMC_REGSC_BGEN_SHIFT (4U) +#define PMC_REGSC_BGEN(x) (((uint8_t)(((uint8_t)(x)) << PMC_REGSC_BGEN_SHIFT)) & PMC_REGSC_BGEN_MASK) + +/*! @name HVDSC1 - High Voltage Detect Status And Control 1 register */ +#define PMC_HVDSC1_HVDV_MASK (0x1U) +#define PMC_HVDSC1_HVDV_SHIFT (0U) +#define PMC_HVDSC1_HVDV(x) (((uint8_t)(((uint8_t)(x)) << PMC_HVDSC1_HVDV_SHIFT)) & PMC_HVDSC1_HVDV_MASK) +#define PMC_HVDSC1_HVDRE_MASK (0x10U) +#define PMC_HVDSC1_HVDRE_SHIFT (4U) +#define PMC_HVDSC1_HVDRE(x) (((uint8_t)(((uint8_t)(x)) << PMC_HVDSC1_HVDRE_SHIFT)) & PMC_HVDSC1_HVDRE_MASK) +#define PMC_HVDSC1_HVDIE_MASK (0x20U) +#define PMC_HVDSC1_HVDIE_SHIFT (5U) +#define PMC_HVDSC1_HVDIE(x) (((uint8_t)(((uint8_t)(x)) << PMC_HVDSC1_HVDIE_SHIFT)) & PMC_HVDSC1_HVDIE_MASK) +#define PMC_HVDSC1_HVDACK_MASK (0x40U) +#define PMC_HVDSC1_HVDACK_SHIFT (6U) +#define PMC_HVDSC1_HVDACK(x) (((uint8_t)(((uint8_t)(x)) << PMC_HVDSC1_HVDACK_SHIFT)) & PMC_HVDSC1_HVDACK_MASK) +#define PMC_HVDSC1_HVDF_MASK (0x80U) +#define PMC_HVDSC1_HVDF_SHIFT (7U) +#define PMC_HVDSC1_HVDF(x) (((uint8_t)(((uint8_t)(x)) << PMC_HVDSC1_HVDF_SHIFT)) & PMC_HVDSC1_HVDF_MASK) + + +/*! + * @} + */ /* end of group PMC_Register_Masks */ + + +/* PMC - Peripheral instance base addresses */ +/** Peripheral PMC base address */ +#define PMC_BASE (0x4007D000u) +/** Peripheral PMC base pointer */ +#define PMC ((PMC_Type *)PMC_BASE) +/** Array initializer of PMC peripheral base addresses */ +#define PMC_BASE_ADDRS { PMC_BASE } +/** Array initializer of PMC peripheral base pointers */ +#define PMC_BASE_PTRS { PMC } +/** Interrupt vectors for the PMC peripheral type */ +#define PMC_IRQS { LVD_LVW_IRQn } + +/*! + * @} + */ /* end of group PMC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PORT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PORT_Peripheral_Access_Layer PORT Peripheral Access Layer + * @{ + */ + +/** PORT - Register Layout Typedef */ +typedef struct { + __IO uint32_t PCR[32]; /**< Pin Control Register n, array offset: 0x0, array step: 0x4 */ + __O uint32_t GPCLR; /**< Global Pin Control Low Register, offset: 0x80 */ + __O uint32_t GPCHR; /**< Global Pin Control High Register, offset: 0x84 */ + uint8_t RESERVED_0[24]; + __IO uint32_t ISFR; /**< Interrupt Status Flag Register, offset: 0xA0 */ + uint8_t RESERVED_1[28]; + __IO uint32_t DFER; /**< Digital Filter Enable Register, offset: 0xC0 */ + __IO uint32_t DFCR; /**< Digital Filter Clock Register, offset: 0xC4 */ + __IO uint32_t DFWR; /**< Digital Filter Width Register, offset: 0xC8 */ +} PORT_Type; + +/* ---------------------------------------------------------------------------- + -- PORT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PORT_Register_Masks PORT Register Masks + * @{ + */ + +/*! @name PCR - Pin Control Register n */ +#define PORT_PCR_PS_MASK (0x1U) +#define PORT_PCR_PS_SHIFT (0U) +#define PORT_PCR_PS(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_PS_SHIFT)) & PORT_PCR_PS_MASK) +#define PORT_PCR_PE_MASK (0x2U) +#define PORT_PCR_PE_SHIFT (1U) +#define PORT_PCR_PE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_PE_SHIFT)) & PORT_PCR_PE_MASK) +#define PORT_PCR_SRE_MASK (0x4U) +#define PORT_PCR_SRE_SHIFT (2U) +#define PORT_PCR_SRE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_SRE_SHIFT)) & PORT_PCR_SRE_MASK) +#define PORT_PCR_PFE_MASK (0x10U) +#define PORT_PCR_PFE_SHIFT (4U) +#define PORT_PCR_PFE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_PFE_SHIFT)) & PORT_PCR_PFE_MASK) +#define PORT_PCR_ODE_MASK (0x20U) +#define PORT_PCR_ODE_SHIFT (5U) +#define PORT_PCR_ODE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_ODE_SHIFT)) & PORT_PCR_ODE_MASK) +#define PORT_PCR_DSE_MASK (0x40U) +#define PORT_PCR_DSE_SHIFT (6U) +#define PORT_PCR_DSE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_DSE_SHIFT)) & PORT_PCR_DSE_MASK) +#define PORT_PCR_MUX_MASK (0x700U) +#define PORT_PCR_MUX_SHIFT (8U) +#define PORT_PCR_MUX(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_MUX_SHIFT)) & PORT_PCR_MUX_MASK) +#define PORT_PCR_LK_MASK (0x8000U) +#define PORT_PCR_LK_SHIFT (15U) +#define PORT_PCR_LK(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_LK_SHIFT)) & PORT_PCR_LK_MASK) +#define PORT_PCR_IRQC_MASK (0xF0000U) +#define PORT_PCR_IRQC_SHIFT (16U) +#define PORT_PCR_IRQC(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_IRQC_SHIFT)) & PORT_PCR_IRQC_MASK) +#define PORT_PCR_ISF_MASK (0x1000000U) +#define PORT_PCR_ISF_SHIFT (24U) +#define PORT_PCR_ISF(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_ISF_SHIFT)) & PORT_PCR_ISF_MASK) + +/* The count of PORT_PCR */ +#define PORT_PCR_COUNT (32U) + +/*! @name GPCLR - Global Pin Control Low Register */ +#define PORT_GPCLR_GPWD_MASK (0xFFFFU) +#define PORT_GPCLR_GPWD_SHIFT (0U) +#define PORT_GPCLR_GPWD(x) (((uint32_t)(((uint32_t)(x)) << PORT_GPCLR_GPWD_SHIFT)) & PORT_GPCLR_GPWD_MASK) +#define PORT_GPCLR_GPWE_MASK (0xFFFF0000U) +#define PORT_GPCLR_GPWE_SHIFT (16U) +#define PORT_GPCLR_GPWE(x) (((uint32_t)(((uint32_t)(x)) << PORT_GPCLR_GPWE_SHIFT)) & PORT_GPCLR_GPWE_MASK) + +/*! @name GPCHR - Global Pin Control High Register */ +#define PORT_GPCHR_GPWD_MASK (0xFFFFU) +#define PORT_GPCHR_GPWD_SHIFT (0U) +#define PORT_GPCHR_GPWD(x) (((uint32_t)(((uint32_t)(x)) << PORT_GPCHR_GPWD_SHIFT)) & PORT_GPCHR_GPWD_MASK) +#define PORT_GPCHR_GPWE_MASK (0xFFFF0000U) +#define PORT_GPCHR_GPWE_SHIFT (16U) +#define PORT_GPCHR_GPWE(x) (((uint32_t)(((uint32_t)(x)) << PORT_GPCHR_GPWE_SHIFT)) & PORT_GPCHR_GPWE_MASK) + +/*! @name ISFR - Interrupt Status Flag Register */ +#define PORT_ISFR_ISF_MASK (0xFFFFFFFFU) +#define PORT_ISFR_ISF_SHIFT (0U) +#define PORT_ISFR_ISF(x) (((uint32_t)(((uint32_t)(x)) << PORT_ISFR_ISF_SHIFT)) & PORT_ISFR_ISF_MASK) + +/*! @name DFER - Digital Filter Enable Register */ +#define PORT_DFER_DFE_MASK (0xFFFFFFFFU) +#define PORT_DFER_DFE_SHIFT (0U) +#define PORT_DFER_DFE(x) (((uint32_t)(((uint32_t)(x)) << PORT_DFER_DFE_SHIFT)) & PORT_DFER_DFE_MASK) + +/*! @name DFCR - Digital Filter Clock Register */ +#define PORT_DFCR_CS_MASK (0x1U) +#define PORT_DFCR_CS_SHIFT (0U) +#define PORT_DFCR_CS(x) (((uint32_t)(((uint32_t)(x)) << PORT_DFCR_CS_SHIFT)) & PORT_DFCR_CS_MASK) + +/*! @name DFWR - Digital Filter Width Register */ +#define PORT_DFWR_FILT_MASK (0x1FU) +#define PORT_DFWR_FILT_SHIFT (0U) +#define PORT_DFWR_FILT(x) (((uint32_t)(((uint32_t)(x)) << PORT_DFWR_FILT_SHIFT)) & PORT_DFWR_FILT_MASK) + + +/*! + * @} + */ /* end of group PORT_Register_Masks */ + + +/* PORT - Peripheral instance base addresses */ +/** Peripheral PORTA base address */ +#define PORTA_BASE (0x40049000u) +/** Peripheral PORTA base pointer */ +#define PORTA ((PORT_Type *)PORTA_BASE) +/** Peripheral PORTB base address */ +#define PORTB_BASE (0x4004A000u) +/** Peripheral PORTB base pointer */ +#define PORTB ((PORT_Type *)PORTB_BASE) +/** Peripheral PORTC base address */ +#define PORTC_BASE (0x4004B000u) +/** Peripheral PORTC base pointer */ +#define PORTC ((PORT_Type *)PORTC_BASE) +/** Peripheral PORTD base address */ +#define PORTD_BASE (0x4004C000u) +/** Peripheral PORTD base pointer */ +#define PORTD ((PORT_Type *)PORTD_BASE) +/** Peripheral PORTE base address */ +#define PORTE_BASE (0x4004D000u) +/** Peripheral PORTE base pointer */ +#define PORTE ((PORT_Type *)PORTE_BASE) +/** Array initializer of PORT peripheral base addresses */ +#define PORT_BASE_ADDRS { PORTA_BASE, PORTB_BASE, PORTC_BASE, PORTD_BASE, PORTE_BASE } +/** Array initializer of PORT peripheral base pointers */ +#define PORT_BASE_PTRS { PORTA, PORTB, PORTC, PORTD, PORTE } +/** Interrupt vectors for the PORT peripheral type */ +#define PORT_IRQS { PORTA_IRQn, PORTB_IRQn, PORTC_IRQn, PORTD_IRQn, PORTE_IRQn } + +/*! + * @} + */ /* end of group PORT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- QuadSPI Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup QuadSPI_Peripheral_Access_Layer QuadSPI Peripheral Access Layer + * @{ + */ + +/** QuadSPI - Register Layout Typedef */ +typedef struct { + __IO uint32_t MCR; /**< Module Configuration Register, offset: 0x0 */ + uint8_t RESERVED_0[4]; + __IO uint32_t IPCR; /**< IP Configuration Register, offset: 0x8 */ + __IO uint32_t FLSHCR; /**< Flash Configuration Register, offset: 0xC */ + __IO uint32_t BUF0CR; /**< Buffer0 Configuration Register, offset: 0x10 */ + __IO uint32_t BUF1CR; /**< Buffer1 Configuration Register, offset: 0x14 */ + __IO uint32_t BUF2CR; /**< Buffer2 Configuration Register, offset: 0x18 */ + __IO uint32_t BUF3CR; /**< Buffer3 Configuration Register, offset: 0x1C */ + __IO uint32_t BFGENCR; /**< Buffer Generic Configuration Register, offset: 0x20 */ + __IO uint32_t SOCCR; /**< SOC Configuration Register, offset: 0x24 */ + uint8_t RESERVED_1[8]; + __IO uint32_t BUF0IND; /**< Buffer0 Top Index Register, offset: 0x30 */ + __IO uint32_t BUF1IND; /**< Buffer1 Top Index Register, offset: 0x34 */ + __IO uint32_t BUF2IND; /**< Buffer2 Top Index Register, offset: 0x38 */ + uint8_t RESERVED_2[196]; + __IO uint32_t SFAR; /**< Serial Flash Address Register, offset: 0x100 */ + __IO uint32_t SFACR; /**< Serial Flash Address Configuration Register, offset: 0x104 */ + __IO uint32_t SMPR; /**< Sampling Register, offset: 0x108 */ + __I uint32_t RBSR; /**< RX Buffer Status Register, offset: 0x10C */ + __IO uint32_t RBCT; /**< RX Buffer Control Register, offset: 0x110 */ + uint8_t RESERVED_3[60]; + __I uint32_t TBSR; /**< TX Buffer Status Register, offset: 0x150 */ + __IO uint32_t TBDR; /**< TX Buffer Data Register, offset: 0x154 */ + __IO uint32_t TBCT; /**< Tx Buffer Control Register, offset: 0x158 */ + __I uint32_t SR; /**< Status Register, offset: 0x15C */ + __IO uint32_t FR; /**< Flag Register, offset: 0x160 */ + __IO uint32_t RSER; /**< Interrupt and DMA Request Select and Enable Register, offset: 0x164 */ + __I uint32_t SPNDST; /**< Sequence Suspend Status Register, offset: 0x168 */ + __IO uint32_t SPTRCLR; /**< Sequence Pointer Clear Register, offset: 0x16C */ + uint8_t RESERVED_4[16]; + __IO uint32_t SFA1AD; /**< Serial Flash A1 Top Address, offset: 0x180 */ + __IO uint32_t SFA2AD; /**< Serial Flash A2 Top Address, offset: 0x184 */ + __IO uint32_t SFB1AD; /**< Serial Flash B1Top Address, offset: 0x188 */ + __IO uint32_t SFB2AD; /**< Serial Flash B2Top Address, offset: 0x18C */ + __IO uint32_t DLPR; /**< Data Learn Pattern Register, offset: 0x190 */ + uint8_t RESERVED_5[108]; + __I uint32_t RBDR[16]; /**< RX Buffer Data Register, array offset: 0x200, array step: 0x4 */ + uint8_t RESERVED_6[192]; + __IO uint32_t LUTKEY; /**< LUT Key Register, offset: 0x300 */ + __IO uint32_t LCKCR; /**< LUT Lock Configuration Register, offset: 0x304 */ + uint8_t RESERVED_7[8]; + __IO uint32_t LUT[64]; /**< Look-up Table register, array offset: 0x310, array step: 0x4 */ +} QuadSPI_Type; + +/* ---------------------------------------------------------------------------- + -- QuadSPI Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup QuadSPI_Register_Masks QuadSPI Register Masks + * @{ + */ + +/*! @name MCR - Module Configuration Register */ +#define QuadSPI_MCR_SWRSTSD_MASK (0x1U) +#define QuadSPI_MCR_SWRSTSD_SHIFT (0U) +#define QuadSPI_MCR_SWRSTSD(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_MCR_SWRSTSD_SHIFT)) & QuadSPI_MCR_SWRSTSD_MASK) +#define QuadSPI_MCR_SWRSTHD_MASK (0x2U) +#define QuadSPI_MCR_SWRSTHD_SHIFT (1U) +#define QuadSPI_MCR_SWRSTHD(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_MCR_SWRSTHD_SHIFT)) & QuadSPI_MCR_SWRSTHD_MASK) +#define QuadSPI_MCR_END_CFG_MASK (0xCU) +#define QuadSPI_MCR_END_CFG_SHIFT (2U) +#define QuadSPI_MCR_END_CFG(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_MCR_END_CFG_SHIFT)) & QuadSPI_MCR_END_CFG_MASK) +#define QuadSPI_MCR_DQS_LAT_EN_MASK (0x20U) +#define QuadSPI_MCR_DQS_LAT_EN_SHIFT (5U) +#define QuadSPI_MCR_DQS_LAT_EN(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_MCR_DQS_LAT_EN_SHIFT)) & QuadSPI_MCR_DQS_LAT_EN_MASK) +#define QuadSPI_MCR_DQS_EN_MASK (0x40U) +#define QuadSPI_MCR_DQS_EN_SHIFT (6U) +#define QuadSPI_MCR_DQS_EN(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_MCR_DQS_EN_SHIFT)) & QuadSPI_MCR_DQS_EN_MASK) +#define QuadSPI_MCR_DDR_EN_MASK (0x80U) +#define QuadSPI_MCR_DDR_EN_SHIFT (7U) +#define QuadSPI_MCR_DDR_EN(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_MCR_DDR_EN_SHIFT)) & QuadSPI_MCR_DDR_EN_MASK) +#define QuadSPI_MCR_CLR_RXF_MASK (0x400U) +#define QuadSPI_MCR_CLR_RXF_SHIFT (10U) +#define QuadSPI_MCR_CLR_RXF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_MCR_CLR_RXF_SHIFT)) & QuadSPI_MCR_CLR_RXF_MASK) +#define QuadSPI_MCR_CLR_TXF_MASK (0x800U) +#define QuadSPI_MCR_CLR_TXF_SHIFT (11U) +#define QuadSPI_MCR_CLR_TXF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_MCR_CLR_TXF_SHIFT)) & QuadSPI_MCR_CLR_TXF_MASK) +#define QuadSPI_MCR_MDIS_MASK (0x4000U) +#define QuadSPI_MCR_MDIS_SHIFT (14U) +#define QuadSPI_MCR_MDIS(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_MCR_MDIS_SHIFT)) & QuadSPI_MCR_MDIS_MASK) +#define QuadSPI_MCR_SCLKCFG_MASK (0xFF000000U) +#define QuadSPI_MCR_SCLKCFG_SHIFT (24U) +#define QuadSPI_MCR_SCLKCFG(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_MCR_SCLKCFG_SHIFT)) & QuadSPI_MCR_SCLKCFG_MASK) + +/*! @name IPCR - IP Configuration Register */ +#define QuadSPI_IPCR_IDATSZ_MASK (0xFFFFU) +#define QuadSPI_IPCR_IDATSZ_SHIFT (0U) +#define QuadSPI_IPCR_IDATSZ(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_IPCR_IDATSZ_SHIFT)) & QuadSPI_IPCR_IDATSZ_MASK) +#define QuadSPI_IPCR_PAR_EN_MASK (0x10000U) +#define QuadSPI_IPCR_PAR_EN_SHIFT (16U) +#define QuadSPI_IPCR_PAR_EN(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_IPCR_PAR_EN_SHIFT)) & QuadSPI_IPCR_PAR_EN_MASK) +#define QuadSPI_IPCR_SEQID_MASK (0xF000000U) +#define QuadSPI_IPCR_SEQID_SHIFT (24U) +#define QuadSPI_IPCR_SEQID(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_IPCR_SEQID_SHIFT)) & QuadSPI_IPCR_SEQID_MASK) + +/*! @name FLSHCR - Flash Configuration Register */ +#define QuadSPI_FLSHCR_TCSS_MASK (0xFU) +#define QuadSPI_FLSHCR_TCSS_SHIFT (0U) +#define QuadSPI_FLSHCR_TCSS(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FLSHCR_TCSS_SHIFT)) & QuadSPI_FLSHCR_TCSS_MASK) +#define QuadSPI_FLSHCR_TCSH_MASK (0xF00U) +#define QuadSPI_FLSHCR_TCSH_SHIFT (8U) +#define QuadSPI_FLSHCR_TCSH(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FLSHCR_TCSH_SHIFT)) & QuadSPI_FLSHCR_TCSH_MASK) +#define QuadSPI_FLSHCR_TDH_MASK (0x30000U) +#define QuadSPI_FLSHCR_TDH_SHIFT (16U) +#define QuadSPI_FLSHCR_TDH(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FLSHCR_TDH_SHIFT)) & QuadSPI_FLSHCR_TDH_MASK) + +/*! @name BUF0CR - Buffer0 Configuration Register */ +#define QuadSPI_BUF0CR_MSTRID_MASK (0xFU) +#define QuadSPI_BUF0CR_MSTRID_SHIFT (0U) +#define QuadSPI_BUF0CR_MSTRID(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF0CR_MSTRID_SHIFT)) & QuadSPI_BUF0CR_MSTRID_MASK) +#define QuadSPI_BUF0CR_ADATSZ_MASK (0x7F00U) +#define QuadSPI_BUF0CR_ADATSZ_SHIFT (8U) +#define QuadSPI_BUF0CR_ADATSZ(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF0CR_ADATSZ_SHIFT)) & QuadSPI_BUF0CR_ADATSZ_MASK) +#define QuadSPI_BUF0CR_HP_EN_MASK (0x80000000U) +#define QuadSPI_BUF0CR_HP_EN_SHIFT (31U) +#define QuadSPI_BUF0CR_HP_EN(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF0CR_HP_EN_SHIFT)) & QuadSPI_BUF0CR_HP_EN_MASK) + +/*! @name BUF1CR - Buffer1 Configuration Register */ +#define QuadSPI_BUF1CR_MSTRID_MASK (0xFU) +#define QuadSPI_BUF1CR_MSTRID_SHIFT (0U) +#define QuadSPI_BUF1CR_MSTRID(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF1CR_MSTRID_SHIFT)) & QuadSPI_BUF1CR_MSTRID_MASK) +#define QuadSPI_BUF1CR_ADATSZ_MASK (0x7F00U) +#define QuadSPI_BUF1CR_ADATSZ_SHIFT (8U) +#define QuadSPI_BUF1CR_ADATSZ(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF1CR_ADATSZ_SHIFT)) & QuadSPI_BUF1CR_ADATSZ_MASK) + +/*! @name BUF2CR - Buffer2 Configuration Register */ +#define QuadSPI_BUF2CR_MSTRID_MASK (0xFU) +#define QuadSPI_BUF2CR_MSTRID_SHIFT (0U) +#define QuadSPI_BUF2CR_MSTRID(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF2CR_MSTRID_SHIFT)) & QuadSPI_BUF2CR_MSTRID_MASK) +#define QuadSPI_BUF2CR_ADATSZ_MASK (0x7F00U) +#define QuadSPI_BUF2CR_ADATSZ_SHIFT (8U) +#define QuadSPI_BUF2CR_ADATSZ(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF2CR_ADATSZ_SHIFT)) & QuadSPI_BUF2CR_ADATSZ_MASK) + +/*! @name BUF3CR - Buffer3 Configuration Register */ +#define QuadSPI_BUF3CR_MSTRID_MASK (0xFU) +#define QuadSPI_BUF3CR_MSTRID_SHIFT (0U) +#define QuadSPI_BUF3CR_MSTRID(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF3CR_MSTRID_SHIFT)) & QuadSPI_BUF3CR_MSTRID_MASK) +#define QuadSPI_BUF3CR_ADATSZ_MASK (0x7F00U) +#define QuadSPI_BUF3CR_ADATSZ_SHIFT (8U) +#define QuadSPI_BUF3CR_ADATSZ(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF3CR_ADATSZ_SHIFT)) & QuadSPI_BUF3CR_ADATSZ_MASK) +#define QuadSPI_BUF3CR_ALLMST_MASK (0x80000000U) +#define QuadSPI_BUF3CR_ALLMST_SHIFT (31U) +#define QuadSPI_BUF3CR_ALLMST(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF3CR_ALLMST_SHIFT)) & QuadSPI_BUF3CR_ALLMST_MASK) + +/*! @name BFGENCR - Buffer Generic Configuration Register */ +#define QuadSPI_BFGENCR_SEQID_MASK (0xF000U) +#define QuadSPI_BFGENCR_SEQID_SHIFT (12U) +#define QuadSPI_BFGENCR_SEQID(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BFGENCR_SEQID_SHIFT)) & QuadSPI_BFGENCR_SEQID_MASK) +#define QuadSPI_BFGENCR_PAR_EN_MASK (0x10000U) +#define QuadSPI_BFGENCR_PAR_EN_SHIFT (16U) +#define QuadSPI_BFGENCR_PAR_EN(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BFGENCR_PAR_EN_SHIFT)) & QuadSPI_BFGENCR_PAR_EN_MASK) + +/*! @name SOCCR - SOC Configuration Register */ +#define QuadSPI_SOCCR_QSPISRC_MASK (0x7U) +#define QuadSPI_SOCCR_QSPISRC_SHIFT (0U) +#define QuadSPI_SOCCR_QSPISRC(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SOCCR_QSPISRC_SHIFT)) & QuadSPI_SOCCR_QSPISRC_MASK) +#define QuadSPI_SOCCR_DQSLPEN_MASK (0x100U) +#define QuadSPI_SOCCR_DQSLPEN_SHIFT (8U) +#define QuadSPI_SOCCR_DQSLPEN(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SOCCR_DQSLPEN_SHIFT)) & QuadSPI_SOCCR_DQSLPEN_MASK) +#define QuadSPI_SOCCR_DQSPADLPEN_MASK (0x200U) +#define QuadSPI_SOCCR_DQSPADLPEN_SHIFT (9U) +#define QuadSPI_SOCCR_DQSPADLPEN(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SOCCR_DQSPADLPEN_SHIFT)) & QuadSPI_SOCCR_DQSPADLPEN_MASK) +#define QuadSPI_SOCCR_DQSPHASEL_MASK (0xC00U) +#define QuadSPI_SOCCR_DQSPHASEL_SHIFT (10U) +#define QuadSPI_SOCCR_DQSPHASEL(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SOCCR_DQSPHASEL_SHIFT)) & QuadSPI_SOCCR_DQSPHASEL_MASK) +#define QuadSPI_SOCCR_DQSINVSEL_MASK (0x1000U) +#define QuadSPI_SOCCR_DQSINVSEL_SHIFT (12U) +#define QuadSPI_SOCCR_DQSINVSEL(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SOCCR_DQSINVSEL_SHIFT)) & QuadSPI_SOCCR_DQSINVSEL_MASK) +#define QuadSPI_SOCCR_CK2EN_MASK (0x2000U) +#define QuadSPI_SOCCR_CK2EN_SHIFT (13U) +#define QuadSPI_SOCCR_CK2EN(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SOCCR_CK2EN_SHIFT)) & QuadSPI_SOCCR_CK2EN_MASK) +#define QuadSPI_SOCCR_DIFFCKEN_MASK (0x4000U) +#define QuadSPI_SOCCR_DIFFCKEN_SHIFT (14U) +#define QuadSPI_SOCCR_DIFFCKEN(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SOCCR_DIFFCKEN_SHIFT)) & QuadSPI_SOCCR_DIFFCKEN_MASK) +#define QuadSPI_SOCCR_OCTEN_MASK (0x8000U) +#define QuadSPI_SOCCR_OCTEN_SHIFT (15U) +#define QuadSPI_SOCCR_OCTEN(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SOCCR_OCTEN_SHIFT)) & QuadSPI_SOCCR_OCTEN_MASK) +#define QuadSPI_SOCCR_DLYTAPSELA_MASK (0x3F0000U) +#define QuadSPI_SOCCR_DLYTAPSELA_SHIFT (16U) +#define QuadSPI_SOCCR_DLYTAPSELA(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SOCCR_DLYTAPSELA_SHIFT)) & QuadSPI_SOCCR_DLYTAPSELA_MASK) +#define QuadSPI_SOCCR_DLYTAPSELB_MASK (0x3F000000U) +#define QuadSPI_SOCCR_DLYTAPSELB_SHIFT (24U) +#define QuadSPI_SOCCR_DLYTAPSELB(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SOCCR_DLYTAPSELB_SHIFT)) & QuadSPI_SOCCR_DLYTAPSELB_MASK) + +/*! @name BUF0IND - Buffer0 Top Index Register */ +#define QuadSPI_BUF0IND_TPINDX0_MASK (0xFFFFFFF8U) +#define QuadSPI_BUF0IND_TPINDX0_SHIFT (3U) +#define QuadSPI_BUF0IND_TPINDX0(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF0IND_TPINDX0_SHIFT)) & QuadSPI_BUF0IND_TPINDX0_MASK) + +/*! @name BUF1IND - Buffer1 Top Index Register */ +#define QuadSPI_BUF1IND_TPINDX1_MASK (0xFFFFFFF8U) +#define QuadSPI_BUF1IND_TPINDX1_SHIFT (3U) +#define QuadSPI_BUF1IND_TPINDX1(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF1IND_TPINDX1_SHIFT)) & QuadSPI_BUF1IND_TPINDX1_MASK) + +/*! @name BUF2IND - Buffer2 Top Index Register */ +#define QuadSPI_BUF2IND_TPINDX2_MASK (0xFFFFFFF8U) +#define QuadSPI_BUF2IND_TPINDX2_SHIFT (3U) +#define QuadSPI_BUF2IND_TPINDX2(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_BUF2IND_TPINDX2_SHIFT)) & QuadSPI_BUF2IND_TPINDX2_MASK) + +/*! @name SFAR - Serial Flash Address Register */ +#define QuadSPI_SFAR_SFADR_MASK (0xFFFFFFFFU) +#define QuadSPI_SFAR_SFADR_SHIFT (0U) +#define QuadSPI_SFAR_SFADR(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SFAR_SFADR_SHIFT)) & QuadSPI_SFAR_SFADR_MASK) + +/*! @name SFACR - Serial Flash Address Configuration Register */ +#define QuadSPI_SFACR_CAS_MASK (0xFU) +#define QuadSPI_SFACR_CAS_SHIFT (0U) +#define QuadSPI_SFACR_CAS(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SFACR_CAS_SHIFT)) & QuadSPI_SFACR_CAS_MASK) +#define QuadSPI_SFACR_WA_MASK (0x10000U) +#define QuadSPI_SFACR_WA_SHIFT (16U) +#define QuadSPI_SFACR_WA(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SFACR_WA_SHIFT)) & QuadSPI_SFACR_WA_MASK) + +/*! @name SMPR - Sampling Register */ +#define QuadSPI_SMPR_HSENA_MASK (0x1U) +#define QuadSPI_SMPR_HSENA_SHIFT (0U) +#define QuadSPI_SMPR_HSENA(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SMPR_HSENA_SHIFT)) & QuadSPI_SMPR_HSENA_MASK) +#define QuadSPI_SMPR_HSPHS_MASK (0x2U) +#define QuadSPI_SMPR_HSPHS_SHIFT (1U) +#define QuadSPI_SMPR_HSPHS(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SMPR_HSPHS_SHIFT)) & QuadSPI_SMPR_HSPHS_MASK) +#define QuadSPI_SMPR_HSDLY_MASK (0x4U) +#define QuadSPI_SMPR_HSDLY_SHIFT (2U) +#define QuadSPI_SMPR_HSDLY(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SMPR_HSDLY_SHIFT)) & QuadSPI_SMPR_HSDLY_MASK) +#define QuadSPI_SMPR_FSPHS_MASK (0x20U) +#define QuadSPI_SMPR_FSPHS_SHIFT (5U) +#define QuadSPI_SMPR_FSPHS(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SMPR_FSPHS_SHIFT)) & QuadSPI_SMPR_FSPHS_MASK) +#define QuadSPI_SMPR_FSDLY_MASK (0x40U) +#define QuadSPI_SMPR_FSDLY_SHIFT (6U) +#define QuadSPI_SMPR_FSDLY(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SMPR_FSDLY_SHIFT)) & QuadSPI_SMPR_FSDLY_MASK) +#define QuadSPI_SMPR_DDRSMP_MASK (0x70000U) +#define QuadSPI_SMPR_DDRSMP_SHIFT (16U) +#define QuadSPI_SMPR_DDRSMP(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SMPR_DDRSMP_SHIFT)) & QuadSPI_SMPR_DDRSMP_MASK) + +/*! @name RBSR - RX Buffer Status Register */ +#define QuadSPI_RBSR_RDBFL_MASK (0x1F00U) +#define QuadSPI_RBSR_RDBFL_SHIFT (8U) +#define QuadSPI_RBSR_RDBFL(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RBSR_RDBFL_SHIFT)) & QuadSPI_RBSR_RDBFL_MASK) +#define QuadSPI_RBSR_RDCTR_MASK (0xFFFF0000U) +#define QuadSPI_RBSR_RDCTR_SHIFT (16U) +#define QuadSPI_RBSR_RDCTR(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RBSR_RDCTR_SHIFT)) & QuadSPI_RBSR_RDCTR_MASK) + +/*! @name RBCT - RX Buffer Control Register */ +#define QuadSPI_RBCT_WMRK_MASK (0xFU) +#define QuadSPI_RBCT_WMRK_SHIFT (0U) +#define QuadSPI_RBCT_WMRK(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RBCT_WMRK_SHIFT)) & QuadSPI_RBCT_WMRK_MASK) +#define QuadSPI_RBCT_RXBRD_MASK (0x100U) +#define QuadSPI_RBCT_RXBRD_SHIFT (8U) +#define QuadSPI_RBCT_RXBRD(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RBCT_RXBRD_SHIFT)) & QuadSPI_RBCT_RXBRD_MASK) + +/*! @name TBSR - TX Buffer Status Register */ +#define QuadSPI_TBSR_TRBFL_MASK (0x1F00U) +#define QuadSPI_TBSR_TRBFL_SHIFT (8U) +#define QuadSPI_TBSR_TRBFL(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_TBSR_TRBFL_SHIFT)) & QuadSPI_TBSR_TRBFL_MASK) +#define QuadSPI_TBSR_TRCTR_MASK (0xFFFF0000U) +#define QuadSPI_TBSR_TRCTR_SHIFT (16U) +#define QuadSPI_TBSR_TRCTR(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_TBSR_TRCTR_SHIFT)) & QuadSPI_TBSR_TRCTR_MASK) + +/*! @name TBDR - TX Buffer Data Register */ +#define QuadSPI_TBDR_TXDATA_MASK (0xFFFFFFFFU) +#define QuadSPI_TBDR_TXDATA_SHIFT (0U) +#define QuadSPI_TBDR_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_TBDR_TXDATA_SHIFT)) & QuadSPI_TBDR_TXDATA_MASK) + +/*! @name TBCT - Tx Buffer Control Register */ +#define QuadSPI_TBCT_WMRK_MASK (0xFU) +#define QuadSPI_TBCT_WMRK_SHIFT (0U) +#define QuadSPI_TBCT_WMRK(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_TBCT_WMRK_SHIFT)) & QuadSPI_TBCT_WMRK_MASK) + +/*! @name SR - Status Register */ +#define QuadSPI_SR_BUSY_MASK (0x1U) +#define QuadSPI_SR_BUSY_SHIFT (0U) +#define QuadSPI_SR_BUSY(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_BUSY_SHIFT)) & QuadSPI_SR_BUSY_MASK) +#define QuadSPI_SR_IP_ACC_MASK (0x2U) +#define QuadSPI_SR_IP_ACC_SHIFT (1U) +#define QuadSPI_SR_IP_ACC(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_IP_ACC_SHIFT)) & QuadSPI_SR_IP_ACC_MASK) +#define QuadSPI_SR_AHB_ACC_MASK (0x4U) +#define QuadSPI_SR_AHB_ACC_SHIFT (2U) +#define QuadSPI_SR_AHB_ACC(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_AHB_ACC_SHIFT)) & QuadSPI_SR_AHB_ACC_MASK) +#define QuadSPI_SR_AHBGNT_MASK (0x20U) +#define QuadSPI_SR_AHBGNT_SHIFT (5U) +#define QuadSPI_SR_AHBGNT(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_AHBGNT_SHIFT)) & QuadSPI_SR_AHBGNT_MASK) +#define QuadSPI_SR_AHBTRN_MASK (0x40U) +#define QuadSPI_SR_AHBTRN_SHIFT (6U) +#define QuadSPI_SR_AHBTRN(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_AHBTRN_SHIFT)) & QuadSPI_SR_AHBTRN_MASK) +#define QuadSPI_SR_AHB0NE_MASK (0x80U) +#define QuadSPI_SR_AHB0NE_SHIFT (7U) +#define QuadSPI_SR_AHB0NE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_AHB0NE_SHIFT)) & QuadSPI_SR_AHB0NE_MASK) +#define QuadSPI_SR_AHB1NE_MASK (0x100U) +#define QuadSPI_SR_AHB1NE_SHIFT (8U) +#define QuadSPI_SR_AHB1NE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_AHB1NE_SHIFT)) & QuadSPI_SR_AHB1NE_MASK) +#define QuadSPI_SR_AHB2NE_MASK (0x200U) +#define QuadSPI_SR_AHB2NE_SHIFT (9U) +#define QuadSPI_SR_AHB2NE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_AHB2NE_SHIFT)) & QuadSPI_SR_AHB2NE_MASK) +#define QuadSPI_SR_AHB3NE_MASK (0x400U) +#define QuadSPI_SR_AHB3NE_SHIFT (10U) +#define QuadSPI_SR_AHB3NE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_AHB3NE_SHIFT)) & QuadSPI_SR_AHB3NE_MASK) +#define QuadSPI_SR_AHB0FUL_MASK (0x800U) +#define QuadSPI_SR_AHB0FUL_SHIFT (11U) +#define QuadSPI_SR_AHB0FUL(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_AHB0FUL_SHIFT)) & QuadSPI_SR_AHB0FUL_MASK) +#define QuadSPI_SR_AHB1FUL_MASK (0x1000U) +#define QuadSPI_SR_AHB1FUL_SHIFT (12U) +#define QuadSPI_SR_AHB1FUL(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_AHB1FUL_SHIFT)) & QuadSPI_SR_AHB1FUL_MASK) +#define QuadSPI_SR_AHB2FUL_MASK (0x2000U) +#define QuadSPI_SR_AHB2FUL_SHIFT (13U) +#define QuadSPI_SR_AHB2FUL(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_AHB2FUL_SHIFT)) & QuadSPI_SR_AHB2FUL_MASK) +#define QuadSPI_SR_AHB3FUL_MASK (0x4000U) +#define QuadSPI_SR_AHB3FUL_SHIFT (14U) +#define QuadSPI_SR_AHB3FUL(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_AHB3FUL_SHIFT)) & QuadSPI_SR_AHB3FUL_MASK) +#define QuadSPI_SR_RXWE_MASK (0x10000U) +#define QuadSPI_SR_RXWE_SHIFT (16U) +#define QuadSPI_SR_RXWE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_RXWE_SHIFT)) & QuadSPI_SR_RXWE_MASK) +#define QuadSPI_SR_RXFULL_MASK (0x80000U) +#define QuadSPI_SR_RXFULL_SHIFT (19U) +#define QuadSPI_SR_RXFULL(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_RXFULL_SHIFT)) & QuadSPI_SR_RXFULL_MASK) +#define QuadSPI_SR_RXDMA_MASK (0x800000U) +#define QuadSPI_SR_RXDMA_SHIFT (23U) +#define QuadSPI_SR_RXDMA(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_RXDMA_SHIFT)) & QuadSPI_SR_RXDMA_MASK) +#define QuadSPI_SR_TXEDA_MASK (0x1000000U) +#define QuadSPI_SR_TXEDA_SHIFT (24U) +#define QuadSPI_SR_TXEDA(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_TXEDA_SHIFT)) & QuadSPI_SR_TXEDA_MASK) +#define QuadSPI_SR_TXWA_MASK (0x2000000U) +#define QuadSPI_SR_TXWA_SHIFT (25U) +#define QuadSPI_SR_TXWA(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_TXWA_SHIFT)) & QuadSPI_SR_TXWA_MASK) +#define QuadSPI_SR_TXDMA_MASK (0x4000000U) +#define QuadSPI_SR_TXDMA_SHIFT (26U) +#define QuadSPI_SR_TXDMA(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_TXDMA_SHIFT)) & QuadSPI_SR_TXDMA_MASK) +#define QuadSPI_SR_TXFULL_MASK (0x8000000U) +#define QuadSPI_SR_TXFULL_SHIFT (27U) +#define QuadSPI_SR_TXFULL(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_TXFULL_SHIFT)) & QuadSPI_SR_TXFULL_MASK) +#define QuadSPI_SR_DLPSMP_MASK (0xE0000000U) +#define QuadSPI_SR_DLPSMP_SHIFT (29U) +#define QuadSPI_SR_DLPSMP(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SR_DLPSMP_SHIFT)) & QuadSPI_SR_DLPSMP_MASK) + +/*! @name FR - Flag Register */ +#define QuadSPI_FR_TFF_MASK (0x1U) +#define QuadSPI_FR_TFF_SHIFT (0U) +#define QuadSPI_FR_TFF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_TFF_SHIFT)) & QuadSPI_FR_TFF_MASK) +#define QuadSPI_FR_IPGEF_MASK (0x10U) +#define QuadSPI_FR_IPGEF_SHIFT (4U) +#define QuadSPI_FR_IPGEF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_IPGEF_SHIFT)) & QuadSPI_FR_IPGEF_MASK) +#define QuadSPI_FR_IPIEF_MASK (0x40U) +#define QuadSPI_FR_IPIEF_SHIFT (6U) +#define QuadSPI_FR_IPIEF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_IPIEF_SHIFT)) & QuadSPI_FR_IPIEF_MASK) +#define QuadSPI_FR_IPAEF_MASK (0x80U) +#define QuadSPI_FR_IPAEF_SHIFT (7U) +#define QuadSPI_FR_IPAEF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_IPAEF_SHIFT)) & QuadSPI_FR_IPAEF_MASK) +#define QuadSPI_FR_IUEF_MASK (0x800U) +#define QuadSPI_FR_IUEF_SHIFT (11U) +#define QuadSPI_FR_IUEF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_IUEF_SHIFT)) & QuadSPI_FR_IUEF_MASK) +#define QuadSPI_FR_ABOF_MASK (0x1000U) +#define QuadSPI_FR_ABOF_SHIFT (12U) +#define QuadSPI_FR_ABOF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_ABOF_SHIFT)) & QuadSPI_FR_ABOF_MASK) +#define QuadSPI_FR_AIBSEF_MASK (0x2000U) +#define QuadSPI_FR_AIBSEF_SHIFT (13U) +#define QuadSPI_FR_AIBSEF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_AIBSEF_SHIFT)) & QuadSPI_FR_AIBSEF_MASK) +#define QuadSPI_FR_AITEF_MASK (0x4000U) +#define QuadSPI_FR_AITEF_SHIFT (14U) +#define QuadSPI_FR_AITEF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_AITEF_SHIFT)) & QuadSPI_FR_AITEF_MASK) +#define QuadSPI_FR_ABSEF_MASK (0x8000U) +#define QuadSPI_FR_ABSEF_SHIFT (15U) +#define QuadSPI_FR_ABSEF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_ABSEF_SHIFT)) & QuadSPI_FR_ABSEF_MASK) +#define QuadSPI_FR_RBDF_MASK (0x10000U) +#define QuadSPI_FR_RBDF_SHIFT (16U) +#define QuadSPI_FR_RBDF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_RBDF_SHIFT)) & QuadSPI_FR_RBDF_MASK) +#define QuadSPI_FR_RBOF_MASK (0x20000U) +#define QuadSPI_FR_RBOF_SHIFT (17U) +#define QuadSPI_FR_RBOF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_RBOF_SHIFT)) & QuadSPI_FR_RBOF_MASK) +#define QuadSPI_FR_ILLINE_MASK (0x800000U) +#define QuadSPI_FR_ILLINE_SHIFT (23U) +#define QuadSPI_FR_ILLINE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_ILLINE_SHIFT)) & QuadSPI_FR_ILLINE_MASK) +#define QuadSPI_FR_TBUF_MASK (0x4000000U) +#define QuadSPI_FR_TBUF_SHIFT (26U) +#define QuadSPI_FR_TBUF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_TBUF_SHIFT)) & QuadSPI_FR_TBUF_MASK) +#define QuadSPI_FR_TBFF_MASK (0x8000000U) +#define QuadSPI_FR_TBFF_SHIFT (27U) +#define QuadSPI_FR_TBFF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_TBFF_SHIFT)) & QuadSPI_FR_TBFF_MASK) +#define QuadSPI_FR_DLPFF_MASK (0x80000000U) +#define QuadSPI_FR_DLPFF_SHIFT (31U) +#define QuadSPI_FR_DLPFF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_FR_DLPFF_SHIFT)) & QuadSPI_FR_DLPFF_MASK) + +/*! @name RSER - Interrupt and DMA Request Select and Enable Register */ +#define QuadSPI_RSER_TFIE_MASK (0x1U) +#define QuadSPI_RSER_TFIE_SHIFT (0U) +#define QuadSPI_RSER_TFIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_TFIE_SHIFT)) & QuadSPI_RSER_TFIE_MASK) +#define QuadSPI_RSER_IPGEIE_MASK (0x10U) +#define QuadSPI_RSER_IPGEIE_SHIFT (4U) +#define QuadSPI_RSER_IPGEIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_IPGEIE_SHIFT)) & QuadSPI_RSER_IPGEIE_MASK) +#define QuadSPI_RSER_IPIEIE_MASK (0x40U) +#define QuadSPI_RSER_IPIEIE_SHIFT (6U) +#define QuadSPI_RSER_IPIEIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_IPIEIE_SHIFT)) & QuadSPI_RSER_IPIEIE_MASK) +#define QuadSPI_RSER_IPAEIE_MASK (0x80U) +#define QuadSPI_RSER_IPAEIE_SHIFT (7U) +#define QuadSPI_RSER_IPAEIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_IPAEIE_SHIFT)) & QuadSPI_RSER_IPAEIE_MASK) +#define QuadSPI_RSER_IUEIE_MASK (0x800U) +#define QuadSPI_RSER_IUEIE_SHIFT (11U) +#define QuadSPI_RSER_IUEIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_IUEIE_SHIFT)) & QuadSPI_RSER_IUEIE_MASK) +#define QuadSPI_RSER_ABOIE_MASK (0x1000U) +#define QuadSPI_RSER_ABOIE_SHIFT (12U) +#define QuadSPI_RSER_ABOIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_ABOIE_SHIFT)) & QuadSPI_RSER_ABOIE_MASK) +#define QuadSPI_RSER_AIBSIE_MASK (0x2000U) +#define QuadSPI_RSER_AIBSIE_SHIFT (13U) +#define QuadSPI_RSER_AIBSIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_AIBSIE_SHIFT)) & QuadSPI_RSER_AIBSIE_MASK) +#define QuadSPI_RSER_AITIE_MASK (0x4000U) +#define QuadSPI_RSER_AITIE_SHIFT (14U) +#define QuadSPI_RSER_AITIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_AITIE_SHIFT)) & QuadSPI_RSER_AITIE_MASK) +#define QuadSPI_RSER_ABSEIE_MASK (0x8000U) +#define QuadSPI_RSER_ABSEIE_SHIFT (15U) +#define QuadSPI_RSER_ABSEIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_ABSEIE_SHIFT)) & QuadSPI_RSER_ABSEIE_MASK) +#define QuadSPI_RSER_RBDIE_MASK (0x10000U) +#define QuadSPI_RSER_RBDIE_SHIFT (16U) +#define QuadSPI_RSER_RBDIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_RBDIE_SHIFT)) & QuadSPI_RSER_RBDIE_MASK) +#define QuadSPI_RSER_RBOIE_MASK (0x20000U) +#define QuadSPI_RSER_RBOIE_SHIFT (17U) +#define QuadSPI_RSER_RBOIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_RBOIE_SHIFT)) & QuadSPI_RSER_RBOIE_MASK) +#define QuadSPI_RSER_RBDDE_MASK (0x200000U) +#define QuadSPI_RSER_RBDDE_SHIFT (21U) +#define QuadSPI_RSER_RBDDE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_RBDDE_SHIFT)) & QuadSPI_RSER_RBDDE_MASK) +#define QuadSPI_RSER_ILLINIE_MASK (0x800000U) +#define QuadSPI_RSER_ILLINIE_SHIFT (23U) +#define QuadSPI_RSER_ILLINIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_ILLINIE_SHIFT)) & QuadSPI_RSER_ILLINIE_MASK) +#define QuadSPI_RSER_TBFDE_MASK (0x2000000U) +#define QuadSPI_RSER_TBFDE_SHIFT (25U) +#define QuadSPI_RSER_TBFDE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_TBFDE_SHIFT)) & QuadSPI_RSER_TBFDE_MASK) +#define QuadSPI_RSER_TBUIE_MASK (0x4000000U) +#define QuadSPI_RSER_TBUIE_SHIFT (26U) +#define QuadSPI_RSER_TBUIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_TBUIE_SHIFT)) & QuadSPI_RSER_TBUIE_MASK) +#define QuadSPI_RSER_TBFIE_MASK (0x8000000U) +#define QuadSPI_RSER_TBFIE_SHIFT (27U) +#define QuadSPI_RSER_TBFIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_TBFIE_SHIFT)) & QuadSPI_RSER_TBFIE_MASK) +#define QuadSPI_RSER_DLPFIE_MASK (0x80000000U) +#define QuadSPI_RSER_DLPFIE_SHIFT (31U) +#define QuadSPI_RSER_DLPFIE(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RSER_DLPFIE_SHIFT)) & QuadSPI_RSER_DLPFIE_MASK) + +/*! @name SPNDST - Sequence Suspend Status Register */ +#define QuadSPI_SPNDST_SUSPND_MASK (0x1U) +#define QuadSPI_SPNDST_SUSPND_SHIFT (0U) +#define QuadSPI_SPNDST_SUSPND(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SPNDST_SUSPND_SHIFT)) & QuadSPI_SPNDST_SUSPND_MASK) +#define QuadSPI_SPNDST_SPDBUF_MASK (0xC0U) +#define QuadSPI_SPNDST_SPDBUF_SHIFT (6U) +#define QuadSPI_SPNDST_SPDBUF(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SPNDST_SPDBUF_SHIFT)) & QuadSPI_SPNDST_SPDBUF_MASK) +#define QuadSPI_SPNDST_DATLFT_MASK (0x7E00U) +#define QuadSPI_SPNDST_DATLFT_SHIFT (9U) +#define QuadSPI_SPNDST_DATLFT(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SPNDST_DATLFT_SHIFT)) & QuadSPI_SPNDST_DATLFT_MASK) + +/*! @name SPTRCLR - Sequence Pointer Clear Register */ +#define QuadSPI_SPTRCLR_BFPTRC_MASK (0x1U) +#define QuadSPI_SPTRCLR_BFPTRC_SHIFT (0U) +#define QuadSPI_SPTRCLR_BFPTRC(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SPTRCLR_BFPTRC_SHIFT)) & QuadSPI_SPTRCLR_BFPTRC_MASK) +#define QuadSPI_SPTRCLR_IPPTRC_MASK (0x100U) +#define QuadSPI_SPTRCLR_IPPTRC_SHIFT (8U) +#define QuadSPI_SPTRCLR_IPPTRC(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SPTRCLR_IPPTRC_SHIFT)) & QuadSPI_SPTRCLR_IPPTRC_MASK) + +/*! @name SFA1AD - Serial Flash A1 Top Address */ +#define QuadSPI_SFA1AD_TPADA1_MASK (0xFFFFFC00U) +#define QuadSPI_SFA1AD_TPADA1_SHIFT (10U) +#define QuadSPI_SFA1AD_TPADA1(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SFA1AD_TPADA1_SHIFT)) & QuadSPI_SFA1AD_TPADA1_MASK) + +/*! @name SFA2AD - Serial Flash A2 Top Address */ +#define QuadSPI_SFA2AD_TPADA2_MASK (0xFFFFFC00U) +#define QuadSPI_SFA2AD_TPADA2_SHIFT (10U) +#define QuadSPI_SFA2AD_TPADA2(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SFA2AD_TPADA2_SHIFT)) & QuadSPI_SFA2AD_TPADA2_MASK) + +/*! @name SFB1AD - Serial Flash B1Top Address */ +#define QuadSPI_SFB1AD_TPADB1_MASK (0xFFFFFC00U) +#define QuadSPI_SFB1AD_TPADB1_SHIFT (10U) +#define QuadSPI_SFB1AD_TPADB1(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SFB1AD_TPADB1_SHIFT)) & QuadSPI_SFB1AD_TPADB1_MASK) + +/*! @name SFB2AD - Serial Flash B2Top Address */ +#define QuadSPI_SFB2AD_TPADB2_MASK (0xFFFFFC00U) +#define QuadSPI_SFB2AD_TPADB2_SHIFT (10U) +#define QuadSPI_SFB2AD_TPADB2(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_SFB2AD_TPADB2_SHIFT)) & QuadSPI_SFB2AD_TPADB2_MASK) + +/*! @name DLPR - Data Learn Pattern Register */ +#define QuadSPI_DLPR_DLPV_MASK (0xFFFFFFFFU) +#define QuadSPI_DLPR_DLPV_SHIFT (0U) +#define QuadSPI_DLPR_DLPV(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_DLPR_DLPV_SHIFT)) & QuadSPI_DLPR_DLPV_MASK) + +/*! @name RBDR - RX Buffer Data Register */ +#define QuadSPI_RBDR_RXDATA_MASK (0xFFFFFFFFU) +#define QuadSPI_RBDR_RXDATA_SHIFT (0U) +#define QuadSPI_RBDR_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_RBDR_RXDATA_SHIFT)) & QuadSPI_RBDR_RXDATA_MASK) + +/* The count of QuadSPI_RBDR */ +#define QuadSPI_RBDR_COUNT (16U) + +/*! @name LUTKEY - LUT Key Register */ +#define QuadSPI_LUTKEY_KEY_MASK (0xFFFFFFFFU) +#define QuadSPI_LUTKEY_KEY_SHIFT (0U) +#define QuadSPI_LUTKEY_KEY(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_LUTKEY_KEY_SHIFT)) & QuadSPI_LUTKEY_KEY_MASK) + +/*! @name LCKCR - LUT Lock Configuration Register */ +#define QuadSPI_LCKCR_LOCK_MASK (0x1U) +#define QuadSPI_LCKCR_LOCK_SHIFT (0U) +#define QuadSPI_LCKCR_LOCK(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_LCKCR_LOCK_SHIFT)) & QuadSPI_LCKCR_LOCK_MASK) +#define QuadSPI_LCKCR_UNLOCK_MASK (0x2U) +#define QuadSPI_LCKCR_UNLOCK_SHIFT (1U) +#define QuadSPI_LCKCR_UNLOCK(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_LCKCR_UNLOCK_SHIFT)) & QuadSPI_LCKCR_UNLOCK_MASK) + +/*! @name LUT - Look-up Table register */ +#define QuadSPI_LUT_OPRND0_MASK (0xFFU) +#define QuadSPI_LUT_OPRND0_SHIFT (0U) +#define QuadSPI_LUT_OPRND0(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_LUT_OPRND0_SHIFT)) & QuadSPI_LUT_OPRND0_MASK) +#define QuadSPI_LUT_PAD0_MASK (0x300U) +#define QuadSPI_LUT_PAD0_SHIFT (8U) +#define QuadSPI_LUT_PAD0(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_LUT_PAD0_SHIFT)) & QuadSPI_LUT_PAD0_MASK) +#define QuadSPI_LUT_INSTR0_MASK (0xFC00U) +#define QuadSPI_LUT_INSTR0_SHIFT (10U) +#define QuadSPI_LUT_INSTR0(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_LUT_INSTR0_SHIFT)) & QuadSPI_LUT_INSTR0_MASK) +#define QuadSPI_LUT_OPRND1_MASK (0xFF0000U) +#define QuadSPI_LUT_OPRND1_SHIFT (16U) +#define QuadSPI_LUT_OPRND1(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_LUT_OPRND1_SHIFT)) & QuadSPI_LUT_OPRND1_MASK) +#define QuadSPI_LUT_PAD1_MASK (0x3000000U) +#define QuadSPI_LUT_PAD1_SHIFT (24U) +#define QuadSPI_LUT_PAD1(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_LUT_PAD1_SHIFT)) & QuadSPI_LUT_PAD1_MASK) +#define QuadSPI_LUT_INSTR1_MASK (0xFC000000U) +#define QuadSPI_LUT_INSTR1_SHIFT (26U) +#define QuadSPI_LUT_INSTR1(x) (((uint32_t)(((uint32_t)(x)) << QuadSPI_LUT_INSTR1_SHIFT)) & QuadSPI_LUT_INSTR1_MASK) + +/* The count of QuadSPI_LUT */ +#define QuadSPI_LUT_COUNT (64U) + + +/*! + * @} + */ /* end of group QuadSPI_Register_Masks */ + + +/* QuadSPI - Peripheral instance base addresses */ +/** Peripheral QuadSPI0 base address */ +#define QuadSPI0_BASE (0x400DA000u) +/** Peripheral QuadSPI0 base pointer */ +#define QuadSPI0 ((QuadSPI_Type *)QuadSPI0_BASE) +/** Array initializer of QuadSPI peripheral base addresses */ +#define QuadSPI_BASE_ADDRS { QuadSPI0_BASE } +/** Array initializer of QuadSPI peripheral base pointers */ +#define QuadSPI_BASE_PTRS { QuadSPI0 } +/** Interrupt vectors for the QuadSPI peripheral type */ +#define QuadSPI_IRQS { QuadSPI0_IRQn } + +/*! + * @} + */ /* end of group QuadSPI_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RCM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RCM_Peripheral_Access_Layer RCM Peripheral Access Layer + * @{ + */ + +/** RCM - Register Layout Typedef */ +typedef struct { + __I uint8_t SRS0; /**< System Reset Status Register 0, offset: 0x0 */ + __I uint8_t SRS1; /**< System Reset Status Register 1, offset: 0x1 */ + uint8_t RESERVED_0[2]; + __IO uint8_t RPFC; /**< Reset Pin Filter Control register, offset: 0x4 */ + __IO uint8_t RPFW; /**< Reset Pin Filter Width register, offset: 0x5 */ + __IO uint8_t FM; /**< Force Mode Register, offset: 0x6 */ + __IO uint8_t MR; /**< Mode Register, offset: 0x7 */ + __IO uint8_t SSRS0; /**< Sticky System Reset Status Register 0, offset: 0x8 */ + __IO uint8_t SSRS1; /**< Sticky System Reset Status Register 1, offset: 0x9 */ +} RCM_Type; + +/* ---------------------------------------------------------------------------- + -- RCM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RCM_Register_Masks RCM Register Masks + * @{ + */ + +/*! @name SRS0 - System Reset Status Register 0 */ +#define RCM_SRS0_WAKEUP_MASK (0x1U) +#define RCM_SRS0_WAKEUP_SHIFT (0U) +#define RCM_SRS0_WAKEUP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_WAKEUP_SHIFT)) & RCM_SRS0_WAKEUP_MASK) +#define RCM_SRS0_LVD_MASK (0x2U) +#define RCM_SRS0_LVD_SHIFT (1U) +#define RCM_SRS0_LVD(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_LVD_SHIFT)) & RCM_SRS0_LVD_MASK) +#define RCM_SRS0_LOC_MASK (0x4U) +#define RCM_SRS0_LOC_SHIFT (2U) +#define RCM_SRS0_LOC(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_LOC_SHIFT)) & RCM_SRS0_LOC_MASK) +#define RCM_SRS0_LOL_MASK (0x8U) +#define RCM_SRS0_LOL_SHIFT (3U) +#define RCM_SRS0_LOL(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_LOL_SHIFT)) & RCM_SRS0_LOL_MASK) +#define RCM_SRS0_WDOG_MASK (0x20U) +#define RCM_SRS0_WDOG_SHIFT (5U) +#define RCM_SRS0_WDOG(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_WDOG_SHIFT)) & RCM_SRS0_WDOG_MASK) +#define RCM_SRS0_PIN_MASK (0x40U) +#define RCM_SRS0_PIN_SHIFT (6U) +#define RCM_SRS0_PIN(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_PIN_SHIFT)) & RCM_SRS0_PIN_MASK) +#define RCM_SRS0_POR_MASK (0x80U) +#define RCM_SRS0_POR_SHIFT (7U) +#define RCM_SRS0_POR(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_POR_SHIFT)) & RCM_SRS0_POR_MASK) + +/*! @name SRS1 - System Reset Status Register 1 */ +#define RCM_SRS1_JTAG_MASK (0x1U) +#define RCM_SRS1_JTAG_SHIFT (0U) +#define RCM_SRS1_JTAG(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_JTAG_SHIFT)) & RCM_SRS1_JTAG_MASK) +#define RCM_SRS1_LOCKUP_MASK (0x2U) +#define RCM_SRS1_LOCKUP_SHIFT (1U) +#define RCM_SRS1_LOCKUP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_LOCKUP_SHIFT)) & RCM_SRS1_LOCKUP_MASK) +#define RCM_SRS1_SW_MASK (0x4U) +#define RCM_SRS1_SW_SHIFT (2U) +#define RCM_SRS1_SW(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_SW_SHIFT)) & RCM_SRS1_SW_MASK) +#define RCM_SRS1_MDM_AP_MASK (0x8U) +#define RCM_SRS1_MDM_AP_SHIFT (3U) +#define RCM_SRS1_MDM_AP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_MDM_AP_SHIFT)) & RCM_SRS1_MDM_AP_MASK) +#define RCM_SRS1_SACKERR_MASK (0x20U) +#define RCM_SRS1_SACKERR_SHIFT (5U) +#define RCM_SRS1_SACKERR(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_SACKERR_SHIFT)) & RCM_SRS1_SACKERR_MASK) + +/*! @name RPFC - Reset Pin Filter Control register */ +#define RCM_RPFC_RSTFLTSRW_MASK (0x3U) +#define RCM_RPFC_RSTFLTSRW_SHIFT (0U) +#define RCM_RPFC_RSTFLTSRW(x) (((uint8_t)(((uint8_t)(x)) << RCM_RPFC_RSTFLTSRW_SHIFT)) & RCM_RPFC_RSTFLTSRW_MASK) +#define RCM_RPFC_RSTFLTSS_MASK (0x4U) +#define RCM_RPFC_RSTFLTSS_SHIFT (2U) +#define RCM_RPFC_RSTFLTSS(x) (((uint8_t)(((uint8_t)(x)) << RCM_RPFC_RSTFLTSS_SHIFT)) & RCM_RPFC_RSTFLTSS_MASK) + +/*! @name RPFW - Reset Pin Filter Width register */ +#define RCM_RPFW_RSTFLTSEL_MASK (0x1FU) +#define RCM_RPFW_RSTFLTSEL_SHIFT (0U) +#define RCM_RPFW_RSTFLTSEL(x) (((uint8_t)(((uint8_t)(x)) << RCM_RPFW_RSTFLTSEL_SHIFT)) & RCM_RPFW_RSTFLTSEL_MASK) + +/*! @name FM - Force Mode Register */ +#define RCM_FM_FORCEROM_MASK (0x6U) +#define RCM_FM_FORCEROM_SHIFT (1U) +#define RCM_FM_FORCEROM(x) (((uint8_t)(((uint8_t)(x)) << RCM_FM_FORCEROM_SHIFT)) & RCM_FM_FORCEROM_MASK) + +/*! @name MR - Mode Register */ +#define RCM_MR_BOOTROM_MASK (0x6U) +#define RCM_MR_BOOTROM_SHIFT (1U) +#define RCM_MR_BOOTROM(x) (((uint8_t)(((uint8_t)(x)) << RCM_MR_BOOTROM_SHIFT)) & RCM_MR_BOOTROM_MASK) + +/*! @name SSRS0 - Sticky System Reset Status Register 0 */ +#define RCM_SSRS0_SWAKEUP_MASK (0x1U) +#define RCM_SSRS0_SWAKEUP_SHIFT (0U) +#define RCM_SSRS0_SWAKEUP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS0_SWAKEUP_SHIFT)) & RCM_SSRS0_SWAKEUP_MASK) +#define RCM_SSRS0_SLVD_MASK (0x2U) +#define RCM_SSRS0_SLVD_SHIFT (1U) +#define RCM_SSRS0_SLVD(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS0_SLVD_SHIFT)) & RCM_SSRS0_SLVD_MASK) +#define RCM_SSRS0_SLOC_MASK (0x4U) +#define RCM_SSRS0_SLOC_SHIFT (2U) +#define RCM_SSRS0_SLOC(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS0_SLOC_SHIFT)) & RCM_SSRS0_SLOC_MASK) +#define RCM_SSRS0_SLOL_MASK (0x8U) +#define RCM_SSRS0_SLOL_SHIFT (3U) +#define RCM_SSRS0_SLOL(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS0_SLOL_SHIFT)) & RCM_SSRS0_SLOL_MASK) +#define RCM_SSRS0_SWDOG_MASK (0x20U) +#define RCM_SSRS0_SWDOG_SHIFT (5U) +#define RCM_SSRS0_SWDOG(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS0_SWDOG_SHIFT)) & RCM_SSRS0_SWDOG_MASK) +#define RCM_SSRS0_SPIN_MASK (0x40U) +#define RCM_SSRS0_SPIN_SHIFT (6U) +#define RCM_SSRS0_SPIN(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS0_SPIN_SHIFT)) & RCM_SSRS0_SPIN_MASK) +#define RCM_SSRS0_SPOR_MASK (0x80U) +#define RCM_SSRS0_SPOR_SHIFT (7U) +#define RCM_SSRS0_SPOR(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS0_SPOR_SHIFT)) & RCM_SSRS0_SPOR_MASK) + +/*! @name SSRS1 - Sticky System Reset Status Register 1 */ +#define RCM_SSRS1_SJTAG_MASK (0x1U) +#define RCM_SSRS1_SJTAG_SHIFT (0U) +#define RCM_SSRS1_SJTAG(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS1_SJTAG_SHIFT)) & RCM_SSRS1_SJTAG_MASK) +#define RCM_SSRS1_SLOCKUP_MASK (0x2U) +#define RCM_SSRS1_SLOCKUP_SHIFT (1U) +#define RCM_SSRS1_SLOCKUP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS1_SLOCKUP_SHIFT)) & RCM_SSRS1_SLOCKUP_MASK) +#define RCM_SSRS1_SSW_MASK (0x4U) +#define RCM_SSRS1_SSW_SHIFT (2U) +#define RCM_SSRS1_SSW(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS1_SSW_SHIFT)) & RCM_SSRS1_SSW_MASK) +#define RCM_SSRS1_SMDM_AP_MASK (0x8U) +#define RCM_SSRS1_SMDM_AP_SHIFT (3U) +#define RCM_SSRS1_SMDM_AP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS1_SMDM_AP_SHIFT)) & RCM_SSRS1_SMDM_AP_MASK) +#define RCM_SSRS1_SSACKERR_MASK (0x20U) +#define RCM_SSRS1_SSACKERR_SHIFT (5U) +#define RCM_SSRS1_SSACKERR(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS1_SSACKERR_SHIFT)) & RCM_SSRS1_SSACKERR_MASK) + + +/*! + * @} + */ /* end of group RCM_Register_Masks */ + + +/* RCM - Peripheral instance base addresses */ +/** Peripheral RCM base address */ +#define RCM_BASE (0x4007F000u) +/** Peripheral RCM base pointer */ +#define RCM ((RCM_Type *)RCM_BASE) +/** Array initializer of RCM peripheral base addresses */ +#define RCM_BASE_ADDRS { RCM_BASE } +/** Array initializer of RCM peripheral base pointers */ +#define RCM_BASE_PTRS { RCM } + +/*! + * @} + */ /* end of group RCM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RFSYS Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RFSYS_Peripheral_Access_Layer RFSYS Peripheral Access Layer + * @{ + */ + +/** RFSYS - Register Layout Typedef */ +typedef struct { + __IO uint32_t REG[8]; /**< Register file register, array offset: 0x0, array step: 0x4 */ +} RFSYS_Type; + +/* ---------------------------------------------------------------------------- + -- RFSYS Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RFSYS_Register_Masks RFSYS Register Masks + * @{ + */ + +/*! @name REG - Register file register */ +#define RFSYS_REG_LL_MASK (0xFFU) +#define RFSYS_REG_LL_SHIFT (0U) +#define RFSYS_REG_LL(x) (((uint32_t)(((uint32_t)(x)) << RFSYS_REG_LL_SHIFT)) & RFSYS_REG_LL_MASK) +#define RFSYS_REG_LH_MASK (0xFF00U) +#define RFSYS_REG_LH_SHIFT (8U) +#define RFSYS_REG_LH(x) (((uint32_t)(((uint32_t)(x)) << RFSYS_REG_LH_SHIFT)) & RFSYS_REG_LH_MASK) +#define RFSYS_REG_HL_MASK (0xFF0000U) +#define RFSYS_REG_HL_SHIFT (16U) +#define RFSYS_REG_HL(x) (((uint32_t)(((uint32_t)(x)) << RFSYS_REG_HL_SHIFT)) & RFSYS_REG_HL_MASK) +#define RFSYS_REG_HH_MASK (0xFF000000U) +#define RFSYS_REG_HH_SHIFT (24U) +#define RFSYS_REG_HH(x) (((uint32_t)(((uint32_t)(x)) << RFSYS_REG_HH_SHIFT)) & RFSYS_REG_HH_MASK) + +/* The count of RFSYS_REG */ +#define RFSYS_REG_COUNT (8U) + + +/*! + * @} + */ /* end of group RFSYS_Register_Masks */ + + +/* RFSYS - Peripheral instance base addresses */ +/** Peripheral RFSYS base address */ +#define RFSYS_BASE (0x40041000u) +/** Peripheral RFSYS base pointer */ +#define RFSYS ((RFSYS_Type *)RFSYS_BASE) +/** Array initializer of RFSYS peripheral base addresses */ +#define RFSYS_BASE_ADDRS { RFSYS_BASE } +/** Array initializer of RFSYS peripheral base pointers */ +#define RFSYS_BASE_PTRS { RFSYS } + +/*! + * @} + */ /* end of group RFSYS_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RFVBAT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RFVBAT_Peripheral_Access_Layer RFVBAT Peripheral Access Layer + * @{ + */ + +/** RFVBAT - Register Layout Typedef */ +typedef struct { + __IO uint32_t REG[8]; /**< VBAT register file register, array offset: 0x0, array step: 0x4 */ +} RFVBAT_Type; + +/* ---------------------------------------------------------------------------- + -- RFVBAT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RFVBAT_Register_Masks RFVBAT Register Masks + * @{ + */ + +/*! @name REG - VBAT register file register */ +#define RFVBAT_REG_LL_MASK (0xFFU) +#define RFVBAT_REG_LL_SHIFT (0U) +#define RFVBAT_REG_LL(x) (((uint32_t)(((uint32_t)(x)) << RFVBAT_REG_LL_SHIFT)) & RFVBAT_REG_LL_MASK) +#define RFVBAT_REG_LH_MASK (0xFF00U) +#define RFVBAT_REG_LH_SHIFT (8U) +#define RFVBAT_REG_LH(x) (((uint32_t)(((uint32_t)(x)) << RFVBAT_REG_LH_SHIFT)) & RFVBAT_REG_LH_MASK) +#define RFVBAT_REG_HL_MASK (0xFF0000U) +#define RFVBAT_REG_HL_SHIFT (16U) +#define RFVBAT_REG_HL(x) (((uint32_t)(((uint32_t)(x)) << RFVBAT_REG_HL_SHIFT)) & RFVBAT_REG_HL_MASK) +#define RFVBAT_REG_HH_MASK (0xFF000000U) +#define RFVBAT_REG_HH_SHIFT (24U) +#define RFVBAT_REG_HH(x) (((uint32_t)(((uint32_t)(x)) << RFVBAT_REG_HH_SHIFT)) & RFVBAT_REG_HH_MASK) + +/* The count of RFVBAT_REG */ +#define RFVBAT_REG_COUNT (8U) + + +/*! + * @} + */ /* end of group RFVBAT_Register_Masks */ + + +/* RFVBAT - Peripheral instance base addresses */ +/** Peripheral RFVBAT base address */ +#define RFVBAT_BASE (0x4003E000u) +/** Peripheral RFVBAT base pointer */ +#define RFVBAT ((RFVBAT_Type *)RFVBAT_BASE) +/** Array initializer of RFVBAT peripheral base addresses */ +#define RFVBAT_BASE_ADDRS { RFVBAT_BASE } +/** Array initializer of RFVBAT peripheral base pointers */ +#define RFVBAT_BASE_PTRS { RFVBAT } + +/*! + * @} + */ /* end of group RFVBAT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RTC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RTC_Peripheral_Access_Layer RTC Peripheral Access Layer + * @{ + */ + +/** RTC - Register Layout Typedef */ +typedef struct { + __IO uint32_t TSR; /**< RTC Time Seconds Register, offset: 0x0 */ + __IO uint32_t TPR; /**< RTC Time Prescaler Register, offset: 0x4 */ + __IO uint32_t TAR; /**< RTC Time Alarm Register, offset: 0x8 */ + __IO uint32_t TCR; /**< RTC Time Compensation Register, offset: 0xC */ + __IO uint32_t CR; /**< RTC Control Register, offset: 0x10 */ + __IO uint32_t SR; /**< RTC Status Register, offset: 0x14 */ + __IO uint32_t LR; /**< RTC Lock Register, offset: 0x18 */ + __IO uint32_t IER; /**< RTC Interrupt Enable Register, offset: 0x1C */ + uint8_t RESERVED_0[2016]; + __IO uint32_t WAR; /**< RTC Write Access Register, offset: 0x800 */ + __IO uint32_t RAR; /**< RTC Read Access Register, offset: 0x804 */ +} RTC_Type; + +/* ---------------------------------------------------------------------------- + -- RTC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RTC_Register_Masks RTC Register Masks + * @{ + */ + +/*! @name TSR - RTC Time Seconds Register */ +#define RTC_TSR_TSR_MASK (0xFFFFFFFFU) +#define RTC_TSR_TSR_SHIFT (0U) +#define RTC_TSR_TSR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TSR_TSR_SHIFT)) & RTC_TSR_TSR_MASK) + +/*! @name TPR - RTC Time Prescaler Register */ +#define RTC_TPR_TPR_MASK (0xFFFFU) +#define RTC_TPR_TPR_SHIFT (0U) +#define RTC_TPR_TPR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TPR_TPR_SHIFT)) & RTC_TPR_TPR_MASK) + +/*! @name TAR - RTC Time Alarm Register */ +#define RTC_TAR_TAR_MASK (0xFFFFFFFFU) +#define RTC_TAR_TAR_SHIFT (0U) +#define RTC_TAR_TAR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TAR_TAR_SHIFT)) & RTC_TAR_TAR_MASK) + +/*! @name TCR - RTC Time Compensation Register */ +#define RTC_TCR_TCR_MASK (0xFFU) +#define RTC_TCR_TCR_SHIFT (0U) +#define RTC_TCR_TCR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TCR_TCR_SHIFT)) & RTC_TCR_TCR_MASK) +#define RTC_TCR_CIR_MASK (0xFF00U) +#define RTC_TCR_CIR_SHIFT (8U) +#define RTC_TCR_CIR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TCR_CIR_SHIFT)) & RTC_TCR_CIR_MASK) +#define RTC_TCR_TCV_MASK (0xFF0000U) +#define RTC_TCR_TCV_SHIFT (16U) +#define RTC_TCR_TCV(x) (((uint32_t)(((uint32_t)(x)) << RTC_TCR_TCV_SHIFT)) & RTC_TCR_TCV_MASK) +#define RTC_TCR_CIC_MASK (0xFF000000U) +#define RTC_TCR_CIC_SHIFT (24U) +#define RTC_TCR_CIC(x) (((uint32_t)(((uint32_t)(x)) << RTC_TCR_CIC_SHIFT)) & RTC_TCR_CIC_MASK) + +/*! @name CR - RTC Control Register */ +#define RTC_CR_SWR_MASK (0x1U) +#define RTC_CR_SWR_SHIFT (0U) +#define RTC_CR_SWR(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SWR_SHIFT)) & RTC_CR_SWR_MASK) +#define RTC_CR_WPE_MASK (0x2U) +#define RTC_CR_WPE_SHIFT (1U) +#define RTC_CR_WPE(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_WPE_SHIFT)) & RTC_CR_WPE_MASK) +#define RTC_CR_SUP_MASK (0x4U) +#define RTC_CR_SUP_SHIFT (2U) +#define RTC_CR_SUP(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SUP_SHIFT)) & RTC_CR_SUP_MASK) +#define RTC_CR_UM_MASK (0x8U) +#define RTC_CR_UM_SHIFT (3U) +#define RTC_CR_UM(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_UM_SHIFT)) & RTC_CR_UM_MASK) +#define RTC_CR_WPS_MASK (0x10U) +#define RTC_CR_WPS_SHIFT (4U) +#define RTC_CR_WPS(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_WPS_SHIFT)) & RTC_CR_WPS_MASK) +#define RTC_CR_OSCE_MASK (0x100U) +#define RTC_CR_OSCE_SHIFT (8U) +#define RTC_CR_OSCE(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_OSCE_SHIFT)) & RTC_CR_OSCE_MASK) +#define RTC_CR_CLKO_MASK (0x200U) +#define RTC_CR_CLKO_SHIFT (9U) +#define RTC_CR_CLKO(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_CLKO_SHIFT)) & RTC_CR_CLKO_MASK) +#define RTC_CR_SC16P_MASK (0x400U) +#define RTC_CR_SC16P_SHIFT (10U) +#define RTC_CR_SC16P(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SC16P_SHIFT)) & RTC_CR_SC16P_MASK) +#define RTC_CR_SC8P_MASK (0x800U) +#define RTC_CR_SC8P_SHIFT (11U) +#define RTC_CR_SC8P(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SC8P_SHIFT)) & RTC_CR_SC8P_MASK) +#define RTC_CR_SC4P_MASK (0x1000U) +#define RTC_CR_SC4P_SHIFT (12U) +#define RTC_CR_SC4P(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SC4P_SHIFT)) & RTC_CR_SC4P_MASK) +#define RTC_CR_SC2P_MASK (0x2000U) +#define RTC_CR_SC2P_SHIFT (13U) +#define RTC_CR_SC2P(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SC2P_SHIFT)) & RTC_CR_SC2P_MASK) + +/*! @name SR - RTC Status Register */ +#define RTC_SR_TIF_MASK (0x1U) +#define RTC_SR_TIF_SHIFT (0U) +#define RTC_SR_TIF(x) (((uint32_t)(((uint32_t)(x)) << RTC_SR_TIF_SHIFT)) & RTC_SR_TIF_MASK) +#define RTC_SR_TOF_MASK (0x2U) +#define RTC_SR_TOF_SHIFT (1U) +#define RTC_SR_TOF(x) (((uint32_t)(((uint32_t)(x)) << RTC_SR_TOF_SHIFT)) & RTC_SR_TOF_MASK) +#define RTC_SR_TAF_MASK (0x4U) +#define RTC_SR_TAF_SHIFT (2U) +#define RTC_SR_TAF(x) (((uint32_t)(((uint32_t)(x)) << RTC_SR_TAF_SHIFT)) & RTC_SR_TAF_MASK) +#define RTC_SR_TCE_MASK (0x10U) +#define RTC_SR_TCE_SHIFT (4U) +#define RTC_SR_TCE(x) (((uint32_t)(((uint32_t)(x)) << RTC_SR_TCE_SHIFT)) & RTC_SR_TCE_MASK) + +/*! @name LR - RTC Lock Register */ +#define RTC_LR_TCL_MASK (0x8U) +#define RTC_LR_TCL_SHIFT (3U) +#define RTC_LR_TCL(x) (((uint32_t)(((uint32_t)(x)) << RTC_LR_TCL_SHIFT)) & RTC_LR_TCL_MASK) +#define RTC_LR_CRL_MASK (0x10U) +#define RTC_LR_CRL_SHIFT (4U) +#define RTC_LR_CRL(x) (((uint32_t)(((uint32_t)(x)) << RTC_LR_CRL_SHIFT)) & RTC_LR_CRL_MASK) +#define RTC_LR_SRL_MASK (0x20U) +#define RTC_LR_SRL_SHIFT (5U) +#define RTC_LR_SRL(x) (((uint32_t)(((uint32_t)(x)) << RTC_LR_SRL_SHIFT)) & RTC_LR_SRL_MASK) +#define RTC_LR_LRL_MASK (0x40U) +#define RTC_LR_LRL_SHIFT (6U) +#define RTC_LR_LRL(x) (((uint32_t)(((uint32_t)(x)) << RTC_LR_LRL_SHIFT)) & RTC_LR_LRL_MASK) + +/*! @name IER - RTC Interrupt Enable Register */ +#define RTC_IER_TIIE_MASK (0x1U) +#define RTC_IER_TIIE_SHIFT (0U) +#define RTC_IER_TIIE(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_TIIE_SHIFT)) & RTC_IER_TIIE_MASK) +#define RTC_IER_TOIE_MASK (0x2U) +#define RTC_IER_TOIE_SHIFT (1U) +#define RTC_IER_TOIE(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_TOIE_SHIFT)) & RTC_IER_TOIE_MASK) +#define RTC_IER_TAIE_MASK (0x4U) +#define RTC_IER_TAIE_SHIFT (2U) +#define RTC_IER_TAIE(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_TAIE_SHIFT)) & RTC_IER_TAIE_MASK) +#define RTC_IER_TSIE_MASK (0x10U) +#define RTC_IER_TSIE_SHIFT (4U) +#define RTC_IER_TSIE(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_TSIE_SHIFT)) & RTC_IER_TSIE_MASK) +#define RTC_IER_WPON_MASK (0x80U) +#define RTC_IER_WPON_SHIFT (7U) +#define RTC_IER_WPON(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_WPON_SHIFT)) & RTC_IER_WPON_MASK) + +/*! @name WAR - RTC Write Access Register */ +#define RTC_WAR_TSRW_MASK (0x1U) +#define RTC_WAR_TSRW_SHIFT (0U) +#define RTC_WAR_TSRW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_TSRW_SHIFT)) & RTC_WAR_TSRW_MASK) +#define RTC_WAR_TPRW_MASK (0x2U) +#define RTC_WAR_TPRW_SHIFT (1U) +#define RTC_WAR_TPRW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_TPRW_SHIFT)) & RTC_WAR_TPRW_MASK) +#define RTC_WAR_TARW_MASK (0x4U) +#define RTC_WAR_TARW_SHIFT (2U) +#define RTC_WAR_TARW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_TARW_SHIFT)) & RTC_WAR_TARW_MASK) +#define RTC_WAR_TCRW_MASK (0x8U) +#define RTC_WAR_TCRW_SHIFT (3U) +#define RTC_WAR_TCRW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_TCRW_SHIFT)) & RTC_WAR_TCRW_MASK) +#define RTC_WAR_CRW_MASK (0x10U) +#define RTC_WAR_CRW_SHIFT (4U) +#define RTC_WAR_CRW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_CRW_SHIFT)) & RTC_WAR_CRW_MASK) +#define RTC_WAR_SRW_MASK (0x20U) +#define RTC_WAR_SRW_SHIFT (5U) +#define RTC_WAR_SRW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_SRW_SHIFT)) & RTC_WAR_SRW_MASK) +#define RTC_WAR_LRW_MASK (0x40U) +#define RTC_WAR_LRW_SHIFT (6U) +#define RTC_WAR_LRW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_LRW_SHIFT)) & RTC_WAR_LRW_MASK) +#define RTC_WAR_IERW_MASK (0x80U) +#define RTC_WAR_IERW_SHIFT (7U) +#define RTC_WAR_IERW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_IERW_SHIFT)) & RTC_WAR_IERW_MASK) + +/*! @name RAR - RTC Read Access Register */ +#define RTC_RAR_TSRR_MASK (0x1U) +#define RTC_RAR_TSRR_SHIFT (0U) +#define RTC_RAR_TSRR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_TSRR_SHIFT)) & RTC_RAR_TSRR_MASK) +#define RTC_RAR_TPRR_MASK (0x2U) +#define RTC_RAR_TPRR_SHIFT (1U) +#define RTC_RAR_TPRR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_TPRR_SHIFT)) & RTC_RAR_TPRR_MASK) +#define RTC_RAR_TARR_MASK (0x4U) +#define RTC_RAR_TARR_SHIFT (2U) +#define RTC_RAR_TARR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_TARR_SHIFT)) & RTC_RAR_TARR_MASK) +#define RTC_RAR_TCRR_MASK (0x8U) +#define RTC_RAR_TCRR_SHIFT (3U) +#define RTC_RAR_TCRR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_TCRR_SHIFT)) & RTC_RAR_TCRR_MASK) +#define RTC_RAR_CRR_MASK (0x10U) +#define RTC_RAR_CRR_SHIFT (4U) +#define RTC_RAR_CRR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_CRR_SHIFT)) & RTC_RAR_CRR_MASK) +#define RTC_RAR_SRR_MASK (0x20U) +#define RTC_RAR_SRR_SHIFT (5U) +#define RTC_RAR_SRR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_SRR_SHIFT)) & RTC_RAR_SRR_MASK) +#define RTC_RAR_LRR_MASK (0x40U) +#define RTC_RAR_LRR_SHIFT (6U) +#define RTC_RAR_LRR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_LRR_SHIFT)) & RTC_RAR_LRR_MASK) +#define RTC_RAR_IERR_MASK (0x80U) +#define RTC_RAR_IERR_SHIFT (7U) +#define RTC_RAR_IERR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_IERR_SHIFT)) & RTC_RAR_IERR_MASK) + + +/*! + * @} + */ /* end of group RTC_Register_Masks */ + + +/* RTC - Peripheral instance base addresses */ +/** Peripheral RTC base address */ +#define RTC_BASE (0x4003D000u) +/** Peripheral RTC base pointer */ +#define RTC ((RTC_Type *)RTC_BASE) +/** Array initializer of RTC peripheral base addresses */ +#define RTC_BASE_ADDRS { RTC_BASE } +/** Array initializer of RTC peripheral base pointers */ +#define RTC_BASE_PTRS { RTC } +/** Interrupt vectors for the RTC peripheral type */ +#define RTC_IRQS { RTC_IRQn } +#define RTC_SECONDS_IRQS { RTC_Seconds_IRQn } + +/*! + * @} + */ /* end of group RTC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SDHC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SDHC_Peripheral_Access_Layer SDHC Peripheral Access Layer + * @{ + */ + +/** SDHC - Register Layout Typedef */ +typedef struct { + __IO uint32_t DSADDR; /**< DMA System Address register, offset: 0x0 */ + __IO uint32_t BLKATTR; /**< Block Attributes register, offset: 0x4 */ + __IO uint32_t CMDARG; /**< Command Argument register, offset: 0x8 */ + __IO uint32_t XFERTYP; /**< Transfer Type register, offset: 0xC */ + __I uint32_t CMDRSP[4]; /**< Command Response 0..Command Response 3, array offset: 0x10, array step: 0x4 */ + __IO uint32_t DATPORT; /**< Buffer Data Port register, offset: 0x20 */ + __I uint32_t PRSSTAT; /**< Present State register, offset: 0x24 */ + __IO uint32_t PROCTL; /**< Protocol Control register, offset: 0x28 */ + __IO uint32_t SYSCTL; /**< System Control register, offset: 0x2C */ + __IO uint32_t IRQSTAT; /**< Interrupt Status register, offset: 0x30 */ + __IO uint32_t IRQSTATEN; /**< Interrupt Status Enable register, offset: 0x34 */ + __IO uint32_t IRQSIGEN; /**< Interrupt Signal Enable register, offset: 0x38 */ + __I uint32_t AC12ERR; /**< Auto CMD12 Error Status Register, offset: 0x3C */ + __I uint32_t HTCAPBLT; /**< Host Controller Capabilities, offset: 0x40 */ + __IO uint32_t WML; /**< Watermark Level Register, offset: 0x44 */ + uint8_t RESERVED_0[8]; + __O uint32_t FEVT; /**< Force Event register, offset: 0x50 */ + __I uint32_t ADMAES; /**< ADMA Error Status register, offset: 0x54 */ + __IO uint32_t ADSADDR; /**< ADMA System Addressregister, offset: 0x58 */ + uint8_t RESERVED_1[100]; + __IO uint32_t VENDOR; /**< Vendor Specific register, offset: 0xC0 */ + __IO uint32_t MMCBOOT; /**< MMC Boot register, offset: 0xC4 */ + uint8_t RESERVED_2[52]; + __I uint32_t HOSTVER; /**< Host Controller Version, offset: 0xFC */ +} SDHC_Type; + +/* ---------------------------------------------------------------------------- + -- SDHC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SDHC_Register_Masks SDHC Register Masks + * @{ + */ + +/*! @name DSADDR - DMA System Address register */ +#define SDHC_DSADDR_DSADDR_MASK (0xFFFFFFFCU) +#define SDHC_DSADDR_DSADDR_SHIFT (2U) +#define SDHC_DSADDR_DSADDR(x) (((uint32_t)(((uint32_t)(x)) << SDHC_DSADDR_DSADDR_SHIFT)) & SDHC_DSADDR_DSADDR_MASK) + +/*! @name BLKATTR - Block Attributes register */ +#define SDHC_BLKATTR_BLKSIZE_MASK (0x1FFFU) +#define SDHC_BLKATTR_BLKSIZE_SHIFT (0U) +#define SDHC_BLKATTR_BLKSIZE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_BLKATTR_BLKSIZE_SHIFT)) & SDHC_BLKATTR_BLKSIZE_MASK) +#define SDHC_BLKATTR_BLKCNT_MASK (0xFFFF0000U) +#define SDHC_BLKATTR_BLKCNT_SHIFT (16U) +#define SDHC_BLKATTR_BLKCNT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_BLKATTR_BLKCNT_SHIFT)) & SDHC_BLKATTR_BLKCNT_MASK) + +/*! @name CMDARG - Command Argument register */ +#define SDHC_CMDARG_CMDARG_MASK (0xFFFFFFFFU) +#define SDHC_CMDARG_CMDARG_SHIFT (0U) +#define SDHC_CMDARG_CMDARG(x) (((uint32_t)(((uint32_t)(x)) << SDHC_CMDARG_CMDARG_SHIFT)) & SDHC_CMDARG_CMDARG_MASK) + +/*! @name XFERTYP - Transfer Type register */ +#define SDHC_XFERTYP_DMAEN_MASK (0x1U) +#define SDHC_XFERTYP_DMAEN_SHIFT (0U) +#define SDHC_XFERTYP_DMAEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_DMAEN_SHIFT)) & SDHC_XFERTYP_DMAEN_MASK) +#define SDHC_XFERTYP_BCEN_MASK (0x2U) +#define SDHC_XFERTYP_BCEN_SHIFT (1U) +#define SDHC_XFERTYP_BCEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_BCEN_SHIFT)) & SDHC_XFERTYP_BCEN_MASK) +#define SDHC_XFERTYP_AC12EN_MASK (0x4U) +#define SDHC_XFERTYP_AC12EN_SHIFT (2U) +#define SDHC_XFERTYP_AC12EN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_AC12EN_SHIFT)) & SDHC_XFERTYP_AC12EN_MASK) +#define SDHC_XFERTYP_DTDSEL_MASK (0x10U) +#define SDHC_XFERTYP_DTDSEL_SHIFT (4U) +#define SDHC_XFERTYP_DTDSEL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_DTDSEL_SHIFT)) & SDHC_XFERTYP_DTDSEL_MASK) +#define SDHC_XFERTYP_MSBSEL_MASK (0x20U) +#define SDHC_XFERTYP_MSBSEL_SHIFT (5U) +#define SDHC_XFERTYP_MSBSEL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_MSBSEL_SHIFT)) & SDHC_XFERTYP_MSBSEL_MASK) +#define SDHC_XFERTYP_RSPTYP_MASK (0x30000U) +#define SDHC_XFERTYP_RSPTYP_SHIFT (16U) +#define SDHC_XFERTYP_RSPTYP(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_RSPTYP_SHIFT)) & SDHC_XFERTYP_RSPTYP_MASK) +#define SDHC_XFERTYP_CCCEN_MASK (0x80000U) +#define SDHC_XFERTYP_CCCEN_SHIFT (19U) +#define SDHC_XFERTYP_CCCEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_CCCEN_SHIFT)) & SDHC_XFERTYP_CCCEN_MASK) +#define SDHC_XFERTYP_CICEN_MASK (0x100000U) +#define SDHC_XFERTYP_CICEN_SHIFT (20U) +#define SDHC_XFERTYP_CICEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_CICEN_SHIFT)) & SDHC_XFERTYP_CICEN_MASK) +#define SDHC_XFERTYP_DPSEL_MASK (0x200000U) +#define SDHC_XFERTYP_DPSEL_SHIFT (21U) +#define SDHC_XFERTYP_DPSEL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_DPSEL_SHIFT)) & SDHC_XFERTYP_DPSEL_MASK) +#define SDHC_XFERTYP_CMDTYP_MASK (0xC00000U) +#define SDHC_XFERTYP_CMDTYP_SHIFT (22U) +#define SDHC_XFERTYP_CMDTYP(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_CMDTYP_SHIFT)) & SDHC_XFERTYP_CMDTYP_MASK) +#define SDHC_XFERTYP_CMDINX_MASK (0x3F000000U) +#define SDHC_XFERTYP_CMDINX_SHIFT (24U) +#define SDHC_XFERTYP_CMDINX(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_CMDINX_SHIFT)) & SDHC_XFERTYP_CMDINX_MASK) + +/*! @name CMDRSP - Command Response 0..Command Response 3 */ +#define SDHC_CMDRSP_CMDRSP0_MASK (0xFFFFFFFFU) +#define SDHC_CMDRSP_CMDRSP0_SHIFT (0U) +#define SDHC_CMDRSP_CMDRSP0(x) (((uint32_t)(((uint32_t)(x)) << SDHC_CMDRSP_CMDRSP0_SHIFT)) & SDHC_CMDRSP_CMDRSP0_MASK) +#define SDHC_CMDRSP_CMDRSP1_MASK (0xFFFFFFFFU) +#define SDHC_CMDRSP_CMDRSP1_SHIFT (0U) +#define SDHC_CMDRSP_CMDRSP1(x) (((uint32_t)(((uint32_t)(x)) << SDHC_CMDRSP_CMDRSP1_SHIFT)) & SDHC_CMDRSP_CMDRSP1_MASK) +#define SDHC_CMDRSP_CMDRSP2_MASK (0xFFFFFFFFU) +#define SDHC_CMDRSP_CMDRSP2_SHIFT (0U) +#define SDHC_CMDRSP_CMDRSP2(x) (((uint32_t)(((uint32_t)(x)) << SDHC_CMDRSP_CMDRSP2_SHIFT)) & SDHC_CMDRSP_CMDRSP2_MASK) +#define SDHC_CMDRSP_CMDRSP3_MASK (0xFFFFFFFFU) +#define SDHC_CMDRSP_CMDRSP3_SHIFT (0U) +#define SDHC_CMDRSP_CMDRSP3(x) (((uint32_t)(((uint32_t)(x)) << SDHC_CMDRSP_CMDRSP3_SHIFT)) & SDHC_CMDRSP_CMDRSP3_MASK) + +/* The count of SDHC_CMDRSP */ +#define SDHC_CMDRSP_COUNT (4U) + +/*! @name DATPORT - Buffer Data Port register */ +#define SDHC_DATPORT_DATCONT_MASK (0xFFFFFFFFU) +#define SDHC_DATPORT_DATCONT_SHIFT (0U) +#define SDHC_DATPORT_DATCONT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_DATPORT_DATCONT_SHIFT)) & SDHC_DATPORT_DATCONT_MASK) + +/*! @name PRSSTAT - Present State register */ +#define SDHC_PRSSTAT_CIHB_MASK (0x1U) +#define SDHC_PRSSTAT_CIHB_SHIFT (0U) +#define SDHC_PRSSTAT_CIHB(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_CIHB_SHIFT)) & SDHC_PRSSTAT_CIHB_MASK) +#define SDHC_PRSSTAT_CDIHB_MASK (0x2U) +#define SDHC_PRSSTAT_CDIHB_SHIFT (1U) +#define SDHC_PRSSTAT_CDIHB(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_CDIHB_SHIFT)) & SDHC_PRSSTAT_CDIHB_MASK) +#define SDHC_PRSSTAT_DLA_MASK (0x4U) +#define SDHC_PRSSTAT_DLA_SHIFT (2U) +#define SDHC_PRSSTAT_DLA(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_DLA_SHIFT)) & SDHC_PRSSTAT_DLA_MASK) +#define SDHC_PRSSTAT_SDSTB_MASK (0x8U) +#define SDHC_PRSSTAT_SDSTB_SHIFT (3U) +#define SDHC_PRSSTAT_SDSTB(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_SDSTB_SHIFT)) & SDHC_PRSSTAT_SDSTB_MASK) +#define SDHC_PRSSTAT_IPGOFF_MASK (0x10U) +#define SDHC_PRSSTAT_IPGOFF_SHIFT (4U) +#define SDHC_PRSSTAT_IPGOFF(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_IPGOFF_SHIFT)) & SDHC_PRSSTAT_IPGOFF_MASK) +#define SDHC_PRSSTAT_HCKOFF_MASK (0x20U) +#define SDHC_PRSSTAT_HCKOFF_SHIFT (5U) +#define SDHC_PRSSTAT_HCKOFF(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_HCKOFF_SHIFT)) & SDHC_PRSSTAT_HCKOFF_MASK) +#define SDHC_PRSSTAT_PEROFF_MASK (0x40U) +#define SDHC_PRSSTAT_PEROFF_SHIFT (6U) +#define SDHC_PRSSTAT_PEROFF(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_PEROFF_SHIFT)) & SDHC_PRSSTAT_PEROFF_MASK) +#define SDHC_PRSSTAT_SDOFF_MASK (0x80U) +#define SDHC_PRSSTAT_SDOFF_SHIFT (7U) +#define SDHC_PRSSTAT_SDOFF(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_SDOFF_SHIFT)) & SDHC_PRSSTAT_SDOFF_MASK) +#define SDHC_PRSSTAT_WTA_MASK (0x100U) +#define SDHC_PRSSTAT_WTA_SHIFT (8U) +#define SDHC_PRSSTAT_WTA(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_WTA_SHIFT)) & SDHC_PRSSTAT_WTA_MASK) +#define SDHC_PRSSTAT_RTA_MASK (0x200U) +#define SDHC_PRSSTAT_RTA_SHIFT (9U) +#define SDHC_PRSSTAT_RTA(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_RTA_SHIFT)) & SDHC_PRSSTAT_RTA_MASK) +#define SDHC_PRSSTAT_BWEN_MASK (0x400U) +#define SDHC_PRSSTAT_BWEN_SHIFT (10U) +#define SDHC_PRSSTAT_BWEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_BWEN_SHIFT)) & SDHC_PRSSTAT_BWEN_MASK) +#define SDHC_PRSSTAT_BREN_MASK (0x800U) +#define SDHC_PRSSTAT_BREN_SHIFT (11U) +#define SDHC_PRSSTAT_BREN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_BREN_SHIFT)) & SDHC_PRSSTAT_BREN_MASK) +#define SDHC_PRSSTAT_CINS_MASK (0x10000U) +#define SDHC_PRSSTAT_CINS_SHIFT (16U) +#define SDHC_PRSSTAT_CINS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_CINS_SHIFT)) & SDHC_PRSSTAT_CINS_MASK) +#define SDHC_PRSSTAT_CLSL_MASK (0x800000U) +#define SDHC_PRSSTAT_CLSL_SHIFT (23U) +#define SDHC_PRSSTAT_CLSL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_CLSL_SHIFT)) & SDHC_PRSSTAT_CLSL_MASK) +#define SDHC_PRSSTAT_DLSL_MASK (0xFF000000U) +#define SDHC_PRSSTAT_DLSL_SHIFT (24U) +#define SDHC_PRSSTAT_DLSL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_DLSL_SHIFT)) & SDHC_PRSSTAT_DLSL_MASK) + +/*! @name PROCTL - Protocol Control register */ +#define SDHC_PROCTL_LCTL_MASK (0x1U) +#define SDHC_PROCTL_LCTL_SHIFT (0U) +#define SDHC_PROCTL_LCTL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_LCTL_SHIFT)) & SDHC_PROCTL_LCTL_MASK) +#define SDHC_PROCTL_DTW_MASK (0x6U) +#define SDHC_PROCTL_DTW_SHIFT (1U) +#define SDHC_PROCTL_DTW(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_DTW_SHIFT)) & SDHC_PROCTL_DTW_MASK) +#define SDHC_PROCTL_D3CD_MASK (0x8U) +#define SDHC_PROCTL_D3CD_SHIFT (3U) +#define SDHC_PROCTL_D3CD(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_D3CD_SHIFT)) & SDHC_PROCTL_D3CD_MASK) +#define SDHC_PROCTL_EMODE_MASK (0x30U) +#define SDHC_PROCTL_EMODE_SHIFT (4U) +#define SDHC_PROCTL_EMODE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_EMODE_SHIFT)) & SDHC_PROCTL_EMODE_MASK) +#define SDHC_PROCTL_CDTL_MASK (0x40U) +#define SDHC_PROCTL_CDTL_SHIFT (6U) +#define SDHC_PROCTL_CDTL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_CDTL_SHIFT)) & SDHC_PROCTL_CDTL_MASK) +#define SDHC_PROCTL_CDSS_MASK (0x80U) +#define SDHC_PROCTL_CDSS_SHIFT (7U) +#define SDHC_PROCTL_CDSS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_CDSS_SHIFT)) & SDHC_PROCTL_CDSS_MASK) +#define SDHC_PROCTL_DMAS_MASK (0x300U) +#define SDHC_PROCTL_DMAS_SHIFT (8U) +#define SDHC_PROCTL_DMAS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_DMAS_SHIFT)) & SDHC_PROCTL_DMAS_MASK) +#define SDHC_PROCTL_SABGREQ_MASK (0x10000U) +#define SDHC_PROCTL_SABGREQ_SHIFT (16U) +#define SDHC_PROCTL_SABGREQ(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_SABGREQ_SHIFT)) & SDHC_PROCTL_SABGREQ_MASK) +#define SDHC_PROCTL_CREQ_MASK (0x20000U) +#define SDHC_PROCTL_CREQ_SHIFT (17U) +#define SDHC_PROCTL_CREQ(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_CREQ_SHIFT)) & SDHC_PROCTL_CREQ_MASK) +#define SDHC_PROCTL_RWCTL_MASK (0x40000U) +#define SDHC_PROCTL_RWCTL_SHIFT (18U) +#define SDHC_PROCTL_RWCTL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_RWCTL_SHIFT)) & SDHC_PROCTL_RWCTL_MASK) +#define SDHC_PROCTL_IABG_MASK (0x80000U) +#define SDHC_PROCTL_IABG_SHIFT (19U) +#define SDHC_PROCTL_IABG(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_IABG_SHIFT)) & SDHC_PROCTL_IABG_MASK) +#define SDHC_PROCTL_WECINT_MASK (0x1000000U) +#define SDHC_PROCTL_WECINT_SHIFT (24U) +#define SDHC_PROCTL_WECINT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_WECINT_SHIFT)) & SDHC_PROCTL_WECINT_MASK) +#define SDHC_PROCTL_WECINS_MASK (0x2000000U) +#define SDHC_PROCTL_WECINS_SHIFT (25U) +#define SDHC_PROCTL_WECINS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_WECINS_SHIFT)) & SDHC_PROCTL_WECINS_MASK) +#define SDHC_PROCTL_WECRM_MASK (0x4000000U) +#define SDHC_PROCTL_WECRM_SHIFT (26U) +#define SDHC_PROCTL_WECRM(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_WECRM_SHIFT)) & SDHC_PROCTL_WECRM_MASK) + +/*! @name SYSCTL - System Control register */ +#define SDHC_SYSCTL_IPGEN_MASK (0x1U) +#define SDHC_SYSCTL_IPGEN_SHIFT (0U) +#define SDHC_SYSCTL_IPGEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_IPGEN_SHIFT)) & SDHC_SYSCTL_IPGEN_MASK) +#define SDHC_SYSCTL_HCKEN_MASK (0x2U) +#define SDHC_SYSCTL_HCKEN_SHIFT (1U) +#define SDHC_SYSCTL_HCKEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_HCKEN_SHIFT)) & SDHC_SYSCTL_HCKEN_MASK) +#define SDHC_SYSCTL_PEREN_MASK (0x4U) +#define SDHC_SYSCTL_PEREN_SHIFT (2U) +#define SDHC_SYSCTL_PEREN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_PEREN_SHIFT)) & SDHC_SYSCTL_PEREN_MASK) +#define SDHC_SYSCTL_SDCLKEN_MASK (0x8U) +#define SDHC_SYSCTL_SDCLKEN_SHIFT (3U) +#define SDHC_SYSCTL_SDCLKEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_SDCLKEN_SHIFT)) & SDHC_SYSCTL_SDCLKEN_MASK) +#define SDHC_SYSCTL_DVS_MASK (0xF0U) +#define SDHC_SYSCTL_DVS_SHIFT (4U) +#define SDHC_SYSCTL_DVS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_DVS_SHIFT)) & SDHC_SYSCTL_DVS_MASK) +#define SDHC_SYSCTL_SDCLKFS_MASK (0xFF00U) +#define SDHC_SYSCTL_SDCLKFS_SHIFT (8U) +#define SDHC_SYSCTL_SDCLKFS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_SDCLKFS_SHIFT)) & SDHC_SYSCTL_SDCLKFS_MASK) +#define SDHC_SYSCTL_DTOCV_MASK (0xF0000U) +#define SDHC_SYSCTL_DTOCV_SHIFT (16U) +#define SDHC_SYSCTL_DTOCV(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_DTOCV_SHIFT)) & SDHC_SYSCTL_DTOCV_MASK) +#define SDHC_SYSCTL_RSTA_MASK (0x1000000U) +#define SDHC_SYSCTL_RSTA_SHIFT (24U) +#define SDHC_SYSCTL_RSTA(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_RSTA_SHIFT)) & SDHC_SYSCTL_RSTA_MASK) +#define SDHC_SYSCTL_RSTC_MASK (0x2000000U) +#define SDHC_SYSCTL_RSTC_SHIFT (25U) +#define SDHC_SYSCTL_RSTC(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_RSTC_SHIFT)) & SDHC_SYSCTL_RSTC_MASK) +#define SDHC_SYSCTL_RSTD_MASK (0x4000000U) +#define SDHC_SYSCTL_RSTD_SHIFT (26U) +#define SDHC_SYSCTL_RSTD(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_RSTD_SHIFT)) & SDHC_SYSCTL_RSTD_MASK) +#define SDHC_SYSCTL_INITA_MASK (0x8000000U) +#define SDHC_SYSCTL_INITA_SHIFT (27U) +#define SDHC_SYSCTL_INITA(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_INITA_SHIFT)) & SDHC_SYSCTL_INITA_MASK) + +/*! @name IRQSTAT - Interrupt Status register */ +#define SDHC_IRQSTAT_CC_MASK (0x1U) +#define SDHC_IRQSTAT_CC_SHIFT (0U) +#define SDHC_IRQSTAT_CC(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CC_SHIFT)) & SDHC_IRQSTAT_CC_MASK) +#define SDHC_IRQSTAT_TC_MASK (0x2U) +#define SDHC_IRQSTAT_TC_SHIFT (1U) +#define SDHC_IRQSTAT_TC(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_TC_SHIFT)) & SDHC_IRQSTAT_TC_MASK) +#define SDHC_IRQSTAT_BGE_MASK (0x4U) +#define SDHC_IRQSTAT_BGE_SHIFT (2U) +#define SDHC_IRQSTAT_BGE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_BGE_SHIFT)) & SDHC_IRQSTAT_BGE_MASK) +#define SDHC_IRQSTAT_DINT_MASK (0x8U) +#define SDHC_IRQSTAT_DINT_SHIFT (3U) +#define SDHC_IRQSTAT_DINT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_DINT_SHIFT)) & SDHC_IRQSTAT_DINT_MASK) +#define SDHC_IRQSTAT_BWR_MASK (0x10U) +#define SDHC_IRQSTAT_BWR_SHIFT (4U) +#define SDHC_IRQSTAT_BWR(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_BWR_SHIFT)) & SDHC_IRQSTAT_BWR_MASK) +#define SDHC_IRQSTAT_BRR_MASK (0x20U) +#define SDHC_IRQSTAT_BRR_SHIFT (5U) +#define SDHC_IRQSTAT_BRR(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_BRR_SHIFT)) & SDHC_IRQSTAT_BRR_MASK) +#define SDHC_IRQSTAT_CINS_MASK (0x40U) +#define SDHC_IRQSTAT_CINS_SHIFT (6U) +#define SDHC_IRQSTAT_CINS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CINS_SHIFT)) & SDHC_IRQSTAT_CINS_MASK) +#define SDHC_IRQSTAT_CRM_MASK (0x80U) +#define SDHC_IRQSTAT_CRM_SHIFT (7U) +#define SDHC_IRQSTAT_CRM(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CRM_SHIFT)) & SDHC_IRQSTAT_CRM_MASK) +#define SDHC_IRQSTAT_CINT_MASK (0x100U) +#define SDHC_IRQSTAT_CINT_SHIFT (8U) +#define SDHC_IRQSTAT_CINT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CINT_SHIFT)) & SDHC_IRQSTAT_CINT_MASK) +#define SDHC_IRQSTAT_CTOE_MASK (0x10000U) +#define SDHC_IRQSTAT_CTOE_SHIFT (16U) +#define SDHC_IRQSTAT_CTOE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CTOE_SHIFT)) & SDHC_IRQSTAT_CTOE_MASK) +#define SDHC_IRQSTAT_CCE_MASK (0x20000U) +#define SDHC_IRQSTAT_CCE_SHIFT (17U) +#define SDHC_IRQSTAT_CCE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CCE_SHIFT)) & SDHC_IRQSTAT_CCE_MASK) +#define SDHC_IRQSTAT_CEBE_MASK (0x40000U) +#define SDHC_IRQSTAT_CEBE_SHIFT (18U) +#define SDHC_IRQSTAT_CEBE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CEBE_SHIFT)) & SDHC_IRQSTAT_CEBE_MASK) +#define SDHC_IRQSTAT_CIE_MASK (0x80000U) +#define SDHC_IRQSTAT_CIE_SHIFT (19U) +#define SDHC_IRQSTAT_CIE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CIE_SHIFT)) & SDHC_IRQSTAT_CIE_MASK) +#define SDHC_IRQSTAT_DTOE_MASK (0x100000U) +#define SDHC_IRQSTAT_DTOE_SHIFT (20U) +#define SDHC_IRQSTAT_DTOE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_DTOE_SHIFT)) & SDHC_IRQSTAT_DTOE_MASK) +#define SDHC_IRQSTAT_DCE_MASK (0x200000U) +#define SDHC_IRQSTAT_DCE_SHIFT (21U) +#define SDHC_IRQSTAT_DCE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_DCE_SHIFT)) & SDHC_IRQSTAT_DCE_MASK) +#define SDHC_IRQSTAT_DEBE_MASK (0x400000U) +#define SDHC_IRQSTAT_DEBE_SHIFT (22U) +#define SDHC_IRQSTAT_DEBE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_DEBE_SHIFT)) & SDHC_IRQSTAT_DEBE_MASK) +#define SDHC_IRQSTAT_AC12E_MASK (0x1000000U) +#define SDHC_IRQSTAT_AC12E_SHIFT (24U) +#define SDHC_IRQSTAT_AC12E(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_AC12E_SHIFT)) & SDHC_IRQSTAT_AC12E_MASK) +#define SDHC_IRQSTAT_DMAE_MASK (0x10000000U) +#define SDHC_IRQSTAT_DMAE_SHIFT (28U) +#define SDHC_IRQSTAT_DMAE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_DMAE_SHIFT)) & SDHC_IRQSTAT_DMAE_MASK) + +/*! @name IRQSTATEN - Interrupt Status Enable register */ +#define SDHC_IRQSTATEN_CCSEN_MASK (0x1U) +#define SDHC_IRQSTATEN_CCSEN_SHIFT (0U) +#define SDHC_IRQSTATEN_CCSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CCSEN_SHIFT)) & SDHC_IRQSTATEN_CCSEN_MASK) +#define SDHC_IRQSTATEN_TCSEN_MASK (0x2U) +#define SDHC_IRQSTATEN_TCSEN_SHIFT (1U) +#define SDHC_IRQSTATEN_TCSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_TCSEN_SHIFT)) & SDHC_IRQSTATEN_TCSEN_MASK) +#define SDHC_IRQSTATEN_BGESEN_MASK (0x4U) +#define SDHC_IRQSTATEN_BGESEN_SHIFT (2U) +#define SDHC_IRQSTATEN_BGESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_BGESEN_SHIFT)) & SDHC_IRQSTATEN_BGESEN_MASK) +#define SDHC_IRQSTATEN_DINTSEN_MASK (0x8U) +#define SDHC_IRQSTATEN_DINTSEN_SHIFT (3U) +#define SDHC_IRQSTATEN_DINTSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_DINTSEN_SHIFT)) & SDHC_IRQSTATEN_DINTSEN_MASK) +#define SDHC_IRQSTATEN_BWRSEN_MASK (0x10U) +#define SDHC_IRQSTATEN_BWRSEN_SHIFT (4U) +#define SDHC_IRQSTATEN_BWRSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_BWRSEN_SHIFT)) & SDHC_IRQSTATEN_BWRSEN_MASK) +#define SDHC_IRQSTATEN_BRRSEN_MASK (0x20U) +#define SDHC_IRQSTATEN_BRRSEN_SHIFT (5U) +#define SDHC_IRQSTATEN_BRRSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_BRRSEN_SHIFT)) & SDHC_IRQSTATEN_BRRSEN_MASK) +#define SDHC_IRQSTATEN_CINSEN_MASK (0x40U) +#define SDHC_IRQSTATEN_CINSEN_SHIFT (6U) +#define SDHC_IRQSTATEN_CINSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CINSEN_SHIFT)) & SDHC_IRQSTATEN_CINSEN_MASK) +#define SDHC_IRQSTATEN_CRMSEN_MASK (0x80U) +#define SDHC_IRQSTATEN_CRMSEN_SHIFT (7U) +#define SDHC_IRQSTATEN_CRMSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CRMSEN_SHIFT)) & SDHC_IRQSTATEN_CRMSEN_MASK) +#define SDHC_IRQSTATEN_CINTSEN_MASK (0x100U) +#define SDHC_IRQSTATEN_CINTSEN_SHIFT (8U) +#define SDHC_IRQSTATEN_CINTSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CINTSEN_SHIFT)) & SDHC_IRQSTATEN_CINTSEN_MASK) +#define SDHC_IRQSTATEN_CTOESEN_MASK (0x10000U) +#define SDHC_IRQSTATEN_CTOESEN_SHIFT (16U) +#define SDHC_IRQSTATEN_CTOESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CTOESEN_SHIFT)) & SDHC_IRQSTATEN_CTOESEN_MASK) +#define SDHC_IRQSTATEN_CCESEN_MASK (0x20000U) +#define SDHC_IRQSTATEN_CCESEN_SHIFT (17U) +#define SDHC_IRQSTATEN_CCESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CCESEN_SHIFT)) & SDHC_IRQSTATEN_CCESEN_MASK) +#define SDHC_IRQSTATEN_CEBESEN_MASK (0x40000U) +#define SDHC_IRQSTATEN_CEBESEN_SHIFT (18U) +#define SDHC_IRQSTATEN_CEBESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CEBESEN_SHIFT)) & SDHC_IRQSTATEN_CEBESEN_MASK) +#define SDHC_IRQSTATEN_CIESEN_MASK (0x80000U) +#define SDHC_IRQSTATEN_CIESEN_SHIFT (19U) +#define SDHC_IRQSTATEN_CIESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CIESEN_SHIFT)) & SDHC_IRQSTATEN_CIESEN_MASK) +#define SDHC_IRQSTATEN_DTOESEN_MASK (0x100000U) +#define SDHC_IRQSTATEN_DTOESEN_SHIFT (20U) +#define SDHC_IRQSTATEN_DTOESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_DTOESEN_SHIFT)) & SDHC_IRQSTATEN_DTOESEN_MASK) +#define SDHC_IRQSTATEN_DCESEN_MASK (0x200000U) +#define SDHC_IRQSTATEN_DCESEN_SHIFT (21U) +#define SDHC_IRQSTATEN_DCESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_DCESEN_SHIFT)) & SDHC_IRQSTATEN_DCESEN_MASK) +#define SDHC_IRQSTATEN_DEBESEN_MASK (0x400000U) +#define SDHC_IRQSTATEN_DEBESEN_SHIFT (22U) +#define SDHC_IRQSTATEN_DEBESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_DEBESEN_SHIFT)) & SDHC_IRQSTATEN_DEBESEN_MASK) +#define SDHC_IRQSTATEN_AC12ESEN_MASK (0x1000000U) +#define SDHC_IRQSTATEN_AC12ESEN_SHIFT (24U) +#define SDHC_IRQSTATEN_AC12ESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_AC12ESEN_SHIFT)) & SDHC_IRQSTATEN_AC12ESEN_MASK) +#define SDHC_IRQSTATEN_DMAESEN_MASK (0x10000000U) +#define SDHC_IRQSTATEN_DMAESEN_SHIFT (28U) +#define SDHC_IRQSTATEN_DMAESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_DMAESEN_SHIFT)) & SDHC_IRQSTATEN_DMAESEN_MASK) + +/*! @name IRQSIGEN - Interrupt Signal Enable register */ +#define SDHC_IRQSIGEN_CCIEN_MASK (0x1U) +#define SDHC_IRQSIGEN_CCIEN_SHIFT (0U) +#define SDHC_IRQSIGEN_CCIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CCIEN_SHIFT)) & SDHC_IRQSIGEN_CCIEN_MASK) +#define SDHC_IRQSIGEN_TCIEN_MASK (0x2U) +#define SDHC_IRQSIGEN_TCIEN_SHIFT (1U) +#define SDHC_IRQSIGEN_TCIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_TCIEN_SHIFT)) & SDHC_IRQSIGEN_TCIEN_MASK) +#define SDHC_IRQSIGEN_BGEIEN_MASK (0x4U) +#define SDHC_IRQSIGEN_BGEIEN_SHIFT (2U) +#define SDHC_IRQSIGEN_BGEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_BGEIEN_SHIFT)) & SDHC_IRQSIGEN_BGEIEN_MASK) +#define SDHC_IRQSIGEN_DINTIEN_MASK (0x8U) +#define SDHC_IRQSIGEN_DINTIEN_SHIFT (3U) +#define SDHC_IRQSIGEN_DINTIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_DINTIEN_SHIFT)) & SDHC_IRQSIGEN_DINTIEN_MASK) +#define SDHC_IRQSIGEN_BWRIEN_MASK (0x10U) +#define SDHC_IRQSIGEN_BWRIEN_SHIFT (4U) +#define SDHC_IRQSIGEN_BWRIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_BWRIEN_SHIFT)) & SDHC_IRQSIGEN_BWRIEN_MASK) +#define SDHC_IRQSIGEN_BRRIEN_MASK (0x20U) +#define SDHC_IRQSIGEN_BRRIEN_SHIFT (5U) +#define SDHC_IRQSIGEN_BRRIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_BRRIEN_SHIFT)) & SDHC_IRQSIGEN_BRRIEN_MASK) +#define SDHC_IRQSIGEN_CINSIEN_MASK (0x40U) +#define SDHC_IRQSIGEN_CINSIEN_SHIFT (6U) +#define SDHC_IRQSIGEN_CINSIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CINSIEN_SHIFT)) & SDHC_IRQSIGEN_CINSIEN_MASK) +#define SDHC_IRQSIGEN_CRMIEN_MASK (0x80U) +#define SDHC_IRQSIGEN_CRMIEN_SHIFT (7U) +#define SDHC_IRQSIGEN_CRMIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CRMIEN_SHIFT)) & SDHC_IRQSIGEN_CRMIEN_MASK) +#define SDHC_IRQSIGEN_CINTIEN_MASK (0x100U) +#define SDHC_IRQSIGEN_CINTIEN_SHIFT (8U) +#define SDHC_IRQSIGEN_CINTIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CINTIEN_SHIFT)) & SDHC_IRQSIGEN_CINTIEN_MASK) +#define SDHC_IRQSIGEN_CTOEIEN_MASK (0x10000U) +#define SDHC_IRQSIGEN_CTOEIEN_SHIFT (16U) +#define SDHC_IRQSIGEN_CTOEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CTOEIEN_SHIFT)) & SDHC_IRQSIGEN_CTOEIEN_MASK) +#define SDHC_IRQSIGEN_CCEIEN_MASK (0x20000U) +#define SDHC_IRQSIGEN_CCEIEN_SHIFT (17U) +#define SDHC_IRQSIGEN_CCEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CCEIEN_SHIFT)) & SDHC_IRQSIGEN_CCEIEN_MASK) +#define SDHC_IRQSIGEN_CEBEIEN_MASK (0x40000U) +#define SDHC_IRQSIGEN_CEBEIEN_SHIFT (18U) +#define SDHC_IRQSIGEN_CEBEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CEBEIEN_SHIFT)) & SDHC_IRQSIGEN_CEBEIEN_MASK) +#define SDHC_IRQSIGEN_CIEIEN_MASK (0x80000U) +#define SDHC_IRQSIGEN_CIEIEN_SHIFT (19U) +#define SDHC_IRQSIGEN_CIEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CIEIEN_SHIFT)) & SDHC_IRQSIGEN_CIEIEN_MASK) +#define SDHC_IRQSIGEN_DTOEIEN_MASK (0x100000U) +#define SDHC_IRQSIGEN_DTOEIEN_SHIFT (20U) +#define SDHC_IRQSIGEN_DTOEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_DTOEIEN_SHIFT)) & SDHC_IRQSIGEN_DTOEIEN_MASK) +#define SDHC_IRQSIGEN_DCEIEN_MASK (0x200000U) +#define SDHC_IRQSIGEN_DCEIEN_SHIFT (21U) +#define SDHC_IRQSIGEN_DCEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_DCEIEN_SHIFT)) & SDHC_IRQSIGEN_DCEIEN_MASK) +#define SDHC_IRQSIGEN_DEBEIEN_MASK (0x400000U) +#define SDHC_IRQSIGEN_DEBEIEN_SHIFT (22U) +#define SDHC_IRQSIGEN_DEBEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_DEBEIEN_SHIFT)) & SDHC_IRQSIGEN_DEBEIEN_MASK) +#define SDHC_IRQSIGEN_AC12EIEN_MASK (0x1000000U) +#define SDHC_IRQSIGEN_AC12EIEN_SHIFT (24U) +#define SDHC_IRQSIGEN_AC12EIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_AC12EIEN_SHIFT)) & SDHC_IRQSIGEN_AC12EIEN_MASK) +#define SDHC_IRQSIGEN_DMAEIEN_MASK (0x10000000U) +#define SDHC_IRQSIGEN_DMAEIEN_SHIFT (28U) +#define SDHC_IRQSIGEN_DMAEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_DMAEIEN_SHIFT)) & SDHC_IRQSIGEN_DMAEIEN_MASK) + +/*! @name AC12ERR - Auto CMD12 Error Status Register */ +#define SDHC_AC12ERR_AC12NE_MASK (0x1U) +#define SDHC_AC12ERR_AC12NE_SHIFT (0U) +#define SDHC_AC12ERR_AC12NE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_AC12ERR_AC12NE_SHIFT)) & SDHC_AC12ERR_AC12NE_MASK) +#define SDHC_AC12ERR_AC12TOE_MASK (0x2U) +#define SDHC_AC12ERR_AC12TOE_SHIFT (1U) +#define SDHC_AC12ERR_AC12TOE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_AC12ERR_AC12TOE_SHIFT)) & SDHC_AC12ERR_AC12TOE_MASK) +#define SDHC_AC12ERR_AC12EBE_MASK (0x4U) +#define SDHC_AC12ERR_AC12EBE_SHIFT (2U) +#define SDHC_AC12ERR_AC12EBE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_AC12ERR_AC12EBE_SHIFT)) & SDHC_AC12ERR_AC12EBE_MASK) +#define SDHC_AC12ERR_AC12CE_MASK (0x8U) +#define SDHC_AC12ERR_AC12CE_SHIFT (3U) +#define SDHC_AC12ERR_AC12CE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_AC12ERR_AC12CE_SHIFT)) & SDHC_AC12ERR_AC12CE_MASK) +#define SDHC_AC12ERR_AC12IE_MASK (0x10U) +#define SDHC_AC12ERR_AC12IE_SHIFT (4U) +#define SDHC_AC12ERR_AC12IE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_AC12ERR_AC12IE_SHIFT)) & SDHC_AC12ERR_AC12IE_MASK) +#define SDHC_AC12ERR_CNIBAC12E_MASK (0x80U) +#define SDHC_AC12ERR_CNIBAC12E_SHIFT (7U) +#define SDHC_AC12ERR_CNIBAC12E(x) (((uint32_t)(((uint32_t)(x)) << SDHC_AC12ERR_CNIBAC12E_SHIFT)) & SDHC_AC12ERR_CNIBAC12E_MASK) + +/*! @name HTCAPBLT - Host Controller Capabilities */ +#define SDHC_HTCAPBLT_MBL_MASK (0x70000U) +#define SDHC_HTCAPBLT_MBL_SHIFT (16U) +#define SDHC_HTCAPBLT_MBL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HTCAPBLT_MBL_SHIFT)) & SDHC_HTCAPBLT_MBL_MASK) +#define SDHC_HTCAPBLT_ADMAS_MASK (0x100000U) +#define SDHC_HTCAPBLT_ADMAS_SHIFT (20U) +#define SDHC_HTCAPBLT_ADMAS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HTCAPBLT_ADMAS_SHIFT)) & SDHC_HTCAPBLT_ADMAS_MASK) +#define SDHC_HTCAPBLT_HSS_MASK (0x200000U) +#define SDHC_HTCAPBLT_HSS_SHIFT (21U) +#define SDHC_HTCAPBLT_HSS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HTCAPBLT_HSS_SHIFT)) & SDHC_HTCAPBLT_HSS_MASK) +#define SDHC_HTCAPBLT_DMAS_MASK (0x400000U) +#define SDHC_HTCAPBLT_DMAS_SHIFT (22U) +#define SDHC_HTCAPBLT_DMAS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HTCAPBLT_DMAS_SHIFT)) & SDHC_HTCAPBLT_DMAS_MASK) +#define SDHC_HTCAPBLT_SRS_MASK (0x800000U) +#define SDHC_HTCAPBLT_SRS_SHIFT (23U) +#define SDHC_HTCAPBLT_SRS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HTCAPBLT_SRS_SHIFT)) & SDHC_HTCAPBLT_SRS_MASK) +#define SDHC_HTCAPBLT_VS33_MASK (0x1000000U) +#define SDHC_HTCAPBLT_VS33_SHIFT (24U) +#define SDHC_HTCAPBLT_VS33(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HTCAPBLT_VS33_SHIFT)) & SDHC_HTCAPBLT_VS33_MASK) + +/*! @name WML - Watermark Level Register */ +#define SDHC_WML_RDWML_MASK (0xFFU) +#define SDHC_WML_RDWML_SHIFT (0U) +#define SDHC_WML_RDWML(x) (((uint32_t)(((uint32_t)(x)) << SDHC_WML_RDWML_SHIFT)) & SDHC_WML_RDWML_MASK) +#define SDHC_WML_WRWML_MASK (0xFF0000U) +#define SDHC_WML_WRWML_SHIFT (16U) +#define SDHC_WML_WRWML(x) (((uint32_t)(((uint32_t)(x)) << SDHC_WML_WRWML_SHIFT)) & SDHC_WML_WRWML_MASK) + +/*! @name FEVT - Force Event register */ +#define SDHC_FEVT_AC12NE_MASK (0x1U) +#define SDHC_FEVT_AC12NE_SHIFT (0U) +#define SDHC_FEVT_AC12NE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_AC12NE_SHIFT)) & SDHC_FEVT_AC12NE_MASK) +#define SDHC_FEVT_AC12TOE_MASK (0x2U) +#define SDHC_FEVT_AC12TOE_SHIFT (1U) +#define SDHC_FEVT_AC12TOE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_AC12TOE_SHIFT)) & SDHC_FEVT_AC12TOE_MASK) +#define SDHC_FEVT_AC12CE_MASK (0x4U) +#define SDHC_FEVT_AC12CE_SHIFT (2U) +#define SDHC_FEVT_AC12CE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_AC12CE_SHIFT)) & SDHC_FEVT_AC12CE_MASK) +#define SDHC_FEVT_AC12EBE_MASK (0x8U) +#define SDHC_FEVT_AC12EBE_SHIFT (3U) +#define SDHC_FEVT_AC12EBE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_AC12EBE_SHIFT)) & SDHC_FEVT_AC12EBE_MASK) +#define SDHC_FEVT_AC12IE_MASK (0x10U) +#define SDHC_FEVT_AC12IE_SHIFT (4U) +#define SDHC_FEVT_AC12IE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_AC12IE_SHIFT)) & SDHC_FEVT_AC12IE_MASK) +#define SDHC_FEVT_CNIBAC12E_MASK (0x80U) +#define SDHC_FEVT_CNIBAC12E_SHIFT (7U) +#define SDHC_FEVT_CNIBAC12E(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_CNIBAC12E_SHIFT)) & SDHC_FEVT_CNIBAC12E_MASK) +#define SDHC_FEVT_CTOE_MASK (0x10000U) +#define SDHC_FEVT_CTOE_SHIFT (16U) +#define SDHC_FEVT_CTOE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_CTOE_SHIFT)) & SDHC_FEVT_CTOE_MASK) +#define SDHC_FEVT_CCE_MASK (0x20000U) +#define SDHC_FEVT_CCE_SHIFT (17U) +#define SDHC_FEVT_CCE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_CCE_SHIFT)) & SDHC_FEVT_CCE_MASK) +#define SDHC_FEVT_CEBE_MASK (0x40000U) +#define SDHC_FEVT_CEBE_SHIFT (18U) +#define SDHC_FEVT_CEBE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_CEBE_SHIFT)) & SDHC_FEVT_CEBE_MASK) +#define SDHC_FEVT_CIE_MASK (0x80000U) +#define SDHC_FEVT_CIE_SHIFT (19U) +#define SDHC_FEVT_CIE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_CIE_SHIFT)) & SDHC_FEVT_CIE_MASK) +#define SDHC_FEVT_DTOE_MASK (0x100000U) +#define SDHC_FEVT_DTOE_SHIFT (20U) +#define SDHC_FEVT_DTOE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_DTOE_SHIFT)) & SDHC_FEVT_DTOE_MASK) +#define SDHC_FEVT_DCE_MASK (0x200000U) +#define SDHC_FEVT_DCE_SHIFT (21U) +#define SDHC_FEVT_DCE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_DCE_SHIFT)) & SDHC_FEVT_DCE_MASK) +#define SDHC_FEVT_DEBE_MASK (0x400000U) +#define SDHC_FEVT_DEBE_SHIFT (22U) +#define SDHC_FEVT_DEBE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_DEBE_SHIFT)) & SDHC_FEVT_DEBE_MASK) +#define SDHC_FEVT_AC12E_MASK (0x1000000U) +#define SDHC_FEVT_AC12E_SHIFT (24U) +#define SDHC_FEVT_AC12E(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_AC12E_SHIFT)) & SDHC_FEVT_AC12E_MASK) +#define SDHC_FEVT_DMAE_MASK (0x10000000U) +#define SDHC_FEVT_DMAE_SHIFT (28U) +#define SDHC_FEVT_DMAE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_DMAE_SHIFT)) & SDHC_FEVT_DMAE_MASK) +#define SDHC_FEVT_CINT_MASK (0x80000000U) +#define SDHC_FEVT_CINT_SHIFT (31U) +#define SDHC_FEVT_CINT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_CINT_SHIFT)) & SDHC_FEVT_CINT_MASK) + +/*! @name ADMAES - ADMA Error Status register */ +#define SDHC_ADMAES_ADMAES_MASK (0x3U) +#define SDHC_ADMAES_ADMAES_SHIFT (0U) +#define SDHC_ADMAES_ADMAES(x) (((uint32_t)(((uint32_t)(x)) << SDHC_ADMAES_ADMAES_SHIFT)) & SDHC_ADMAES_ADMAES_MASK) +#define SDHC_ADMAES_ADMALME_MASK (0x4U) +#define SDHC_ADMAES_ADMALME_SHIFT (2U) +#define SDHC_ADMAES_ADMALME(x) (((uint32_t)(((uint32_t)(x)) << SDHC_ADMAES_ADMALME_SHIFT)) & SDHC_ADMAES_ADMALME_MASK) +#define SDHC_ADMAES_ADMADCE_MASK (0x8U) +#define SDHC_ADMAES_ADMADCE_SHIFT (3U) +#define SDHC_ADMAES_ADMADCE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_ADMAES_ADMADCE_SHIFT)) & SDHC_ADMAES_ADMADCE_MASK) + +/*! @name ADSADDR - ADMA System Addressregister */ +#define SDHC_ADSADDR_ADSADDR_MASK (0xFFFFFFFCU) +#define SDHC_ADSADDR_ADSADDR_SHIFT (2U) +#define SDHC_ADSADDR_ADSADDR(x) (((uint32_t)(((uint32_t)(x)) << SDHC_ADSADDR_ADSADDR_SHIFT)) & SDHC_ADSADDR_ADSADDR_MASK) + +/*! @name VENDOR - Vendor Specific register */ +#define SDHC_VENDOR_EXBLKNU_MASK (0x2U) +#define SDHC_VENDOR_EXBLKNU_SHIFT (1U) +#define SDHC_VENDOR_EXBLKNU(x) (((uint32_t)(((uint32_t)(x)) << SDHC_VENDOR_EXBLKNU_SHIFT)) & SDHC_VENDOR_EXBLKNU_MASK) +#define SDHC_VENDOR_INTSTVAL_MASK (0xFF0000U) +#define SDHC_VENDOR_INTSTVAL_SHIFT (16U) +#define SDHC_VENDOR_INTSTVAL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_VENDOR_INTSTVAL_SHIFT)) & SDHC_VENDOR_INTSTVAL_MASK) + +/*! @name MMCBOOT - MMC Boot register */ +#define SDHC_MMCBOOT_DTOCVACK_MASK (0xFU) +#define SDHC_MMCBOOT_DTOCVACK_SHIFT (0U) +#define SDHC_MMCBOOT_DTOCVACK(x) (((uint32_t)(((uint32_t)(x)) << SDHC_MMCBOOT_DTOCVACK_SHIFT)) & SDHC_MMCBOOT_DTOCVACK_MASK) +#define SDHC_MMCBOOT_BOOTACK_MASK (0x10U) +#define SDHC_MMCBOOT_BOOTACK_SHIFT (4U) +#define SDHC_MMCBOOT_BOOTACK(x) (((uint32_t)(((uint32_t)(x)) << SDHC_MMCBOOT_BOOTACK_SHIFT)) & SDHC_MMCBOOT_BOOTACK_MASK) +#define SDHC_MMCBOOT_BOOTMODE_MASK (0x20U) +#define SDHC_MMCBOOT_BOOTMODE_SHIFT (5U) +#define SDHC_MMCBOOT_BOOTMODE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_MMCBOOT_BOOTMODE_SHIFT)) & SDHC_MMCBOOT_BOOTMODE_MASK) +#define SDHC_MMCBOOT_BOOTEN_MASK (0x40U) +#define SDHC_MMCBOOT_BOOTEN_SHIFT (6U) +#define SDHC_MMCBOOT_BOOTEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_MMCBOOT_BOOTEN_SHIFT)) & SDHC_MMCBOOT_BOOTEN_MASK) +#define SDHC_MMCBOOT_AUTOSABGEN_MASK (0x80U) +#define SDHC_MMCBOOT_AUTOSABGEN_SHIFT (7U) +#define SDHC_MMCBOOT_AUTOSABGEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_MMCBOOT_AUTOSABGEN_SHIFT)) & SDHC_MMCBOOT_AUTOSABGEN_MASK) +#define SDHC_MMCBOOT_BOOTBLKCNT_MASK (0xFFFF0000U) +#define SDHC_MMCBOOT_BOOTBLKCNT_SHIFT (16U) +#define SDHC_MMCBOOT_BOOTBLKCNT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_MMCBOOT_BOOTBLKCNT_SHIFT)) & SDHC_MMCBOOT_BOOTBLKCNT_MASK) + +/*! @name HOSTVER - Host Controller Version */ +#define SDHC_HOSTVER_SVN_MASK (0xFFU) +#define SDHC_HOSTVER_SVN_SHIFT (0U) +#define SDHC_HOSTVER_SVN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HOSTVER_SVN_SHIFT)) & SDHC_HOSTVER_SVN_MASK) +#define SDHC_HOSTVER_VVN_MASK (0xFF00U) +#define SDHC_HOSTVER_VVN_SHIFT (8U) +#define SDHC_HOSTVER_VVN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HOSTVER_VVN_SHIFT)) & SDHC_HOSTVER_VVN_MASK) + + +/*! + * @} + */ /* end of group SDHC_Register_Masks */ + + +/* SDHC - Peripheral instance base addresses */ +/** Peripheral SDHC base address */ +#define SDHC_BASE (0x400B1000u) +/** Peripheral SDHC base pointer */ +#define SDHC ((SDHC_Type *)SDHC_BASE) +/** Array initializer of SDHC peripheral base addresses */ +#define SDHC_BASE_ADDRS { SDHC_BASE } +/** Array initializer of SDHC peripheral base pointers */ +#define SDHC_BASE_PTRS { SDHC } +/** Interrupt vectors for the SDHC peripheral type */ +#define SDHC_IRQS { SDHC_IRQn } + +/*! + * @} + */ /* end of group SDHC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SDRAM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SDRAM_Peripheral_Access_Layer SDRAM Peripheral Access Layer + * @{ + */ + +/** SDRAM - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[66]; + __IO uint16_t CTRL; /**< Control Register, offset: 0x42 */ + uint8_t RESERVED_1[4]; + struct { /* offset: 0x48, array step: 0x8 */ + __IO uint32_t AC; /**< Address and Control Register, array offset: 0x48, array step: 0x8 */ + __IO uint32_t CM; /**< Control Mask, array offset: 0x4C, array step: 0x8 */ + } BLOCK[2]; +} SDRAM_Type; + +/* ---------------------------------------------------------------------------- + -- SDRAM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SDRAM_Register_Masks SDRAM Register Masks + * @{ + */ + +/*! @name CTRL - Control Register */ +#define SDRAM_CTRL_RC_MASK (0x1FFU) +#define SDRAM_CTRL_RC_SHIFT (0U) +#define SDRAM_CTRL_RC(x) (((uint16_t)(((uint16_t)(x)) << SDRAM_CTRL_RC_SHIFT)) & SDRAM_CTRL_RC_MASK) +#define SDRAM_CTRL_RTIM_MASK (0x600U) +#define SDRAM_CTRL_RTIM_SHIFT (9U) +#define SDRAM_CTRL_RTIM(x) (((uint16_t)(((uint16_t)(x)) << SDRAM_CTRL_RTIM_SHIFT)) & SDRAM_CTRL_RTIM_MASK) +#define SDRAM_CTRL_IS_MASK (0x800U) +#define SDRAM_CTRL_IS_SHIFT (11U) +#define SDRAM_CTRL_IS(x) (((uint16_t)(((uint16_t)(x)) << SDRAM_CTRL_IS_SHIFT)) & SDRAM_CTRL_IS_MASK) + +/*! @name AC - Address and Control Register */ +#define SDRAM_AC_IP_MASK (0x8U) +#define SDRAM_AC_IP_SHIFT (3U) +#define SDRAM_AC_IP(x) (((uint32_t)(((uint32_t)(x)) << SDRAM_AC_IP_SHIFT)) & SDRAM_AC_IP_MASK) +#define SDRAM_AC_PS_MASK (0x30U) +#define SDRAM_AC_PS_SHIFT (4U) +#define SDRAM_AC_PS(x) (((uint32_t)(((uint32_t)(x)) << SDRAM_AC_PS_SHIFT)) & SDRAM_AC_PS_MASK) +#define SDRAM_AC_IMRS_MASK (0x40U) +#define SDRAM_AC_IMRS_SHIFT (6U) +#define SDRAM_AC_IMRS(x) (((uint32_t)(((uint32_t)(x)) << SDRAM_AC_IMRS_SHIFT)) & SDRAM_AC_IMRS_MASK) +#define SDRAM_AC_CBM_MASK (0x700U) +#define SDRAM_AC_CBM_SHIFT (8U) +#define SDRAM_AC_CBM(x) (((uint32_t)(((uint32_t)(x)) << SDRAM_AC_CBM_SHIFT)) & SDRAM_AC_CBM_MASK) +#define SDRAM_AC_CASL_MASK (0x3000U) +#define SDRAM_AC_CASL_SHIFT (12U) +#define SDRAM_AC_CASL(x) (((uint32_t)(((uint32_t)(x)) << SDRAM_AC_CASL_SHIFT)) & SDRAM_AC_CASL_MASK) +#define SDRAM_AC_RE_MASK (0x8000U) +#define SDRAM_AC_RE_SHIFT (15U) +#define SDRAM_AC_RE(x) (((uint32_t)(((uint32_t)(x)) << SDRAM_AC_RE_SHIFT)) & SDRAM_AC_RE_MASK) +#define SDRAM_AC_BA_MASK (0xFFFC0000U) +#define SDRAM_AC_BA_SHIFT (18U) +#define SDRAM_AC_BA(x) (((uint32_t)(((uint32_t)(x)) << SDRAM_AC_BA_SHIFT)) & SDRAM_AC_BA_MASK) + +/* The count of SDRAM_AC */ +#define SDRAM_AC_COUNT (2U) + +/*! @name CM - Control Mask */ +#define SDRAM_CM_V_MASK (0x1U) +#define SDRAM_CM_V_SHIFT (0U) +#define SDRAM_CM_V(x) (((uint32_t)(((uint32_t)(x)) << SDRAM_CM_V_SHIFT)) & SDRAM_CM_V_MASK) +#define SDRAM_CM_WP_MASK (0x100U) +#define SDRAM_CM_WP_SHIFT (8U) +#define SDRAM_CM_WP(x) (((uint32_t)(((uint32_t)(x)) << SDRAM_CM_WP_SHIFT)) & SDRAM_CM_WP_MASK) +#define SDRAM_CM_BAM_MASK (0xFFFC0000U) +#define SDRAM_CM_BAM_SHIFT (18U) +#define SDRAM_CM_BAM(x) (((uint32_t)(((uint32_t)(x)) << SDRAM_CM_BAM_SHIFT)) & SDRAM_CM_BAM_MASK) + +/* The count of SDRAM_CM */ +#define SDRAM_CM_COUNT (2U) + + +/*! + * @} + */ /* end of group SDRAM_Register_Masks */ + + +/* SDRAM - Peripheral instance base addresses */ +/** Peripheral SDRAM base address */ +#define SDRAM_BASE (0x4000F000u) +/** Peripheral SDRAM base pointer */ +#define SDRAM ((SDRAM_Type *)SDRAM_BASE) +/** Array initializer of SDRAM peripheral base addresses */ +#define SDRAM_BASE_ADDRS { SDRAM_BASE } +/** Array initializer of SDRAM peripheral base pointers */ +#define SDRAM_BASE_PTRS { SDRAM } + +/*! + * @} + */ /* end of group SDRAM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SIM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SIM_Peripheral_Access_Layer SIM Peripheral Access Layer + * @{ + */ + +/** SIM - Register Layout Typedef */ +typedef struct { + __IO uint32_t SOPT1; /**< System Options Register 1, offset: 0x0 */ + __IO uint32_t SOPT1CFG; /**< SOPT1 Configuration Register, offset: 0x4 */ + uint8_t RESERVED_0[4092]; + __IO uint32_t SOPT2; /**< System Options Register 2, offset: 0x1004 */ + uint8_t RESERVED_1[4]; + __IO uint32_t SOPT4; /**< System Options Register 4, offset: 0x100C */ + __IO uint32_t SOPT5; /**< System Options Register 5, offset: 0x1010 */ + uint8_t RESERVED_2[4]; + __IO uint32_t SOPT7; /**< System Options Register 7, offset: 0x1018 */ + __IO uint32_t SOPT8; /**< System Options Register 8, offset: 0x101C */ + __IO uint32_t SOPT9; /**< System Options Register 9, offset: 0x1020 */ + __I uint32_t SDID; /**< System Device Identification Register, offset: 0x1024 */ + __IO uint32_t SCGC1; /**< System Clock Gating Control Register 1, offset: 0x1028 */ + __IO uint32_t SCGC2; /**< System Clock Gating Control Register 2, offset: 0x102C */ + __IO uint32_t SCGC3; /**< System Clock Gating Control Register 3, offset: 0x1030 */ + __IO uint32_t SCGC4; /**< System Clock Gating Control Register 4, offset: 0x1034 */ + __IO uint32_t SCGC5; /**< System Clock Gating Control Register 5, offset: 0x1038 */ + __IO uint32_t SCGC6; /**< System Clock Gating Control Register 6, offset: 0x103C */ + __IO uint32_t SCGC7; /**< System Clock Gating Control Register 7, offset: 0x1040 */ + __IO uint32_t CLKDIV1; /**< System Clock Divider Register 1, offset: 0x1044 */ + __IO uint32_t CLKDIV2; /**< System Clock Divider Register 2, offset: 0x1048 */ + __IO uint32_t FCFG1; /**< Flash Configuration Register 1, offset: 0x104C */ + __I uint32_t FCFG2; /**< Flash Configuration Register 2, offset: 0x1050 */ + __I uint32_t UIDH; /**< Unique Identification Register High, offset: 0x1054 */ + __I uint32_t UIDMH; /**< Unique Identification Register Mid-High, offset: 0x1058 */ + __I uint32_t UIDML; /**< Unique Identification Register Mid Low, offset: 0x105C */ + __I uint32_t UIDL; /**< Unique Identification Register Low, offset: 0x1060 */ + __IO uint32_t CLKDIV3; /**< System Clock Divider Register 3, offset: 0x1064 */ + __IO uint32_t CLKDIV4; /**< System Clock Divider Register 4, offset: 0x1068 */ +} SIM_Type; + +/* ---------------------------------------------------------------------------- + -- SIM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SIM_Register_Masks SIM Register Masks + * @{ + */ + +/*! @name SOPT1 - System Options Register 1 */ +#define SIM_SOPT1_RAMSIZE_MASK (0xF000U) +#define SIM_SOPT1_RAMSIZE_SHIFT (12U) +#define SIM_SOPT1_RAMSIZE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_RAMSIZE_SHIFT)) & SIM_SOPT1_RAMSIZE_MASK) +#define SIM_SOPT1_OSC32KSEL_MASK (0xC0000U) +#define SIM_SOPT1_OSC32KSEL_SHIFT (18U) +#define SIM_SOPT1_OSC32KSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_OSC32KSEL_SHIFT)) & SIM_SOPT1_OSC32KSEL_MASK) +#define SIM_SOPT1_USBVSTBY_MASK (0x20000000U) +#define SIM_SOPT1_USBVSTBY_SHIFT (29U) +#define SIM_SOPT1_USBVSTBY(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_USBVSTBY_SHIFT)) & SIM_SOPT1_USBVSTBY_MASK) +#define SIM_SOPT1_USBSSTBY_MASK (0x40000000U) +#define SIM_SOPT1_USBSSTBY_SHIFT (30U) +#define SIM_SOPT1_USBSSTBY(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_USBSSTBY_SHIFT)) & SIM_SOPT1_USBSSTBY_MASK) +#define SIM_SOPT1_USBREGEN_MASK (0x80000000U) +#define SIM_SOPT1_USBREGEN_SHIFT (31U) +#define SIM_SOPT1_USBREGEN(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_USBREGEN_SHIFT)) & SIM_SOPT1_USBREGEN_MASK) + +/*! @name SOPT1CFG - SOPT1 Configuration Register */ +#define SIM_SOPT1CFG_URWE_MASK (0x1000000U) +#define SIM_SOPT1CFG_URWE_SHIFT (24U) +#define SIM_SOPT1CFG_URWE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1CFG_URWE_SHIFT)) & SIM_SOPT1CFG_URWE_MASK) +#define SIM_SOPT1CFG_UVSWE_MASK (0x2000000U) +#define SIM_SOPT1CFG_UVSWE_SHIFT (25U) +#define SIM_SOPT1CFG_UVSWE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1CFG_UVSWE_SHIFT)) & SIM_SOPT1CFG_UVSWE_MASK) +#define SIM_SOPT1CFG_USSWE_MASK (0x4000000U) +#define SIM_SOPT1CFG_USSWE_SHIFT (26U) +#define SIM_SOPT1CFG_USSWE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1CFG_USSWE_SHIFT)) & SIM_SOPT1CFG_USSWE_MASK) + +/*! @name SOPT2 - System Options Register 2 */ +#define SIM_SOPT2_RTCCLKOUTSEL_MASK (0x10U) +#define SIM_SOPT2_RTCCLKOUTSEL_SHIFT (4U) +#define SIM_SOPT2_RTCCLKOUTSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_RTCCLKOUTSEL_SHIFT)) & SIM_SOPT2_RTCCLKOUTSEL_MASK) +#define SIM_SOPT2_CLKOUTSEL_MASK (0xE0U) +#define SIM_SOPT2_CLKOUTSEL_SHIFT (5U) +#define SIM_SOPT2_CLKOUTSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_CLKOUTSEL_SHIFT)) & SIM_SOPT2_CLKOUTSEL_MASK) +#define SIM_SOPT2_FBSL_MASK (0x300U) +#define SIM_SOPT2_FBSL_SHIFT (8U) +#define SIM_SOPT2_FBSL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_FBSL_SHIFT)) & SIM_SOPT2_FBSL_MASK) +#define SIM_SOPT2_TRACECLKSEL_MASK (0x1000U) +#define SIM_SOPT2_TRACECLKSEL_SHIFT (12U) +#define SIM_SOPT2_TRACECLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_TRACECLKSEL_SHIFT)) & SIM_SOPT2_TRACECLKSEL_MASK) +#define SIM_SOPT2_PLLFLLSEL_MASK (0x30000U) +#define SIM_SOPT2_PLLFLLSEL_SHIFT (16U) +#define SIM_SOPT2_PLLFLLSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_PLLFLLSEL_SHIFT)) & SIM_SOPT2_PLLFLLSEL_MASK) +#define SIM_SOPT2_USBSRC_MASK (0x40000U) +#define SIM_SOPT2_USBSRC_SHIFT (18U) +#define SIM_SOPT2_USBSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_USBSRC_SHIFT)) & SIM_SOPT2_USBSRC_MASK) +#define SIM_SOPT2_FLEXIOSRC_MASK (0xC00000U) +#define SIM_SOPT2_FLEXIOSRC_SHIFT (22U) +#define SIM_SOPT2_FLEXIOSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_FLEXIOSRC_SHIFT)) & SIM_SOPT2_FLEXIOSRC_MASK) +#define SIM_SOPT2_TPMSRC_MASK (0x3000000U) +#define SIM_SOPT2_TPMSRC_SHIFT (24U) +#define SIM_SOPT2_TPMSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_TPMSRC_SHIFT)) & SIM_SOPT2_TPMSRC_MASK) +#define SIM_SOPT2_LPUARTSRC_MASK (0xC000000U) +#define SIM_SOPT2_LPUARTSRC_SHIFT (26U) +#define SIM_SOPT2_LPUARTSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_LPUARTSRC_SHIFT)) & SIM_SOPT2_LPUARTSRC_MASK) +#define SIM_SOPT2_SDHCSRC_MASK (0x30000000U) +#define SIM_SOPT2_SDHCSRC_SHIFT (28U) +#define SIM_SOPT2_SDHCSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_SDHCSRC_SHIFT)) & SIM_SOPT2_SDHCSRC_MASK) +#define SIM_SOPT2_EMVSIMSRC_MASK (0xC0000000U) +#define SIM_SOPT2_EMVSIMSRC_SHIFT (30U) +#define SIM_SOPT2_EMVSIMSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_EMVSIMSRC_SHIFT)) & SIM_SOPT2_EMVSIMSRC_MASK) + +/*! @name SOPT4 - System Options Register 4 */ +#define SIM_SOPT4_FTM0FLT0_MASK (0x1U) +#define SIM_SOPT4_FTM0FLT0_SHIFT (0U) +#define SIM_SOPT4_FTM0FLT0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM0FLT0_SHIFT)) & SIM_SOPT4_FTM0FLT0_MASK) +#define SIM_SOPT4_FTM0FLT1_MASK (0x2U) +#define SIM_SOPT4_FTM0FLT1_SHIFT (1U) +#define SIM_SOPT4_FTM0FLT1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM0FLT1_SHIFT)) & SIM_SOPT4_FTM0FLT1_MASK) +#define SIM_SOPT4_FTM1FLT0_MASK (0x10U) +#define SIM_SOPT4_FTM1FLT0_SHIFT (4U) +#define SIM_SOPT4_FTM1FLT0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM1FLT0_SHIFT)) & SIM_SOPT4_FTM1FLT0_MASK) +#define SIM_SOPT4_FTM2FLT0_MASK (0x100U) +#define SIM_SOPT4_FTM2FLT0_SHIFT (8U) +#define SIM_SOPT4_FTM2FLT0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM2FLT0_SHIFT)) & SIM_SOPT4_FTM2FLT0_MASK) +#define SIM_SOPT4_FTM3FLT0_MASK (0x1000U) +#define SIM_SOPT4_FTM3FLT0_SHIFT (12U) +#define SIM_SOPT4_FTM3FLT0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM3FLT0_SHIFT)) & SIM_SOPT4_FTM3FLT0_MASK) +#define SIM_SOPT4_FTM1CH0SRC_MASK (0xC0000U) +#define SIM_SOPT4_FTM1CH0SRC_SHIFT (18U) +#define SIM_SOPT4_FTM1CH0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM1CH0SRC_SHIFT)) & SIM_SOPT4_FTM1CH0SRC_MASK) +#define SIM_SOPT4_FTM2CH0SRC_MASK (0x300000U) +#define SIM_SOPT4_FTM2CH0SRC_SHIFT (20U) +#define SIM_SOPT4_FTM2CH0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM2CH0SRC_SHIFT)) & SIM_SOPT4_FTM2CH0SRC_MASK) +#define SIM_SOPT4_FTM2CH1SRC_MASK (0x400000U) +#define SIM_SOPT4_FTM2CH1SRC_SHIFT (22U) +#define SIM_SOPT4_FTM2CH1SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM2CH1SRC_SHIFT)) & SIM_SOPT4_FTM2CH1SRC_MASK) +#define SIM_SOPT4_FTM0CLKSEL_MASK (0x1000000U) +#define SIM_SOPT4_FTM0CLKSEL_SHIFT (24U) +#define SIM_SOPT4_FTM0CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM0CLKSEL_SHIFT)) & SIM_SOPT4_FTM0CLKSEL_MASK) +#define SIM_SOPT4_FTM1CLKSEL_MASK (0x2000000U) +#define SIM_SOPT4_FTM1CLKSEL_SHIFT (25U) +#define SIM_SOPT4_FTM1CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM1CLKSEL_SHIFT)) & SIM_SOPT4_FTM1CLKSEL_MASK) +#define SIM_SOPT4_FTM2CLKSEL_MASK (0x4000000U) +#define SIM_SOPT4_FTM2CLKSEL_SHIFT (26U) +#define SIM_SOPT4_FTM2CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM2CLKSEL_SHIFT)) & SIM_SOPT4_FTM2CLKSEL_MASK) +#define SIM_SOPT4_FTM3CLKSEL_MASK (0x8000000U) +#define SIM_SOPT4_FTM3CLKSEL_SHIFT (27U) +#define SIM_SOPT4_FTM3CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM3CLKSEL_SHIFT)) & SIM_SOPT4_FTM3CLKSEL_MASK) +#define SIM_SOPT4_FTM0TRG0SRC_MASK (0x10000000U) +#define SIM_SOPT4_FTM0TRG0SRC_SHIFT (28U) +#define SIM_SOPT4_FTM0TRG0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM0TRG0SRC_SHIFT)) & SIM_SOPT4_FTM0TRG0SRC_MASK) +#define SIM_SOPT4_FTM0TRG1SRC_MASK (0x20000000U) +#define SIM_SOPT4_FTM0TRG1SRC_SHIFT (29U) +#define SIM_SOPT4_FTM0TRG1SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM0TRG1SRC_SHIFT)) & SIM_SOPT4_FTM0TRG1SRC_MASK) +#define SIM_SOPT4_FTM3TRG0SRC_MASK (0x40000000U) +#define SIM_SOPT4_FTM3TRG0SRC_SHIFT (30U) +#define SIM_SOPT4_FTM3TRG0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM3TRG0SRC_SHIFT)) & SIM_SOPT4_FTM3TRG0SRC_MASK) +#define SIM_SOPT4_FTM3TRG1SRC_MASK (0x80000000U) +#define SIM_SOPT4_FTM3TRG1SRC_SHIFT (31U) +#define SIM_SOPT4_FTM3TRG1SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM3TRG1SRC_SHIFT)) & SIM_SOPT4_FTM3TRG1SRC_MASK) + +/*! @name SOPT5 - System Options Register 5 */ +#define SIM_SOPT5_LPUART0TXSRC_MASK (0x30000U) +#define SIM_SOPT5_LPUART0TXSRC_SHIFT (16U) +#define SIM_SOPT5_LPUART0TXSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_LPUART0TXSRC_SHIFT)) & SIM_SOPT5_LPUART0TXSRC_MASK) +#define SIM_SOPT5_LPUART0RXSRC_MASK (0xC0000U) +#define SIM_SOPT5_LPUART0RXSRC_SHIFT (18U) +#define SIM_SOPT5_LPUART0RXSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_LPUART0RXSRC_SHIFT)) & SIM_SOPT5_LPUART0RXSRC_MASK) +#define SIM_SOPT5_LPUART1TXSRC_MASK (0x300000U) +#define SIM_SOPT5_LPUART1TXSRC_SHIFT (20U) +#define SIM_SOPT5_LPUART1TXSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_LPUART1TXSRC_SHIFT)) & SIM_SOPT5_LPUART1TXSRC_MASK) +#define SIM_SOPT5_LPUART1RXSRC_MASK (0xC00000U) +#define SIM_SOPT5_LPUART1RXSRC_SHIFT (22U) +#define SIM_SOPT5_LPUART1RXSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_LPUART1RXSRC_SHIFT)) & SIM_SOPT5_LPUART1RXSRC_MASK) + +/*! @name SOPT7 - System Options Register 7 */ +#define SIM_SOPT7_ADC0TRGSEL_MASK (0xFU) +#define SIM_SOPT7_ADC0TRGSEL_SHIFT (0U) +#define SIM_SOPT7_ADC0TRGSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT7_ADC0TRGSEL_SHIFT)) & SIM_SOPT7_ADC0TRGSEL_MASK) +#define SIM_SOPT7_ADC0PRETRGSEL_MASK (0x10U) +#define SIM_SOPT7_ADC0PRETRGSEL_SHIFT (4U) +#define SIM_SOPT7_ADC0PRETRGSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT7_ADC0PRETRGSEL_SHIFT)) & SIM_SOPT7_ADC0PRETRGSEL_MASK) +#define SIM_SOPT7_ADC0ALTTRGEN_MASK (0x80U) +#define SIM_SOPT7_ADC0ALTTRGEN_SHIFT (7U) +#define SIM_SOPT7_ADC0ALTTRGEN(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT7_ADC0ALTTRGEN_SHIFT)) & SIM_SOPT7_ADC0ALTTRGEN_MASK) + +/*! @name SOPT8 - System Options Register 8 */ +#define SIM_SOPT8_FTM0SYNCBIT_MASK (0x1U) +#define SIM_SOPT8_FTM0SYNCBIT_SHIFT (0U) +#define SIM_SOPT8_FTM0SYNCBIT(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM0SYNCBIT_SHIFT)) & SIM_SOPT8_FTM0SYNCBIT_MASK) +#define SIM_SOPT8_FTM1SYNCBIT_MASK (0x2U) +#define SIM_SOPT8_FTM1SYNCBIT_SHIFT (1U) +#define SIM_SOPT8_FTM1SYNCBIT(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM1SYNCBIT_SHIFT)) & SIM_SOPT8_FTM1SYNCBIT_MASK) +#define SIM_SOPT8_FTM2SYNCBIT_MASK (0x4U) +#define SIM_SOPT8_FTM2SYNCBIT_SHIFT (2U) +#define SIM_SOPT8_FTM2SYNCBIT(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM2SYNCBIT_SHIFT)) & SIM_SOPT8_FTM2SYNCBIT_MASK) +#define SIM_SOPT8_FTM3SYNCBIT_MASK (0x8U) +#define SIM_SOPT8_FTM3SYNCBIT_SHIFT (3U) +#define SIM_SOPT8_FTM3SYNCBIT(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM3SYNCBIT_SHIFT)) & SIM_SOPT8_FTM3SYNCBIT_MASK) +#define SIM_SOPT8_FTM0OCH0SRC_MASK (0x10000U) +#define SIM_SOPT8_FTM0OCH0SRC_SHIFT (16U) +#define SIM_SOPT8_FTM0OCH0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM0OCH0SRC_SHIFT)) & SIM_SOPT8_FTM0OCH0SRC_MASK) +#define SIM_SOPT8_FTM0OCH1SRC_MASK (0x20000U) +#define SIM_SOPT8_FTM0OCH1SRC_SHIFT (17U) +#define SIM_SOPT8_FTM0OCH1SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM0OCH1SRC_SHIFT)) & SIM_SOPT8_FTM0OCH1SRC_MASK) +#define SIM_SOPT8_FTM0OCH2SRC_MASK (0x40000U) +#define SIM_SOPT8_FTM0OCH2SRC_SHIFT (18U) +#define SIM_SOPT8_FTM0OCH2SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM0OCH2SRC_SHIFT)) & SIM_SOPT8_FTM0OCH2SRC_MASK) +#define SIM_SOPT8_FTM0OCH3SRC_MASK (0x80000U) +#define SIM_SOPT8_FTM0OCH3SRC_SHIFT (19U) +#define SIM_SOPT8_FTM0OCH3SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM0OCH3SRC_SHIFT)) & SIM_SOPT8_FTM0OCH3SRC_MASK) +#define SIM_SOPT8_FTM0OCH4SRC_MASK (0x100000U) +#define SIM_SOPT8_FTM0OCH4SRC_SHIFT (20U) +#define SIM_SOPT8_FTM0OCH4SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM0OCH4SRC_SHIFT)) & SIM_SOPT8_FTM0OCH4SRC_MASK) +#define SIM_SOPT8_FTM0OCH5SRC_MASK (0x200000U) +#define SIM_SOPT8_FTM0OCH5SRC_SHIFT (21U) +#define SIM_SOPT8_FTM0OCH5SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM0OCH5SRC_SHIFT)) & SIM_SOPT8_FTM0OCH5SRC_MASK) +#define SIM_SOPT8_FTM0OCH6SRC_MASK (0x400000U) +#define SIM_SOPT8_FTM0OCH6SRC_SHIFT (22U) +#define SIM_SOPT8_FTM0OCH6SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM0OCH6SRC_SHIFT)) & SIM_SOPT8_FTM0OCH6SRC_MASK) +#define SIM_SOPT8_FTM0OCH7SRC_MASK (0x800000U) +#define SIM_SOPT8_FTM0OCH7SRC_SHIFT (23U) +#define SIM_SOPT8_FTM0OCH7SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM0OCH7SRC_SHIFT)) & SIM_SOPT8_FTM0OCH7SRC_MASK) +#define SIM_SOPT8_FTM3OCH0SRC_MASK (0x1000000U) +#define SIM_SOPT8_FTM3OCH0SRC_SHIFT (24U) +#define SIM_SOPT8_FTM3OCH0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM3OCH0SRC_SHIFT)) & SIM_SOPT8_FTM3OCH0SRC_MASK) +#define SIM_SOPT8_FTM3OCH1SRC_MASK (0x2000000U) +#define SIM_SOPT8_FTM3OCH1SRC_SHIFT (25U) +#define SIM_SOPT8_FTM3OCH1SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM3OCH1SRC_SHIFT)) & SIM_SOPT8_FTM3OCH1SRC_MASK) +#define SIM_SOPT8_FTM3OCH2SRC_MASK (0x4000000U) +#define SIM_SOPT8_FTM3OCH2SRC_SHIFT (26U) +#define SIM_SOPT8_FTM3OCH2SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM3OCH2SRC_SHIFT)) & SIM_SOPT8_FTM3OCH2SRC_MASK) +#define SIM_SOPT8_FTM3OCH3SRC_MASK (0x8000000U) +#define SIM_SOPT8_FTM3OCH3SRC_SHIFT (27U) +#define SIM_SOPT8_FTM3OCH3SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM3OCH3SRC_SHIFT)) & SIM_SOPT8_FTM3OCH3SRC_MASK) +#define SIM_SOPT8_FTM3OCH4SRC_MASK (0x10000000U) +#define SIM_SOPT8_FTM3OCH4SRC_SHIFT (28U) +#define SIM_SOPT8_FTM3OCH4SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM3OCH4SRC_SHIFT)) & SIM_SOPT8_FTM3OCH4SRC_MASK) +#define SIM_SOPT8_FTM3OCH5SRC_MASK (0x20000000U) +#define SIM_SOPT8_FTM3OCH5SRC_SHIFT (29U) +#define SIM_SOPT8_FTM3OCH5SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM3OCH5SRC_SHIFT)) & SIM_SOPT8_FTM3OCH5SRC_MASK) +#define SIM_SOPT8_FTM3OCH6SRC_MASK (0x40000000U) +#define SIM_SOPT8_FTM3OCH6SRC_SHIFT (30U) +#define SIM_SOPT8_FTM3OCH6SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM3OCH6SRC_SHIFT)) & SIM_SOPT8_FTM3OCH6SRC_MASK) +#define SIM_SOPT8_FTM3OCH7SRC_MASK (0x80000000U) +#define SIM_SOPT8_FTM3OCH7SRC_SHIFT (31U) +#define SIM_SOPT8_FTM3OCH7SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT8_FTM3OCH7SRC_SHIFT)) & SIM_SOPT8_FTM3OCH7SRC_MASK) + +/*! @name SOPT9 - System Options Register 9 */ +#define SIM_SOPT9_TPM1CH0SRC_MASK (0xC0000U) +#define SIM_SOPT9_TPM1CH0SRC_SHIFT (18U) +#define SIM_SOPT9_TPM1CH0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT9_TPM1CH0SRC_SHIFT)) & SIM_SOPT9_TPM1CH0SRC_MASK) +#define SIM_SOPT9_TPM2CH0SRC_MASK (0x300000U) +#define SIM_SOPT9_TPM2CH0SRC_SHIFT (20U) +#define SIM_SOPT9_TPM2CH0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT9_TPM2CH0SRC_SHIFT)) & SIM_SOPT9_TPM2CH0SRC_MASK) +#define SIM_SOPT9_TPM1CLKSEL_MASK (0x2000000U) +#define SIM_SOPT9_TPM1CLKSEL_SHIFT (25U) +#define SIM_SOPT9_TPM1CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT9_TPM1CLKSEL_SHIFT)) & SIM_SOPT9_TPM1CLKSEL_MASK) +#define SIM_SOPT9_TPM2CLKSEL_MASK (0x4000000U) +#define SIM_SOPT9_TPM2CLKSEL_SHIFT (26U) +#define SIM_SOPT9_TPM2CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT9_TPM2CLKSEL_SHIFT)) & SIM_SOPT9_TPM2CLKSEL_MASK) + +/*! @name SDID - System Device Identification Register */ +#define SIM_SDID_PINID_MASK (0xFU) +#define SIM_SDID_PINID_SHIFT (0U) +#define SIM_SDID_PINID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_PINID_SHIFT)) & SIM_SDID_PINID_MASK) +#define SIM_SDID_FAMID_MASK (0x70U) +#define SIM_SDID_FAMID_SHIFT (4U) +#define SIM_SDID_FAMID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_FAMID_SHIFT)) & SIM_SDID_FAMID_MASK) +#define SIM_SDID_DIEID_MASK (0xF80U) +#define SIM_SDID_DIEID_SHIFT (7U) +#define SIM_SDID_DIEID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_DIEID_SHIFT)) & SIM_SDID_DIEID_MASK) +#define SIM_SDID_REVID_MASK (0xF000U) +#define SIM_SDID_REVID_SHIFT (12U) +#define SIM_SDID_REVID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_REVID_SHIFT)) & SIM_SDID_REVID_MASK) +#define SIM_SDID_SERIESID_MASK (0xF00000U) +#define SIM_SDID_SERIESID_SHIFT (20U) +#define SIM_SDID_SERIESID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_SERIESID_SHIFT)) & SIM_SDID_SERIESID_MASK) +#define SIM_SDID_SUBFAMID_MASK (0xF000000U) +#define SIM_SDID_SUBFAMID_SHIFT (24U) +#define SIM_SDID_SUBFAMID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_SUBFAMID_SHIFT)) & SIM_SDID_SUBFAMID_MASK) +#define SIM_SDID_FAMILYID_MASK (0xF0000000U) +#define SIM_SDID_FAMILYID_SHIFT (28U) +#define SIM_SDID_FAMILYID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_FAMILYID_SHIFT)) & SIM_SDID_FAMILYID_MASK) + +/*! @name SCGC1 - System Clock Gating Control Register 1 */ +#define SIM_SCGC1_I2C2_MASK (0x40U) +#define SIM_SCGC1_I2C2_SHIFT (6U) +#define SIM_SCGC1_I2C2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC1_I2C2_SHIFT)) & SIM_SCGC1_I2C2_MASK) +#define SIM_SCGC1_I2C3_MASK (0x80U) +#define SIM_SCGC1_I2C3_SHIFT (7U) +#define SIM_SCGC1_I2C3(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC1_I2C3_SHIFT)) & SIM_SCGC1_I2C3_MASK) + +/*! @name SCGC2 - System Clock Gating Control Register 2 */ +#define SIM_SCGC2_LPUART0_MASK (0x10U) +#define SIM_SCGC2_LPUART0_SHIFT (4U) +#define SIM_SCGC2_LPUART0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_LPUART0_SHIFT)) & SIM_SCGC2_LPUART0_MASK) +#define SIM_SCGC2_LPUART1_MASK (0x20U) +#define SIM_SCGC2_LPUART1_SHIFT (5U) +#define SIM_SCGC2_LPUART1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_LPUART1_SHIFT)) & SIM_SCGC2_LPUART1_MASK) +#define SIM_SCGC2_LPUART2_MASK (0x40U) +#define SIM_SCGC2_LPUART2_SHIFT (6U) +#define SIM_SCGC2_LPUART2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_LPUART2_SHIFT)) & SIM_SCGC2_LPUART2_MASK) +#define SIM_SCGC2_LPUART3_MASK (0x80U) +#define SIM_SCGC2_LPUART3_SHIFT (7U) +#define SIM_SCGC2_LPUART3(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_LPUART3_SHIFT)) & SIM_SCGC2_LPUART3_MASK) +#define SIM_SCGC2_TPM1_MASK (0x200U) +#define SIM_SCGC2_TPM1_SHIFT (9U) +#define SIM_SCGC2_TPM1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_TPM1_SHIFT)) & SIM_SCGC2_TPM1_MASK) +#define SIM_SCGC2_TPM2_MASK (0x400U) +#define SIM_SCGC2_TPM2_SHIFT (10U) +#define SIM_SCGC2_TPM2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_TPM2_SHIFT)) & SIM_SCGC2_TPM2_MASK) +#define SIM_SCGC2_DAC0_MASK (0x1000U) +#define SIM_SCGC2_DAC0_SHIFT (12U) +#define SIM_SCGC2_DAC0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_DAC0_SHIFT)) & SIM_SCGC2_DAC0_MASK) +#define SIM_SCGC2_LTC_MASK (0x20000U) +#define SIM_SCGC2_LTC_SHIFT (17U) +#define SIM_SCGC2_LTC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_LTC_SHIFT)) & SIM_SCGC2_LTC_MASK) +#define SIM_SCGC2_EMVSIM0_MASK (0x100000U) +#define SIM_SCGC2_EMVSIM0_SHIFT (20U) +#define SIM_SCGC2_EMVSIM0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_EMVSIM0_SHIFT)) & SIM_SCGC2_EMVSIM0_MASK) +#define SIM_SCGC2_EMVSIM1_MASK (0x200000U) +#define SIM_SCGC2_EMVSIM1_SHIFT (21U) +#define SIM_SCGC2_EMVSIM1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_EMVSIM1_SHIFT)) & SIM_SCGC2_EMVSIM1_MASK) +#define SIM_SCGC2_LPUART4_MASK (0x400000U) +#define SIM_SCGC2_LPUART4_SHIFT (22U) +#define SIM_SCGC2_LPUART4(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_LPUART4_SHIFT)) & SIM_SCGC2_LPUART4_MASK) +#define SIM_SCGC2_QSPI_MASK (0x4000000U) +#define SIM_SCGC2_QSPI_SHIFT (26U) +#define SIM_SCGC2_QSPI(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_QSPI_SHIFT)) & SIM_SCGC2_QSPI_MASK) +#define SIM_SCGC2_FLEXIO_MASK (0x80000000U) +#define SIM_SCGC2_FLEXIO_SHIFT (31U) +#define SIM_SCGC2_FLEXIO(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_FLEXIO_SHIFT)) & SIM_SCGC2_FLEXIO_MASK) + +/*! @name SCGC3 - System Clock Gating Control Register 3 */ +#define SIM_SCGC3_TRNG_MASK (0x1U) +#define SIM_SCGC3_TRNG_SHIFT (0U) +#define SIM_SCGC3_TRNG(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC3_TRNG_SHIFT)) & SIM_SCGC3_TRNG_MASK) +#define SIM_SCGC3_SPI2_MASK (0x1000U) +#define SIM_SCGC3_SPI2_SHIFT (12U) +#define SIM_SCGC3_SPI2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC3_SPI2_SHIFT)) & SIM_SCGC3_SPI2_MASK) +#define SIM_SCGC3_SDHC_MASK (0x20000U) +#define SIM_SCGC3_SDHC_SHIFT (17U) +#define SIM_SCGC3_SDHC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC3_SDHC_SHIFT)) & SIM_SCGC3_SDHC_MASK) +#define SIM_SCGC3_FTM2_MASK (0x1000000U) +#define SIM_SCGC3_FTM2_SHIFT (24U) +#define SIM_SCGC3_FTM2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC3_FTM2_SHIFT)) & SIM_SCGC3_FTM2_MASK) +#define SIM_SCGC3_FTM3_MASK (0x2000000U) +#define SIM_SCGC3_FTM3_SHIFT (25U) +#define SIM_SCGC3_FTM3(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC3_FTM3_SHIFT)) & SIM_SCGC3_FTM3_MASK) + +/*! @name SCGC4 - System Clock Gating Control Register 4 */ +#define SIM_SCGC4_EWM_MASK (0x2U) +#define SIM_SCGC4_EWM_SHIFT (1U) +#define SIM_SCGC4_EWM(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_EWM_SHIFT)) & SIM_SCGC4_EWM_MASK) +#define SIM_SCGC4_CMT_MASK (0x4U) +#define SIM_SCGC4_CMT_SHIFT (2U) +#define SIM_SCGC4_CMT(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_CMT_SHIFT)) & SIM_SCGC4_CMT_MASK) +#define SIM_SCGC4_I2C0_MASK (0x40U) +#define SIM_SCGC4_I2C0_SHIFT (6U) +#define SIM_SCGC4_I2C0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_I2C0_SHIFT)) & SIM_SCGC4_I2C0_MASK) +#define SIM_SCGC4_I2C1_MASK (0x80U) +#define SIM_SCGC4_I2C1_SHIFT (7U) +#define SIM_SCGC4_I2C1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_I2C1_SHIFT)) & SIM_SCGC4_I2C1_MASK) +#define SIM_SCGC4_USBOTG_MASK (0x40000U) +#define SIM_SCGC4_USBOTG_SHIFT (18U) +#define SIM_SCGC4_USBOTG(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_USBOTG_SHIFT)) & SIM_SCGC4_USBOTG_MASK) +#define SIM_SCGC4_CMP_MASK (0x80000U) +#define SIM_SCGC4_CMP_SHIFT (19U) +#define SIM_SCGC4_CMP(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_CMP_SHIFT)) & SIM_SCGC4_CMP_MASK) +#define SIM_SCGC4_VREF_MASK (0x100000U) +#define SIM_SCGC4_VREF_SHIFT (20U) +#define SIM_SCGC4_VREF(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_VREF_SHIFT)) & SIM_SCGC4_VREF_MASK) + +/*! @name SCGC5 - System Clock Gating Control Register 5 */ +#define SIM_SCGC5_LPTMR_MASK (0x1U) +#define SIM_SCGC5_LPTMR_SHIFT (0U) +#define SIM_SCGC5_LPTMR(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_LPTMR_SHIFT)) & SIM_SCGC5_LPTMR_MASK) +#define SIM_SCGC5_LPTMR1_MASK (0x10U) +#define SIM_SCGC5_LPTMR1_SHIFT (4U) +#define SIM_SCGC5_LPTMR1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_LPTMR1_SHIFT)) & SIM_SCGC5_LPTMR1_MASK) +#define SIM_SCGC5_TSI_MASK (0x20U) +#define SIM_SCGC5_TSI_SHIFT (5U) +#define SIM_SCGC5_TSI(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_TSI_SHIFT)) & SIM_SCGC5_TSI_MASK) +#define SIM_SCGC5_PORTA_MASK (0x200U) +#define SIM_SCGC5_PORTA_SHIFT (9U) +#define SIM_SCGC5_PORTA(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTA_SHIFT)) & SIM_SCGC5_PORTA_MASK) +#define SIM_SCGC5_PORTB_MASK (0x400U) +#define SIM_SCGC5_PORTB_SHIFT (10U) +#define SIM_SCGC5_PORTB(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTB_SHIFT)) & SIM_SCGC5_PORTB_MASK) +#define SIM_SCGC5_PORTC_MASK (0x800U) +#define SIM_SCGC5_PORTC_SHIFT (11U) +#define SIM_SCGC5_PORTC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTC_SHIFT)) & SIM_SCGC5_PORTC_MASK) +#define SIM_SCGC5_PORTD_MASK (0x1000U) +#define SIM_SCGC5_PORTD_SHIFT (12U) +#define SIM_SCGC5_PORTD(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTD_SHIFT)) & SIM_SCGC5_PORTD_MASK) +#define SIM_SCGC5_PORTE_MASK (0x2000U) +#define SIM_SCGC5_PORTE_SHIFT (13U) +#define SIM_SCGC5_PORTE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTE_SHIFT)) & SIM_SCGC5_PORTE_MASK) + +/*! @name SCGC6 - System Clock Gating Control Register 6 */ +#define SIM_SCGC6_FTF_MASK (0x1U) +#define SIM_SCGC6_FTF_SHIFT (0U) +#define SIM_SCGC6_FTF(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_FTF_SHIFT)) & SIM_SCGC6_FTF_MASK) +#define SIM_SCGC6_DMAMUX_MASK (0x2U) +#define SIM_SCGC6_DMAMUX_SHIFT (1U) +#define SIM_SCGC6_DMAMUX(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_DMAMUX_SHIFT)) & SIM_SCGC6_DMAMUX_MASK) +#define SIM_SCGC6_SPI0_MASK (0x1000U) +#define SIM_SCGC6_SPI0_SHIFT (12U) +#define SIM_SCGC6_SPI0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_SPI0_SHIFT)) & SIM_SCGC6_SPI0_MASK) +#define SIM_SCGC6_SPI1_MASK (0x2000U) +#define SIM_SCGC6_SPI1_SHIFT (13U) +#define SIM_SCGC6_SPI1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_SPI1_SHIFT)) & SIM_SCGC6_SPI1_MASK) +#define SIM_SCGC6_I2S_MASK (0x8000U) +#define SIM_SCGC6_I2S_SHIFT (15U) +#define SIM_SCGC6_I2S(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_I2S_SHIFT)) & SIM_SCGC6_I2S_MASK) +#define SIM_SCGC6_CRC_MASK (0x40000U) +#define SIM_SCGC6_CRC_SHIFT (18U) +#define SIM_SCGC6_CRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_CRC_SHIFT)) & SIM_SCGC6_CRC_MASK) +#define SIM_SCGC6_USBDCD_MASK (0x200000U) +#define SIM_SCGC6_USBDCD_SHIFT (21U) +#define SIM_SCGC6_USBDCD(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_USBDCD_SHIFT)) & SIM_SCGC6_USBDCD_MASK) +#define SIM_SCGC6_PDB_MASK (0x400000U) +#define SIM_SCGC6_PDB_SHIFT (22U) +#define SIM_SCGC6_PDB(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_PDB_SHIFT)) & SIM_SCGC6_PDB_MASK) +#define SIM_SCGC6_PIT_MASK (0x800000U) +#define SIM_SCGC6_PIT_SHIFT (23U) +#define SIM_SCGC6_PIT(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_PIT_SHIFT)) & SIM_SCGC6_PIT_MASK) +#define SIM_SCGC6_FTM0_MASK (0x1000000U) +#define SIM_SCGC6_FTM0_SHIFT (24U) +#define SIM_SCGC6_FTM0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_FTM0_SHIFT)) & SIM_SCGC6_FTM0_MASK) +#define SIM_SCGC6_FTM1_MASK (0x2000000U) +#define SIM_SCGC6_FTM1_SHIFT (25U) +#define SIM_SCGC6_FTM1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_FTM1_SHIFT)) & SIM_SCGC6_FTM1_MASK) +#define SIM_SCGC6_FTM2_MASK (0x4000000U) +#define SIM_SCGC6_FTM2_SHIFT (26U) +#define SIM_SCGC6_FTM2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_FTM2_SHIFT)) & SIM_SCGC6_FTM2_MASK) +#define SIM_SCGC6_ADC0_MASK (0x8000000U) +#define SIM_SCGC6_ADC0_SHIFT (27U) +#define SIM_SCGC6_ADC0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_ADC0_SHIFT)) & SIM_SCGC6_ADC0_MASK) +#define SIM_SCGC6_RTC_MASK (0x20000000U) +#define SIM_SCGC6_RTC_SHIFT (29U) +#define SIM_SCGC6_RTC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_RTC_SHIFT)) & SIM_SCGC6_RTC_MASK) +#define SIM_SCGC6_DAC0_MASK (0x80000000U) +#define SIM_SCGC6_DAC0_SHIFT (31U) +#define SIM_SCGC6_DAC0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_DAC0_SHIFT)) & SIM_SCGC6_DAC0_MASK) + +/*! @name SCGC7 - System Clock Gating Control Register 7 */ +#define SIM_SCGC7_FLEXBUS_MASK (0x1U) +#define SIM_SCGC7_FLEXBUS_SHIFT (0U) +#define SIM_SCGC7_FLEXBUS(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC7_FLEXBUS_SHIFT)) & SIM_SCGC7_FLEXBUS_MASK) +#define SIM_SCGC7_DMA_MASK (0x2U) +#define SIM_SCGC7_DMA_SHIFT (1U) +#define SIM_SCGC7_DMA(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC7_DMA_SHIFT)) & SIM_SCGC7_DMA_MASK) +#define SIM_SCGC7_MPU_MASK (0x4U) +#define SIM_SCGC7_MPU_SHIFT (2U) +#define SIM_SCGC7_MPU(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC7_MPU_SHIFT)) & SIM_SCGC7_MPU_MASK) +#define SIM_SCGC7_SDRAMC_MASK (0x8U) +#define SIM_SCGC7_SDRAMC_SHIFT (3U) +#define SIM_SCGC7_SDRAMC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC7_SDRAMC_SHIFT)) & SIM_SCGC7_SDRAMC_MASK) + +/*! @name CLKDIV1 - System Clock Divider Register 1 */ +#define SIM_CLKDIV1_OUTDIV4_MASK (0xF0000U) +#define SIM_CLKDIV1_OUTDIV4_SHIFT (16U) +#define SIM_CLKDIV1_OUTDIV4(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV1_OUTDIV4_SHIFT)) & SIM_CLKDIV1_OUTDIV4_MASK) +#define SIM_CLKDIV1_OUTDIV3_MASK (0xF00000U) +#define SIM_CLKDIV1_OUTDIV3_SHIFT (20U) +#define SIM_CLKDIV1_OUTDIV3(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV1_OUTDIV3_SHIFT)) & SIM_CLKDIV1_OUTDIV3_MASK) +#define SIM_CLKDIV1_OUTDIV2_MASK (0xF000000U) +#define SIM_CLKDIV1_OUTDIV2_SHIFT (24U) +#define SIM_CLKDIV1_OUTDIV2(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV1_OUTDIV2_SHIFT)) & SIM_CLKDIV1_OUTDIV2_MASK) +#define SIM_CLKDIV1_OUTDIV1_MASK (0xF0000000U) +#define SIM_CLKDIV1_OUTDIV1_SHIFT (28U) +#define SIM_CLKDIV1_OUTDIV1(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV1_OUTDIV1_SHIFT)) & SIM_CLKDIV1_OUTDIV1_MASK) + +/*! @name CLKDIV2 - System Clock Divider Register 2 */ +#define SIM_CLKDIV2_USBFRAC_MASK (0x1U) +#define SIM_CLKDIV2_USBFRAC_SHIFT (0U) +#define SIM_CLKDIV2_USBFRAC(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV2_USBFRAC_SHIFT)) & SIM_CLKDIV2_USBFRAC_MASK) +#define SIM_CLKDIV2_USBDIV_MASK (0xEU) +#define SIM_CLKDIV2_USBDIV_SHIFT (1U) +#define SIM_CLKDIV2_USBDIV(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV2_USBDIV_SHIFT)) & SIM_CLKDIV2_USBDIV_MASK) + +/*! @name FCFG1 - Flash Configuration Register 1 */ +#define SIM_FCFG1_FLASHDIS_MASK (0x1U) +#define SIM_FCFG1_FLASHDIS_SHIFT (0U) +#define SIM_FCFG1_FLASHDIS(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG1_FLASHDIS_SHIFT)) & SIM_FCFG1_FLASHDIS_MASK) +#define SIM_FCFG1_FLASHDOZE_MASK (0x2U) +#define SIM_FCFG1_FLASHDOZE_SHIFT (1U) +#define SIM_FCFG1_FLASHDOZE(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG1_FLASHDOZE_SHIFT)) & SIM_FCFG1_FLASHDOZE_MASK) +#define SIM_FCFG1_PFSIZE_MASK (0xF000000U) +#define SIM_FCFG1_PFSIZE_SHIFT (24U) +#define SIM_FCFG1_PFSIZE(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG1_PFSIZE_SHIFT)) & SIM_FCFG1_PFSIZE_MASK) + +/*! @name FCFG2 - Flash Configuration Register 2 */ +#define SIM_FCFG2_MAXADDR1_MASK (0x7F0000U) +#define SIM_FCFG2_MAXADDR1_SHIFT (16U) +#define SIM_FCFG2_MAXADDR1(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG2_MAXADDR1_SHIFT)) & SIM_FCFG2_MAXADDR1_MASK) +#define SIM_FCFG2_MAXADDR0_MASK (0x7F000000U) +#define SIM_FCFG2_MAXADDR0_SHIFT (24U) +#define SIM_FCFG2_MAXADDR0(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG2_MAXADDR0_SHIFT)) & SIM_FCFG2_MAXADDR0_MASK) + +/*! @name UIDH - Unique Identification Register High */ +#define SIM_UIDH_UID_MASK (0xFFFFFFFFU) +#define SIM_UIDH_UID_SHIFT (0U) +#define SIM_UIDH_UID(x) (((uint32_t)(((uint32_t)(x)) << SIM_UIDH_UID_SHIFT)) & SIM_UIDH_UID_MASK) + +/*! @name UIDMH - Unique Identification Register Mid-High */ +#define SIM_UIDMH_UID_MASK (0xFFFFFFFFU) +#define SIM_UIDMH_UID_SHIFT (0U) +#define SIM_UIDMH_UID(x) (((uint32_t)(((uint32_t)(x)) << SIM_UIDMH_UID_SHIFT)) & SIM_UIDMH_UID_MASK) + +/*! @name UIDML - Unique Identification Register Mid Low */ +#define SIM_UIDML_UID_MASK (0xFFFFFFFFU) +#define SIM_UIDML_UID_SHIFT (0U) +#define SIM_UIDML_UID(x) (((uint32_t)(((uint32_t)(x)) << SIM_UIDML_UID_SHIFT)) & SIM_UIDML_UID_MASK) + +/*! @name UIDL - Unique Identification Register Low */ +#define SIM_UIDL_UID_MASK (0xFFFFFFFFU) +#define SIM_UIDL_UID_SHIFT (0U) +#define SIM_UIDL_UID(x) (((uint32_t)(((uint32_t)(x)) << SIM_UIDL_UID_SHIFT)) & SIM_UIDL_UID_MASK) + +/*! @name CLKDIV3 - System Clock Divider Register 3 */ +#define SIM_CLKDIV3_PLLFLLFRAC_MASK (0x1U) +#define SIM_CLKDIV3_PLLFLLFRAC_SHIFT (0U) +#define SIM_CLKDIV3_PLLFLLFRAC(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV3_PLLFLLFRAC_SHIFT)) & SIM_CLKDIV3_PLLFLLFRAC_MASK) +#define SIM_CLKDIV3_PLLFLLDIV_MASK (0xEU) +#define SIM_CLKDIV3_PLLFLLDIV_SHIFT (1U) +#define SIM_CLKDIV3_PLLFLLDIV(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV3_PLLFLLDIV_SHIFT)) & SIM_CLKDIV3_PLLFLLDIV_MASK) + +/*! @name CLKDIV4 - System Clock Divider Register 4 */ +#define SIM_CLKDIV4_TRACEFRAC_MASK (0x1U) +#define SIM_CLKDIV4_TRACEFRAC_SHIFT (0U) +#define SIM_CLKDIV4_TRACEFRAC(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV4_TRACEFRAC_SHIFT)) & SIM_CLKDIV4_TRACEFRAC_MASK) +#define SIM_CLKDIV4_TRACEDIV_MASK (0xEU) +#define SIM_CLKDIV4_TRACEDIV_SHIFT (1U) +#define SIM_CLKDIV4_TRACEDIV(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV4_TRACEDIV_SHIFT)) & SIM_CLKDIV4_TRACEDIV_MASK) + + +/*! + * @} + */ /* end of group SIM_Register_Masks */ + + +/* SIM - Peripheral instance base addresses */ +/** Peripheral SIM base address */ +#define SIM_BASE (0x40047000u) +/** Peripheral SIM base pointer */ +#define SIM ((SIM_Type *)SIM_BASE) +/** Array initializer of SIM peripheral base addresses */ +#define SIM_BASE_ADDRS { SIM_BASE } +/** Array initializer of SIM peripheral base pointers */ +#define SIM_BASE_PTRS { SIM } + +/*! + * @} + */ /* end of group SIM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SMC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SMC_Peripheral_Access_Layer SMC Peripheral Access Layer + * @{ + */ + +/** SMC - Register Layout Typedef */ +typedef struct { + __IO uint8_t PMPROT; /**< Power Mode Protection register, offset: 0x0 */ + __IO uint8_t PMCTRL; /**< Power Mode Control register, offset: 0x1 */ + __IO uint8_t STOPCTRL; /**< Stop Control Register, offset: 0x2 */ + __I uint8_t PMSTAT; /**< Power Mode Status register, offset: 0x3 */ +} SMC_Type; + +/* ---------------------------------------------------------------------------- + -- SMC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SMC_Register_Masks SMC Register Masks + * @{ + */ + +/*! @name PMPROT - Power Mode Protection register */ +#define SMC_PMPROT_AVLLS_MASK (0x2U) +#define SMC_PMPROT_AVLLS_SHIFT (1U) +#define SMC_PMPROT_AVLLS(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMPROT_AVLLS_SHIFT)) & SMC_PMPROT_AVLLS_MASK) +#define SMC_PMPROT_ALLS_MASK (0x8U) +#define SMC_PMPROT_ALLS_SHIFT (3U) +#define SMC_PMPROT_ALLS(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMPROT_ALLS_SHIFT)) & SMC_PMPROT_ALLS_MASK) +#define SMC_PMPROT_AVLP_MASK (0x20U) +#define SMC_PMPROT_AVLP_SHIFT (5U) +#define SMC_PMPROT_AVLP(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMPROT_AVLP_SHIFT)) & SMC_PMPROT_AVLP_MASK) +#define SMC_PMPROT_AHSRUN_MASK (0x80U) +#define SMC_PMPROT_AHSRUN_SHIFT (7U) +#define SMC_PMPROT_AHSRUN(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMPROT_AHSRUN_SHIFT)) & SMC_PMPROT_AHSRUN_MASK) + +/*! @name PMCTRL - Power Mode Control register */ +#define SMC_PMCTRL_STOPM_MASK (0x7U) +#define SMC_PMCTRL_STOPM_SHIFT (0U) +#define SMC_PMCTRL_STOPM(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMCTRL_STOPM_SHIFT)) & SMC_PMCTRL_STOPM_MASK) +#define SMC_PMCTRL_STOPA_MASK (0x8U) +#define SMC_PMCTRL_STOPA_SHIFT (3U) +#define SMC_PMCTRL_STOPA(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMCTRL_STOPA_SHIFT)) & SMC_PMCTRL_STOPA_MASK) +#define SMC_PMCTRL_RUNM_MASK (0x60U) +#define SMC_PMCTRL_RUNM_SHIFT (5U) +#define SMC_PMCTRL_RUNM(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMCTRL_RUNM_SHIFT)) & SMC_PMCTRL_RUNM_MASK) + +/*! @name STOPCTRL - Stop Control Register */ +#define SMC_STOPCTRL_LLSM_MASK (0x7U) +#define SMC_STOPCTRL_LLSM_SHIFT (0U) +#define SMC_STOPCTRL_LLSM(x) (((uint8_t)(((uint8_t)(x)) << SMC_STOPCTRL_LLSM_SHIFT)) & SMC_STOPCTRL_LLSM_MASK) +#define SMC_STOPCTRL_LPOPO_MASK (0x8U) +#define SMC_STOPCTRL_LPOPO_SHIFT (3U) +#define SMC_STOPCTRL_LPOPO(x) (((uint8_t)(((uint8_t)(x)) << SMC_STOPCTRL_LPOPO_SHIFT)) & SMC_STOPCTRL_LPOPO_MASK) +#define SMC_STOPCTRL_RAM2PO_MASK (0x10U) +#define SMC_STOPCTRL_RAM2PO_SHIFT (4U) +#define SMC_STOPCTRL_RAM2PO(x) (((uint8_t)(((uint8_t)(x)) << SMC_STOPCTRL_RAM2PO_SHIFT)) & SMC_STOPCTRL_RAM2PO_MASK) +#define SMC_STOPCTRL_PORPO_MASK (0x20U) +#define SMC_STOPCTRL_PORPO_SHIFT (5U) +#define SMC_STOPCTRL_PORPO(x) (((uint8_t)(((uint8_t)(x)) << SMC_STOPCTRL_PORPO_SHIFT)) & SMC_STOPCTRL_PORPO_MASK) +#define SMC_STOPCTRL_PSTOPO_MASK (0xC0U) +#define SMC_STOPCTRL_PSTOPO_SHIFT (6U) +#define SMC_STOPCTRL_PSTOPO(x) (((uint8_t)(((uint8_t)(x)) << SMC_STOPCTRL_PSTOPO_SHIFT)) & SMC_STOPCTRL_PSTOPO_MASK) + +/*! @name PMSTAT - Power Mode Status register */ +#define SMC_PMSTAT_PMSTAT_MASK (0xFFU) +#define SMC_PMSTAT_PMSTAT_SHIFT (0U) +#define SMC_PMSTAT_PMSTAT(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMSTAT_PMSTAT_SHIFT)) & SMC_PMSTAT_PMSTAT_MASK) + + +/*! + * @} + */ /* end of group SMC_Register_Masks */ + + +/* SMC - Peripheral instance base addresses */ +/** Peripheral SMC base address */ +#define SMC_BASE (0x4007E000u) +/** Peripheral SMC base pointer */ +#define SMC ((SMC_Type *)SMC_BASE) +/** Array initializer of SMC peripheral base addresses */ +#define SMC_BASE_ADDRS { SMC_BASE } +/** Array initializer of SMC peripheral base pointers */ +#define SMC_BASE_PTRS { SMC } + +/*! + * @} + */ /* end of group SMC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SPI Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPI_Peripheral_Access_Layer SPI Peripheral Access Layer + * @{ + */ + +/** SPI - Register Layout Typedef */ +typedef struct { + __IO uint32_t MCR; /**< Module Configuration Register, offset: 0x0 */ + uint8_t RESERVED_0[4]; + __IO uint32_t TCR; /**< Transfer Count Register, offset: 0x8 */ + union { /* offset: 0xC */ + __IO uint32_t CTAR[2]; /**< Clock and Transfer Attributes Register (In Master Mode), array offset: 0xC, array step: 0x4 */ + __IO uint32_t CTAR_SLAVE[1]; /**< Clock and Transfer Attributes Register (In Slave Mode), array offset: 0xC, array step: 0x4 */ + }; + uint8_t RESERVED_1[24]; + __IO uint32_t SR; /**< Status Register, offset: 0x2C */ + __IO uint32_t RSER; /**< DMA/Interrupt Request Select and Enable Register, offset: 0x30 */ + union { /* offset: 0x34 */ + __IO uint32_t PUSHR; /**< PUSH TX FIFO Register In Master Mode, offset: 0x34 */ + __IO uint32_t PUSHR_SLAVE; /**< PUSH TX FIFO Register In Slave Mode, offset: 0x34 */ + }; + __I uint32_t POPR; /**< POP RX FIFO Register, offset: 0x38 */ + __I uint32_t TXFR0; /**< Transmit FIFO Registers, offset: 0x3C */ + __I uint32_t TXFR1; /**< Transmit FIFO Registers, offset: 0x40 */ + __I uint32_t TXFR2; /**< Transmit FIFO Registers, offset: 0x44 */ + __I uint32_t TXFR3; /**< Transmit FIFO Registers, offset: 0x48 */ + uint8_t RESERVED_2[48]; + __I uint32_t RXFR0; /**< Receive FIFO Registers, offset: 0x7C */ + __I uint32_t RXFR1; /**< Receive FIFO Registers, offset: 0x80 */ + __I uint32_t RXFR2; /**< Receive FIFO Registers, offset: 0x84 */ + __I uint32_t RXFR3; /**< Receive FIFO Registers, offset: 0x88 */ +} SPI_Type; + +/* ---------------------------------------------------------------------------- + -- SPI Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPI_Register_Masks SPI Register Masks + * @{ + */ + +/*! @name MCR - Module Configuration Register */ +#define SPI_MCR_HALT_MASK (0x1U) +#define SPI_MCR_HALT_SHIFT (0U) +#define SPI_MCR_HALT(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_HALT_SHIFT)) & SPI_MCR_HALT_MASK) +#define SPI_MCR_SMPL_PT_MASK (0x300U) +#define SPI_MCR_SMPL_PT_SHIFT (8U) +#define SPI_MCR_SMPL_PT(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_SMPL_PT_SHIFT)) & SPI_MCR_SMPL_PT_MASK) +#define SPI_MCR_CLR_RXF_MASK (0x400U) +#define SPI_MCR_CLR_RXF_SHIFT (10U) +#define SPI_MCR_CLR_RXF(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_CLR_RXF_SHIFT)) & SPI_MCR_CLR_RXF_MASK) +#define SPI_MCR_CLR_TXF_MASK (0x800U) +#define SPI_MCR_CLR_TXF_SHIFT (11U) +#define SPI_MCR_CLR_TXF(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_CLR_TXF_SHIFT)) & SPI_MCR_CLR_TXF_MASK) +#define SPI_MCR_DIS_RXF_MASK (0x1000U) +#define SPI_MCR_DIS_RXF_SHIFT (12U) +#define SPI_MCR_DIS_RXF(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_DIS_RXF_SHIFT)) & SPI_MCR_DIS_RXF_MASK) +#define SPI_MCR_DIS_TXF_MASK (0x2000U) +#define SPI_MCR_DIS_TXF_SHIFT (13U) +#define SPI_MCR_DIS_TXF(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_DIS_TXF_SHIFT)) & SPI_MCR_DIS_TXF_MASK) +#define SPI_MCR_MDIS_MASK (0x4000U) +#define SPI_MCR_MDIS_SHIFT (14U) +#define SPI_MCR_MDIS(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_MDIS_SHIFT)) & SPI_MCR_MDIS_MASK) +#define SPI_MCR_DOZE_MASK (0x8000U) +#define SPI_MCR_DOZE_SHIFT (15U) +#define SPI_MCR_DOZE(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_DOZE_SHIFT)) & SPI_MCR_DOZE_MASK) +#define SPI_MCR_PCSIS_MASK (0x3F0000U) +#define SPI_MCR_PCSIS_SHIFT (16U) +#define SPI_MCR_PCSIS(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_PCSIS_SHIFT)) & SPI_MCR_PCSIS_MASK) +#define SPI_MCR_ROOE_MASK (0x1000000U) +#define SPI_MCR_ROOE_SHIFT (24U) +#define SPI_MCR_ROOE(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_ROOE_SHIFT)) & SPI_MCR_ROOE_MASK) +#define SPI_MCR_PCSSE_MASK (0x2000000U) +#define SPI_MCR_PCSSE_SHIFT (25U) +#define SPI_MCR_PCSSE(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_PCSSE_SHIFT)) & SPI_MCR_PCSSE_MASK) +#define SPI_MCR_MTFE_MASK (0x4000000U) +#define SPI_MCR_MTFE_SHIFT (26U) +#define SPI_MCR_MTFE(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_MTFE_SHIFT)) & SPI_MCR_MTFE_MASK) +#define SPI_MCR_FRZ_MASK (0x8000000U) +#define SPI_MCR_FRZ_SHIFT (27U) +#define SPI_MCR_FRZ(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_FRZ_SHIFT)) & SPI_MCR_FRZ_MASK) +#define SPI_MCR_DCONF_MASK (0x30000000U) +#define SPI_MCR_DCONF_SHIFT (28U) +#define SPI_MCR_DCONF(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_DCONF_SHIFT)) & SPI_MCR_DCONF_MASK) +#define SPI_MCR_CONT_SCKE_MASK (0x40000000U) +#define SPI_MCR_CONT_SCKE_SHIFT (30U) +#define SPI_MCR_CONT_SCKE(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_CONT_SCKE_SHIFT)) & SPI_MCR_CONT_SCKE_MASK) +#define SPI_MCR_MSTR_MASK (0x80000000U) +#define SPI_MCR_MSTR_SHIFT (31U) +#define SPI_MCR_MSTR(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_MSTR_SHIFT)) & SPI_MCR_MSTR_MASK) + +/*! @name TCR - Transfer Count Register */ +#define SPI_TCR_SPI_TCNT_MASK (0xFFFF0000U) +#define SPI_TCR_SPI_TCNT_SHIFT (16U) +#define SPI_TCR_SPI_TCNT(x) (((uint32_t)(((uint32_t)(x)) << SPI_TCR_SPI_TCNT_SHIFT)) & SPI_TCR_SPI_TCNT_MASK) + +/*! @name CTAR - Clock and Transfer Attributes Register (In Master Mode) */ +#define SPI_CTAR_BR_MASK (0xFU) +#define SPI_CTAR_BR_SHIFT (0U) +#define SPI_CTAR_BR(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_BR_SHIFT)) & SPI_CTAR_BR_MASK) +#define SPI_CTAR_DT_MASK (0xF0U) +#define SPI_CTAR_DT_SHIFT (4U) +#define SPI_CTAR_DT(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_DT_SHIFT)) & SPI_CTAR_DT_MASK) +#define SPI_CTAR_ASC_MASK (0xF00U) +#define SPI_CTAR_ASC_SHIFT (8U) +#define SPI_CTAR_ASC(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_ASC_SHIFT)) & SPI_CTAR_ASC_MASK) +#define SPI_CTAR_CSSCK_MASK (0xF000U) +#define SPI_CTAR_CSSCK_SHIFT (12U) +#define SPI_CTAR_CSSCK(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_CSSCK_SHIFT)) & SPI_CTAR_CSSCK_MASK) +#define SPI_CTAR_PBR_MASK (0x30000U) +#define SPI_CTAR_PBR_SHIFT (16U) +#define SPI_CTAR_PBR(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_PBR_SHIFT)) & SPI_CTAR_PBR_MASK) +#define SPI_CTAR_PDT_MASK (0xC0000U) +#define SPI_CTAR_PDT_SHIFT (18U) +#define SPI_CTAR_PDT(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_PDT_SHIFT)) & SPI_CTAR_PDT_MASK) +#define SPI_CTAR_PASC_MASK (0x300000U) +#define SPI_CTAR_PASC_SHIFT (20U) +#define SPI_CTAR_PASC(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_PASC_SHIFT)) & SPI_CTAR_PASC_MASK) +#define SPI_CTAR_PCSSCK_MASK (0xC00000U) +#define SPI_CTAR_PCSSCK_SHIFT (22U) +#define SPI_CTAR_PCSSCK(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_PCSSCK_SHIFT)) & SPI_CTAR_PCSSCK_MASK) +#define SPI_CTAR_LSBFE_MASK (0x1000000U) +#define SPI_CTAR_LSBFE_SHIFT (24U) +#define SPI_CTAR_LSBFE(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_LSBFE_SHIFT)) & SPI_CTAR_LSBFE_MASK) +#define SPI_CTAR_CPHA_MASK (0x2000000U) +#define SPI_CTAR_CPHA_SHIFT (25U) +#define SPI_CTAR_CPHA(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_CPHA_SHIFT)) & SPI_CTAR_CPHA_MASK) +#define SPI_CTAR_CPOL_MASK (0x4000000U) +#define SPI_CTAR_CPOL_SHIFT (26U) +#define SPI_CTAR_CPOL(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_CPOL_SHIFT)) & SPI_CTAR_CPOL_MASK) +#define SPI_CTAR_FMSZ_MASK (0x78000000U) +#define SPI_CTAR_FMSZ_SHIFT (27U) +#define SPI_CTAR_FMSZ(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_FMSZ_SHIFT)) & SPI_CTAR_FMSZ_MASK) +#define SPI_CTAR_DBR_MASK (0x80000000U) +#define SPI_CTAR_DBR_SHIFT (31U) +#define SPI_CTAR_DBR(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_DBR_SHIFT)) & SPI_CTAR_DBR_MASK) + +/* The count of SPI_CTAR */ +#define SPI_CTAR_COUNT (2U) + +/*! @name CTAR_SLAVE - Clock and Transfer Attributes Register (In Slave Mode) */ +#define SPI_CTAR_SLAVE_CPHA_MASK (0x2000000U) +#define SPI_CTAR_SLAVE_CPHA_SHIFT (25U) +#define SPI_CTAR_SLAVE_CPHA(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_SLAVE_CPHA_SHIFT)) & SPI_CTAR_SLAVE_CPHA_MASK) +#define SPI_CTAR_SLAVE_CPOL_MASK (0x4000000U) +#define SPI_CTAR_SLAVE_CPOL_SHIFT (26U) +#define SPI_CTAR_SLAVE_CPOL(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_SLAVE_CPOL_SHIFT)) & SPI_CTAR_SLAVE_CPOL_MASK) +#define SPI_CTAR_SLAVE_FMSZ_MASK (0x78000000U) +#define SPI_CTAR_SLAVE_FMSZ_SHIFT (27U) +#define SPI_CTAR_SLAVE_FMSZ(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_SLAVE_FMSZ_SHIFT)) & SPI_CTAR_SLAVE_FMSZ_MASK) + +/* The count of SPI_CTAR_SLAVE */ +#define SPI_CTAR_SLAVE_COUNT (1U) + +/*! @name SR - Status Register */ +#define SPI_SR_POPNXTPTR_MASK (0xFU) +#define SPI_SR_POPNXTPTR_SHIFT (0U) +#define SPI_SR_POPNXTPTR(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_POPNXTPTR_SHIFT)) & SPI_SR_POPNXTPTR_MASK) +#define SPI_SR_RXCTR_MASK (0xF0U) +#define SPI_SR_RXCTR_SHIFT (4U) +#define SPI_SR_RXCTR(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_RXCTR_SHIFT)) & SPI_SR_RXCTR_MASK) +#define SPI_SR_TXNXTPTR_MASK (0xF00U) +#define SPI_SR_TXNXTPTR_SHIFT (8U) +#define SPI_SR_TXNXTPTR(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_TXNXTPTR_SHIFT)) & SPI_SR_TXNXTPTR_MASK) +#define SPI_SR_TXCTR_MASK (0xF000U) +#define SPI_SR_TXCTR_SHIFT (12U) +#define SPI_SR_TXCTR(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_TXCTR_SHIFT)) & SPI_SR_TXCTR_MASK) +#define SPI_SR_RFDF_MASK (0x20000U) +#define SPI_SR_RFDF_SHIFT (17U) +#define SPI_SR_RFDF(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_RFDF_SHIFT)) & SPI_SR_RFDF_MASK) +#define SPI_SR_RFOF_MASK (0x80000U) +#define SPI_SR_RFOF_SHIFT (19U) +#define SPI_SR_RFOF(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_RFOF_SHIFT)) & SPI_SR_RFOF_MASK) +#define SPI_SR_TFFF_MASK (0x2000000U) +#define SPI_SR_TFFF_SHIFT (25U) +#define SPI_SR_TFFF(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_TFFF_SHIFT)) & SPI_SR_TFFF_MASK) +#define SPI_SR_TFUF_MASK (0x8000000U) +#define SPI_SR_TFUF_SHIFT (27U) +#define SPI_SR_TFUF(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_TFUF_SHIFT)) & SPI_SR_TFUF_MASK) +#define SPI_SR_EOQF_MASK (0x10000000U) +#define SPI_SR_EOQF_SHIFT (28U) +#define SPI_SR_EOQF(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_EOQF_SHIFT)) & SPI_SR_EOQF_MASK) +#define SPI_SR_TXRXS_MASK (0x40000000U) +#define SPI_SR_TXRXS_SHIFT (30U) +#define SPI_SR_TXRXS(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_TXRXS_SHIFT)) & SPI_SR_TXRXS_MASK) +#define SPI_SR_TCF_MASK (0x80000000U) +#define SPI_SR_TCF_SHIFT (31U) +#define SPI_SR_TCF(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_TCF_SHIFT)) & SPI_SR_TCF_MASK) + +/*! @name RSER - DMA/Interrupt Request Select and Enable Register */ +#define SPI_RSER_RFDF_DIRS_MASK (0x10000U) +#define SPI_RSER_RFDF_DIRS_SHIFT (16U) +#define SPI_RSER_RFDF_DIRS(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_RFDF_DIRS_SHIFT)) & SPI_RSER_RFDF_DIRS_MASK) +#define SPI_RSER_RFDF_RE_MASK (0x20000U) +#define SPI_RSER_RFDF_RE_SHIFT (17U) +#define SPI_RSER_RFDF_RE(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_RFDF_RE_SHIFT)) & SPI_RSER_RFDF_RE_MASK) +#define SPI_RSER_RFOF_RE_MASK (0x80000U) +#define SPI_RSER_RFOF_RE_SHIFT (19U) +#define SPI_RSER_RFOF_RE(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_RFOF_RE_SHIFT)) & SPI_RSER_RFOF_RE_MASK) +#define SPI_RSER_TFFF_DIRS_MASK (0x1000000U) +#define SPI_RSER_TFFF_DIRS_SHIFT (24U) +#define SPI_RSER_TFFF_DIRS(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_TFFF_DIRS_SHIFT)) & SPI_RSER_TFFF_DIRS_MASK) +#define SPI_RSER_TFFF_RE_MASK (0x2000000U) +#define SPI_RSER_TFFF_RE_SHIFT (25U) +#define SPI_RSER_TFFF_RE(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_TFFF_RE_SHIFT)) & SPI_RSER_TFFF_RE_MASK) +#define SPI_RSER_TFUF_RE_MASK (0x8000000U) +#define SPI_RSER_TFUF_RE_SHIFT (27U) +#define SPI_RSER_TFUF_RE(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_TFUF_RE_SHIFT)) & SPI_RSER_TFUF_RE_MASK) +#define SPI_RSER_EOQF_RE_MASK (0x10000000U) +#define SPI_RSER_EOQF_RE_SHIFT (28U) +#define SPI_RSER_EOQF_RE(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_EOQF_RE_SHIFT)) & SPI_RSER_EOQF_RE_MASK) +#define SPI_RSER_TCF_RE_MASK (0x80000000U) +#define SPI_RSER_TCF_RE_SHIFT (31U) +#define SPI_RSER_TCF_RE(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_TCF_RE_SHIFT)) & SPI_RSER_TCF_RE_MASK) + +/*! @name PUSHR - PUSH TX FIFO Register In Master Mode */ +#define SPI_PUSHR_TXDATA_MASK (0xFFFFU) +#define SPI_PUSHR_TXDATA_SHIFT (0U) +#define SPI_PUSHR_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_TXDATA_SHIFT)) & SPI_PUSHR_TXDATA_MASK) +#define SPI_PUSHR_PCS_MASK (0x3F0000U) +#define SPI_PUSHR_PCS_SHIFT (16U) +#define SPI_PUSHR_PCS(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_PCS_SHIFT)) & SPI_PUSHR_PCS_MASK) +#define SPI_PUSHR_CTCNT_MASK (0x4000000U) +#define SPI_PUSHR_CTCNT_SHIFT (26U) +#define SPI_PUSHR_CTCNT(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_CTCNT_SHIFT)) & SPI_PUSHR_CTCNT_MASK) +#define SPI_PUSHR_EOQ_MASK (0x8000000U) +#define SPI_PUSHR_EOQ_SHIFT (27U) +#define SPI_PUSHR_EOQ(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_EOQ_SHIFT)) & SPI_PUSHR_EOQ_MASK) +#define SPI_PUSHR_CTAS_MASK (0x70000000U) +#define SPI_PUSHR_CTAS_SHIFT (28U) +#define SPI_PUSHR_CTAS(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_CTAS_SHIFT)) & SPI_PUSHR_CTAS_MASK) +#define SPI_PUSHR_CONT_MASK (0x80000000U) +#define SPI_PUSHR_CONT_SHIFT (31U) +#define SPI_PUSHR_CONT(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_CONT_SHIFT)) & SPI_PUSHR_CONT_MASK) + +/*! @name PUSHR_SLAVE - PUSH TX FIFO Register In Slave Mode */ +#define SPI_PUSHR_SLAVE_TXDATA_MASK (0xFFFFU) +#define SPI_PUSHR_SLAVE_TXDATA_SHIFT (0U) +#define SPI_PUSHR_SLAVE_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_SLAVE_TXDATA_SHIFT)) & SPI_PUSHR_SLAVE_TXDATA_MASK) + +/*! @name POPR - POP RX FIFO Register */ +#define SPI_POPR_RXDATA_MASK (0xFFFFFFFFU) +#define SPI_POPR_RXDATA_SHIFT (0U) +#define SPI_POPR_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_POPR_RXDATA_SHIFT)) & SPI_POPR_RXDATA_MASK) + +/*! @name TXFR0 - Transmit FIFO Registers */ +#define SPI_TXFR0_TXDATA_MASK (0xFFFFU) +#define SPI_TXFR0_TXDATA_SHIFT (0U) +#define SPI_TXFR0_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR0_TXDATA_SHIFT)) & SPI_TXFR0_TXDATA_MASK) +#define SPI_TXFR0_TXCMD_TXDATA_MASK (0xFFFF0000U) +#define SPI_TXFR0_TXCMD_TXDATA_SHIFT (16U) +#define SPI_TXFR0_TXCMD_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR0_TXCMD_TXDATA_SHIFT)) & SPI_TXFR0_TXCMD_TXDATA_MASK) + +/*! @name TXFR1 - Transmit FIFO Registers */ +#define SPI_TXFR1_TXDATA_MASK (0xFFFFU) +#define SPI_TXFR1_TXDATA_SHIFT (0U) +#define SPI_TXFR1_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR1_TXDATA_SHIFT)) & SPI_TXFR1_TXDATA_MASK) +#define SPI_TXFR1_TXCMD_TXDATA_MASK (0xFFFF0000U) +#define SPI_TXFR1_TXCMD_TXDATA_SHIFT (16U) +#define SPI_TXFR1_TXCMD_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR1_TXCMD_TXDATA_SHIFT)) & SPI_TXFR1_TXCMD_TXDATA_MASK) + +/*! @name TXFR2 - Transmit FIFO Registers */ +#define SPI_TXFR2_TXDATA_MASK (0xFFFFU) +#define SPI_TXFR2_TXDATA_SHIFT (0U) +#define SPI_TXFR2_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR2_TXDATA_SHIFT)) & SPI_TXFR2_TXDATA_MASK) +#define SPI_TXFR2_TXCMD_TXDATA_MASK (0xFFFF0000U) +#define SPI_TXFR2_TXCMD_TXDATA_SHIFT (16U) +#define SPI_TXFR2_TXCMD_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR2_TXCMD_TXDATA_SHIFT)) & SPI_TXFR2_TXCMD_TXDATA_MASK) + +/*! @name TXFR3 - Transmit FIFO Registers */ +#define SPI_TXFR3_TXDATA_MASK (0xFFFFU) +#define SPI_TXFR3_TXDATA_SHIFT (0U) +#define SPI_TXFR3_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR3_TXDATA_SHIFT)) & SPI_TXFR3_TXDATA_MASK) +#define SPI_TXFR3_TXCMD_TXDATA_MASK (0xFFFF0000U) +#define SPI_TXFR3_TXCMD_TXDATA_SHIFT (16U) +#define SPI_TXFR3_TXCMD_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR3_TXCMD_TXDATA_SHIFT)) & SPI_TXFR3_TXCMD_TXDATA_MASK) + +/*! @name RXFR0 - Receive FIFO Registers */ +#define SPI_RXFR0_RXDATA_MASK (0xFFFFFFFFU) +#define SPI_RXFR0_RXDATA_SHIFT (0U) +#define SPI_RXFR0_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXFR0_RXDATA_SHIFT)) & SPI_RXFR0_RXDATA_MASK) + +/*! @name RXFR1 - Receive FIFO Registers */ +#define SPI_RXFR1_RXDATA_MASK (0xFFFFFFFFU) +#define SPI_RXFR1_RXDATA_SHIFT (0U) +#define SPI_RXFR1_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXFR1_RXDATA_SHIFT)) & SPI_RXFR1_RXDATA_MASK) + +/*! @name RXFR2 - Receive FIFO Registers */ +#define SPI_RXFR2_RXDATA_MASK (0xFFFFFFFFU) +#define SPI_RXFR2_RXDATA_SHIFT (0U) +#define SPI_RXFR2_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXFR2_RXDATA_SHIFT)) & SPI_RXFR2_RXDATA_MASK) + +/*! @name RXFR3 - Receive FIFO Registers */ +#define SPI_RXFR3_RXDATA_MASK (0xFFFFFFFFU) +#define SPI_RXFR3_RXDATA_SHIFT (0U) +#define SPI_RXFR3_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXFR3_RXDATA_SHIFT)) & SPI_RXFR3_RXDATA_MASK) + + +/*! + * @} + */ /* end of group SPI_Register_Masks */ + + +/* SPI - Peripheral instance base addresses */ +/** Peripheral SPI0 base address */ +#define SPI0_BASE (0x4002C000u) +/** Peripheral SPI0 base pointer */ +#define SPI0 ((SPI_Type *)SPI0_BASE) +/** Peripheral SPI1 base address */ +#define SPI1_BASE (0x4002D000u) +/** Peripheral SPI1 base pointer */ +#define SPI1 ((SPI_Type *)SPI1_BASE) +/** Peripheral SPI2 base address */ +#define SPI2_BASE (0x400AC000u) +/** Peripheral SPI2 base pointer */ +#define SPI2 ((SPI_Type *)SPI2_BASE) +/** Array initializer of SPI peripheral base addresses */ +#define SPI_BASE_ADDRS { SPI0_BASE, SPI1_BASE, SPI2_BASE } +/** Array initializer of SPI peripheral base pointers */ +#define SPI_BASE_PTRS { SPI0, SPI1, SPI2 } +/** Interrupt vectors for the SPI peripheral type */ +#define SPI_IRQS { SPI0_IRQn, SPI1_IRQn, SPI2_IRQn } + +/*! + * @} + */ /* end of group SPI_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- TPM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup TPM_Peripheral_Access_Layer TPM Peripheral Access Layer + * @{ + */ + +/** TPM - Register Layout Typedef */ +typedef struct { + __IO uint32_t SC; /**< Status and Control, offset: 0x0 */ + __IO uint32_t CNT; /**< Counter, offset: 0x4 */ + __IO uint32_t MOD; /**< Modulo, offset: 0x8 */ + struct { /* offset: 0xC, array step: 0x8 */ + __IO uint32_t CnSC; /**< Channel (n) Status and Control, array offset: 0xC, array step: 0x8 */ + __IO uint32_t CnV; /**< Channel (n) Value, array offset: 0x10, array step: 0x8 */ + } CONTROLS[2]; + uint8_t RESERVED_0[52]; + __IO uint32_t STATUS; /**< Capture and Compare Status, offset: 0x50 */ + uint8_t RESERVED_1[16]; + __IO uint32_t COMBINE; /**< Combine Channel Register, offset: 0x64 */ + uint8_t RESERVED_2[8]; + __IO uint32_t POL; /**< Channel Polarity, offset: 0x70 */ + uint8_t RESERVED_3[4]; + __IO uint32_t FILTER; /**< Filter Control, offset: 0x78 */ + uint8_t RESERVED_4[4]; + __IO uint32_t QDCTRL; /**< Quadrature Decoder Control and Status, offset: 0x80 */ + __IO uint32_t CONF; /**< Configuration, offset: 0x84 */ +} TPM_Type; + +/* ---------------------------------------------------------------------------- + -- TPM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup TPM_Register_Masks TPM Register Masks + * @{ + */ + +/*! @name SC - Status and Control */ +#define TPM_SC_PS_MASK (0x7U) +#define TPM_SC_PS_SHIFT (0U) +#define TPM_SC_PS(x) (((uint32_t)(((uint32_t)(x)) << TPM_SC_PS_SHIFT)) & TPM_SC_PS_MASK) +#define TPM_SC_CMOD_MASK (0x18U) +#define TPM_SC_CMOD_SHIFT (3U) +#define TPM_SC_CMOD(x) (((uint32_t)(((uint32_t)(x)) << TPM_SC_CMOD_SHIFT)) & TPM_SC_CMOD_MASK) +#define TPM_SC_CPWMS_MASK (0x20U) +#define TPM_SC_CPWMS_SHIFT (5U) +#define TPM_SC_CPWMS(x) (((uint32_t)(((uint32_t)(x)) << TPM_SC_CPWMS_SHIFT)) & TPM_SC_CPWMS_MASK) +#define TPM_SC_TOIE_MASK (0x40U) +#define TPM_SC_TOIE_SHIFT (6U) +#define TPM_SC_TOIE(x) (((uint32_t)(((uint32_t)(x)) << TPM_SC_TOIE_SHIFT)) & TPM_SC_TOIE_MASK) +#define TPM_SC_TOF_MASK (0x80U) +#define TPM_SC_TOF_SHIFT (7U) +#define TPM_SC_TOF(x) (((uint32_t)(((uint32_t)(x)) << TPM_SC_TOF_SHIFT)) & TPM_SC_TOF_MASK) +#define TPM_SC_DMA_MASK (0x100U) +#define TPM_SC_DMA_SHIFT (8U) +#define TPM_SC_DMA(x) (((uint32_t)(((uint32_t)(x)) << TPM_SC_DMA_SHIFT)) & TPM_SC_DMA_MASK) + +/*! @name CNT - Counter */ +#define TPM_CNT_COUNT_MASK (0xFFFFU) +#define TPM_CNT_COUNT_SHIFT (0U) +#define TPM_CNT_COUNT(x) (((uint32_t)(((uint32_t)(x)) << TPM_CNT_COUNT_SHIFT)) & TPM_CNT_COUNT_MASK) + +/*! @name MOD - Modulo */ +#define TPM_MOD_MOD_MASK (0xFFFFU) +#define TPM_MOD_MOD_SHIFT (0U) +#define TPM_MOD_MOD(x) (((uint32_t)(((uint32_t)(x)) << TPM_MOD_MOD_SHIFT)) & TPM_MOD_MOD_MASK) + +/*! @name CnSC - Channel (n) Status and Control */ +#define TPM_CnSC_DMA_MASK (0x1U) +#define TPM_CnSC_DMA_SHIFT (0U) +#define TPM_CnSC_DMA(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_DMA_SHIFT)) & TPM_CnSC_DMA_MASK) +#define TPM_CnSC_ELSA_MASK (0x4U) +#define TPM_CnSC_ELSA_SHIFT (2U) +#define TPM_CnSC_ELSA(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_ELSA_SHIFT)) & TPM_CnSC_ELSA_MASK) +#define TPM_CnSC_ELSB_MASK (0x8U) +#define TPM_CnSC_ELSB_SHIFT (3U) +#define TPM_CnSC_ELSB(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_ELSB_SHIFT)) & TPM_CnSC_ELSB_MASK) +#define TPM_CnSC_MSA_MASK (0x10U) +#define TPM_CnSC_MSA_SHIFT (4U) +#define TPM_CnSC_MSA(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_MSA_SHIFT)) & TPM_CnSC_MSA_MASK) +#define TPM_CnSC_MSB_MASK (0x20U) +#define TPM_CnSC_MSB_SHIFT (5U) +#define TPM_CnSC_MSB(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_MSB_SHIFT)) & TPM_CnSC_MSB_MASK) +#define TPM_CnSC_CHIE_MASK (0x40U) +#define TPM_CnSC_CHIE_SHIFT (6U) +#define TPM_CnSC_CHIE(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_CHIE_SHIFT)) & TPM_CnSC_CHIE_MASK) +#define TPM_CnSC_CHF_MASK (0x80U) +#define TPM_CnSC_CHF_SHIFT (7U) +#define TPM_CnSC_CHF(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_CHF_SHIFT)) & TPM_CnSC_CHF_MASK) + +/* The count of TPM_CnSC */ +#define TPM_CnSC_COUNT (2U) + +/*! @name CnV - Channel (n) Value */ +#define TPM_CnV_VAL_MASK (0xFFFFU) +#define TPM_CnV_VAL_SHIFT (0U) +#define TPM_CnV_VAL(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnV_VAL_SHIFT)) & TPM_CnV_VAL_MASK) + +/* The count of TPM_CnV */ +#define TPM_CnV_COUNT (2U) + +/*! @name STATUS - Capture and Compare Status */ +#define TPM_STATUS_CH0F_MASK (0x1U) +#define TPM_STATUS_CH0F_SHIFT (0U) +#define TPM_STATUS_CH0F(x) (((uint32_t)(((uint32_t)(x)) << TPM_STATUS_CH0F_SHIFT)) & TPM_STATUS_CH0F_MASK) +#define TPM_STATUS_CH1F_MASK (0x2U) +#define TPM_STATUS_CH1F_SHIFT (1U) +#define TPM_STATUS_CH1F(x) (((uint32_t)(((uint32_t)(x)) << TPM_STATUS_CH1F_SHIFT)) & TPM_STATUS_CH1F_MASK) +#define TPM_STATUS_TOF_MASK (0x100U) +#define TPM_STATUS_TOF_SHIFT (8U) +#define TPM_STATUS_TOF(x) (((uint32_t)(((uint32_t)(x)) << TPM_STATUS_TOF_SHIFT)) & TPM_STATUS_TOF_MASK) + +/*! @name COMBINE - Combine Channel Register */ +#define TPM_COMBINE_COMBINE0_MASK (0x1U) +#define TPM_COMBINE_COMBINE0_SHIFT (0U) +#define TPM_COMBINE_COMBINE0(x) (((uint32_t)(((uint32_t)(x)) << TPM_COMBINE_COMBINE0_SHIFT)) & TPM_COMBINE_COMBINE0_MASK) +#define TPM_COMBINE_COMSWAP0_MASK (0x2U) +#define TPM_COMBINE_COMSWAP0_SHIFT (1U) +#define TPM_COMBINE_COMSWAP0(x) (((uint32_t)(((uint32_t)(x)) << TPM_COMBINE_COMSWAP0_SHIFT)) & TPM_COMBINE_COMSWAP0_MASK) + +/*! @name POL - Channel Polarity */ +#define TPM_POL_POL0_MASK (0x1U) +#define TPM_POL_POL0_SHIFT (0U) +#define TPM_POL_POL0(x) (((uint32_t)(((uint32_t)(x)) << TPM_POL_POL0_SHIFT)) & TPM_POL_POL0_MASK) +#define TPM_POL_POL1_MASK (0x2U) +#define TPM_POL_POL1_SHIFT (1U) +#define TPM_POL_POL1(x) (((uint32_t)(((uint32_t)(x)) << TPM_POL_POL1_SHIFT)) & TPM_POL_POL1_MASK) + +/*! @name FILTER - Filter Control */ +#define TPM_FILTER_CH0FVAL_MASK (0xFU) +#define TPM_FILTER_CH0FVAL_SHIFT (0U) +#define TPM_FILTER_CH0FVAL(x) (((uint32_t)(((uint32_t)(x)) << TPM_FILTER_CH0FVAL_SHIFT)) & TPM_FILTER_CH0FVAL_MASK) +#define TPM_FILTER_CH1FVAL_MASK (0xF0U) +#define TPM_FILTER_CH1FVAL_SHIFT (4U) +#define TPM_FILTER_CH1FVAL(x) (((uint32_t)(((uint32_t)(x)) << TPM_FILTER_CH1FVAL_SHIFT)) & TPM_FILTER_CH1FVAL_MASK) + +/*! @name QDCTRL - Quadrature Decoder Control and Status */ +#define TPM_QDCTRL_QUADEN_MASK (0x1U) +#define TPM_QDCTRL_QUADEN_SHIFT (0U) +#define TPM_QDCTRL_QUADEN(x) (((uint32_t)(((uint32_t)(x)) << TPM_QDCTRL_QUADEN_SHIFT)) & TPM_QDCTRL_QUADEN_MASK) +#define TPM_QDCTRL_TOFDIR_MASK (0x2U) +#define TPM_QDCTRL_TOFDIR_SHIFT (1U) +#define TPM_QDCTRL_TOFDIR(x) (((uint32_t)(((uint32_t)(x)) << TPM_QDCTRL_TOFDIR_SHIFT)) & TPM_QDCTRL_TOFDIR_MASK) +#define TPM_QDCTRL_QUADIR_MASK (0x4U) +#define TPM_QDCTRL_QUADIR_SHIFT (2U) +#define TPM_QDCTRL_QUADIR(x) (((uint32_t)(((uint32_t)(x)) << TPM_QDCTRL_QUADIR_SHIFT)) & TPM_QDCTRL_QUADIR_MASK) +#define TPM_QDCTRL_QUADMODE_MASK (0x8U) +#define TPM_QDCTRL_QUADMODE_SHIFT (3U) +#define TPM_QDCTRL_QUADMODE(x) (((uint32_t)(((uint32_t)(x)) << TPM_QDCTRL_QUADMODE_SHIFT)) & TPM_QDCTRL_QUADMODE_MASK) + +/*! @name CONF - Configuration */ +#define TPM_CONF_DOZEEN_MASK (0x20U) +#define TPM_CONF_DOZEEN_SHIFT (5U) +#define TPM_CONF_DOZEEN(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_DOZEEN_SHIFT)) & TPM_CONF_DOZEEN_MASK) +#define TPM_CONF_DBGMODE_MASK (0xC0U) +#define TPM_CONF_DBGMODE_SHIFT (6U) +#define TPM_CONF_DBGMODE(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_DBGMODE_SHIFT)) & TPM_CONF_DBGMODE_MASK) +#define TPM_CONF_GTBSYNC_MASK (0x100U) +#define TPM_CONF_GTBSYNC_SHIFT (8U) +#define TPM_CONF_GTBSYNC(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_GTBSYNC_SHIFT)) & TPM_CONF_GTBSYNC_MASK) +#define TPM_CONF_GTBEEN_MASK (0x200U) +#define TPM_CONF_GTBEEN_SHIFT (9U) +#define TPM_CONF_GTBEEN(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_GTBEEN_SHIFT)) & TPM_CONF_GTBEEN_MASK) +#define TPM_CONF_CSOT_MASK (0x10000U) +#define TPM_CONF_CSOT_SHIFT (16U) +#define TPM_CONF_CSOT(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_CSOT_SHIFT)) & TPM_CONF_CSOT_MASK) +#define TPM_CONF_CSOO_MASK (0x20000U) +#define TPM_CONF_CSOO_SHIFT (17U) +#define TPM_CONF_CSOO(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_CSOO_SHIFT)) & TPM_CONF_CSOO_MASK) +#define TPM_CONF_CROT_MASK (0x40000U) +#define TPM_CONF_CROT_SHIFT (18U) +#define TPM_CONF_CROT(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_CROT_SHIFT)) & TPM_CONF_CROT_MASK) +#define TPM_CONF_CPOT_MASK (0x80000U) +#define TPM_CONF_CPOT_SHIFT (19U) +#define TPM_CONF_CPOT(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_CPOT_SHIFT)) & TPM_CONF_CPOT_MASK) +#define TPM_CONF_TRGPOL_MASK (0x400000U) +#define TPM_CONF_TRGPOL_SHIFT (22U) +#define TPM_CONF_TRGPOL(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_TRGPOL_SHIFT)) & TPM_CONF_TRGPOL_MASK) +#define TPM_CONF_TRGSRC_MASK (0x800000U) +#define TPM_CONF_TRGSRC_SHIFT (23U) +#define TPM_CONF_TRGSRC(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_TRGSRC_SHIFT)) & TPM_CONF_TRGSRC_MASK) +#define TPM_CONF_TRGSEL_MASK (0xF000000U) +#define TPM_CONF_TRGSEL_SHIFT (24U) +#define TPM_CONF_TRGSEL(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_TRGSEL_SHIFT)) & TPM_CONF_TRGSEL_MASK) + + +/*! + * @} + */ /* end of group TPM_Register_Masks */ + + +/* TPM - Peripheral instance base addresses */ +/** Peripheral TPM1 base address */ +#define TPM1_BASE (0x400C9000u) +/** Peripheral TPM1 base pointer */ +#define TPM1 ((TPM_Type *)TPM1_BASE) +/** Peripheral TPM2 base address */ +#define TPM2_BASE (0x400CA000u) +/** Peripheral TPM2 base pointer */ +#define TPM2 ((TPM_Type *)TPM2_BASE) +/** Array initializer of TPM peripheral base addresses */ +#define TPM_BASE_ADDRS { 0u, TPM1_BASE, TPM2_BASE } +/** Array initializer of TPM peripheral base pointers */ +#define TPM_BASE_PTRS { (TPM_Type *)0u, TPM1, TPM2 } +/** Interrupt vectors for the TPM peripheral type */ +#define TPM_IRQS { NotAvail_IRQn, TPM1_IRQn, TPM2_IRQn } + +/*! + * @} + */ /* end of group TPM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- TRNG Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup TRNG_Peripheral_Access_Layer TRNG Peripheral Access Layer + * @{ + */ + +/** TRNG - Register Layout Typedef */ +typedef struct { + __IO uint32_t MCTL; /**< RNG Miscellaneous Control Register, offset: 0x0 */ + __IO uint32_t SCMISC; /**< RNG Statistical Check Miscellaneous Register, offset: 0x4 */ + __IO uint32_t PKRRNG; /**< RNG Poker Range Register, offset: 0x8 */ + union { /* offset: 0xC */ + __IO uint32_t PKRMAX; /**< RNG Poker Maximum Limit Register, offset: 0xC */ + __I uint32_t PKRSQ; /**< RNG Poker Square Calculation Result Register, offset: 0xC */ + }; + __IO uint32_t SDCTL; /**< RNG Seed Control Register, offset: 0x10 */ + union { /* offset: 0x14 */ + __IO uint32_t SBLIM; /**< RNG Sparse Bit Limit Register, offset: 0x14 */ + __I uint32_t TOTSAM; /**< RNG Total Samples Register, offset: 0x14 */ + }; + __IO uint32_t FRQMIN; /**< RNG Frequency Count Minimum Limit Register, offset: 0x18 */ + union { /* offset: 0x1C */ + __I uint32_t FRQCNT; /**< RNG Frequency Count Register, offset: 0x1C */ + __IO uint32_t FRQMAX; /**< RNG Frequency Count Maximum Limit Register, offset: 0x1C */ + }; + union { /* offset: 0x20 */ + __I uint32_t SCMC; /**< RNG Statistical Check Monobit Count Register, offset: 0x20 */ + __IO uint32_t SCML; /**< RNG Statistical Check Monobit Limit Register, offset: 0x20 */ + }; + union { /* offset: 0x24 */ + __I uint32_t SCR1C; /**< RNG Statistical Check Run Length 1 Count Register, offset: 0x24 */ + __IO uint32_t SCR1L; /**< RNG Statistical Check Run Length 1 Limit Register, offset: 0x24 */ + }; + union { /* offset: 0x28 */ + __I uint32_t SCR2C; /**< RNG Statistical Check Run Length 2 Count Register, offset: 0x28 */ + __IO uint32_t SCR2L; /**< RNG Statistical Check Run Length 2 Limit Register, offset: 0x28 */ + }; + union { /* offset: 0x2C */ + __I uint32_t SCR3C; /**< RNG Statistical Check Run Length 3 Count Register, offset: 0x2C */ + __IO uint32_t SCR3L; /**< RNG Statistical Check Run Length 3 Limit Register, offset: 0x2C */ + }; + union { /* offset: 0x30 */ + __I uint32_t SCR4C; /**< RNG Statistical Check Run Length 4 Count Register, offset: 0x30 */ + __IO uint32_t SCR4L; /**< RNG Statistical Check Run Length 4 Limit Register, offset: 0x30 */ + }; + union { /* offset: 0x34 */ + __I uint32_t SCR5C; /**< RNG Statistical Check Run Length 5 Count Register, offset: 0x34 */ + __IO uint32_t SCR5L; /**< RNG Statistical Check Run Length 5 Limit Register, offset: 0x34 */ + }; + union { /* offset: 0x38 */ + __I uint32_t SCR6PC; /**< RNG Statistical Check Run Length 6+ Count Register, offset: 0x38 */ + __IO uint32_t SCR6PL; /**< RNG Statistical Check Run Length 6+ Limit Register, offset: 0x38 */ + }; + __I uint32_t STATUS; /**< RNG Status Register, offset: 0x3C */ + __I uint32_t ENT[16]; /**< RNG TRNG Entropy Read Register, array offset: 0x40, array step: 0x4 */ + __I uint32_t PKRCNT10; /**< RNG Statistical Check Poker Count 1 and 0 Register, offset: 0x80 */ + __I uint32_t PKRCNT32; /**< RNG Statistical Check Poker Count 3 and 2 Register, offset: 0x84 */ + __I uint32_t PKRCNT54; /**< RNG Statistical Check Poker Count 5 and 4 Register, offset: 0x88 */ + __I uint32_t PKRCNT76; /**< RNG Statistical Check Poker Count 7 and 6 Register, offset: 0x8C */ + __I uint32_t PKRCNT98; /**< RNG Statistical Check Poker Count 9 and 8 Register, offset: 0x90 */ + __I uint32_t PKRCNTBA; /**< RNG Statistical Check Poker Count B and A Register, offset: 0x94 */ + __I uint32_t PKRCNTDC; /**< RNG Statistical Check Poker Count D and C Register, offset: 0x98 */ + __I uint32_t PKRCNTFE; /**< RNG Statistical Check Poker Count F and E Register, offset: 0x9C */ + uint8_t RESERVED_0[16]; + __IO uint32_t SEC_CFG; /**< RNG Security Configuration Register, offset: 0xB0 */ + __IO uint32_t INT_CTRL; /**< RNG Interrupt Control Register, offset: 0xB4 */ + __IO uint32_t INT_MASK; /**< RNG Mask Register, offset: 0xB8 */ + __IO uint32_t INT_STATUS; /**< RNG Interrupt Status Register, offset: 0xBC */ + uint8_t RESERVED_1[48]; + __I uint32_t VID1; /**< RNG Version ID Register (MS), offset: 0xF0 */ + __I uint32_t VID2; /**< RNG Version ID Register (LS), offset: 0xF4 */ +} TRNG_Type; + +/* ---------------------------------------------------------------------------- + -- TRNG Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup TRNG_Register_Masks TRNG Register Masks + * @{ + */ + +/*! @name MCTL - RNG Miscellaneous Control Register */ +#define TRNG_MCTL_SAMP_MODE_MASK (0x3U) +#define TRNG_MCTL_SAMP_MODE_SHIFT (0U) +#define TRNG_MCTL_SAMP_MODE(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_SAMP_MODE_SHIFT)) & TRNG_MCTL_SAMP_MODE_MASK) +#define TRNG_MCTL_OSC_DIV_MASK (0xCU) +#define TRNG_MCTL_OSC_DIV_SHIFT (2U) +#define TRNG_MCTL_OSC_DIV(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_OSC_DIV_SHIFT)) & TRNG_MCTL_OSC_DIV_MASK) +#define TRNG_MCTL_UNUSED_MASK (0x10U) +#define TRNG_MCTL_UNUSED_SHIFT (4U) +#define TRNG_MCTL_UNUSED(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_UNUSED_SHIFT)) & TRNG_MCTL_UNUSED_MASK) +#define TRNG_MCTL_TRNG_ACC_MASK (0x20U) +#define TRNG_MCTL_TRNG_ACC_SHIFT (5U) +#define TRNG_MCTL_TRNG_ACC(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_TRNG_ACC_SHIFT)) & TRNG_MCTL_TRNG_ACC_MASK) +#define TRNG_MCTL_RST_DEF_MASK (0x40U) +#define TRNG_MCTL_RST_DEF_SHIFT (6U) +#define TRNG_MCTL_RST_DEF(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_RST_DEF_SHIFT)) & TRNG_MCTL_RST_DEF_MASK) +#define TRNG_MCTL_FOR_SCLK_MASK (0x80U) +#define TRNG_MCTL_FOR_SCLK_SHIFT (7U) +#define TRNG_MCTL_FOR_SCLK(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_FOR_SCLK_SHIFT)) & TRNG_MCTL_FOR_SCLK_MASK) +#define TRNG_MCTL_FCT_FAIL_MASK (0x100U) +#define TRNG_MCTL_FCT_FAIL_SHIFT (8U) +#define TRNG_MCTL_FCT_FAIL(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_FCT_FAIL_SHIFT)) & TRNG_MCTL_FCT_FAIL_MASK) +#define TRNG_MCTL_FCT_VAL_MASK (0x200U) +#define TRNG_MCTL_FCT_VAL_SHIFT (9U) +#define TRNG_MCTL_FCT_VAL(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_FCT_VAL_SHIFT)) & TRNG_MCTL_FCT_VAL_MASK) +#define TRNG_MCTL_ENT_VAL_MASK (0x400U) +#define TRNG_MCTL_ENT_VAL_SHIFT (10U) +#define TRNG_MCTL_ENT_VAL(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_ENT_VAL_SHIFT)) & TRNG_MCTL_ENT_VAL_MASK) +#define TRNG_MCTL_TST_OUT_MASK (0x800U) +#define TRNG_MCTL_TST_OUT_SHIFT (11U) +#define TRNG_MCTL_TST_OUT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_TST_OUT_SHIFT)) & TRNG_MCTL_TST_OUT_MASK) +#define TRNG_MCTL_ERR_MASK (0x1000U) +#define TRNG_MCTL_ERR_SHIFT (12U) +#define TRNG_MCTL_ERR(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_ERR_SHIFT)) & TRNG_MCTL_ERR_MASK) +#define TRNG_MCTL_TSTOP_OK_MASK (0x2000U) +#define TRNG_MCTL_TSTOP_OK_SHIFT (13U) +#define TRNG_MCTL_TSTOP_OK(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_TSTOP_OK_SHIFT)) & TRNG_MCTL_TSTOP_OK_MASK) +#define TRNG_MCTL_PRGM_MASK (0x10000U) +#define TRNG_MCTL_PRGM_SHIFT (16U) +#define TRNG_MCTL_PRGM(x) (((uint32_t)(((uint32_t)(x)) << TRNG_MCTL_PRGM_SHIFT)) & TRNG_MCTL_PRGM_MASK) + +/*! @name SCMISC - RNG Statistical Check Miscellaneous Register */ +#define TRNG_SCMISC_LRUN_MAX_MASK (0xFFU) +#define TRNG_SCMISC_LRUN_MAX_SHIFT (0U) +#define TRNG_SCMISC_LRUN_MAX(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCMISC_LRUN_MAX_SHIFT)) & TRNG_SCMISC_LRUN_MAX_MASK) +#define TRNG_SCMISC_RTY_CT_MASK (0xF0000U) +#define TRNG_SCMISC_RTY_CT_SHIFT (16U) +#define TRNG_SCMISC_RTY_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCMISC_RTY_CT_SHIFT)) & TRNG_SCMISC_RTY_CT_MASK) + +/*! @name PKRRNG - RNG Poker Range Register */ +#define TRNG_PKRRNG_PKR_RNG_MASK (0xFFFFU) +#define TRNG_PKRRNG_PKR_RNG_SHIFT (0U) +#define TRNG_PKRRNG_PKR_RNG(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRRNG_PKR_RNG_SHIFT)) & TRNG_PKRRNG_PKR_RNG_MASK) + +/*! @name PKRMAX - RNG Poker Maximum Limit Register */ +#define TRNG_PKRMAX_PKR_MAX_MASK (0xFFFFFFU) +#define TRNG_PKRMAX_PKR_MAX_SHIFT (0U) +#define TRNG_PKRMAX_PKR_MAX(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRMAX_PKR_MAX_SHIFT)) & TRNG_PKRMAX_PKR_MAX_MASK) + +/*! @name PKRSQ - RNG Poker Square Calculation Result Register */ +#define TRNG_PKRSQ_PKR_SQ_MASK (0xFFFFFFU) +#define TRNG_PKRSQ_PKR_SQ_SHIFT (0U) +#define TRNG_PKRSQ_PKR_SQ(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRSQ_PKR_SQ_SHIFT)) & TRNG_PKRSQ_PKR_SQ_MASK) + +/*! @name SDCTL - RNG Seed Control Register */ +#define TRNG_SDCTL_SAMP_SIZE_MASK (0xFFFFU) +#define TRNG_SDCTL_SAMP_SIZE_SHIFT (0U) +#define TRNG_SDCTL_SAMP_SIZE(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SDCTL_SAMP_SIZE_SHIFT)) & TRNG_SDCTL_SAMP_SIZE_MASK) +#define TRNG_SDCTL_ENT_DLY_MASK (0xFFFF0000U) +#define TRNG_SDCTL_ENT_DLY_SHIFT (16U) +#define TRNG_SDCTL_ENT_DLY(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SDCTL_ENT_DLY_SHIFT)) & TRNG_SDCTL_ENT_DLY_MASK) + +/*! @name SBLIM - RNG Sparse Bit Limit Register */ +#define TRNG_SBLIM_SB_LIM_MASK (0x3FFU) +#define TRNG_SBLIM_SB_LIM_SHIFT (0U) +#define TRNG_SBLIM_SB_LIM(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SBLIM_SB_LIM_SHIFT)) & TRNG_SBLIM_SB_LIM_MASK) + +/*! @name TOTSAM - RNG Total Samples Register */ +#define TRNG_TOTSAM_TOT_SAM_MASK (0xFFFFFU) +#define TRNG_TOTSAM_TOT_SAM_SHIFT (0U) +#define TRNG_TOTSAM_TOT_SAM(x) (((uint32_t)(((uint32_t)(x)) << TRNG_TOTSAM_TOT_SAM_SHIFT)) & TRNG_TOTSAM_TOT_SAM_MASK) + +/*! @name FRQMIN - RNG Frequency Count Minimum Limit Register */ +#define TRNG_FRQMIN_FRQ_MIN_MASK (0x3FFFFFU) +#define TRNG_FRQMIN_FRQ_MIN_SHIFT (0U) +#define TRNG_FRQMIN_FRQ_MIN(x) (((uint32_t)(((uint32_t)(x)) << TRNG_FRQMIN_FRQ_MIN_SHIFT)) & TRNG_FRQMIN_FRQ_MIN_MASK) + +/*! @name FRQCNT - RNG Frequency Count Register */ +#define TRNG_FRQCNT_FRQ_CT_MASK (0x3FFFFFU) +#define TRNG_FRQCNT_FRQ_CT_SHIFT (0U) +#define TRNG_FRQCNT_FRQ_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_FRQCNT_FRQ_CT_SHIFT)) & TRNG_FRQCNT_FRQ_CT_MASK) + +/*! @name FRQMAX - RNG Frequency Count Maximum Limit Register */ +#define TRNG_FRQMAX_FRQ_MAX_MASK (0x3FFFFFU) +#define TRNG_FRQMAX_FRQ_MAX_SHIFT (0U) +#define TRNG_FRQMAX_FRQ_MAX(x) (((uint32_t)(((uint32_t)(x)) << TRNG_FRQMAX_FRQ_MAX_SHIFT)) & TRNG_FRQMAX_FRQ_MAX_MASK) + +/*! @name SCMC - RNG Statistical Check Monobit Count Register */ +#define TRNG_SCMC_MONO_CT_MASK (0xFFFFU) +#define TRNG_SCMC_MONO_CT_SHIFT (0U) +#define TRNG_SCMC_MONO_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCMC_MONO_CT_SHIFT)) & TRNG_SCMC_MONO_CT_MASK) + +/*! @name SCML - RNG Statistical Check Monobit Limit Register */ +#define TRNG_SCML_MONO_MAX_MASK (0xFFFFU) +#define TRNG_SCML_MONO_MAX_SHIFT (0U) +#define TRNG_SCML_MONO_MAX(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCML_MONO_MAX_SHIFT)) & TRNG_SCML_MONO_MAX_MASK) +#define TRNG_SCML_MONO_RNG_MASK (0xFFFF0000U) +#define TRNG_SCML_MONO_RNG_SHIFT (16U) +#define TRNG_SCML_MONO_RNG(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCML_MONO_RNG_SHIFT)) & TRNG_SCML_MONO_RNG_MASK) + +/*! @name SCR1C - RNG Statistical Check Run Length 1 Count Register */ +#define TRNG_SCR1C_R1_0_CT_MASK (0x7FFFU) +#define TRNG_SCR1C_R1_0_CT_SHIFT (0U) +#define TRNG_SCR1C_R1_0_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR1C_R1_0_CT_SHIFT)) & TRNG_SCR1C_R1_0_CT_MASK) +#define TRNG_SCR1C_R1_1_CT_MASK (0x7FFF0000U) +#define TRNG_SCR1C_R1_1_CT_SHIFT (16U) +#define TRNG_SCR1C_R1_1_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR1C_R1_1_CT_SHIFT)) & TRNG_SCR1C_R1_1_CT_MASK) + +/*! @name SCR1L - RNG Statistical Check Run Length 1 Limit Register */ +#define TRNG_SCR1L_RUN1_MAX_MASK (0x7FFFU) +#define TRNG_SCR1L_RUN1_MAX_SHIFT (0U) +#define TRNG_SCR1L_RUN1_MAX(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR1L_RUN1_MAX_SHIFT)) & TRNG_SCR1L_RUN1_MAX_MASK) +#define TRNG_SCR1L_RUN1_RNG_MASK (0x7FFF0000U) +#define TRNG_SCR1L_RUN1_RNG_SHIFT (16U) +#define TRNG_SCR1L_RUN1_RNG(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR1L_RUN1_RNG_SHIFT)) & TRNG_SCR1L_RUN1_RNG_MASK) + +/*! @name SCR2C - RNG Statistical Check Run Length 2 Count Register */ +#define TRNG_SCR2C_R2_0_CT_MASK (0x3FFFU) +#define TRNG_SCR2C_R2_0_CT_SHIFT (0U) +#define TRNG_SCR2C_R2_0_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR2C_R2_0_CT_SHIFT)) & TRNG_SCR2C_R2_0_CT_MASK) +#define TRNG_SCR2C_R2_1_CT_MASK (0x3FFF0000U) +#define TRNG_SCR2C_R2_1_CT_SHIFT (16U) +#define TRNG_SCR2C_R2_1_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR2C_R2_1_CT_SHIFT)) & TRNG_SCR2C_R2_1_CT_MASK) + +/*! @name SCR2L - RNG Statistical Check Run Length 2 Limit Register */ +#define TRNG_SCR2L_RUN2_MAX_MASK (0x3FFFU) +#define TRNG_SCR2L_RUN2_MAX_SHIFT (0U) +#define TRNG_SCR2L_RUN2_MAX(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR2L_RUN2_MAX_SHIFT)) & TRNG_SCR2L_RUN2_MAX_MASK) +#define TRNG_SCR2L_RUN2_RNG_MASK (0x3FFF0000U) +#define TRNG_SCR2L_RUN2_RNG_SHIFT (16U) +#define TRNG_SCR2L_RUN2_RNG(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR2L_RUN2_RNG_SHIFT)) & TRNG_SCR2L_RUN2_RNG_MASK) + +/*! @name SCR3C - RNG Statistical Check Run Length 3 Count Register */ +#define TRNG_SCR3C_R3_0_CT_MASK (0x1FFFU) +#define TRNG_SCR3C_R3_0_CT_SHIFT (0U) +#define TRNG_SCR3C_R3_0_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR3C_R3_0_CT_SHIFT)) & TRNG_SCR3C_R3_0_CT_MASK) +#define TRNG_SCR3C_R3_1_CT_MASK (0x1FFF0000U) +#define TRNG_SCR3C_R3_1_CT_SHIFT (16U) +#define TRNG_SCR3C_R3_1_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR3C_R3_1_CT_SHIFT)) & TRNG_SCR3C_R3_1_CT_MASK) + +/*! @name SCR3L - RNG Statistical Check Run Length 3 Limit Register */ +#define TRNG_SCR3L_RUN3_MAX_MASK (0x1FFFU) +#define TRNG_SCR3L_RUN3_MAX_SHIFT (0U) +#define TRNG_SCR3L_RUN3_MAX(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR3L_RUN3_MAX_SHIFT)) & TRNG_SCR3L_RUN3_MAX_MASK) +#define TRNG_SCR3L_RUN3_RNG_MASK (0x1FFF0000U) +#define TRNG_SCR3L_RUN3_RNG_SHIFT (16U) +#define TRNG_SCR3L_RUN3_RNG(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR3L_RUN3_RNG_SHIFT)) & TRNG_SCR3L_RUN3_RNG_MASK) + +/*! @name SCR4C - RNG Statistical Check Run Length 4 Count Register */ +#define TRNG_SCR4C_R4_0_CT_MASK (0xFFFU) +#define TRNG_SCR4C_R4_0_CT_SHIFT (0U) +#define TRNG_SCR4C_R4_0_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR4C_R4_0_CT_SHIFT)) & TRNG_SCR4C_R4_0_CT_MASK) +#define TRNG_SCR4C_R4_1_CT_MASK (0xFFF0000U) +#define TRNG_SCR4C_R4_1_CT_SHIFT (16U) +#define TRNG_SCR4C_R4_1_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR4C_R4_1_CT_SHIFT)) & TRNG_SCR4C_R4_1_CT_MASK) + +/*! @name SCR4L - RNG Statistical Check Run Length 4 Limit Register */ +#define TRNG_SCR4L_RUN4_MAX_MASK (0xFFFU) +#define TRNG_SCR4L_RUN4_MAX_SHIFT (0U) +#define TRNG_SCR4L_RUN4_MAX(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR4L_RUN4_MAX_SHIFT)) & TRNG_SCR4L_RUN4_MAX_MASK) +#define TRNG_SCR4L_RUN4_RNG_MASK (0xFFF0000U) +#define TRNG_SCR4L_RUN4_RNG_SHIFT (16U) +#define TRNG_SCR4L_RUN4_RNG(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR4L_RUN4_RNG_SHIFT)) & TRNG_SCR4L_RUN4_RNG_MASK) + +/*! @name SCR5C - RNG Statistical Check Run Length 5 Count Register */ +#define TRNG_SCR5C_R5_0_CT_MASK (0x7FFU) +#define TRNG_SCR5C_R5_0_CT_SHIFT (0U) +#define TRNG_SCR5C_R5_0_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR5C_R5_0_CT_SHIFT)) & TRNG_SCR5C_R5_0_CT_MASK) +#define TRNG_SCR5C_R5_1_CT_MASK (0x7FF0000U) +#define TRNG_SCR5C_R5_1_CT_SHIFT (16U) +#define TRNG_SCR5C_R5_1_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR5C_R5_1_CT_SHIFT)) & TRNG_SCR5C_R5_1_CT_MASK) + +/*! @name SCR5L - RNG Statistical Check Run Length 5 Limit Register */ +#define TRNG_SCR5L_RUN5_MAX_MASK (0x7FFU) +#define TRNG_SCR5L_RUN5_MAX_SHIFT (0U) +#define TRNG_SCR5L_RUN5_MAX(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR5L_RUN5_MAX_SHIFT)) & TRNG_SCR5L_RUN5_MAX_MASK) +#define TRNG_SCR5L_RUN5_RNG_MASK (0x7FF0000U) +#define TRNG_SCR5L_RUN5_RNG_SHIFT (16U) +#define TRNG_SCR5L_RUN5_RNG(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR5L_RUN5_RNG_SHIFT)) & TRNG_SCR5L_RUN5_RNG_MASK) + +/*! @name SCR6PC - RNG Statistical Check Run Length 6+ Count Register */ +#define TRNG_SCR6PC_R6P_0_CT_MASK (0x7FFU) +#define TRNG_SCR6PC_R6P_0_CT_SHIFT (0U) +#define TRNG_SCR6PC_R6P_0_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR6PC_R6P_0_CT_SHIFT)) & TRNG_SCR6PC_R6P_0_CT_MASK) +#define TRNG_SCR6PC_R6P_1_CT_MASK (0x7FF0000U) +#define TRNG_SCR6PC_R6P_1_CT_SHIFT (16U) +#define TRNG_SCR6PC_R6P_1_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR6PC_R6P_1_CT_SHIFT)) & TRNG_SCR6PC_R6P_1_CT_MASK) + +/*! @name SCR6PL - RNG Statistical Check Run Length 6+ Limit Register */ +#define TRNG_SCR6PL_RUN6P_MAX_MASK (0x7FFU) +#define TRNG_SCR6PL_RUN6P_MAX_SHIFT (0U) +#define TRNG_SCR6PL_RUN6P_MAX(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR6PL_RUN6P_MAX_SHIFT)) & TRNG_SCR6PL_RUN6P_MAX_MASK) +#define TRNG_SCR6PL_RUN6P_RNG_MASK (0x7FF0000U) +#define TRNG_SCR6PL_RUN6P_RNG_SHIFT (16U) +#define TRNG_SCR6PL_RUN6P_RNG(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SCR6PL_RUN6P_RNG_SHIFT)) & TRNG_SCR6PL_RUN6P_RNG_MASK) + +/*! @name STATUS - RNG Status Register */ +#define TRNG_STATUS_TF1BR0_MASK (0x1U) +#define TRNG_STATUS_TF1BR0_SHIFT (0U) +#define TRNG_STATUS_TF1BR0(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TF1BR0_SHIFT)) & TRNG_STATUS_TF1BR0_MASK) +#define TRNG_STATUS_TF1BR1_MASK (0x2U) +#define TRNG_STATUS_TF1BR1_SHIFT (1U) +#define TRNG_STATUS_TF1BR1(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TF1BR1_SHIFT)) & TRNG_STATUS_TF1BR1_MASK) +#define TRNG_STATUS_TF2BR0_MASK (0x4U) +#define TRNG_STATUS_TF2BR0_SHIFT (2U) +#define TRNG_STATUS_TF2BR0(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TF2BR0_SHIFT)) & TRNG_STATUS_TF2BR0_MASK) +#define TRNG_STATUS_TF2BR1_MASK (0x8U) +#define TRNG_STATUS_TF2BR1_SHIFT (3U) +#define TRNG_STATUS_TF2BR1(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TF2BR1_SHIFT)) & TRNG_STATUS_TF2BR1_MASK) +#define TRNG_STATUS_TF3BR0_MASK (0x10U) +#define TRNG_STATUS_TF3BR0_SHIFT (4U) +#define TRNG_STATUS_TF3BR0(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TF3BR0_SHIFT)) & TRNG_STATUS_TF3BR0_MASK) +#define TRNG_STATUS_TF3BR1_MASK (0x20U) +#define TRNG_STATUS_TF3BR1_SHIFT (5U) +#define TRNG_STATUS_TF3BR1(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TF3BR1_SHIFT)) & TRNG_STATUS_TF3BR1_MASK) +#define TRNG_STATUS_TF4BR0_MASK (0x40U) +#define TRNG_STATUS_TF4BR0_SHIFT (6U) +#define TRNG_STATUS_TF4BR0(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TF4BR0_SHIFT)) & TRNG_STATUS_TF4BR0_MASK) +#define TRNG_STATUS_TF4BR1_MASK (0x80U) +#define TRNG_STATUS_TF4BR1_SHIFT (7U) +#define TRNG_STATUS_TF4BR1(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TF4BR1_SHIFT)) & TRNG_STATUS_TF4BR1_MASK) +#define TRNG_STATUS_TF5BR0_MASK (0x100U) +#define TRNG_STATUS_TF5BR0_SHIFT (8U) +#define TRNG_STATUS_TF5BR0(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TF5BR0_SHIFT)) & TRNG_STATUS_TF5BR0_MASK) +#define TRNG_STATUS_TF5BR1_MASK (0x200U) +#define TRNG_STATUS_TF5BR1_SHIFT (9U) +#define TRNG_STATUS_TF5BR1(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TF5BR1_SHIFT)) & TRNG_STATUS_TF5BR1_MASK) +#define TRNG_STATUS_TF6PBR0_MASK (0x400U) +#define TRNG_STATUS_TF6PBR0_SHIFT (10U) +#define TRNG_STATUS_TF6PBR0(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TF6PBR0_SHIFT)) & TRNG_STATUS_TF6PBR0_MASK) +#define TRNG_STATUS_TF6PBR1_MASK (0x800U) +#define TRNG_STATUS_TF6PBR1_SHIFT (11U) +#define TRNG_STATUS_TF6PBR1(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TF6PBR1_SHIFT)) & TRNG_STATUS_TF6PBR1_MASK) +#define TRNG_STATUS_TFSB_MASK (0x1000U) +#define TRNG_STATUS_TFSB_SHIFT (12U) +#define TRNG_STATUS_TFSB(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TFSB_SHIFT)) & TRNG_STATUS_TFSB_MASK) +#define TRNG_STATUS_TFLR_MASK (0x2000U) +#define TRNG_STATUS_TFLR_SHIFT (13U) +#define TRNG_STATUS_TFLR(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TFLR_SHIFT)) & TRNG_STATUS_TFLR_MASK) +#define TRNG_STATUS_TFP_MASK (0x4000U) +#define TRNG_STATUS_TFP_SHIFT (14U) +#define TRNG_STATUS_TFP(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TFP_SHIFT)) & TRNG_STATUS_TFP_MASK) +#define TRNG_STATUS_TFMB_MASK (0x8000U) +#define TRNG_STATUS_TFMB_SHIFT (15U) +#define TRNG_STATUS_TFMB(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_TFMB_SHIFT)) & TRNG_STATUS_TFMB_MASK) +#define TRNG_STATUS_RETRY_CT_MASK (0xF0000U) +#define TRNG_STATUS_RETRY_CT_SHIFT (16U) +#define TRNG_STATUS_RETRY_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_STATUS_RETRY_CT_SHIFT)) & TRNG_STATUS_RETRY_CT_MASK) + +/*! @name ENT - RNG TRNG Entropy Read Register */ +#define TRNG_ENT_ENT_MASK (0xFFFFFFFFU) +#define TRNG_ENT_ENT_SHIFT (0U) +#define TRNG_ENT_ENT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_ENT_ENT_SHIFT)) & TRNG_ENT_ENT_MASK) + +/* The count of TRNG_ENT */ +#define TRNG_ENT_COUNT (16U) + +/*! @name PKRCNT10 - RNG Statistical Check Poker Count 1 and 0 Register */ +#define TRNG_PKRCNT10_PKR_0_CT_MASK (0xFFFFU) +#define TRNG_PKRCNT10_PKR_0_CT_SHIFT (0U) +#define TRNG_PKRCNT10_PKR_0_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNT10_PKR_0_CT_SHIFT)) & TRNG_PKRCNT10_PKR_0_CT_MASK) +#define TRNG_PKRCNT10_PKR_1_CT_MASK (0xFFFF0000U) +#define TRNG_PKRCNT10_PKR_1_CT_SHIFT (16U) +#define TRNG_PKRCNT10_PKR_1_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNT10_PKR_1_CT_SHIFT)) & TRNG_PKRCNT10_PKR_1_CT_MASK) + +/*! @name PKRCNT32 - RNG Statistical Check Poker Count 3 and 2 Register */ +#define TRNG_PKRCNT32_PKR_2_CT_MASK (0xFFFFU) +#define TRNG_PKRCNT32_PKR_2_CT_SHIFT (0U) +#define TRNG_PKRCNT32_PKR_2_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNT32_PKR_2_CT_SHIFT)) & TRNG_PKRCNT32_PKR_2_CT_MASK) +#define TRNG_PKRCNT32_PKR_3_CT_MASK (0xFFFF0000U) +#define TRNG_PKRCNT32_PKR_3_CT_SHIFT (16U) +#define TRNG_PKRCNT32_PKR_3_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNT32_PKR_3_CT_SHIFT)) & TRNG_PKRCNT32_PKR_3_CT_MASK) + +/*! @name PKRCNT54 - RNG Statistical Check Poker Count 5 and 4 Register */ +#define TRNG_PKRCNT54_PKR_4_CT_MASK (0xFFFFU) +#define TRNG_PKRCNT54_PKR_4_CT_SHIFT (0U) +#define TRNG_PKRCNT54_PKR_4_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNT54_PKR_4_CT_SHIFT)) & TRNG_PKRCNT54_PKR_4_CT_MASK) +#define TRNG_PKRCNT54_PKR_5_CT_MASK (0xFFFF0000U) +#define TRNG_PKRCNT54_PKR_5_CT_SHIFT (16U) +#define TRNG_PKRCNT54_PKR_5_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNT54_PKR_5_CT_SHIFT)) & TRNG_PKRCNT54_PKR_5_CT_MASK) + +/*! @name PKRCNT76 - RNG Statistical Check Poker Count 7 and 6 Register */ +#define TRNG_PKRCNT76_PKR_6_CT_MASK (0xFFFFU) +#define TRNG_PKRCNT76_PKR_6_CT_SHIFT (0U) +#define TRNG_PKRCNT76_PKR_6_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNT76_PKR_6_CT_SHIFT)) & TRNG_PKRCNT76_PKR_6_CT_MASK) +#define TRNG_PKRCNT76_PKR_7_CT_MASK (0xFFFF0000U) +#define TRNG_PKRCNT76_PKR_7_CT_SHIFT (16U) +#define TRNG_PKRCNT76_PKR_7_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNT76_PKR_7_CT_SHIFT)) & TRNG_PKRCNT76_PKR_7_CT_MASK) + +/*! @name PKRCNT98 - RNG Statistical Check Poker Count 9 and 8 Register */ +#define TRNG_PKRCNT98_PKR_8_CT_MASK (0xFFFFU) +#define TRNG_PKRCNT98_PKR_8_CT_SHIFT (0U) +#define TRNG_PKRCNT98_PKR_8_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNT98_PKR_8_CT_SHIFT)) & TRNG_PKRCNT98_PKR_8_CT_MASK) +#define TRNG_PKRCNT98_PKR_9_CT_MASK (0xFFFF0000U) +#define TRNG_PKRCNT98_PKR_9_CT_SHIFT (16U) +#define TRNG_PKRCNT98_PKR_9_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNT98_PKR_9_CT_SHIFT)) & TRNG_PKRCNT98_PKR_9_CT_MASK) + +/*! @name PKRCNTBA - RNG Statistical Check Poker Count B and A Register */ +#define TRNG_PKRCNTBA_PKR_A_CT_MASK (0xFFFFU) +#define TRNG_PKRCNTBA_PKR_A_CT_SHIFT (0U) +#define TRNG_PKRCNTBA_PKR_A_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNTBA_PKR_A_CT_SHIFT)) & TRNG_PKRCNTBA_PKR_A_CT_MASK) +#define TRNG_PKRCNTBA_PKR_B_CT_MASK (0xFFFF0000U) +#define TRNG_PKRCNTBA_PKR_B_CT_SHIFT (16U) +#define TRNG_PKRCNTBA_PKR_B_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNTBA_PKR_B_CT_SHIFT)) & TRNG_PKRCNTBA_PKR_B_CT_MASK) + +/*! @name PKRCNTDC - RNG Statistical Check Poker Count D and C Register */ +#define TRNG_PKRCNTDC_PKR_C_CT_MASK (0xFFFFU) +#define TRNG_PKRCNTDC_PKR_C_CT_SHIFT (0U) +#define TRNG_PKRCNTDC_PKR_C_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNTDC_PKR_C_CT_SHIFT)) & TRNG_PKRCNTDC_PKR_C_CT_MASK) +#define TRNG_PKRCNTDC_PKR_D_CT_MASK (0xFFFF0000U) +#define TRNG_PKRCNTDC_PKR_D_CT_SHIFT (16U) +#define TRNG_PKRCNTDC_PKR_D_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNTDC_PKR_D_CT_SHIFT)) & TRNG_PKRCNTDC_PKR_D_CT_MASK) + +/*! @name PKRCNTFE - RNG Statistical Check Poker Count F and E Register */ +#define TRNG_PKRCNTFE_PKR_E_CT_MASK (0xFFFFU) +#define TRNG_PKRCNTFE_PKR_E_CT_SHIFT (0U) +#define TRNG_PKRCNTFE_PKR_E_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNTFE_PKR_E_CT_SHIFT)) & TRNG_PKRCNTFE_PKR_E_CT_MASK) +#define TRNG_PKRCNTFE_PKR_F_CT_MASK (0xFFFF0000U) +#define TRNG_PKRCNTFE_PKR_F_CT_SHIFT (16U) +#define TRNG_PKRCNTFE_PKR_F_CT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_PKRCNTFE_PKR_F_CT_SHIFT)) & TRNG_PKRCNTFE_PKR_F_CT_MASK) + +/*! @name SEC_CFG - RNG Security Configuration Register */ +#define TRNG_SEC_CFG_SH0_MASK (0x1U) +#define TRNG_SEC_CFG_SH0_SHIFT (0U) +#define TRNG_SEC_CFG_SH0(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SEC_CFG_SH0_SHIFT)) & TRNG_SEC_CFG_SH0_MASK) +#define TRNG_SEC_CFG_NO_PRGM_MASK (0x2U) +#define TRNG_SEC_CFG_NO_PRGM_SHIFT (1U) +#define TRNG_SEC_CFG_NO_PRGM(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SEC_CFG_NO_PRGM_SHIFT)) & TRNG_SEC_CFG_NO_PRGM_MASK) +#define TRNG_SEC_CFG_SK_VAL_MASK (0x4U) +#define TRNG_SEC_CFG_SK_VAL_SHIFT (2U) +#define TRNG_SEC_CFG_SK_VAL(x) (((uint32_t)(((uint32_t)(x)) << TRNG_SEC_CFG_SK_VAL_SHIFT)) & TRNG_SEC_CFG_SK_VAL_MASK) + +/*! @name INT_CTRL - RNG Interrupt Control Register */ +#define TRNG_INT_CTRL_HW_ERR_MASK (0x1U) +#define TRNG_INT_CTRL_HW_ERR_SHIFT (0U) +#define TRNG_INT_CTRL_HW_ERR(x) (((uint32_t)(((uint32_t)(x)) << TRNG_INT_CTRL_HW_ERR_SHIFT)) & TRNG_INT_CTRL_HW_ERR_MASK) +#define TRNG_INT_CTRL_ENT_VAL_MASK (0x2U) +#define TRNG_INT_CTRL_ENT_VAL_SHIFT (1U) +#define TRNG_INT_CTRL_ENT_VAL(x) (((uint32_t)(((uint32_t)(x)) << TRNG_INT_CTRL_ENT_VAL_SHIFT)) & TRNG_INT_CTRL_ENT_VAL_MASK) +#define TRNG_INT_CTRL_FRQ_CT_FAIL_MASK (0x4U) +#define TRNG_INT_CTRL_FRQ_CT_FAIL_SHIFT (2U) +#define TRNG_INT_CTRL_FRQ_CT_FAIL(x) (((uint32_t)(((uint32_t)(x)) << TRNG_INT_CTRL_FRQ_CT_FAIL_SHIFT)) & TRNG_INT_CTRL_FRQ_CT_FAIL_MASK) +#define TRNG_INT_CTRL_UNUSED_MASK (0xFFFFFFF8U) +#define TRNG_INT_CTRL_UNUSED_SHIFT (3U) +#define TRNG_INT_CTRL_UNUSED(x) (((uint32_t)(((uint32_t)(x)) << TRNG_INT_CTRL_UNUSED_SHIFT)) & TRNG_INT_CTRL_UNUSED_MASK) + +/*! @name INT_MASK - RNG Mask Register */ +#define TRNG_INT_MASK_HW_ERR_MASK (0x1U) +#define TRNG_INT_MASK_HW_ERR_SHIFT (0U) +#define TRNG_INT_MASK_HW_ERR(x) (((uint32_t)(((uint32_t)(x)) << TRNG_INT_MASK_HW_ERR_SHIFT)) & TRNG_INT_MASK_HW_ERR_MASK) +#define TRNG_INT_MASK_ENT_VAL_MASK (0x2U) +#define TRNG_INT_MASK_ENT_VAL_SHIFT (1U) +#define TRNG_INT_MASK_ENT_VAL(x) (((uint32_t)(((uint32_t)(x)) << TRNG_INT_MASK_ENT_VAL_SHIFT)) & TRNG_INT_MASK_ENT_VAL_MASK) +#define TRNG_INT_MASK_FRQ_CT_FAIL_MASK (0x4U) +#define TRNG_INT_MASK_FRQ_CT_FAIL_SHIFT (2U) +#define TRNG_INT_MASK_FRQ_CT_FAIL(x) (((uint32_t)(((uint32_t)(x)) << TRNG_INT_MASK_FRQ_CT_FAIL_SHIFT)) & TRNG_INT_MASK_FRQ_CT_FAIL_MASK) + +/*! @name INT_STATUS - RNG Interrupt Status Register */ +#define TRNG_INT_STATUS_HW_ERR_MASK (0x1U) +#define TRNG_INT_STATUS_HW_ERR_SHIFT (0U) +#define TRNG_INT_STATUS_HW_ERR(x) (((uint32_t)(((uint32_t)(x)) << TRNG_INT_STATUS_HW_ERR_SHIFT)) & TRNG_INT_STATUS_HW_ERR_MASK) +#define TRNG_INT_STATUS_ENT_VAL_MASK (0x2U) +#define TRNG_INT_STATUS_ENT_VAL_SHIFT (1U) +#define TRNG_INT_STATUS_ENT_VAL(x) (((uint32_t)(((uint32_t)(x)) << TRNG_INT_STATUS_ENT_VAL_SHIFT)) & TRNG_INT_STATUS_ENT_VAL_MASK) +#define TRNG_INT_STATUS_FRQ_CT_FAIL_MASK (0x4U) +#define TRNG_INT_STATUS_FRQ_CT_FAIL_SHIFT (2U) +#define TRNG_INT_STATUS_FRQ_CT_FAIL(x) (((uint32_t)(((uint32_t)(x)) << TRNG_INT_STATUS_FRQ_CT_FAIL_SHIFT)) & TRNG_INT_STATUS_FRQ_CT_FAIL_MASK) + +/*! @name VID1 - RNG Version ID Register (MS) */ +#define TRNG_VID1_RNG_MIN_REV_MASK (0xFFU) +#define TRNG_VID1_RNG_MIN_REV_SHIFT (0U) +#define TRNG_VID1_RNG_MIN_REV(x) (((uint32_t)(((uint32_t)(x)) << TRNG_VID1_RNG_MIN_REV_SHIFT)) & TRNG_VID1_RNG_MIN_REV_MASK) +#define TRNG_VID1_RNG_MAJ_REV_MASK (0xFF00U) +#define TRNG_VID1_RNG_MAJ_REV_SHIFT (8U) +#define TRNG_VID1_RNG_MAJ_REV(x) (((uint32_t)(((uint32_t)(x)) << TRNG_VID1_RNG_MAJ_REV_SHIFT)) & TRNG_VID1_RNG_MAJ_REV_MASK) +#define TRNG_VID1_RNG_IP_ID_MASK (0xFFFF0000U) +#define TRNG_VID1_RNG_IP_ID_SHIFT (16U) +#define TRNG_VID1_RNG_IP_ID(x) (((uint32_t)(((uint32_t)(x)) << TRNG_VID1_RNG_IP_ID_SHIFT)) & TRNG_VID1_RNG_IP_ID_MASK) + +/*! @name VID2 - RNG Version ID Register (LS) */ +#define TRNG_VID2_RNG_CONFIG_OPT_MASK (0xFFU) +#define TRNG_VID2_RNG_CONFIG_OPT_SHIFT (0U) +#define TRNG_VID2_RNG_CONFIG_OPT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_VID2_RNG_CONFIG_OPT_SHIFT)) & TRNG_VID2_RNG_CONFIG_OPT_MASK) +#define TRNG_VID2_RNG_ECO_REV_MASK (0xFF00U) +#define TRNG_VID2_RNG_ECO_REV_SHIFT (8U) +#define TRNG_VID2_RNG_ECO_REV(x) (((uint32_t)(((uint32_t)(x)) << TRNG_VID2_RNG_ECO_REV_SHIFT)) & TRNG_VID2_RNG_ECO_REV_MASK) +#define TRNG_VID2_RNG_INTG_OPT_MASK (0xFF0000U) +#define TRNG_VID2_RNG_INTG_OPT_SHIFT (16U) +#define TRNG_VID2_RNG_INTG_OPT(x) (((uint32_t)(((uint32_t)(x)) << TRNG_VID2_RNG_INTG_OPT_SHIFT)) & TRNG_VID2_RNG_INTG_OPT_MASK) +#define TRNG_VID2_RNG_ERA_MASK (0xFF000000U) +#define TRNG_VID2_RNG_ERA_SHIFT (24U) +#define TRNG_VID2_RNG_ERA(x) (((uint32_t)(((uint32_t)(x)) << TRNG_VID2_RNG_ERA_SHIFT)) & TRNG_VID2_RNG_ERA_MASK) + + +/*! + * @} + */ /* end of group TRNG_Register_Masks */ + + +/* TRNG - Peripheral instance base addresses */ +/** Peripheral TRNG0 base address */ +#define TRNG0_BASE (0x400A0000u) +/** Peripheral TRNG0 base pointer */ +#define TRNG0 ((TRNG_Type *)TRNG0_BASE) +/** Array initializer of TRNG peripheral base addresses */ +#define TRNG_BASE_ADDRS { TRNG0_BASE } +/** Array initializer of TRNG peripheral base pointers */ +#define TRNG_BASE_PTRS { TRNG0 } +/** Interrupt vectors for the TRNG peripheral type */ +#define TRNG_IRQS { TRNG0_IRQn } + +/*! + * @} + */ /* end of group TRNG_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- TSI Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup TSI_Peripheral_Access_Layer TSI Peripheral Access Layer + * @{ + */ + +/** TSI - Register Layout Typedef */ +typedef struct { + __IO uint32_t GENCS; /**< TSI General Control and Status Register, offset: 0x0 */ + __IO uint32_t DATA; /**< TSI DATA Register, offset: 0x4 */ + __IO uint32_t TSHD; /**< TSI Threshold Register, offset: 0x8 */ +} TSI_Type; + +/* ---------------------------------------------------------------------------- + -- TSI Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup TSI_Register_Masks TSI Register Masks + * @{ + */ + +/*! @name GENCS - TSI General Control and Status Register */ +#define TSI_GENCS_EOSDMEO_MASK (0x1U) +#define TSI_GENCS_EOSDMEO_SHIFT (0U) +#define TSI_GENCS_EOSDMEO(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_EOSDMEO_SHIFT)) & TSI_GENCS_EOSDMEO_MASK) +#define TSI_GENCS_CURSW_MASK (0x2U) +#define TSI_GENCS_CURSW_SHIFT (1U) +#define TSI_GENCS_CURSW(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_CURSW_SHIFT)) & TSI_GENCS_CURSW_MASK) +#define TSI_GENCS_EOSF_MASK (0x4U) +#define TSI_GENCS_EOSF_SHIFT (2U) +#define TSI_GENCS_EOSF(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_EOSF_SHIFT)) & TSI_GENCS_EOSF_MASK) +#define TSI_GENCS_SCNIP_MASK (0x8U) +#define TSI_GENCS_SCNIP_SHIFT (3U) +#define TSI_GENCS_SCNIP(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_SCNIP_SHIFT)) & TSI_GENCS_SCNIP_MASK) +#define TSI_GENCS_STM_MASK (0x10U) +#define TSI_GENCS_STM_SHIFT (4U) +#define TSI_GENCS_STM(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_STM_SHIFT)) & TSI_GENCS_STM_MASK) +#define TSI_GENCS_STPE_MASK (0x20U) +#define TSI_GENCS_STPE_SHIFT (5U) +#define TSI_GENCS_STPE(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_STPE_SHIFT)) & TSI_GENCS_STPE_MASK) +#define TSI_GENCS_TSIIEN_MASK (0x40U) +#define TSI_GENCS_TSIIEN_SHIFT (6U) +#define TSI_GENCS_TSIIEN(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_TSIIEN_SHIFT)) & TSI_GENCS_TSIIEN_MASK) +#define TSI_GENCS_TSIEN_MASK (0x80U) +#define TSI_GENCS_TSIEN_SHIFT (7U) +#define TSI_GENCS_TSIEN(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_TSIEN_SHIFT)) & TSI_GENCS_TSIEN_MASK) +#define TSI_GENCS_NSCN_MASK (0x1F00U) +#define TSI_GENCS_NSCN_SHIFT (8U) +#define TSI_GENCS_NSCN(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_NSCN_SHIFT)) & TSI_GENCS_NSCN_MASK) +#define TSI_GENCS_PS_MASK (0xE000U) +#define TSI_GENCS_PS_SHIFT (13U) +#define TSI_GENCS_PS(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_PS_SHIFT)) & TSI_GENCS_PS_MASK) +#define TSI_GENCS_EXTCHRG_MASK (0x70000U) +#define TSI_GENCS_EXTCHRG_SHIFT (16U) +#define TSI_GENCS_EXTCHRG(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_EXTCHRG_SHIFT)) & TSI_GENCS_EXTCHRG_MASK) +#define TSI_GENCS_DVOLT_MASK (0x180000U) +#define TSI_GENCS_DVOLT_SHIFT (19U) +#define TSI_GENCS_DVOLT(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_DVOLT_SHIFT)) & TSI_GENCS_DVOLT_MASK) +#define TSI_GENCS_REFCHRG_MASK (0xE00000U) +#define TSI_GENCS_REFCHRG_SHIFT (21U) +#define TSI_GENCS_REFCHRG(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_REFCHRG_SHIFT)) & TSI_GENCS_REFCHRG_MASK) +#define TSI_GENCS_MODE_MASK (0xF000000U) +#define TSI_GENCS_MODE_SHIFT (24U) +#define TSI_GENCS_MODE(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_MODE_SHIFT)) & TSI_GENCS_MODE_MASK) +#define TSI_GENCS_ESOR_MASK (0x10000000U) +#define TSI_GENCS_ESOR_SHIFT (28U) +#define TSI_GENCS_ESOR(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_ESOR_SHIFT)) & TSI_GENCS_ESOR_MASK) +#define TSI_GENCS_OUTRGF_MASK (0x80000000U) +#define TSI_GENCS_OUTRGF_SHIFT (31U) +#define TSI_GENCS_OUTRGF(x) (((uint32_t)(((uint32_t)(x)) << TSI_GENCS_OUTRGF_SHIFT)) & TSI_GENCS_OUTRGF_MASK) + +/*! @name DATA - TSI DATA Register */ +#define TSI_DATA_TSICNT_MASK (0xFFFFU) +#define TSI_DATA_TSICNT_SHIFT (0U) +#define TSI_DATA_TSICNT(x) (((uint32_t)(((uint32_t)(x)) << TSI_DATA_TSICNT_SHIFT)) & TSI_DATA_TSICNT_MASK) +#define TSI_DATA_SWTS_MASK (0x400000U) +#define TSI_DATA_SWTS_SHIFT (22U) +#define TSI_DATA_SWTS(x) (((uint32_t)(((uint32_t)(x)) << TSI_DATA_SWTS_SHIFT)) & TSI_DATA_SWTS_MASK) +#define TSI_DATA_DMAEN_MASK (0x800000U) +#define TSI_DATA_DMAEN_SHIFT (23U) +#define TSI_DATA_DMAEN(x) (((uint32_t)(((uint32_t)(x)) << TSI_DATA_DMAEN_SHIFT)) & TSI_DATA_DMAEN_MASK) +#define TSI_DATA_TSICH_MASK (0xF0000000U) +#define TSI_DATA_TSICH_SHIFT (28U) +#define TSI_DATA_TSICH(x) (((uint32_t)(((uint32_t)(x)) << TSI_DATA_TSICH_SHIFT)) & TSI_DATA_TSICH_MASK) + +/*! @name TSHD - TSI Threshold Register */ +#define TSI_TSHD_THRESL_MASK (0xFFFFU) +#define TSI_TSHD_THRESL_SHIFT (0U) +#define TSI_TSHD_THRESL(x) (((uint32_t)(((uint32_t)(x)) << TSI_TSHD_THRESL_SHIFT)) & TSI_TSHD_THRESL_MASK) +#define TSI_TSHD_THRESH_MASK (0xFFFF0000U) +#define TSI_TSHD_THRESH_SHIFT (16U) +#define TSI_TSHD_THRESH(x) (((uint32_t)(((uint32_t)(x)) << TSI_TSHD_THRESH_SHIFT)) & TSI_TSHD_THRESH_MASK) + + +/*! + * @} + */ /* end of group TSI_Register_Masks */ + + +/* TSI - Peripheral instance base addresses */ +/** Peripheral TSI0 base address */ +#define TSI0_BASE (0x40045000u) +/** Peripheral TSI0 base pointer */ +#define TSI0 ((TSI_Type *)TSI0_BASE) +/** Array initializer of TSI peripheral base addresses */ +#define TSI_BASE_ADDRS { TSI0_BASE } +/** Array initializer of TSI peripheral base pointers */ +#define TSI_BASE_PTRS { TSI0 } +/** Interrupt vectors for the TSI peripheral type */ +#define TSI_IRQS { TSI0_IRQn } + +/*! + * @} + */ /* end of group TSI_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- USB Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USB_Peripheral_Access_Layer USB Peripheral Access Layer + * @{ + */ + +/** USB - Register Layout Typedef */ +typedef struct { + __I uint8_t PERID; /**< Peripheral ID register, offset: 0x0 */ + uint8_t RESERVED_0[3]; + __I uint8_t IDCOMP; /**< Peripheral ID Complement register, offset: 0x4 */ + uint8_t RESERVED_1[3]; + __I uint8_t REV; /**< Peripheral Revision register, offset: 0x8 */ + uint8_t RESERVED_2[3]; + __I uint8_t ADDINFO; /**< Peripheral Additional Info register, offset: 0xC */ + uint8_t RESERVED_3[3]; + __IO uint8_t OTGISTAT; /**< OTG Interrupt Status register, offset: 0x10 */ + uint8_t RESERVED_4[3]; + __IO uint8_t OTGICR; /**< OTG Interrupt Control register, offset: 0x14 */ + uint8_t RESERVED_5[3]; + __IO uint8_t OTGSTAT; /**< OTG Status register, offset: 0x18 */ + uint8_t RESERVED_6[3]; + __IO uint8_t OTGCTL; /**< OTG Control register, offset: 0x1C */ + uint8_t RESERVED_7[99]; + __IO uint8_t ISTAT; /**< Interrupt Status register, offset: 0x80 */ + uint8_t RESERVED_8[3]; + __IO uint8_t INTEN; /**< Interrupt Enable register, offset: 0x84 */ + uint8_t RESERVED_9[3]; + __IO uint8_t ERRSTAT; /**< Error Interrupt Status register, offset: 0x88 */ + uint8_t RESERVED_10[3]; + __IO uint8_t ERREN; /**< Error Interrupt Enable register, offset: 0x8C */ + uint8_t RESERVED_11[3]; + __I uint8_t STAT; /**< Status register, offset: 0x90 */ + uint8_t RESERVED_12[3]; + __IO uint8_t CTL; /**< Control register, offset: 0x94 */ + uint8_t RESERVED_13[3]; + __IO uint8_t ADDR; /**< Address register, offset: 0x98 */ + uint8_t RESERVED_14[3]; + __IO uint8_t BDTPAGE1; /**< BDT Page register 1, offset: 0x9C */ + uint8_t RESERVED_15[3]; + __IO uint8_t FRMNUML; /**< Frame Number register Low, offset: 0xA0 */ + uint8_t RESERVED_16[3]; + __IO uint8_t FRMNUMH; /**< Frame Number register High, offset: 0xA4 */ + uint8_t RESERVED_17[3]; + __IO uint8_t TOKEN; /**< Token register, offset: 0xA8 */ + uint8_t RESERVED_18[3]; + __IO uint8_t SOFTHLD; /**< SOF Threshold register, offset: 0xAC */ + uint8_t RESERVED_19[3]; + __IO uint8_t BDTPAGE2; /**< BDT Page Register 2, offset: 0xB0 */ + uint8_t RESERVED_20[3]; + __IO uint8_t BDTPAGE3; /**< BDT Page Register 3, offset: 0xB4 */ + uint8_t RESERVED_21[11]; + struct { /* offset: 0xC0, array step: 0x4 */ + __IO uint8_t ENDPT; /**< Endpoint Control register, array offset: 0xC0, array step: 0x4 */ + uint8_t RESERVED_0[3]; + } ENDPOINT[16]; + __IO uint8_t USBCTRL; /**< USB Control register, offset: 0x100 */ + uint8_t RESERVED_22[3]; + __I uint8_t OBSERVE; /**< USB OTG Observe register, offset: 0x104 */ + uint8_t RESERVED_23[3]; + __IO uint8_t CONTROL; /**< USB OTG Control register, offset: 0x108 */ + uint8_t RESERVED_24[3]; + __IO uint8_t USBTRC0; /**< USB Transceiver Control register 0, offset: 0x10C */ + uint8_t RESERVED_25[7]; + __IO uint8_t USBFRMADJUST; /**< Frame Adjust Register, offset: 0x114 */ + uint8_t RESERVED_26[23]; + __IO uint8_t MISCCTRL; /**< Miscellaneous Control register, offset: 0x12C */ + uint8_t RESERVED_27[19]; + __IO uint8_t CLK_RECOVER_CTRL; /**< USB Clock recovery control, offset: 0x140 */ + uint8_t RESERVED_28[3]; + __IO uint8_t CLK_RECOVER_IRC_EN; /**< IRC48M oscillator enable register, offset: 0x144 */ + uint8_t RESERVED_29[15]; + __IO uint8_t CLK_RECOVER_INT_EN; /**< Clock recovery combined interrupt enable, offset: 0x154 */ + uint8_t RESERVED_30[7]; + __IO uint8_t CLK_RECOVER_INT_STATUS; /**< Clock recovery separated interrupt status, offset: 0x15C */ +} USB_Type; + +/* ---------------------------------------------------------------------------- + -- USB Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USB_Register_Masks USB Register Masks + * @{ + */ + +/*! @name PERID - Peripheral ID register */ +#define USB_PERID_ID_MASK (0x3FU) +#define USB_PERID_ID_SHIFT (0U) +#define USB_PERID_ID(x) (((uint8_t)(((uint8_t)(x)) << USB_PERID_ID_SHIFT)) & USB_PERID_ID_MASK) + +/*! @name IDCOMP - Peripheral ID Complement register */ +#define USB_IDCOMP_NID_MASK (0x3FU) +#define USB_IDCOMP_NID_SHIFT (0U) +#define USB_IDCOMP_NID(x) (((uint8_t)(((uint8_t)(x)) << USB_IDCOMP_NID_SHIFT)) & USB_IDCOMP_NID_MASK) + +/*! @name REV - Peripheral Revision register */ +#define USB_REV_REV_MASK (0xFFU) +#define USB_REV_REV_SHIFT (0U) +#define USB_REV_REV(x) (((uint8_t)(((uint8_t)(x)) << USB_REV_REV_SHIFT)) & USB_REV_REV_MASK) + +/*! @name ADDINFO - Peripheral Additional Info register */ +#define USB_ADDINFO_IEHOST_MASK (0x1U) +#define USB_ADDINFO_IEHOST_SHIFT (0U) +#define USB_ADDINFO_IEHOST(x) (((uint8_t)(((uint8_t)(x)) << USB_ADDINFO_IEHOST_SHIFT)) & USB_ADDINFO_IEHOST_MASK) + +/*! @name OTGISTAT - OTG Interrupt Status register */ +#define USB_OTGISTAT_AVBUSCHG_MASK (0x1U) +#define USB_OTGISTAT_AVBUSCHG_SHIFT (0U) +#define USB_OTGISTAT_AVBUSCHG(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_AVBUSCHG_SHIFT)) & USB_OTGISTAT_AVBUSCHG_MASK) +#define USB_OTGISTAT_B_SESS_CHG_MASK (0x4U) +#define USB_OTGISTAT_B_SESS_CHG_SHIFT (2U) +#define USB_OTGISTAT_B_SESS_CHG(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_B_SESS_CHG_SHIFT)) & USB_OTGISTAT_B_SESS_CHG_MASK) +#define USB_OTGISTAT_SESSVLDCHG_MASK (0x8U) +#define USB_OTGISTAT_SESSVLDCHG_SHIFT (3U) +#define USB_OTGISTAT_SESSVLDCHG(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_SESSVLDCHG_SHIFT)) & USB_OTGISTAT_SESSVLDCHG_MASK) +#define USB_OTGISTAT_LINE_STATE_CHG_MASK (0x20U) +#define USB_OTGISTAT_LINE_STATE_CHG_SHIFT (5U) +#define USB_OTGISTAT_LINE_STATE_CHG(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_LINE_STATE_CHG_SHIFT)) & USB_OTGISTAT_LINE_STATE_CHG_MASK) +#define USB_OTGISTAT_ONEMSEC_MASK (0x40U) +#define USB_OTGISTAT_ONEMSEC_SHIFT (6U) +#define USB_OTGISTAT_ONEMSEC(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_ONEMSEC_SHIFT)) & USB_OTGISTAT_ONEMSEC_MASK) +#define USB_OTGISTAT_IDCHG_MASK (0x80U) +#define USB_OTGISTAT_IDCHG_SHIFT (7U) +#define USB_OTGISTAT_IDCHG(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_IDCHG_SHIFT)) & USB_OTGISTAT_IDCHG_MASK) + +/*! @name OTGICR - OTG Interrupt Control register */ +#define USB_OTGICR_AVBUSEN_MASK (0x1U) +#define USB_OTGICR_AVBUSEN_SHIFT (0U) +#define USB_OTGICR_AVBUSEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_AVBUSEN_SHIFT)) & USB_OTGICR_AVBUSEN_MASK) +#define USB_OTGICR_BSESSEN_MASK (0x4U) +#define USB_OTGICR_BSESSEN_SHIFT (2U) +#define USB_OTGICR_BSESSEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_BSESSEN_SHIFT)) & USB_OTGICR_BSESSEN_MASK) +#define USB_OTGICR_SESSVLDEN_MASK (0x8U) +#define USB_OTGICR_SESSVLDEN_SHIFT (3U) +#define USB_OTGICR_SESSVLDEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_SESSVLDEN_SHIFT)) & USB_OTGICR_SESSVLDEN_MASK) +#define USB_OTGICR_LINESTATEEN_MASK (0x20U) +#define USB_OTGICR_LINESTATEEN_SHIFT (5U) +#define USB_OTGICR_LINESTATEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_LINESTATEEN_SHIFT)) & USB_OTGICR_LINESTATEEN_MASK) +#define USB_OTGICR_ONEMSECEN_MASK (0x40U) +#define USB_OTGICR_ONEMSECEN_SHIFT (6U) +#define USB_OTGICR_ONEMSECEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_ONEMSECEN_SHIFT)) & USB_OTGICR_ONEMSECEN_MASK) +#define USB_OTGICR_IDEN_MASK (0x80U) +#define USB_OTGICR_IDEN_SHIFT (7U) +#define USB_OTGICR_IDEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_IDEN_SHIFT)) & USB_OTGICR_IDEN_MASK) + +/*! @name OTGSTAT - OTG Status register */ +#define USB_OTGSTAT_AVBUSVLD_MASK (0x1U) +#define USB_OTGSTAT_AVBUSVLD_SHIFT (0U) +#define USB_OTGSTAT_AVBUSVLD(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_AVBUSVLD_SHIFT)) & USB_OTGSTAT_AVBUSVLD_MASK) +#define USB_OTGSTAT_BSESSEND_MASK (0x4U) +#define USB_OTGSTAT_BSESSEND_SHIFT (2U) +#define USB_OTGSTAT_BSESSEND(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_BSESSEND_SHIFT)) & USB_OTGSTAT_BSESSEND_MASK) +#define USB_OTGSTAT_SESS_VLD_MASK (0x8U) +#define USB_OTGSTAT_SESS_VLD_SHIFT (3U) +#define USB_OTGSTAT_SESS_VLD(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_SESS_VLD_SHIFT)) & USB_OTGSTAT_SESS_VLD_MASK) +#define USB_OTGSTAT_LINESTATESTABLE_MASK (0x20U) +#define USB_OTGSTAT_LINESTATESTABLE_SHIFT (5U) +#define USB_OTGSTAT_LINESTATESTABLE(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_LINESTATESTABLE_SHIFT)) & USB_OTGSTAT_LINESTATESTABLE_MASK) +#define USB_OTGSTAT_ONEMSECEN_MASK (0x40U) +#define USB_OTGSTAT_ONEMSECEN_SHIFT (6U) +#define USB_OTGSTAT_ONEMSECEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_ONEMSECEN_SHIFT)) & USB_OTGSTAT_ONEMSECEN_MASK) +#define USB_OTGSTAT_ID_MASK (0x80U) +#define USB_OTGSTAT_ID_SHIFT (7U) +#define USB_OTGSTAT_ID(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_ID_SHIFT)) & USB_OTGSTAT_ID_MASK) + +/*! @name OTGCTL - OTG Control register */ +#define USB_OTGCTL_OTGEN_MASK (0x4U) +#define USB_OTGCTL_OTGEN_SHIFT (2U) +#define USB_OTGCTL_OTGEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_OTGEN_SHIFT)) & USB_OTGCTL_OTGEN_MASK) +#define USB_OTGCTL_DMLOW_MASK (0x10U) +#define USB_OTGCTL_DMLOW_SHIFT (4U) +#define USB_OTGCTL_DMLOW(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_DMLOW_SHIFT)) & USB_OTGCTL_DMLOW_MASK) +#define USB_OTGCTL_DPLOW_MASK (0x20U) +#define USB_OTGCTL_DPLOW_SHIFT (5U) +#define USB_OTGCTL_DPLOW(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_DPLOW_SHIFT)) & USB_OTGCTL_DPLOW_MASK) +#define USB_OTGCTL_DPHIGH_MASK (0x80U) +#define USB_OTGCTL_DPHIGH_SHIFT (7U) +#define USB_OTGCTL_DPHIGH(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_DPHIGH_SHIFT)) & USB_OTGCTL_DPHIGH_MASK) + +/*! @name ISTAT - Interrupt Status register */ +#define USB_ISTAT_USBRST_MASK (0x1U) +#define USB_ISTAT_USBRST_SHIFT (0U) +#define USB_ISTAT_USBRST(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_USBRST_SHIFT)) & USB_ISTAT_USBRST_MASK) +#define USB_ISTAT_ERROR_MASK (0x2U) +#define USB_ISTAT_ERROR_SHIFT (1U) +#define USB_ISTAT_ERROR(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_ERROR_SHIFT)) & USB_ISTAT_ERROR_MASK) +#define USB_ISTAT_SOFTOK_MASK (0x4U) +#define USB_ISTAT_SOFTOK_SHIFT (2U) +#define USB_ISTAT_SOFTOK(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_SOFTOK_SHIFT)) & USB_ISTAT_SOFTOK_MASK) +#define USB_ISTAT_TOKDNE_MASK (0x8U) +#define USB_ISTAT_TOKDNE_SHIFT (3U) +#define USB_ISTAT_TOKDNE(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_TOKDNE_SHIFT)) & USB_ISTAT_TOKDNE_MASK) +#define USB_ISTAT_SLEEP_MASK (0x10U) +#define USB_ISTAT_SLEEP_SHIFT (4U) +#define USB_ISTAT_SLEEP(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_SLEEP_SHIFT)) & USB_ISTAT_SLEEP_MASK) +#define USB_ISTAT_RESUME_MASK (0x20U) +#define USB_ISTAT_RESUME_SHIFT (5U) +#define USB_ISTAT_RESUME(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_RESUME_SHIFT)) & USB_ISTAT_RESUME_MASK) +#define USB_ISTAT_ATTACH_MASK (0x40U) +#define USB_ISTAT_ATTACH_SHIFT (6U) +#define USB_ISTAT_ATTACH(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_ATTACH_SHIFT)) & USB_ISTAT_ATTACH_MASK) +#define USB_ISTAT_STALL_MASK (0x80U) +#define USB_ISTAT_STALL_SHIFT (7U) +#define USB_ISTAT_STALL(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_STALL_SHIFT)) & USB_ISTAT_STALL_MASK) + +/*! @name INTEN - Interrupt Enable register */ +#define USB_INTEN_USBRSTEN_MASK (0x1U) +#define USB_INTEN_USBRSTEN_SHIFT (0U) +#define USB_INTEN_USBRSTEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_USBRSTEN_SHIFT)) & USB_INTEN_USBRSTEN_MASK) +#define USB_INTEN_ERROREN_MASK (0x2U) +#define USB_INTEN_ERROREN_SHIFT (1U) +#define USB_INTEN_ERROREN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_ERROREN_SHIFT)) & USB_INTEN_ERROREN_MASK) +#define USB_INTEN_SOFTOKEN_MASK (0x4U) +#define USB_INTEN_SOFTOKEN_SHIFT (2U) +#define USB_INTEN_SOFTOKEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_SOFTOKEN_SHIFT)) & USB_INTEN_SOFTOKEN_MASK) +#define USB_INTEN_TOKDNEEN_MASK (0x8U) +#define USB_INTEN_TOKDNEEN_SHIFT (3U) +#define USB_INTEN_TOKDNEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_TOKDNEEN_SHIFT)) & USB_INTEN_TOKDNEEN_MASK) +#define USB_INTEN_SLEEPEN_MASK (0x10U) +#define USB_INTEN_SLEEPEN_SHIFT (4U) +#define USB_INTEN_SLEEPEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_SLEEPEN_SHIFT)) & USB_INTEN_SLEEPEN_MASK) +#define USB_INTEN_RESUMEEN_MASK (0x20U) +#define USB_INTEN_RESUMEEN_SHIFT (5U) +#define USB_INTEN_RESUMEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_RESUMEEN_SHIFT)) & USB_INTEN_RESUMEEN_MASK) +#define USB_INTEN_ATTACHEN_MASK (0x40U) +#define USB_INTEN_ATTACHEN_SHIFT (6U) +#define USB_INTEN_ATTACHEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_ATTACHEN_SHIFT)) & USB_INTEN_ATTACHEN_MASK) +#define USB_INTEN_STALLEN_MASK (0x80U) +#define USB_INTEN_STALLEN_SHIFT (7U) +#define USB_INTEN_STALLEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_STALLEN_SHIFT)) & USB_INTEN_STALLEN_MASK) + +/*! @name ERRSTAT - Error Interrupt Status register */ +#define USB_ERRSTAT_PIDERR_MASK (0x1U) +#define USB_ERRSTAT_PIDERR_SHIFT (0U) +#define USB_ERRSTAT_PIDERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_PIDERR_SHIFT)) & USB_ERRSTAT_PIDERR_MASK) +#define USB_ERRSTAT_CRC5EOF_MASK (0x2U) +#define USB_ERRSTAT_CRC5EOF_SHIFT (1U) +#define USB_ERRSTAT_CRC5EOF(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_CRC5EOF_SHIFT)) & USB_ERRSTAT_CRC5EOF_MASK) +#define USB_ERRSTAT_CRC16_MASK (0x4U) +#define USB_ERRSTAT_CRC16_SHIFT (2U) +#define USB_ERRSTAT_CRC16(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_CRC16_SHIFT)) & USB_ERRSTAT_CRC16_MASK) +#define USB_ERRSTAT_DFN8_MASK (0x8U) +#define USB_ERRSTAT_DFN8_SHIFT (3U) +#define USB_ERRSTAT_DFN8(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_DFN8_SHIFT)) & USB_ERRSTAT_DFN8_MASK) +#define USB_ERRSTAT_BTOERR_MASK (0x10U) +#define USB_ERRSTAT_BTOERR_SHIFT (4U) +#define USB_ERRSTAT_BTOERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_BTOERR_SHIFT)) & USB_ERRSTAT_BTOERR_MASK) +#define USB_ERRSTAT_DMAERR_MASK (0x20U) +#define USB_ERRSTAT_DMAERR_SHIFT (5U) +#define USB_ERRSTAT_DMAERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_DMAERR_SHIFT)) & USB_ERRSTAT_DMAERR_MASK) +#define USB_ERRSTAT_OWNERR_MASK (0x40U) +#define USB_ERRSTAT_OWNERR_SHIFT (6U) +#define USB_ERRSTAT_OWNERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_OWNERR_SHIFT)) & USB_ERRSTAT_OWNERR_MASK) +#define USB_ERRSTAT_BTSERR_MASK (0x80U) +#define USB_ERRSTAT_BTSERR_SHIFT (7U) +#define USB_ERRSTAT_BTSERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_BTSERR_SHIFT)) & USB_ERRSTAT_BTSERR_MASK) + +/*! @name ERREN - Error Interrupt Enable register */ +#define USB_ERREN_PIDERREN_MASK (0x1U) +#define USB_ERREN_PIDERREN_SHIFT (0U) +#define USB_ERREN_PIDERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_PIDERREN_SHIFT)) & USB_ERREN_PIDERREN_MASK) +#define USB_ERREN_CRC5EOFEN_MASK (0x2U) +#define USB_ERREN_CRC5EOFEN_SHIFT (1U) +#define USB_ERREN_CRC5EOFEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_CRC5EOFEN_SHIFT)) & USB_ERREN_CRC5EOFEN_MASK) +#define USB_ERREN_CRC16EN_MASK (0x4U) +#define USB_ERREN_CRC16EN_SHIFT (2U) +#define USB_ERREN_CRC16EN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_CRC16EN_SHIFT)) & USB_ERREN_CRC16EN_MASK) +#define USB_ERREN_DFN8EN_MASK (0x8U) +#define USB_ERREN_DFN8EN_SHIFT (3U) +#define USB_ERREN_DFN8EN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_DFN8EN_SHIFT)) & USB_ERREN_DFN8EN_MASK) +#define USB_ERREN_BTOERREN_MASK (0x10U) +#define USB_ERREN_BTOERREN_SHIFT (4U) +#define USB_ERREN_BTOERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_BTOERREN_SHIFT)) & USB_ERREN_BTOERREN_MASK) +#define USB_ERREN_DMAERREN_MASK (0x20U) +#define USB_ERREN_DMAERREN_SHIFT (5U) +#define USB_ERREN_DMAERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_DMAERREN_SHIFT)) & USB_ERREN_DMAERREN_MASK) +#define USB_ERREN_OWNERREN_MASK (0x40U) +#define USB_ERREN_OWNERREN_SHIFT (6U) +#define USB_ERREN_OWNERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_OWNERREN_SHIFT)) & USB_ERREN_OWNERREN_MASK) +#define USB_ERREN_BTSERREN_MASK (0x80U) +#define USB_ERREN_BTSERREN_SHIFT (7U) +#define USB_ERREN_BTSERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_BTSERREN_SHIFT)) & USB_ERREN_BTSERREN_MASK) + +/*! @name STAT - Status register */ +#define USB_STAT_ODD_MASK (0x4U) +#define USB_STAT_ODD_SHIFT (2U) +#define USB_STAT_ODD(x) (((uint8_t)(((uint8_t)(x)) << USB_STAT_ODD_SHIFT)) & USB_STAT_ODD_MASK) +#define USB_STAT_TX_MASK (0x8U) +#define USB_STAT_TX_SHIFT (3U) +#define USB_STAT_TX(x) (((uint8_t)(((uint8_t)(x)) << USB_STAT_TX_SHIFT)) & USB_STAT_TX_MASK) +#define USB_STAT_ENDP_MASK (0xF0U) +#define USB_STAT_ENDP_SHIFT (4U) +#define USB_STAT_ENDP(x) (((uint8_t)(((uint8_t)(x)) << USB_STAT_ENDP_SHIFT)) & USB_STAT_ENDP_MASK) + +/*! @name CTL - Control register */ +#define USB_CTL_USBENSOFEN_MASK (0x1U) +#define USB_CTL_USBENSOFEN_SHIFT (0U) +#define USB_CTL_USBENSOFEN(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_USBENSOFEN_SHIFT)) & USB_CTL_USBENSOFEN_MASK) +#define USB_CTL_ODDRST_MASK (0x2U) +#define USB_CTL_ODDRST_SHIFT (1U) +#define USB_CTL_ODDRST(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_ODDRST_SHIFT)) & USB_CTL_ODDRST_MASK) +#define USB_CTL_RESUME_MASK (0x4U) +#define USB_CTL_RESUME_SHIFT (2U) +#define USB_CTL_RESUME(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_RESUME_SHIFT)) & USB_CTL_RESUME_MASK) +#define USB_CTL_HOSTMODEEN_MASK (0x8U) +#define USB_CTL_HOSTMODEEN_SHIFT (3U) +#define USB_CTL_HOSTMODEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_HOSTMODEEN_SHIFT)) & USB_CTL_HOSTMODEEN_MASK) +#define USB_CTL_RESET_MASK (0x10U) +#define USB_CTL_RESET_SHIFT (4U) +#define USB_CTL_RESET(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_RESET_SHIFT)) & USB_CTL_RESET_MASK) +#define USB_CTL_TXSUSPENDTOKENBUSY_MASK (0x20U) +#define USB_CTL_TXSUSPENDTOKENBUSY_SHIFT (5U) +#define USB_CTL_TXSUSPENDTOKENBUSY(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_TXSUSPENDTOKENBUSY_SHIFT)) & USB_CTL_TXSUSPENDTOKENBUSY_MASK) +#define USB_CTL_SE0_MASK (0x40U) +#define USB_CTL_SE0_SHIFT (6U) +#define USB_CTL_SE0(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_SE0_SHIFT)) & USB_CTL_SE0_MASK) +#define USB_CTL_JSTATE_MASK (0x80U) +#define USB_CTL_JSTATE_SHIFT (7U) +#define USB_CTL_JSTATE(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_JSTATE_SHIFT)) & USB_CTL_JSTATE_MASK) + +/*! @name ADDR - Address register */ +#define USB_ADDR_ADDR_MASK (0x7FU) +#define USB_ADDR_ADDR_SHIFT (0U) +#define USB_ADDR_ADDR(x) (((uint8_t)(((uint8_t)(x)) << USB_ADDR_ADDR_SHIFT)) & USB_ADDR_ADDR_MASK) +#define USB_ADDR_LSEN_MASK (0x80U) +#define USB_ADDR_LSEN_SHIFT (7U) +#define USB_ADDR_LSEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ADDR_LSEN_SHIFT)) & USB_ADDR_LSEN_MASK) + +/*! @name BDTPAGE1 - BDT Page register 1 */ +#define USB_BDTPAGE1_BDTBA_MASK (0xFEU) +#define USB_BDTPAGE1_BDTBA_SHIFT (1U) +#define USB_BDTPAGE1_BDTBA(x) (((uint8_t)(((uint8_t)(x)) << USB_BDTPAGE1_BDTBA_SHIFT)) & USB_BDTPAGE1_BDTBA_MASK) + +/*! @name FRMNUML - Frame Number register Low */ +#define USB_FRMNUML_FRM_MASK (0xFFU) +#define USB_FRMNUML_FRM_SHIFT (0U) +#define USB_FRMNUML_FRM(x) (((uint8_t)(((uint8_t)(x)) << USB_FRMNUML_FRM_SHIFT)) & USB_FRMNUML_FRM_MASK) + +/*! @name FRMNUMH - Frame Number register High */ +#define USB_FRMNUMH_FRM_MASK (0x7U) +#define USB_FRMNUMH_FRM_SHIFT (0U) +#define USB_FRMNUMH_FRM(x) (((uint8_t)(((uint8_t)(x)) << USB_FRMNUMH_FRM_SHIFT)) & USB_FRMNUMH_FRM_MASK) + +/*! @name TOKEN - Token register */ +#define USB_TOKEN_TOKENENDPT_MASK (0xFU) +#define USB_TOKEN_TOKENENDPT_SHIFT (0U) +#define USB_TOKEN_TOKENENDPT(x) (((uint8_t)(((uint8_t)(x)) << USB_TOKEN_TOKENENDPT_SHIFT)) & USB_TOKEN_TOKENENDPT_MASK) +#define USB_TOKEN_TOKENPID_MASK (0xF0U) +#define USB_TOKEN_TOKENPID_SHIFT (4U) +#define USB_TOKEN_TOKENPID(x) (((uint8_t)(((uint8_t)(x)) << USB_TOKEN_TOKENPID_SHIFT)) & USB_TOKEN_TOKENPID_MASK) + +/*! @name SOFTHLD - SOF Threshold register */ +#define USB_SOFTHLD_CNT_MASK (0xFFU) +#define USB_SOFTHLD_CNT_SHIFT (0U) +#define USB_SOFTHLD_CNT(x) (((uint8_t)(((uint8_t)(x)) << USB_SOFTHLD_CNT_SHIFT)) & USB_SOFTHLD_CNT_MASK) + +/*! @name BDTPAGE2 - BDT Page Register 2 */ +#define USB_BDTPAGE2_BDTBA_MASK (0xFFU) +#define USB_BDTPAGE2_BDTBA_SHIFT (0U) +#define USB_BDTPAGE2_BDTBA(x) (((uint8_t)(((uint8_t)(x)) << USB_BDTPAGE2_BDTBA_SHIFT)) & USB_BDTPAGE2_BDTBA_MASK) + +/*! @name BDTPAGE3 - BDT Page Register 3 */ +#define USB_BDTPAGE3_BDTBA_MASK (0xFFU) +#define USB_BDTPAGE3_BDTBA_SHIFT (0U) +#define USB_BDTPAGE3_BDTBA(x) (((uint8_t)(((uint8_t)(x)) << USB_BDTPAGE3_BDTBA_SHIFT)) & USB_BDTPAGE3_BDTBA_MASK) + +/*! @name ENDPT - Endpoint Control register */ +#define USB_ENDPT_EPHSHK_MASK (0x1U) +#define USB_ENDPT_EPHSHK_SHIFT (0U) +#define USB_ENDPT_EPHSHK(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPHSHK_SHIFT)) & USB_ENDPT_EPHSHK_MASK) +#define USB_ENDPT_EPSTALL_MASK (0x2U) +#define USB_ENDPT_EPSTALL_SHIFT (1U) +#define USB_ENDPT_EPSTALL(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPSTALL_SHIFT)) & USB_ENDPT_EPSTALL_MASK) +#define USB_ENDPT_EPTXEN_MASK (0x4U) +#define USB_ENDPT_EPTXEN_SHIFT (2U) +#define USB_ENDPT_EPTXEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPTXEN_SHIFT)) & USB_ENDPT_EPTXEN_MASK) +#define USB_ENDPT_EPRXEN_MASK (0x8U) +#define USB_ENDPT_EPRXEN_SHIFT (3U) +#define USB_ENDPT_EPRXEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPRXEN_SHIFT)) & USB_ENDPT_EPRXEN_MASK) +#define USB_ENDPT_EPCTLDIS_MASK (0x10U) +#define USB_ENDPT_EPCTLDIS_SHIFT (4U) +#define USB_ENDPT_EPCTLDIS(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPCTLDIS_SHIFT)) & USB_ENDPT_EPCTLDIS_MASK) +#define USB_ENDPT_RETRYDIS_MASK (0x40U) +#define USB_ENDPT_RETRYDIS_SHIFT (6U) +#define USB_ENDPT_RETRYDIS(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_RETRYDIS_SHIFT)) & USB_ENDPT_RETRYDIS_MASK) +#define USB_ENDPT_HOSTWOHUB_MASK (0x80U) +#define USB_ENDPT_HOSTWOHUB_SHIFT (7U) +#define USB_ENDPT_HOSTWOHUB(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_HOSTWOHUB_SHIFT)) & USB_ENDPT_HOSTWOHUB_MASK) + +/* The count of USB_ENDPT */ +#define USB_ENDPT_COUNT (16U) + +/*! @name USBCTRL - USB Control register */ +#define USB_USBCTRL_UARTSEL_MASK (0x10U) +#define USB_USBCTRL_UARTSEL_SHIFT (4U) +#define USB_USBCTRL_UARTSEL(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_UARTSEL_SHIFT)) & USB_USBCTRL_UARTSEL_MASK) +#define USB_USBCTRL_UARTCHLS_MASK (0x20U) +#define USB_USBCTRL_UARTCHLS_SHIFT (5U) +#define USB_USBCTRL_UARTCHLS(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_UARTCHLS_SHIFT)) & USB_USBCTRL_UARTCHLS_MASK) +#define USB_USBCTRL_PDE_MASK (0x40U) +#define USB_USBCTRL_PDE_SHIFT (6U) +#define USB_USBCTRL_PDE(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_PDE_SHIFT)) & USB_USBCTRL_PDE_MASK) +#define USB_USBCTRL_SUSP_MASK (0x80U) +#define USB_USBCTRL_SUSP_SHIFT (7U) +#define USB_USBCTRL_SUSP(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_SUSP_SHIFT)) & USB_USBCTRL_SUSP_MASK) + +/*! @name OBSERVE - USB OTG Observe register */ +#define USB_OBSERVE_DMPD_MASK (0x10U) +#define USB_OBSERVE_DMPD_SHIFT (4U) +#define USB_OBSERVE_DMPD(x) (((uint8_t)(((uint8_t)(x)) << USB_OBSERVE_DMPD_SHIFT)) & USB_OBSERVE_DMPD_MASK) +#define USB_OBSERVE_DPPD_MASK (0x40U) +#define USB_OBSERVE_DPPD_SHIFT (6U) +#define USB_OBSERVE_DPPD(x) (((uint8_t)(((uint8_t)(x)) << USB_OBSERVE_DPPD_SHIFT)) & USB_OBSERVE_DPPD_MASK) +#define USB_OBSERVE_DPPU_MASK (0x80U) +#define USB_OBSERVE_DPPU_SHIFT (7U) +#define USB_OBSERVE_DPPU(x) (((uint8_t)(((uint8_t)(x)) << USB_OBSERVE_DPPU_SHIFT)) & USB_OBSERVE_DPPU_MASK) + +/*! @name CONTROL - USB OTG Control register */ +#define USB_CONTROL_DPPULLUPNONOTG_MASK (0x10U) +#define USB_CONTROL_DPPULLUPNONOTG_SHIFT (4U) +#define USB_CONTROL_DPPULLUPNONOTG(x) (((uint8_t)(((uint8_t)(x)) << USB_CONTROL_DPPULLUPNONOTG_SHIFT)) & USB_CONTROL_DPPULLUPNONOTG_MASK) + +/*! @name USBTRC0 - USB Transceiver Control register 0 */ +#define USB_USBTRC0_USB_RESUME_INT_MASK (0x1U) +#define USB_USBTRC0_USB_RESUME_INT_SHIFT (0U) +#define USB_USBTRC0_USB_RESUME_INT(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USB_RESUME_INT_SHIFT)) & USB_USBTRC0_USB_RESUME_INT_MASK) +#define USB_USBTRC0_SYNC_DET_MASK (0x2U) +#define USB_USBTRC0_SYNC_DET_SHIFT (1U) +#define USB_USBTRC0_SYNC_DET(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_SYNC_DET_SHIFT)) & USB_USBTRC0_SYNC_DET_MASK) +#define USB_USBTRC0_USB_CLK_RECOVERY_INT_MASK (0x4U) +#define USB_USBTRC0_USB_CLK_RECOVERY_INT_SHIFT (2U) +#define USB_USBTRC0_USB_CLK_RECOVERY_INT(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USB_CLK_RECOVERY_INT_SHIFT)) & USB_USBTRC0_USB_CLK_RECOVERY_INT_MASK) +#define USB_USBTRC0_VREDG_DET_MASK (0x8U) +#define USB_USBTRC0_VREDG_DET_SHIFT (3U) +#define USB_USBTRC0_VREDG_DET(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_VREDG_DET_SHIFT)) & USB_USBTRC0_VREDG_DET_MASK) +#define USB_USBTRC0_VFEDG_DET_MASK (0x10U) +#define USB_USBTRC0_VFEDG_DET_SHIFT (4U) +#define USB_USBTRC0_VFEDG_DET(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_VFEDG_DET_SHIFT)) & USB_USBTRC0_VFEDG_DET_MASK) +#define USB_USBTRC0_USBRESMEN_MASK (0x20U) +#define USB_USBTRC0_USBRESMEN_SHIFT (5U) +#define USB_USBTRC0_USBRESMEN(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USBRESMEN_SHIFT)) & USB_USBTRC0_USBRESMEN_MASK) +#define USB_USBTRC0_USBRESET_MASK (0x80U) +#define USB_USBTRC0_USBRESET_SHIFT (7U) +#define USB_USBTRC0_USBRESET(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USBRESET_SHIFT)) & USB_USBTRC0_USBRESET_MASK) + +/*! @name USBFRMADJUST - Frame Adjust Register */ +#define USB_USBFRMADJUST_ADJ_MASK (0xFFU) +#define USB_USBFRMADJUST_ADJ_SHIFT (0U) +#define USB_USBFRMADJUST_ADJ(x) (((uint8_t)(((uint8_t)(x)) << USB_USBFRMADJUST_ADJ_SHIFT)) & USB_USBFRMADJUST_ADJ_MASK) + +/*! @name MISCCTRL - Miscellaneous Control register */ +#define USB_MISCCTRL_SOFDYNTHLD_MASK (0x1U) +#define USB_MISCCTRL_SOFDYNTHLD_SHIFT (0U) +#define USB_MISCCTRL_SOFDYNTHLD(x) (((uint8_t)(((uint8_t)(x)) << USB_MISCCTRL_SOFDYNTHLD_SHIFT)) & USB_MISCCTRL_SOFDYNTHLD_MASK) +#define USB_MISCCTRL_SOFBUSSET_MASK (0x2U) +#define USB_MISCCTRL_SOFBUSSET_SHIFT (1U) +#define USB_MISCCTRL_SOFBUSSET(x) (((uint8_t)(((uint8_t)(x)) << USB_MISCCTRL_SOFBUSSET_SHIFT)) & USB_MISCCTRL_SOFBUSSET_MASK) +#define USB_MISCCTRL_OWNERRISODIS_MASK (0x4U) +#define USB_MISCCTRL_OWNERRISODIS_SHIFT (2U) +#define USB_MISCCTRL_OWNERRISODIS(x) (((uint8_t)(((uint8_t)(x)) << USB_MISCCTRL_OWNERRISODIS_SHIFT)) & USB_MISCCTRL_OWNERRISODIS_MASK) +#define USB_MISCCTRL_VREDG_EN_MASK (0x8U) +#define USB_MISCCTRL_VREDG_EN_SHIFT (3U) +#define USB_MISCCTRL_VREDG_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_MISCCTRL_VREDG_EN_SHIFT)) & USB_MISCCTRL_VREDG_EN_MASK) +#define USB_MISCCTRL_VFEDG_EN_MASK (0x10U) +#define USB_MISCCTRL_VFEDG_EN_SHIFT (4U) +#define USB_MISCCTRL_VFEDG_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_MISCCTRL_VFEDG_EN_SHIFT)) & USB_MISCCTRL_VFEDG_EN_MASK) + +/*! @name CLK_RECOVER_CTRL - USB Clock recovery control */ +#define USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_MASK (0x20U) +#define USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_SHIFT (5U) +#define USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_SHIFT)) & USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_MASK) +#define USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_MASK (0x40U) +#define USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_SHIFT (6U) +#define USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_SHIFT)) & USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_MASK) +#define USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK (0x80U) +#define USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_SHIFT (7U) +#define USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_SHIFT)) & USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK) + +/*! @name CLK_RECOVER_IRC_EN - IRC48M oscillator enable register */ +#define USB_CLK_RECOVER_IRC_EN_REG_EN_MASK (0x1U) +#define USB_CLK_RECOVER_IRC_EN_REG_EN_SHIFT (0U) +#define USB_CLK_RECOVER_IRC_EN_REG_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_IRC_EN_REG_EN_SHIFT)) & USB_CLK_RECOVER_IRC_EN_REG_EN_MASK) +#define USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK (0x2U) +#define USB_CLK_RECOVER_IRC_EN_IRC_EN_SHIFT (1U) +#define USB_CLK_RECOVER_IRC_EN_IRC_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_IRC_EN_IRC_EN_SHIFT)) & USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK) + +/*! @name CLK_RECOVER_INT_EN - Clock recovery combined interrupt enable */ +#define USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN_MASK (0x10U) +#define USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN_SHIFT (4U) +#define USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN_SHIFT)) & USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN_MASK) + +/*! @name CLK_RECOVER_INT_STATUS - Clock recovery separated interrupt status */ +#define USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_MASK (0x10U) +#define USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_SHIFT (4U) +#define USB_CLK_RECOVER_INT_STATUS_OVF_ERROR(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_SHIFT)) & USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_MASK) + + +/*! + * @} + */ /* end of group USB_Register_Masks */ + + +/* USB - Peripheral instance base addresses */ +/** Peripheral USB0 base address */ +#define USB0_BASE (0x40072000u) +/** Peripheral USB0 base pointer */ +#define USB0 ((USB_Type *)USB0_BASE) +/** Array initializer of USB peripheral base addresses */ +#define USB_BASE_ADDRS { USB0_BASE } +/** Array initializer of USB peripheral base pointers */ +#define USB_BASE_PTRS { USB0 } +/** Interrupt vectors for the USB peripheral type */ +#define USB_IRQS { USB0_IRQn } + +/*! + * @} + */ /* end of group USB_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- USBDCD Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USBDCD_Peripheral_Access_Layer USBDCD Peripheral Access Layer + * @{ + */ + +/** USBDCD - Register Layout Typedef */ +typedef struct { + __IO uint32_t CONTROL; /**< Control register, offset: 0x0 */ + __IO uint32_t CLOCK; /**< Clock register, offset: 0x4 */ + __I uint32_t STATUS; /**< Status register, offset: 0x8 */ + __IO uint32_t SIGNAL_OVERRIDE; /**< Signal Override Register, offset: 0xC */ + __IO uint32_t TIMER0; /**< TIMER0 register, offset: 0x10 */ + __IO uint32_t TIMER1; /**< TIMER1 register, offset: 0x14 */ + union { /* offset: 0x18 */ + __IO uint32_t TIMER2_BC11; /**< TIMER2_BC11 register, offset: 0x18 */ + __IO uint32_t TIMER2_BC12; /**< TIMER2_BC12 register, offset: 0x18 */ + }; +} USBDCD_Type; + +/* ---------------------------------------------------------------------------- + -- USBDCD Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USBDCD_Register_Masks USBDCD Register Masks + * @{ + */ + +/*! @name CONTROL - Control register */ +#define USBDCD_CONTROL_IACK_MASK (0x1U) +#define USBDCD_CONTROL_IACK_SHIFT (0U) +#define USBDCD_CONTROL_IACK(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CONTROL_IACK_SHIFT)) & USBDCD_CONTROL_IACK_MASK) +#define USBDCD_CONTROL_IF_MASK (0x100U) +#define USBDCD_CONTROL_IF_SHIFT (8U) +#define USBDCD_CONTROL_IF(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CONTROL_IF_SHIFT)) & USBDCD_CONTROL_IF_MASK) +#define USBDCD_CONTROL_IE_MASK (0x10000U) +#define USBDCD_CONTROL_IE_SHIFT (16U) +#define USBDCD_CONTROL_IE(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CONTROL_IE_SHIFT)) & USBDCD_CONTROL_IE_MASK) +#define USBDCD_CONTROL_BC12_MASK (0x20000U) +#define USBDCD_CONTROL_BC12_SHIFT (17U) +#define USBDCD_CONTROL_BC12(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CONTROL_BC12_SHIFT)) & USBDCD_CONTROL_BC12_MASK) +#define USBDCD_CONTROL_START_MASK (0x1000000U) +#define USBDCD_CONTROL_START_SHIFT (24U) +#define USBDCD_CONTROL_START(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CONTROL_START_SHIFT)) & USBDCD_CONTROL_START_MASK) +#define USBDCD_CONTROL_SR_MASK (0x2000000U) +#define USBDCD_CONTROL_SR_SHIFT (25U) +#define USBDCD_CONTROL_SR(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CONTROL_SR_SHIFT)) & USBDCD_CONTROL_SR_MASK) + +/*! @name CLOCK - Clock register */ +#define USBDCD_CLOCK_CLOCK_UNIT_MASK (0x1U) +#define USBDCD_CLOCK_CLOCK_UNIT_SHIFT (0U) +#define USBDCD_CLOCK_CLOCK_UNIT(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CLOCK_CLOCK_UNIT_SHIFT)) & USBDCD_CLOCK_CLOCK_UNIT_MASK) +#define USBDCD_CLOCK_CLOCK_SPEED_MASK (0xFFCU) +#define USBDCD_CLOCK_CLOCK_SPEED_SHIFT (2U) +#define USBDCD_CLOCK_CLOCK_SPEED(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CLOCK_CLOCK_SPEED_SHIFT)) & USBDCD_CLOCK_CLOCK_SPEED_MASK) + +/*! @name STATUS - Status register */ +#define USBDCD_STATUS_SEQ_RES_MASK (0x30000U) +#define USBDCD_STATUS_SEQ_RES_SHIFT (16U) +#define USBDCD_STATUS_SEQ_RES(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_STATUS_SEQ_RES_SHIFT)) & USBDCD_STATUS_SEQ_RES_MASK) +#define USBDCD_STATUS_SEQ_STAT_MASK (0xC0000U) +#define USBDCD_STATUS_SEQ_STAT_SHIFT (18U) +#define USBDCD_STATUS_SEQ_STAT(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_STATUS_SEQ_STAT_SHIFT)) & USBDCD_STATUS_SEQ_STAT_MASK) +#define USBDCD_STATUS_ERR_MASK (0x100000U) +#define USBDCD_STATUS_ERR_SHIFT (20U) +#define USBDCD_STATUS_ERR(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_STATUS_ERR_SHIFT)) & USBDCD_STATUS_ERR_MASK) +#define USBDCD_STATUS_TO_MASK (0x200000U) +#define USBDCD_STATUS_TO_SHIFT (21U) +#define USBDCD_STATUS_TO(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_STATUS_TO_SHIFT)) & USBDCD_STATUS_TO_MASK) +#define USBDCD_STATUS_ACTIVE_MASK (0x400000U) +#define USBDCD_STATUS_ACTIVE_SHIFT (22U) +#define USBDCD_STATUS_ACTIVE(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_STATUS_ACTIVE_SHIFT)) & USBDCD_STATUS_ACTIVE_MASK) + +/*! @name SIGNAL_OVERRIDE - Signal Override Register */ +#define USBDCD_SIGNAL_OVERRIDE_PS_MASK (0x3U) +#define USBDCD_SIGNAL_OVERRIDE_PS_SHIFT (0U) +#define USBDCD_SIGNAL_OVERRIDE_PS(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_SIGNAL_OVERRIDE_PS_SHIFT)) & USBDCD_SIGNAL_OVERRIDE_PS_MASK) + +/*! @name TIMER0 - TIMER0 register */ +#define USBDCD_TIMER0_TUNITCON_MASK (0xFFFU) +#define USBDCD_TIMER0_TUNITCON_SHIFT (0U) +#define USBDCD_TIMER0_TUNITCON(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER0_TUNITCON_SHIFT)) & USBDCD_TIMER0_TUNITCON_MASK) +#define USBDCD_TIMER0_TSEQ_INIT_MASK (0x3FF0000U) +#define USBDCD_TIMER0_TSEQ_INIT_SHIFT (16U) +#define USBDCD_TIMER0_TSEQ_INIT(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER0_TSEQ_INIT_SHIFT)) & USBDCD_TIMER0_TSEQ_INIT_MASK) + +/*! @name TIMER1 - TIMER1 register */ +#define USBDCD_TIMER1_TVDPSRC_ON_MASK (0x3FFU) +#define USBDCD_TIMER1_TVDPSRC_ON_SHIFT (0U) +#define USBDCD_TIMER1_TVDPSRC_ON(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER1_TVDPSRC_ON_SHIFT)) & USBDCD_TIMER1_TVDPSRC_ON_MASK) +#define USBDCD_TIMER1_TDCD_DBNC_MASK (0x3FF0000U) +#define USBDCD_TIMER1_TDCD_DBNC_SHIFT (16U) +#define USBDCD_TIMER1_TDCD_DBNC(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER1_TDCD_DBNC_SHIFT)) & USBDCD_TIMER1_TDCD_DBNC_MASK) + +/*! @name TIMER2_BC11 - TIMER2_BC11 register */ +#define USBDCD_TIMER2_BC11_CHECK_DM_MASK (0xFU) +#define USBDCD_TIMER2_BC11_CHECK_DM_SHIFT (0U) +#define USBDCD_TIMER2_BC11_CHECK_DM(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER2_BC11_CHECK_DM_SHIFT)) & USBDCD_TIMER2_BC11_CHECK_DM_MASK) +#define USBDCD_TIMER2_BC11_TVDPSRC_CON_MASK (0x3FF0000U) +#define USBDCD_TIMER2_BC11_TVDPSRC_CON_SHIFT (16U) +#define USBDCD_TIMER2_BC11_TVDPSRC_CON(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER2_BC11_TVDPSRC_CON_SHIFT)) & USBDCD_TIMER2_BC11_TVDPSRC_CON_MASK) + +/*! @name TIMER2_BC12 - TIMER2_BC12 register */ +#define USBDCD_TIMER2_BC12_TVDMSRC_ON_MASK (0x3FFU) +#define USBDCD_TIMER2_BC12_TVDMSRC_ON_SHIFT (0U) +#define USBDCD_TIMER2_BC12_TVDMSRC_ON(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER2_BC12_TVDMSRC_ON_SHIFT)) & USBDCD_TIMER2_BC12_TVDMSRC_ON_MASK) +#define USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD_MASK (0x3FF0000U) +#define USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD_SHIFT (16U) +#define USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD_SHIFT)) & USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD_MASK) + + +/*! + * @} + */ /* end of group USBDCD_Register_Masks */ + + +/* USBDCD - Peripheral instance base addresses */ +/** Peripheral USBDCD base address */ +#define USBDCD_BASE (0x40035000u) +/** Peripheral USBDCD base pointer */ +#define USBDCD ((USBDCD_Type *)USBDCD_BASE) +/** Array initializer of USBDCD peripheral base addresses */ +#define USBDCD_BASE_ADDRS { USBDCD_BASE } +/** Array initializer of USBDCD peripheral base pointers */ +#define USBDCD_BASE_PTRS { USBDCD } +/** Interrupt vectors for the USBDCD peripheral type */ +#define USBDCD_IRQS { USBDCD_IRQn } + +/*! + * @} + */ /* end of group USBDCD_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- VREF Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup VREF_Peripheral_Access_Layer VREF Peripheral Access Layer + * @{ + */ + +/** VREF - Register Layout Typedef */ +typedef struct { + __IO uint8_t TRM; /**< VREF Trim Register, offset: 0x0 */ + __IO uint8_t SC; /**< VREF Status and Control Register, offset: 0x1 */ +} VREF_Type; + +/* ---------------------------------------------------------------------------- + -- VREF Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup VREF_Register_Masks VREF Register Masks + * @{ + */ + +/*! @name TRM - VREF Trim Register */ +#define VREF_TRM_TRIM_MASK (0x3FU) +#define VREF_TRM_TRIM_SHIFT (0U) +#define VREF_TRM_TRIM(x) (((uint8_t)(((uint8_t)(x)) << VREF_TRM_TRIM_SHIFT)) & VREF_TRM_TRIM_MASK) +#define VREF_TRM_CHOPEN_MASK (0x40U) +#define VREF_TRM_CHOPEN_SHIFT (6U) +#define VREF_TRM_CHOPEN(x) (((uint8_t)(((uint8_t)(x)) << VREF_TRM_CHOPEN_SHIFT)) & VREF_TRM_CHOPEN_MASK) + +/*! @name SC - VREF Status and Control Register */ +#define VREF_SC_MODE_LV_MASK (0x3U) +#define VREF_SC_MODE_LV_SHIFT (0U) +#define VREF_SC_MODE_LV(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_MODE_LV_SHIFT)) & VREF_SC_MODE_LV_MASK) +#define VREF_SC_VREFST_MASK (0x4U) +#define VREF_SC_VREFST_SHIFT (2U) +#define VREF_SC_VREFST(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_VREFST_SHIFT)) & VREF_SC_VREFST_MASK) +#define VREF_SC_ICOMPEN_MASK (0x20U) +#define VREF_SC_ICOMPEN_SHIFT (5U) +#define VREF_SC_ICOMPEN(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_ICOMPEN_SHIFT)) & VREF_SC_ICOMPEN_MASK) +#define VREF_SC_REGEN_MASK (0x40U) +#define VREF_SC_REGEN_SHIFT (6U) +#define VREF_SC_REGEN(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_REGEN_SHIFT)) & VREF_SC_REGEN_MASK) +#define VREF_SC_VREFEN_MASK (0x80U) +#define VREF_SC_VREFEN_SHIFT (7U) +#define VREF_SC_VREFEN(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_VREFEN_SHIFT)) & VREF_SC_VREFEN_MASK) + + +/*! + * @} + */ /* end of group VREF_Register_Masks */ + + +/* VREF - Peripheral instance base addresses */ +/** Peripheral VREF base address */ +#define VREF_BASE (0x40074000u) +/** Peripheral VREF base pointer */ +#define VREF ((VREF_Type *)VREF_BASE) +/** Array initializer of VREF peripheral base addresses */ +#define VREF_BASE_ADDRS { VREF_BASE } +/** Array initializer of VREF peripheral base pointers */ +#define VREF_BASE_PTRS { VREF } + +/*! + * @} + */ /* end of group VREF_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- WDOG Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup WDOG_Peripheral_Access_Layer WDOG Peripheral Access Layer + * @{ + */ + +/** WDOG - Register Layout Typedef */ +typedef struct { + __IO uint16_t STCTRLH; /**< Watchdog Status and Control Register High, offset: 0x0 */ + __IO uint16_t STCTRLL; /**< Watchdog Status and Control Register Low, offset: 0x2 */ + __IO uint16_t TOVALH; /**< Watchdog Time-out Value Register High, offset: 0x4 */ + __IO uint16_t TOVALL; /**< Watchdog Time-out Value Register Low, offset: 0x6 */ + __IO uint16_t WINH; /**< Watchdog Window Register High, offset: 0x8 */ + __IO uint16_t WINL; /**< Watchdog Window Register Low, offset: 0xA */ + __IO uint16_t REFRESH; /**< Watchdog Refresh register, offset: 0xC */ + __IO uint16_t UNLOCK; /**< Watchdog Unlock register, offset: 0xE */ + __IO uint16_t TMROUTH; /**< Watchdog Timer Output Register High, offset: 0x10 */ + __IO uint16_t TMROUTL; /**< Watchdog Timer Output Register Low, offset: 0x12 */ + __IO uint16_t RSTCNT; /**< Watchdog Reset Count register, offset: 0x14 */ + __IO uint16_t PRESC; /**< Watchdog Prescaler register, offset: 0x16 */ +} WDOG_Type; + +/* ---------------------------------------------------------------------------- + -- WDOG Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup WDOG_Register_Masks WDOG Register Masks + * @{ + */ + +/*! @name STCTRLH - Watchdog Status and Control Register High */ +#define WDOG_STCTRLH_WDOGEN_MASK (0x1U) +#define WDOG_STCTRLH_WDOGEN_SHIFT (0U) +#define WDOG_STCTRLH_WDOGEN(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_WDOGEN_SHIFT)) & WDOG_STCTRLH_WDOGEN_MASK) +#define WDOG_STCTRLH_CLKSRC_MASK (0x2U) +#define WDOG_STCTRLH_CLKSRC_SHIFT (1U) +#define WDOG_STCTRLH_CLKSRC(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_CLKSRC_SHIFT)) & WDOG_STCTRLH_CLKSRC_MASK) +#define WDOG_STCTRLH_IRQRSTEN_MASK (0x4U) +#define WDOG_STCTRLH_IRQRSTEN_SHIFT (2U) +#define WDOG_STCTRLH_IRQRSTEN(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_IRQRSTEN_SHIFT)) & WDOG_STCTRLH_IRQRSTEN_MASK) +#define WDOG_STCTRLH_WINEN_MASK (0x8U) +#define WDOG_STCTRLH_WINEN_SHIFT (3U) +#define WDOG_STCTRLH_WINEN(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_WINEN_SHIFT)) & WDOG_STCTRLH_WINEN_MASK) +#define WDOG_STCTRLH_ALLOWUPDATE_MASK (0x10U) +#define WDOG_STCTRLH_ALLOWUPDATE_SHIFT (4U) +#define WDOG_STCTRLH_ALLOWUPDATE(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_ALLOWUPDATE_SHIFT)) & WDOG_STCTRLH_ALLOWUPDATE_MASK) +#define WDOG_STCTRLH_DBGEN_MASK (0x20U) +#define WDOG_STCTRLH_DBGEN_SHIFT (5U) +#define WDOG_STCTRLH_DBGEN(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_DBGEN_SHIFT)) & WDOG_STCTRLH_DBGEN_MASK) +#define WDOG_STCTRLH_STOPEN_MASK (0x40U) +#define WDOG_STCTRLH_STOPEN_SHIFT (6U) +#define WDOG_STCTRLH_STOPEN(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_STOPEN_SHIFT)) & WDOG_STCTRLH_STOPEN_MASK) +#define WDOG_STCTRLH_WAITEN_MASK (0x80U) +#define WDOG_STCTRLH_WAITEN_SHIFT (7U) +#define WDOG_STCTRLH_WAITEN(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_WAITEN_SHIFT)) & WDOG_STCTRLH_WAITEN_MASK) +#define WDOG_STCTRLH_TESTWDOG_MASK (0x400U) +#define WDOG_STCTRLH_TESTWDOG_SHIFT (10U) +#define WDOG_STCTRLH_TESTWDOG(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_TESTWDOG_SHIFT)) & WDOG_STCTRLH_TESTWDOG_MASK) +#define WDOG_STCTRLH_TESTSEL_MASK (0x800U) +#define WDOG_STCTRLH_TESTSEL_SHIFT (11U) +#define WDOG_STCTRLH_TESTSEL(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_TESTSEL_SHIFT)) & WDOG_STCTRLH_TESTSEL_MASK) +#define WDOG_STCTRLH_BYTESEL_MASK (0x3000U) +#define WDOG_STCTRLH_BYTESEL_SHIFT (12U) +#define WDOG_STCTRLH_BYTESEL(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_BYTESEL_SHIFT)) & WDOG_STCTRLH_BYTESEL_MASK) +#define WDOG_STCTRLH_DISTESTWDOG_MASK (0x4000U) +#define WDOG_STCTRLH_DISTESTWDOG_SHIFT (14U) +#define WDOG_STCTRLH_DISTESTWDOG(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_DISTESTWDOG_SHIFT)) & WDOG_STCTRLH_DISTESTWDOG_MASK) + +/*! @name STCTRLL - Watchdog Status and Control Register Low */ +#define WDOG_STCTRLL_INTFLG_MASK (0x8000U) +#define WDOG_STCTRLL_INTFLG_SHIFT (15U) +#define WDOG_STCTRLL_INTFLG(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLL_INTFLG_SHIFT)) & WDOG_STCTRLL_INTFLG_MASK) + +/*! @name TOVALH - Watchdog Time-out Value Register High */ +#define WDOG_TOVALH_TOVALHIGH_MASK (0xFFFFU) +#define WDOG_TOVALH_TOVALHIGH_SHIFT (0U) +#define WDOG_TOVALH_TOVALHIGH(x) (((uint16_t)(((uint16_t)(x)) << WDOG_TOVALH_TOVALHIGH_SHIFT)) & WDOG_TOVALH_TOVALHIGH_MASK) + +/*! @name TOVALL - Watchdog Time-out Value Register Low */ +#define WDOG_TOVALL_TOVALLOW_MASK (0xFFFFU) +#define WDOG_TOVALL_TOVALLOW_SHIFT (0U) +#define WDOG_TOVALL_TOVALLOW(x) (((uint16_t)(((uint16_t)(x)) << WDOG_TOVALL_TOVALLOW_SHIFT)) & WDOG_TOVALL_TOVALLOW_MASK) + +/*! @name WINH - Watchdog Window Register High */ +#define WDOG_WINH_WINHIGH_MASK (0xFFFFU) +#define WDOG_WINH_WINHIGH_SHIFT (0U) +#define WDOG_WINH_WINHIGH(x) (((uint16_t)(((uint16_t)(x)) << WDOG_WINH_WINHIGH_SHIFT)) & WDOG_WINH_WINHIGH_MASK) + +/*! @name WINL - Watchdog Window Register Low */ +#define WDOG_WINL_WINLOW_MASK (0xFFFFU) +#define WDOG_WINL_WINLOW_SHIFT (0U) +#define WDOG_WINL_WINLOW(x) (((uint16_t)(((uint16_t)(x)) << WDOG_WINL_WINLOW_SHIFT)) & WDOG_WINL_WINLOW_MASK) + +/*! @name REFRESH - Watchdog Refresh register */ +#define WDOG_REFRESH_WDOGREFRESH_MASK (0xFFFFU) +#define WDOG_REFRESH_WDOGREFRESH_SHIFT (0U) +#define WDOG_REFRESH_WDOGREFRESH(x) (((uint16_t)(((uint16_t)(x)) << WDOG_REFRESH_WDOGREFRESH_SHIFT)) & WDOG_REFRESH_WDOGREFRESH_MASK) + +/*! @name UNLOCK - Watchdog Unlock register */ +#define WDOG_UNLOCK_WDOGUNLOCK_MASK (0xFFFFU) +#define WDOG_UNLOCK_WDOGUNLOCK_SHIFT (0U) +#define WDOG_UNLOCK_WDOGUNLOCK(x) (((uint16_t)(((uint16_t)(x)) << WDOG_UNLOCK_WDOGUNLOCK_SHIFT)) & WDOG_UNLOCK_WDOGUNLOCK_MASK) + +/*! @name TMROUTH - Watchdog Timer Output Register High */ +#define WDOG_TMROUTH_TIMEROUTHIGH_MASK (0xFFFFU) +#define WDOG_TMROUTH_TIMEROUTHIGH_SHIFT (0U) +#define WDOG_TMROUTH_TIMEROUTHIGH(x) (((uint16_t)(((uint16_t)(x)) << WDOG_TMROUTH_TIMEROUTHIGH_SHIFT)) & WDOG_TMROUTH_TIMEROUTHIGH_MASK) + +/*! @name TMROUTL - Watchdog Timer Output Register Low */ +#define WDOG_TMROUTL_TIMEROUTLOW_MASK (0xFFFFU) +#define WDOG_TMROUTL_TIMEROUTLOW_SHIFT (0U) +#define WDOG_TMROUTL_TIMEROUTLOW(x) (((uint16_t)(((uint16_t)(x)) << WDOG_TMROUTL_TIMEROUTLOW_SHIFT)) & WDOG_TMROUTL_TIMEROUTLOW_MASK) + +/*! @name RSTCNT - Watchdog Reset Count register */ +#define WDOG_RSTCNT_RSTCNT_MASK (0xFFFFU) +#define WDOG_RSTCNT_RSTCNT_SHIFT (0U) +#define WDOG_RSTCNT_RSTCNT(x) (((uint16_t)(((uint16_t)(x)) << WDOG_RSTCNT_RSTCNT_SHIFT)) & WDOG_RSTCNT_RSTCNT_MASK) + +/*! @name PRESC - Watchdog Prescaler register */ +#define WDOG_PRESC_PRESCVAL_MASK (0x700U) +#define WDOG_PRESC_PRESCVAL_SHIFT (8U) +#define WDOG_PRESC_PRESCVAL(x) (((uint16_t)(((uint16_t)(x)) << WDOG_PRESC_PRESCVAL_SHIFT)) & WDOG_PRESC_PRESCVAL_MASK) + + +/*! + * @} + */ /* end of group WDOG_Register_Masks */ + + +/* WDOG - Peripheral instance base addresses */ +/** Peripheral WDOG base address */ +#define WDOG_BASE (0x40052000u) +/** Peripheral WDOG base pointer */ +#define WDOG ((WDOG_Type *)WDOG_BASE) +/** Array initializer of WDOG peripheral base addresses */ +#define WDOG_BASE_ADDRS { WDOG_BASE } +/** Array initializer of WDOG peripheral base pointers */ +#define WDOG_BASE_PTRS { WDOG } +/** Interrupt vectors for the WDOG peripheral type */ +#define WDOG_IRQS { WDOG_EWM_IRQn } + +/*! + * @} + */ /* end of group WDOG_Peripheral_Access_Layer */ + + +/* +** End of section using anonymous unions +*/ + +#if defined(__ARMCC_VERSION) + #pragma pop +#elif defined(__CWCC__) + #pragma pop +#elif defined(__GNUC__) + /* leave anonymous unions enabled */ +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma language=default +#else + #error Not supported compiler type +#endif + +/*! + * @} + */ /* end of group Peripheral_access_layer */ + + +/* ---------------------------------------------------------------------------- + -- SDK Compatibility + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SDK_Compatibility_Symbols SDK Compatibility + * @{ + */ + +#define PIT0_IRQn PIT0CH0_IRQn +#define PIT1_IRQn PIT0CH1_IRQn +#define PIT2_IRQn PIT0CH2_IRQn +#define PIT3_IRQn PIT0CH3_IRQn +#define PIT_BASE PIT0_BASE +#define PIT PIT0 +#define PIT_MCR PIT0_MCR +#define PIT_LDVAL0 PIT0_LDVAL0 +#define PIT_CVAL0 PIT0_CVAL0 +#define PIT_TCTRL0 PIT0_TCTRL0 +#define PIT_TFLG0 PIT0_TFLG0 +#define PIT_LDVAL1 PIT0_LDVAL1 +#define PIT_CVAL1 PIT0_CVAL1 +#define PIT_TCTRL1 PIT0_TCTRL1 +#define PIT_TFLG1 PIT0_TFLG1 +#define PIT_LDVAL2 PIT0_LDVAL2 +#define PIT_CVAL2 PIT0_CVAL2 +#define PIT_TCTRL2 PIT0_TCTRL2 +#define PIT_TFLG2 PIT0_TFLG2 +#define PIT_LDVAL3 PIT0_LDVAL3 +#define PIT_CVAL3 PIT0_CVAL3 +#define PIT_TCTRL3 PIT0_TCTRL3 +#define PIT_TFLG3 PIT0_TFLG3 +#define PIT_LDVAL(index) PIT0_LDVAL(index) +#define PIT_CVAL(index) PIT0_CVAL(index) +#define PIT_TCTRL(index) PIT0_TCTRL(index) +#define PIT_TFLG(index) PIT0_TFLG(index) +#define PIT0_IRQHandler PIT0CH0_IRQHandler +#define PIT1_IRQHandler PIT0CH1_IRQHandler +#define PIT2_IRQHandler PIT0CH2_IRQHandler +#define PIT3_IRQHandler PIT0CH3_IRQHandler +#define DSPI0 SPI0 +#define DSPI1 SPI1 +#define DSPI2 SPI2 +#define DMAMUX0 DMAMUX + +/*! + * @} + */ /* end of group SDK_Compatibility_Symbols */ + + +#endif /* _MK82F25615_H_ */ + diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/MK82F25615_features.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/MK82F25615_features.h new file mode 100644 index 00000000000..94879d630c5 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/MK82F25615_features.h @@ -0,0 +1,2171 @@ +/* +** ################################################################### +** Version: rev. 1.5, 2015-08-17 +** Build: b160829 +** +** Abstract: +** Chip specific module features. +** +** Copyright (c) 2016 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** Revisions: +** - rev. 1.0 (2015-04-09) +** Initial version +** - rev. 1.1 (2015-05-19) +** FSL_FEATURE_SOC_CAU_COUNT remamed to FSL_FEATURE_SOC_MMCAU_COUNT. +** Added FSL_FEATURE_SOC_peripheral_COUNT for TRNG and HSADC. +** Added features for PDB, PORT and LTC. +** - rev. 1.2 (2015-05-25) +** Added FSL_FEATURE_FLASH_PFLASH_START_ADDRESS +** - rev. 1.3 (2015-05-27) +** Several USB features added. +** - rev. 1.4 (2015-06-08) +** FTM features BUS_CLOCK and FAST_CLOCK removed. +** - rev. 1.5 (2015-08-17) +** LLWU features updated (pinout update). +** +** ################################################################### +*/ + +#ifndef _MK82F25615_FEATURES_H_ +#define _MK82F25615_FEATURES_H_ + +/* SOC module features */ + +/* @brief ACMP availability on the SoC. */ +#define FSL_FEATURE_SOC_ACMP_COUNT (0) +/* @brief ADC16 availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC16_COUNT (1) +/* @brief ADC12 availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC12_COUNT (0) +/* @brief AFE availability on the SoC. */ +#define FSL_FEATURE_SOC_AFE_COUNT (0) +/* @brief AIPS availability on the SoC. */ +#define FSL_FEATURE_SOC_AIPS_COUNT (2) +/* @brief AOI availability on the SoC. */ +#define FSL_FEATURE_SOC_AOI_COUNT (0) +/* @brief AXBS availability on the SoC. */ +#define FSL_FEATURE_SOC_AXBS_COUNT (1) +/* @brief ASMC availability on the SoC. */ +#define FSL_FEATURE_SOC_ASMC_COUNT (0) +/* @brief CADC availability on the SoC. */ +#define FSL_FEATURE_SOC_CADC_COUNT (0) +/* @brief FLEXCAN availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXCAN_COUNT (0) +/* @brief MMCAU availability on the SoC. */ +#define FSL_FEATURE_SOC_MMCAU_COUNT (1) +/* @brief CMP availability on the SoC. */ +#define FSL_FEATURE_SOC_CMP_COUNT (2) +/* @brief CMT availability on the SoC. */ +#define FSL_FEATURE_SOC_CMT_COUNT (1) +/* @brief CNC availability on the SoC. */ +#define FSL_FEATURE_SOC_CNC_COUNT (0) +/* @brief CRC availability on the SoC. */ +#define FSL_FEATURE_SOC_CRC_COUNT (1) +/* @brief DAC availability on the SoC. */ +#define FSL_FEATURE_SOC_DAC_COUNT (1) +/* @brief DAC32 availability on the SoC. */ +#define FSL_FEATURE_SOC_DAC32_COUNT (0) +/* @brief DCDC availability on the SoC. */ +#define FSL_FEATURE_SOC_DCDC_COUNT (0) +/* @brief DDR availability on the SoC. */ +#define FSL_FEATURE_SOC_DDR_COUNT (0) +/* @brief DMA availability on the SoC. */ +#define FSL_FEATURE_SOC_DMA_COUNT (0) +/* @brief EDMA availability on the SoC. */ +#define FSL_FEATURE_SOC_EDMA_COUNT (1) +/* @brief DMAMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_DMAMUX_COUNT (1) +/* @brief DRY availability on the SoC. */ +#define FSL_FEATURE_SOC_DRY_COUNT (0) +/* @brief DSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_DSPI_COUNT (3) +/* @brief EMVSIM availability on the SoC. */ +#define FSL_FEATURE_SOC_EMVSIM_COUNT (2) +/* @brief ENC availability on the SoC. */ +#define FSL_FEATURE_SOC_ENC_COUNT (0) +/* @brief ENET availability on the SoC. */ +#define FSL_FEATURE_SOC_ENET_COUNT (0) +/* @brief EWM availability on the SoC. */ +#define FSL_FEATURE_SOC_EWM_COUNT (1) +/* @brief FB availability on the SoC. */ +#define FSL_FEATURE_SOC_FB_COUNT (1) +/* @brief FGPIO availability on the SoC. */ +#define FSL_FEATURE_SOC_FGPIO_COUNT (0) +/* @brief FLEXIO availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXIO_COUNT (1) +/* @brief FMC availability on the SoC. */ +#define FSL_FEATURE_SOC_FMC_COUNT (1) +/* @brief FSKDT availability on the SoC. */ +#define FSL_FEATURE_SOC_FSKDT_COUNT (0) +/* @brief FTFA availability on the SoC. */ +#define FSL_FEATURE_SOC_FTFA_COUNT (1) +/* @brief FTFE availability on the SoC. */ +#define FSL_FEATURE_SOC_FTFE_COUNT (0) +/* @brief FTFL availability on the SoC. */ +#define FSL_FEATURE_SOC_FTFL_COUNT (0) +/* @brief FTM availability on the SoC. */ +#define FSL_FEATURE_SOC_FTM_COUNT (4) +/* @brief FTMRA availability on the SoC. */ +#define FSL_FEATURE_SOC_FTMRA_COUNT (0) +/* @brief FTMRE availability on the SoC. */ +#define FSL_FEATURE_SOC_FTMRE_COUNT (0) +/* @brief FTMRH availability on the SoC. */ +#define FSL_FEATURE_SOC_FTMRH_COUNT (0) +/* @brief GPIO availability on the SoC. */ +#define FSL_FEATURE_SOC_GPIO_COUNT (5) +/* @brief HSADC availability on the SoC. */ +#define FSL_FEATURE_SOC_HSADC_COUNT (0) +/* @brief I2C availability on the SoC. */ +#define FSL_FEATURE_SOC_I2C_COUNT (4) +/* @brief I2S availability on the SoC. */ +#define FSL_FEATURE_SOC_I2S_COUNT (1) +/* @brief ICS availability on the SoC. */ +#define FSL_FEATURE_SOC_ICS_COUNT (0) +/* @brief INTMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_INTMUX_COUNT (0) +/* @brief IRQ availability on the SoC. */ +#define FSL_FEATURE_SOC_IRQ_COUNT (0) +/* @brief KBI availability on the SoC. */ +#define FSL_FEATURE_SOC_KBI_COUNT (0) +/* @brief SLCD availability on the SoC. */ +#define FSL_FEATURE_SOC_SLCD_COUNT (0) +/* @brief LCDC availability on the SoC. */ +#define FSL_FEATURE_SOC_LCDC_COUNT (0) +/* @brief LDO availability on the SoC. */ +#define FSL_FEATURE_SOC_LDO_COUNT (0) +/* @brief LLWU availability on the SoC. */ +#define FSL_FEATURE_SOC_LLWU_COUNT (1) +/* @brief LMEM availability on the SoC. */ +#define FSL_FEATURE_SOC_LMEM_COUNT (1) +/* @brief LPI2C availability on the SoC. */ +#define FSL_FEATURE_SOC_LPI2C_COUNT (0) +/* @brief LPIT availability on the SoC. */ +#define FSL_FEATURE_SOC_LPIT_COUNT (0) +/* @brief LPSCI availability on the SoC. */ +#define FSL_FEATURE_SOC_LPSCI_COUNT (0) +/* @brief LPSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_LPSPI_COUNT (0) +/* @brief LPTMR availability on the SoC. */ +#define FSL_FEATURE_SOC_LPTMR_COUNT (2) +/* @brief LPTPM availability on the SoC. */ +#define FSL_FEATURE_SOC_LPTPM_COUNT (0) +/* @brief LPUART availability on the SoC. */ +#define FSL_FEATURE_SOC_LPUART_COUNT (5) +/* @brief LTC availability on the SoC. */ +#define FSL_FEATURE_SOC_LTC_COUNT (1) +/* @brief MC availability on the SoC. */ +#define FSL_FEATURE_SOC_MC_COUNT (0) +/* @brief MCG availability on the SoC. */ +#define FSL_FEATURE_SOC_MCG_COUNT (1) +/* @brief MCGLITE availability on the SoC. */ +#define FSL_FEATURE_SOC_MCGLITE_COUNT (0) +/* @brief MCM availability on the SoC. */ +#define FSL_FEATURE_SOC_MCM_COUNT (1) +/* @brief MMAU availability on the SoC. */ +#define FSL_FEATURE_SOC_MMAU_COUNT (0) +/* @brief MMDVSQ availability on the SoC. */ +#define FSL_FEATURE_SOC_MMDVSQ_COUNT (0) +/* @brief MPU availability on the SoC. */ +#define FSL_FEATURE_SOC_MPU_COUNT (1) +/* @brief MSCAN availability on the SoC. */ +#define FSL_FEATURE_SOC_MSCAN_COUNT (0) +/* @brief MSCM availability on the SoC. */ +#define FSL_FEATURE_SOC_MSCM_COUNT (0) +/* @brief MTB availability on the SoC. */ +#define FSL_FEATURE_SOC_MTB_COUNT (0) +/* @brief MTBDWT availability on the SoC. */ +#define FSL_FEATURE_SOC_MTBDWT_COUNT (0) +/* @brief MU availability on the SoC. */ +#define FSL_FEATURE_SOC_MU_COUNT (0) +/* @brief NFC availability on the SoC. */ +#define FSL_FEATURE_SOC_NFC_COUNT (0) +/* @brief OPAMP availability on the SoC. */ +#define FSL_FEATURE_SOC_OPAMP_COUNT (0) +/* @brief OSC availability on the SoC. */ +#define FSL_FEATURE_SOC_OSC_COUNT (1) +/* @brief OSC32 availability on the SoC. */ +#define FSL_FEATURE_SOC_OSC32_COUNT (0) +/* @brief OTFAD availability on the SoC. */ +#define FSL_FEATURE_SOC_OTFAD_COUNT (1) +/* @brief PDB availability on the SoC. */ +#define FSL_FEATURE_SOC_PDB_COUNT (1) +/* @brief PCC availability on the SoC. */ +#define FSL_FEATURE_SOC_PCC_COUNT (0) +/* @brief PGA availability on the SoC. */ +#define FSL_FEATURE_SOC_PGA_COUNT (0) +/* @brief PIT availability on the SoC. */ +#define FSL_FEATURE_SOC_PIT_COUNT (1) +/* @brief PMC availability on the SoC. */ +#define FSL_FEATURE_SOC_PMC_COUNT (1) +/* @brief PORT availability on the SoC. */ +#define FSL_FEATURE_SOC_PORT_COUNT (5) +/* @brief PWM availability on the SoC. */ +#define FSL_FEATURE_SOC_PWM_COUNT (0) +/* @brief PWT availability on the SoC. */ +#define FSL_FEATURE_SOC_PWT_COUNT (0) +/* @brief QuadSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_QuadSPI_COUNT (1) +/* @brief RCM availability on the SoC. */ +#define FSL_FEATURE_SOC_RCM_COUNT (1) +/* @brief RFSYS availability on the SoC. */ +#define FSL_FEATURE_SOC_RFSYS_COUNT (1) +/* @brief RFVBAT availability on the SoC. */ +#define FSL_FEATURE_SOC_RFVBAT_COUNT (1) +/* @brief RNG availability on the SoC. */ +#define FSL_FEATURE_SOC_RNG_COUNT (0) +/* @brief RNGB availability on the SoC. */ +#define FSL_FEATURE_SOC_RNGB_COUNT (0) +/* @brief ROM availability on the SoC. */ +#define FSL_FEATURE_SOC_ROM_COUNT (0) +/* @brief RSIM availability on the SoC. */ +#define FSL_FEATURE_SOC_RSIM_COUNT (0) +/* @brief RTC availability on the SoC. */ +#define FSL_FEATURE_SOC_RTC_COUNT (1) +/* @brief SCG availability on the SoC. */ +#define FSL_FEATURE_SOC_SCG_COUNT (0) +/* @brief SCI availability on the SoC. */ +#define FSL_FEATURE_SOC_SCI_COUNT (0) +/* @brief SDHC availability on the SoC. */ +#define FSL_FEATURE_SOC_SDHC_COUNT (1) +/* @brief SDRAM availability on the SoC. */ +#define FSL_FEATURE_SOC_SDRAM_COUNT (1) +/* @brief SEMA42 availability on the SoC. */ +#define FSL_FEATURE_SOC_SEMA42_COUNT (0) +/* @brief SIM availability on the SoC. */ +#define FSL_FEATURE_SOC_SIM_COUNT (1) +/* @brief SMC availability on the SoC. */ +#define FSL_FEATURE_SOC_SMC_COUNT (1) +/* @brief SPI availability on the SoC. */ +#define FSL_FEATURE_SOC_SPI_COUNT (0) +/* @brief TMR availability on the SoC. */ +#define FSL_FEATURE_SOC_TMR_COUNT (0) +/* @brief TPM availability on the SoC. */ +#define FSL_FEATURE_SOC_TPM_COUNT (2) +/* @brief TRGMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_TRGMUX_COUNT (0) +/* @brief TRIAMP availability on the SoC. */ +#define FSL_FEATURE_SOC_TRIAMP_COUNT (0) +/* @brief TRNG availability on the SoC. */ +#define FSL_FEATURE_SOC_TRNG_COUNT (1) +/* @brief TSI availability on the SoC. */ +#define FSL_FEATURE_SOC_TSI_COUNT (1) +/* @brief TSTMR availability on the SoC. */ +#define FSL_FEATURE_SOC_TSTMR_COUNT (0) +/* @brief UART availability on the SoC. */ +#define FSL_FEATURE_SOC_UART_COUNT (0) +/* @brief USB availability on the SoC. */ +#define FSL_FEATURE_SOC_USB_COUNT (1) +/* @brief USBDCD availability on the SoC. */ +#define FSL_FEATURE_SOC_USBDCD_COUNT (1) +/* @brief USBHSDCD availability on the SoC. */ +#define FSL_FEATURE_SOC_USBHSDCD_COUNT (0) +/* @brief USBPHY availability on the SoC. */ +#define FSL_FEATURE_SOC_USBPHY_COUNT (0) +/* @brief VREF availability on the SoC. */ +#define FSL_FEATURE_SOC_VREF_COUNT (1) +/* @brief WDOG availability on the SoC. */ +#define FSL_FEATURE_SOC_WDOG_COUNT (1) +/* @brief XBAR availability on the SoC. */ +#define FSL_FEATURE_SOC_XBAR_COUNT (0) +/* @brief XBARA availability on the SoC. */ +#define FSL_FEATURE_SOC_XBARA_COUNT (0) +/* @brief XBARB availability on the SoC. */ +#define FSL_FEATURE_SOC_XBARB_COUNT (0) +/* @brief XCVR availability on the SoC. */ +#define FSL_FEATURE_SOC_XCVR_COUNT (0) +/* @brief XRDC availability on the SoC. */ +#define FSL_FEATURE_SOC_XRDC_COUNT (0) +/* @brief ZLL availability on the SoC. */ +#define FSL_FEATURE_SOC_ZLL_COUNT (0) + +/* ADC16 module features */ + +/* @brief Has Programmable Gain Amplifier (PGA) in ADC (register PGA). */ +#define FSL_FEATURE_ADC16_HAS_PGA (0) +/* @brief Has PGA chopping control in ADC (bit PGA[PGACHPb] or PGA[PGACHP]). */ +#define FSL_FEATURE_ADC16_HAS_PGA_CHOPPING (0) +/* @brief Has PGA offset measurement mode in ADC (bit PGA[PGAOFSM]). */ +#define FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT (0) +/* @brief Has DMA support (bit SC2[DMAEN] or SC4[DMAEN]). */ +#define FSL_FEATURE_ADC16_HAS_DMA (1) +/* @brief Has differential mode (bitfield SC1x[DIFF]). */ +#define FSL_FEATURE_ADC16_HAS_DIFF_MODE (1) +/* @brief Has FIFO (bit SC4[AFDEP]). */ +#define FSL_FEATURE_ADC16_HAS_FIFO (0) +/* @brief FIFO size if available (bitfield SC4[AFDEP]). */ +#define FSL_FEATURE_ADC16_FIFO_SIZE (0) +/* @brief Has channel set a/b multiplexor (bitfield CFG2[MUXSEL]). */ +#define FSL_FEATURE_ADC16_HAS_MUX_SELECT (1) +/* @brief Has HW trigger masking (bitfield SC5[HTRGMASKE]. */ +#define FSL_FEATURE_ADC16_HAS_HW_TRIGGER_MASK (0) +/* @brief Has calibration feature (bit SC3[CAL] and registers CLPx, CLMx). */ +#define FSL_FEATURE_ADC16_HAS_CALIBRATION (1) +/* @brief Has HW averaging (bit SC3[AVGE]). */ +#define FSL_FEATURE_ADC16_HAS_HW_AVERAGE (1) +/* @brief Has offset correction (register OFS). */ +#define FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION (1) +/* @brief Maximum ADC resolution. */ +#define FSL_FEATURE_ADC16_MAX_RESOLUTION (16) +/* @brief Number of SC1x and Rx register pairs (conversion control and result registers). */ +#define FSL_FEATURE_ADC16_CONVERSION_CONTROL_COUNT (2) + +/* CMP module features */ + +/* @brief Has Trigger mode in CMP (register bit field CR1[TRIGM]). */ +#define FSL_FEATURE_CMP_HAS_TRIGGER_MODE (1) +/* @brief Has Window mode in CMP (register bit field CR1[WE]). */ +#define FSL_FEATURE_CMP_HAS_WINDOW_MODE (1) +/* @brief Has External sample supported in CMP (register bit field CR1[SE]). */ +#define FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT (1) +/* @brief Has DMA support in CMP (register bit field SCR[DMAEN]). */ +#define FSL_FEATURE_CMP_HAS_DMA (1) +/* @brief Has Pass Through mode in CMP (register bit field MUXCR[PSTM]). */ +#define FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE (0) +/* @brief Has DAC Test function in CMP (register DACTEST). */ +#define FSL_FEATURE_CMP_HAS_DAC_TEST (0) + +/* CRC module features */ + +/* @brief Has data register with name CRC */ +#define FSL_FEATURE_CRC_HAS_CRC_REG (0) + +/* DAC module features */ + +/* @brief Define the size of hardware buffer */ +#define FSL_FEATURE_DAC_BUFFER_SIZE (16) +/* @brief Define whether the buffer supports watermark event detection or not. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION (1) +/* @brief Define whether the buffer supports watermark selection detection or not. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION (1) +/* @brief Define whether the buffer supports watermark event 1 word before buffer upper limit. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD (1) +/* @brief Define whether the buffer supports watermark event 2 words before buffer upper limit. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS (1) +/* @brief Define whether the buffer supports watermark event 3 words before buffer upper limit. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS (1) +/* @brief Define whether the buffer supports watermark event 4 words before buffer upper limit. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS (1) +/* @brief Define whether FIFO buffer mode is available or not. */ +#define FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE (1) +/* @brief Define whether swing buffer mode is available or not.. */ +#define FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE (1) + +/* EDMA module features */ + +/* @brief Number of DMA channels (related to number of registers TCD, DCHPRI, bit fields ERQ[ERQn], EEI[EEIn], INT[INTn], ERR[ERRn], HRS[HRSn] and bit field widths ES[ERRCHN], CEEI[CEEI], SEEI[SEEI], CERQ[CERQ], SERQ[SERQ], CDNE[CDNE], SSRT[SSRT], CERR[CERR], CINT[CINT], TCDn_CITER_ELINKYES[LINKCH], TCDn_CSR[MAJORLINKCH], TCDn_BITER_ELINKYES[LINKCH]). (Valid only for eDMA modules.) */ +#define FSL_FEATURE_EDMA_MODULE_CHANNEL (32) +/* @brief Total number of DMA channels on all modules. */ +#define FSL_FEATURE_EDMA_DMAMUX_CHANNELS (FSL_FEATURE_SOC_EDMA_COUNT * 32) +/* @brief Number of DMA channel groups (register bit fields CR[ERGA], CR[GRPnPRI], ES[GPE], DCHPRIn[GRPPRI]). (Valid only for eDMA modules.) */ +#define FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT (2) +/* @brief Has DMA_Error interrupt vector. */ +#define FSL_FEATURE_EDMA_HAS_ERROR_IRQ (1) +/* @brief Number of DMA channels with asynchronous request capability (register EARS). (Valid only for eDMA modules.) */ +#define FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT (32) + +/* DMAMUX module features */ + +/* @brief Number of DMA channels (related to number of register CHCFGn). */ +#define FSL_FEATURE_DMAMUX_MODULE_CHANNEL (32) +/* @brief Total number of DMA channels on all modules. */ +#define FSL_FEATURE_DMAMUX_DMAMUX_CHANNELS (FSL_FEATURE_SOC_DMAMUX_COUNT * 32) +/* @brief Has the periodic trigger capability for the triggered DMA channel (register bit CHCFG0[TRIG]). */ +#define FSL_FEATURE_DMAMUX_HAS_TRIG (1) + +/* EWM module features */ + +/* @brief Has clock select (register CLKCTRL). */ +#define FSL_FEATURE_EWM_HAS_CLOCK_SELECT (1) +/* @brief Has clock prescaler (register CLKPRESCALER). */ +#define FSL_FEATURE_EWM_HAS_PRESCALER (1) + +/* FLEXBUS module features */ + +/* No feature definitions */ + +/* FLEXIO module features */ + +/* @brief Has Shifter Status Register (FLEXIO_SHIFTSTAT) */ +#define FSL_FEATURE_FLEXIO_HAS_SHIFTER_STATUS (1) +/* @brief Has Pin Data Input Register (FLEXIO_PIN) */ +#define FSL_FEATURE_FLEXIO_HAS_PIN_STATUS (1) +/* @brief Has Shifter Buffer N Nibble Byte Swapped Register (FLEXIO_SHIFTBUFNBSn) */ +#define FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP (1) +/* @brief Has Shifter Buffer N Half Word Swapped Register (FLEXIO_SHIFTBUFHWSn) */ +#define FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP (1) +/* @brief Has Shifter Buffer N Nibble Swapped Register (FLEXIO_SHIFTBUFNISn) */ +#define FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP (1) +/* @brief Supports Shifter State Mode (FLEXIO_SHIFTCTLn[SMOD]) */ +#define FSL_FEATURE_FLEXIO_HAS_STATE_MODE (1) +/* @brief Supports Shifter Logic Mode (FLEXIO_SHIFTCTLn[SMOD]) */ +#define FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE (1) +/* @brief Supports paralle width (FLEXIO_SHIFTCFGn[PWIDTH]) */ +#define FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH (1) +/* @brief Reset value of the FLEXIO_VERID register */ +#define FSL_FEATURE_FLEXIO_VERID_RESET_VALUE (0x1010001) +/* @brief Reset value of the FLEXIO_PARAM register */ +#define FSL_FEATURE_FLEXIO_PARAM_RESET_VALUE (0x10200808) +/* @brief Flexio DMA request base channel */ +#define FSL_FEATURE_FLEXIO_DMA_REQUEST_BASE_CHANNEL (16) + +/* FLASH module features */ + +/* @brief Is of type FTFA. */ +#define FSL_FEATURE_FLASH_IS_FTFA (1) +/* @brief Is of type FTFE. */ +#define FSL_FEATURE_FLASH_IS_FTFE (0) +/* @brief Is of type FTFL. */ +#define FSL_FEATURE_FLASH_IS_FTFL (0) +/* @brief Has flags indicating the status of the FlexRAM (register bits FCNFG[EEERDY], FCNFG[RAMRDY] and FCNFG[PFLSH]). */ +#define FSL_FEATURE_FLASH_HAS_FLEX_RAM_FLAGS (0) +/* @brief Has program flash swapping status flag (register bit FCNFG[SWAP]). */ +#define FSL_FEATURE_FLASH_HAS_PFLASH_SWAPPING_STATUS_FLAG (0) +/* @brief Has EEPROM region protection (register FEPROT). */ +#define FSL_FEATURE_FLASH_HAS_EEROM_REGION_PROTECTION (0) +/* @brief Has data flash region protection (register FDPROT). */ +#define FSL_FEATURE_FLASH_HAS_DATA_FLASH_REGION_PROTECTION (0) +/* @brief Has flash access control (registers XACCHn, SACCHn, where n is a number, FACSS and FACSN). */ +#define FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL (1) +/* @brief Has flash cache control in FMC module. */ +#define FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS (1) +/* @brief Has flash cache control in MCM module. */ +#define FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS (0) +/* @brief Has flash cache control in MSCM module. */ +#define FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS (0) +/* @brief P-Flash start address. */ +#define FSL_FEATURE_FLASH_PFLASH_START_ADDRESS (0x00000000) +/* @brief P-Flash block count. */ +#define FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT (1) +/* @brief P-Flash block size. */ +#define FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE (262144) +/* @brief P-Flash sector size. */ +#define FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE (4096) +/* @brief P-Flash write unit size. */ +#define FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE (4) +/* @brief P-Flash data path width. */ +#define FSL_FEATURE_FLASH_PFLASH_BLOCK_DATA_PATH_WIDTH (16) +/* @brief P-Flash block swap feature. */ +#define FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP (0) +/* @brief P-Flash protection region count. */ +#define FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT (32) +/* @brief Has FlexNVM memory. */ +#define FSL_FEATURE_FLASH_HAS_FLEX_NVM (0) +/* @brief FlexNVM start address. (Valid only if FlexNVM is available.) */ +#define FSL_FEATURE_FLASH_FLEX_NVM_START_ADDRESS (0x00000000) +/* @brief FlexNVM block count. */ +#define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT (0) +/* @brief FlexNVM block size. */ +#define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SIZE (0) +/* @brief FlexNVM sector size. */ +#define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE (0) +/* @brief FlexNVM write unit size. */ +#define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_WRITE_UNIT_SIZE (0) +/* @brief FlexNVM data path width. */ +#define FSL_FEATURE_FLASH_FLEX_BLOCK_DATA_PATH_WIDTH (0) +/* @brief Has FlexRAM memory. */ +#define FSL_FEATURE_FLASH_HAS_FLEX_RAM (0) +/* @brief FlexRAM start address. (Valid only if FlexRAM is available.) */ +#define FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS (0x00000000) +/* @brief FlexRAM size. */ +#define FSL_FEATURE_FLASH_FLEX_RAM_SIZE (0) +/* @brief Has 0x00 Read 1s Block command. */ +#define FSL_FEATURE_FLASH_HAS_READ_1S_BLOCK_CMD (0) +/* @brief Has 0x01 Read 1s Section command. */ +#define FSL_FEATURE_FLASH_HAS_READ_1S_SECTION_CMD (1) +/* @brief Has 0x02 Program Check command. */ +#define FSL_FEATURE_FLASH_HAS_PROGRAM_CHECK_CMD (1) +/* @brief Has 0x03 Read Resource command. */ +#define FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD (1) +/* @brief Has 0x06 Program Longword command. */ +#define FSL_FEATURE_FLASH_HAS_PROGRAM_LONGWORD_CMD (1) +/* @brief Has 0x07 Program Phrase command. */ +#define FSL_FEATURE_FLASH_HAS_PROGRAM_PHRASE_CMD (0) +/* @brief Has 0x08 Erase Flash Block command. */ +#define FSL_FEATURE_FLASH_HAS_ERASE_FLASH_BLOCK_CMD (0) +/* @brief Has 0x09 Erase Flash Sector command. */ +#define FSL_FEATURE_FLASH_HAS_ERASE_FLASH_SECTOR_CMD (1) +/* @brief Has 0x0B Program Section command. */ +#define FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD (0) +/* @brief Has 0x40 Read 1s All Blocks command. */ +#define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_BLOCKS_CMD (1) +/* @brief Has 0x41 Read Once command. */ +#define FSL_FEATURE_FLASH_HAS_READ_ONCE_CMD (1) +/* @brief Has 0x43 Program Once command. */ +#define FSL_FEATURE_FLASH_HAS_PROGRAM_ONCE_CMD (1) +/* @brief Has 0x44 Erase All Blocks command. */ +#define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_CMD (1) +/* @brief Has 0x45 Verify Backdoor Access Key command. */ +#define FSL_FEATURE_FLASH_HAS_VERIFY_BACKDOOR_ACCESS_KEY_CMD (1) +/* @brief Has 0x46 Swap Control command. */ +#define FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD (0) +/* @brief Has 0x49 Erase All Blocks Unsecure command. */ +#define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD (1) +/* @brief Has 0x4A Read 1s All Execute-only Segments command. */ +#define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0) +/* @brief Has 0x4B Erase All Execute-only Segments command. */ +#define FSL_FEATURE_FLASH_HAS_ERASE_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0) +/* @brief Has 0x80 Program Partition command. */ +#define FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD (0) +/* @brief Has 0x81 Set FlexRAM Function command. */ +#define FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD (0) +/* @brief P-Flash Erase/Read 1st all block command address alignment. */ +#define FSL_FEATURE_FLASH_PFLASH_BLOCK_CMD_ADDRESS_ALIGMENT (16) +/* @brief P-Flash Erase sector command address alignment. */ +#define FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT (16) +/* @brief P-Flash Rrogram/Verify section command address alignment. */ +#define FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT (16) +/* @brief P-Flash Read resource command address alignment. */ +#define FSL_FEATURE_FLASH_PFLASH_RESOURCE_CMD_ADDRESS_ALIGMENT (4) +/* @brief P-Flash Program check command address alignment. */ +#define FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT (4) +/* @brief P-Flash Program check command address alignment. */ +#define FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT (0) +/* @brief FlexNVM Erase/Read 1st all block command address alignment. */ +#define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_CMD_ADDRESS_ALIGMENT (0) +/* @brief FlexNVM Erase sector command address alignment. */ +#define FSL_FEATURE_FLASH_FLEX_NVM_SECTOR_CMD_ADDRESS_ALIGMENT (0) +/* @brief FlexNVM Rrogram/Verify section command address alignment. */ +#define FSL_FEATURE_FLASH_FLEX_NVM_SECTION_CMD_ADDRESS_ALIGMENT (0) +/* @brief FlexNVM Read resource command address alignment. */ +#define FSL_FEATURE_FLASH_FLEX_NVM_RESOURCE_CMD_ADDRESS_ALIGMENT (0) +/* @brief FlexNVM Program check command address alignment. */ +#define FSL_FEATURE_FLASH_FLEX_NVM_CHECK_CMD_ADDRESS_ALIGMENT (0) +/* @brief FlexNVM partition code 0000 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 (0xFFFFFFFF) +/* @brief FlexNVM partition code 0001 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 (0xFFFFFFFF) +/* @brief FlexNVM partition code 0010 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 (0xFFFFFFFF) +/* @brief FlexNVM partition code 0011 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 (0xFFFFFFFF) +/* @brief FlexNVM partition code 0100 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 (0xFFFFFFFF) +/* @brief FlexNVM partition code 0101 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 (0xFFFFFFFF) +/* @brief FlexNVM partition code 0110 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 (0xFFFFFFFF) +/* @brief FlexNVM partition code 0111 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 (0xFFFFFFFF) +/* @brief FlexNVM partition code 1000 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 (0xFFFFFFFF) +/* @brief FlexNVM partition code 1001 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 (0xFFFFFFFF) +/* @brief FlexNVM partition code 1010 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 (0xFFFFFFFF) +/* @brief FlexNVM partition code 1011 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 (0xFFFFFFFF) +/* @brief FlexNVM partition code 1100 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 (0xFFFFFFFF) +/* @brief FlexNVM partition code 1101 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 (0xFFFFFFFF) +/* @brief FlexNVM partition code 1110 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 (0xFFFFFFFF) +/* @brief FlexNVM partition code 1111 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 (0xFFFFFFFF) +/* @brief Emulated eeprom size code 0000 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0000 (0xFFFF) +/* @brief Emulated eeprom size code 0001 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0001 (0xFFFF) +/* @brief Emulated eeprom size code 0010 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0010 (0xFFFF) +/* @brief Emulated eeprom size code 0011 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0011 (0xFFFF) +/* @brief Emulated eeprom size code 0100 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0100 (0xFFFF) +/* @brief Emulated eeprom size code 0101 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0101 (0xFFFF) +/* @brief Emulated eeprom size code 0110 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0110 (0xFFFF) +/* @brief Emulated eeprom size code 0111 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0111 (0xFFFF) +/* @brief Emulated eeprom size code 1000 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1000 (0xFFFF) +/* @brief Emulated eeprom size code 1001 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1001 (0xFFFF) +/* @brief Emulated eeprom size code 1010 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1010 (0xFFFF) +/* @brief Emulated eeprom size code 1011 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1011 (0xFFFF) +/* @brief Emulated eeprom size code 1100 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1100 (0xFFFF) +/* @brief Emulated eeprom size code 1101 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1101 (0xFFFF) +/* @brief Emulated eeprom size code 1110 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110 (0xFFFF) +/* @brief Emulated eeprom size code 1111 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ +#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111 (0xFFFF) + +/* FTM module features */ + +/* @brief Number of channels. */ +#define FSL_FEATURE_FTM_CHANNEL_COUNTn(x) \ + ((x) == FTM0 ? (8) : \ + ((x) == FTM1 ? (2) : \ + ((x) == FTM2 ? (2) : \ + ((x) == FTM3 ? (8) : (-1))))) +/* @brief Has counter reset by the selected input capture event (register bits C0SC[ICRST], C1SC[ICRST], ...). */ +#define FSL_FEATURE_FTM_HAS_COUNTER_RESET_BY_CAPTURE_EVENT (1) +/* @brief Has extended deadtime value. */ +#define FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE (0) +/* @brief Enable pwm output for the module. */ +#define FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT (0) +/* @brief Has half-cycle reload for the module. */ +#define FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD (0) +/* @brief Has reload interrupt. */ +#define FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT (0) +/* @brief Has reload initialization trigger. */ +#define FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER (0) + +/* GPIO module features */ + +/* @brief Has fast (single cycle) access capability via a dedicated memory region. */ +#define FSL_FEATURE_GPIO_HAS_FAST_GPIO (0) +/* @brief Has port input disable register (PIDR). */ +#define FSL_FEATURE_GPIO_HAS_INPUT_DISABLE (0) +/* @brief Has dedicated interrupt vector. */ +#define FSL_FEATURE_GPIO_HAS_PORT_INTERRUPT_VECTOR (1) + +/* I2C module features */ + +/* @brief Has System Management Bus support (registers SMB, A2, SLTL and SLTH). */ +#define FSL_FEATURE_I2C_HAS_SMBUS (1) +/* @brief Maximum supported baud rate in kilobit per second. */ +#define FSL_FEATURE_I2C_MAX_BAUD_KBPS (400) +/* @brief Is affected by errata with ID 6070 (repeat start cannot be generated if the F[MULT] bit field is set to a non-zero value). */ +#define FSL_FEATURE_I2C_HAS_ERRATA_6070 (0) +/* @brief Has DMA support (register bit C1[DMAEN]). */ +#define FSL_FEATURE_I2C_HAS_DMA_SUPPORT (1) +/* @brief Has I2C bus start and stop detection (register bits FLT[SSIE], FLT[STARTF] and FLT[STOPF]). */ +#define FSL_FEATURE_I2C_HAS_START_STOP_DETECT (1) +/* @brief Has I2C bus stop detection (register bits FLT[STOPIE] and FLT[STOPF]). */ +#define FSL_FEATURE_I2C_HAS_STOP_DETECT (0) +/* @brief Has I2C bus stop hold off (register bit FLT[SHEN]). */ +#define FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF (1) +/* @brief Maximum width of the glitch filter in number of bus clocks. */ +#define FSL_FEATURE_I2C_MAX_GLITCH_FILTER_WIDTH (15) +/* @brief Has control of the drive capability of the I2C pins. */ +#define FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION (1) +/* @brief Has double buffering support (register S2). */ +#define FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING (1) +/* @brief Has double buffer enable. */ +#define FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE (0) + +/* SAI module features */ + +/* @brief Receive/transmit FIFO size in item count (register bit fields TCSR[FRDE], TCSR[FRIE], TCSR[FRF], TCR1[TFW], RCSR[FRDE], RCSR[FRIE], RCSR[FRF], RCR1[RFW], registers TFRn, RFRn). */ +#define FSL_FEATURE_SAI_FIFO_COUNT (8) +/* @brief Receive/transmit channel number (register bit fields TCR3[TCE], RCR3[RCE], registers TDRn and RDRn). */ +#define FSL_FEATURE_SAI_CHANNEL_COUNT (2) +/* @brief Maximum words per frame (register bit fields TCR3[WDFL], TCR4[FRSZ], TMR[TWM], RCR3[WDFL], RCR4[FRSZ], RMR[RWM]). */ +#define FSL_FEATURE_SAI_MAX_WORDS_PER_FRAME (32) +/* @brief Has support of combining multiple data channel FIFOs into single channel FIFO (register bit fields TCR3[CFR], TCR4[FCOMB], TFR0[WCP], TFR1[WCP], RCR3[CFR], RCR4[FCOMB], RFR0[RCP], RFR1[RCP]). */ +#define FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE (1) +/* @brief Has packing of 8-bit and 16-bit data into each 32-bit FIFO word (register bit fields TCR4[FPACK], RCR4[FPACK]). */ +#define FSL_FEATURE_SAI_HAS_FIFO_PACKING (1) +/* @brief Configures when the SAI will continue transmitting after a FIFO error has been detected (register bit fields TCR4[FCONT], RCR4[FCONT]). */ +#define FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR (1) +/* @brief Configures if the frame sync is generated internally, a frame sync is only generated when the FIFO warning flag is clear or continuously (register bit fields TCR4[ONDEM], RCR4[ONDEM]). */ +#define FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE (1) +/* @brief Simplified bit clock source and asynchronous/synchronous mode selection (register bit fields TCR2[CLKMODE], RCR2[CLKMODE]), in comparison with the exclusively implemented TCR2[SYNC,BCS,BCI,MSEL], RCR2[SYNC,BCS,BCI,MSEL]. */ +#define FSL_FEATURE_SAI_HAS_CLOCKING_MODE (0) +/* @brief Has register for configuration of the MCLK divide ratio (register bit fields MDR[FRACT], MDR[DIVIDE]). */ +#define FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER (1) +/* @brief Ihe interrupt source number */ +#define FSL_FEATURE_SAI_INT_SOURCE_NUM (2) +/* @brief Has register of MCR. */ +#define FSL_FEATURE_SAI_HAS_MCR (1) +/* @brief Has register of MDR */ +#define FSL_FEATURE_SAI_HAS_MDR (1) + +/* LLWU module features */ + +#if defined(CPU_MK82FN256CAx15) || defined(CPU_MK82FN256VDC15) + /* @brief Maximum number of pins (maximal index plus one) connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN (26) + /* @brief Has pins 8-15 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_EXTERNAL_PIN_GROUP2 (1) + /* @brief Maximum number of internal modules connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE (8) + /* @brief Number of digital filters. */ + #define FSL_FEATURE_LLWU_HAS_PIN_FILTER (4) + /* @brief Has MF register. */ + #define FSL_FEATURE_LLWU_HAS_MF (1) + /* @brief Has PF register. */ + #define FSL_FEATURE_LLWU_HAS_PF (1) + /* @brief Has possibility to enable reset in low leakage power mode and enable digital filter for RESET pin (register LLWU_RST). */ + #define FSL_FEATURE_LLWU_HAS_RESET_ENABLE (0) + /* @brief Has external pin 0 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN0 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN0_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN0_GPIO_PIN (1) + /* @brief Has external pin 1 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN1 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN1_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN1_GPIO_PIN (2) + /* @brief Has external pin 2 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN2 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN2_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN2_GPIO_PIN (4) + /* @brief Has external pin 3 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN3 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN3_GPIO_IDX (GPIOA_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN3_GPIO_PIN (4) + /* @brief Has external pin 4 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN4 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN4_GPIO_IDX (GPIOA_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN4_GPIO_PIN (13) + /* @brief Has external pin 5 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN5 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN5_GPIO_IDX (GPIOB_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN5_GPIO_PIN (0) + /* @brief Has external pin 6 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN6 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN6_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN6_GPIO_PIN (1) + /* @brief Has external pin 7 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN7 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN7_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN7_GPIO_PIN (3) + /* @brief Has external pin 8 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN8 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN8_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN8_GPIO_PIN (4) + /* @brief Has external pin 9 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN9 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN9_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN9_GPIO_PIN (5) + /* @brief Has external pin 10 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN10 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN10_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN10_GPIO_PIN (6) + /* @brief Has external pin 11 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN11 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN11_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN11_GPIO_PIN (11) + /* @brief Has external pin 12 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN12 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN12_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN12_GPIO_PIN (0) + /* @brief Has external pin 13 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN13 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN13_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN13_GPIO_PIN (2) + /* @brief Has external pin 14 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN14 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN14_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN14_GPIO_PIN (4) + /* @brief Has external pin 15 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN15 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN15_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN15_GPIO_PIN (6) + /* @brief Has external pin 16 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN16 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN16_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN16_GPIO_PIN (6) + /* @brief Has external pin 17 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN17 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN17_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN17_GPIO_PIN (9) + /* @brief Has external pin 18 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN18 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN18_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN18_GPIO_PIN (10) + /* @brief Has external pin 19 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN19 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN19_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN19_GPIO_PIN (0) + /* @brief Has external pin 20 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN20 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN20_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN20_GPIO_PIN (0) + /* @brief Has external pin 21 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN21 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN21_GPIO_IDX (GPIOA_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN21_GPIO_PIN (21) + /* @brief Has external pin 22 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN22 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN22_GPIO_IDX (GPIOA_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN22_GPIO_PIN (10) + /* @brief Has external pin 23 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN23 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN23_GPIO_IDX (GPIOA_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN23_GPIO_PIN (11) + /* @brief Has external pin 24 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN24 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN24_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN24_GPIO_PIN (8) + /* @brief Has external pin 25 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN25 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN25_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN25_GPIO_PIN (11) + /* @brief Has external pin 26 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN26 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN26_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN26_GPIO_PIN (0) + /* @brief Has external pin 27 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN27 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN27_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN27_GPIO_PIN (0) + /* @brief Has external pin 28 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN28 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN28_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN28_GPIO_PIN (0) + /* @brief Has external pin 29 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN29 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN29_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN29_GPIO_PIN (0) + /* @brief Has external pin 30 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN30 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN30_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN30_GPIO_PIN (0) + /* @brief Has external pin 31 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN31 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN31_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN31_GPIO_PIN (0) + /* @brief Has internal module 0 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE0 (1) + /* @brief Has internal module 1 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE1 (1) + /* @brief Has internal module 2 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE2 (1) + /* @brief Has internal module 3 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE3 (0) + /* @brief Has internal module 4 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE4 (1) + /* @brief Has internal module 5 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE5 (1) + /* @brief Has internal module 6 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE6 (0) + /* @brief Has internal module 7 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE7 (1) + /* @brief Has Version ID Register (LLWU_VERID). */ + #define FSL_FEATURE_LLWU_HAS_VERID (0) + /* @brief Has Parameter Register (LLWU_PARAM). */ + #define FSL_FEATURE_LLWU_HAS_PARAM (0) + /* @brief Width of registers of the LLWU. */ + #define FSL_FEATURE_LLWU_REG_BITWIDTH (8) + /* @brief Has DMA Enable register (LLWU_DE). */ + #define FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG (0) +#elif defined(CPU_MK82FN256VLL15) + /* @brief Maximum number of pins (maximal index plus one) connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN (19) + /* @brief Has pins 8-15 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_EXTERNAL_PIN_GROUP2 (1) + /* @brief Maximum number of internal modules connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE (8) + /* @brief Number of digital filters. */ + #define FSL_FEATURE_LLWU_HAS_PIN_FILTER (4) + /* @brief Has MF register. */ + #define FSL_FEATURE_LLWU_HAS_MF (1) + /* @brief Has PF register. */ + #define FSL_FEATURE_LLWU_HAS_PF (1) + /* @brief Has possibility to enable reset in low leakage power mode and enable digital filter for RESET pin (register LLWU_RST). */ + #define FSL_FEATURE_LLWU_HAS_RESET_ENABLE (0) + /* @brief Has external pin 0 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN0 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN0_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN0_GPIO_PIN (1) + /* @brief Has external pin 1 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN1 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN1_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN1_GPIO_PIN (2) + /* @brief Has external pin 2 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN2 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN2_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN2_GPIO_PIN (4) + /* @brief Has external pin 3 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN3 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN3_GPIO_IDX (GPIOA_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN3_GPIO_PIN (4) + /* @brief Has external pin 4 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN4 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN4_GPIO_IDX (GPIOA_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN4_GPIO_PIN (13) + /* @brief Has external pin 5 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN5 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN5_GPIO_IDX (GPIOB_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN5_GPIO_PIN (0) + /* @brief Has external pin 6 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN6 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN6_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN6_GPIO_PIN (1) + /* @brief Has external pin 7 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN7 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN7_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN7_GPIO_PIN (3) + /* @brief Has external pin 8 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN8 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN8_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN8_GPIO_PIN (4) + /* @brief Has external pin 9 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN9 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN9_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN9_GPIO_PIN (5) + /* @brief Has external pin 10 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN10 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN10_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN10_GPIO_PIN (6) + /* @brief Has external pin 11 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN11 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN11_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN11_GPIO_PIN (11) + /* @brief Has external pin 12 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN12 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN12_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN12_GPIO_PIN (0) + /* @brief Has external pin 13 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN13 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN13_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN13_GPIO_PIN (2) + /* @brief Has external pin 14 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN14 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN14_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN14_GPIO_PIN (4) + /* @brief Has external pin 15 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN15 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN15_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN15_GPIO_PIN (6) + /* @brief Has external pin 16 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN16 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN16_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN16_GPIO_PIN (6) + /* @brief Has external pin 17 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN17 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN17_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN17_GPIO_PIN (9) + /* @brief Has external pin 18 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN18 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN18_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN18_GPIO_PIN (10) + /* @brief Has external pin 19 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN19 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN19_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN19_GPIO_PIN (0) + /* @brief Has external pin 20 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN20 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN20_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN20_GPIO_PIN (0) + /* @brief Has external pin 21 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN21 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN21_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN21_GPIO_PIN (0) + /* @brief Has external pin 22 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN22 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN22_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN22_GPIO_PIN (0) + /* @brief Has external pin 23 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN23 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN23_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN23_GPIO_PIN (0) + /* @brief Has external pin 24 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN24 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN24_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN24_GPIO_PIN (0) + /* @brief Has external pin 25 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN25 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN25_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN25_GPIO_PIN (0) + /* @brief Has external pin 26 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN26 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN26_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN26_GPIO_PIN (0) + /* @brief Has external pin 27 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN27 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN27_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN27_GPIO_PIN (0) + /* @brief Has external pin 28 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN28 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN28_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN28_GPIO_PIN (0) + /* @brief Has external pin 29 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN29 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN29_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN29_GPIO_PIN (0) + /* @brief Has external pin 30 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN30 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN30_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN30_GPIO_PIN (0) + /* @brief Has external pin 31 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN31 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN31_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN31_GPIO_PIN (0) + /* @brief Has internal module 0 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE0 (1) + /* @brief Has internal module 1 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE1 (1) + /* @brief Has internal module 2 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE2 (1) + /* @brief Has internal module 3 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE3 (0) + /* @brief Has internal module 4 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE4 (1) + /* @brief Has internal module 5 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE5 (1) + /* @brief Has internal module 6 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE6 (0) + /* @brief Has internal module 7 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE7 (1) + /* @brief Has Version ID Register (LLWU_VERID). */ + #define FSL_FEATURE_LLWU_HAS_VERID (0) + /* @brief Has Parameter Register (LLWU_PARAM). */ + #define FSL_FEATURE_LLWU_HAS_PARAM (0) + /* @brief Width of registers of the LLWU. */ + #define FSL_FEATURE_LLWU_REG_BITWIDTH (8) + /* @brief Has DMA Enable register (LLWU_DE). */ + #define FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG (0) +#elif defined(CPU_MK82FN256VLQ15) + /* @brief Maximum number of pins (maximal index plus one) connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN (26) + /* @brief Has pins 8-15 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_EXTERNAL_PIN_GROUP2 (1) + /* @brief Maximum number of internal modules connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE (8) + /* @brief Number of digital filters. */ + #define FSL_FEATURE_LLWU_HAS_PIN_FILTER (4) + /* @brief Has MF register. */ + #define FSL_FEATURE_LLWU_HAS_MF (1) + /* @brief Has PF register. */ + #define FSL_FEATURE_LLWU_HAS_PF (1) + /* @brief Has possibility to enable reset in low leakage power mode and enable digital filter for RESET pin (register LLWU_RST). */ + #define FSL_FEATURE_LLWU_HAS_RESET_ENABLE (0) + /* @brief Has external pin 0 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN0 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN0_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN0_GPIO_PIN (1) + /* @brief Has external pin 1 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN1 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN1_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN1_GPIO_PIN (2) + /* @brief Has external pin 2 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN2 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN2_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN2_GPIO_PIN (4) + /* @brief Has external pin 3 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN3 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN3_GPIO_IDX (GPIOA_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN3_GPIO_PIN (4) + /* @brief Has external pin 4 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN4 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN4_GPIO_IDX (GPIOA_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN4_GPIO_PIN (13) + /* @brief Has external pin 5 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN5 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN5_GPIO_IDX (GPIOB_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN5_GPIO_PIN (0) + /* @brief Has external pin 6 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN6 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN6_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN6_GPIO_PIN (1) + /* @brief Has external pin 7 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN7 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN7_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN7_GPIO_PIN (3) + /* @brief Has external pin 8 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN8 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN8_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN8_GPIO_PIN (4) + /* @brief Has external pin 9 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN9 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN9_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN9_GPIO_PIN (5) + /* @brief Has external pin 10 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN10 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN10_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN10_GPIO_PIN (6) + /* @brief Has external pin 11 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN11 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN11_GPIO_IDX (GPIOC_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN11_GPIO_PIN (11) + /* @brief Has external pin 12 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN12 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN12_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN12_GPIO_PIN (0) + /* @brief Has external pin 13 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN13 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN13_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN13_GPIO_PIN (2) + /* @brief Has external pin 14 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN14 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN14_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN14_GPIO_PIN (4) + /* @brief Has external pin 15 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN15 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN15_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN15_GPIO_PIN (6) + /* @brief Has external pin 16 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN16 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN16_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN16_GPIO_PIN (6) + /* @brief Has external pin 17 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN17 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN17_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN17_GPIO_PIN (9) + /* @brief Has external pin 18 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN18 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN18_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN18_GPIO_PIN (10) + /* @brief Has external pin 19 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN19 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN19_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN19_GPIO_PIN (17) + /* @brief Has external pin 20 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN20 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN20_GPIO_IDX (GPIOE_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN20_GPIO_PIN (18) + /* @brief Has external pin 21 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN21 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN21_GPIO_IDX (GPIOA_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN21_GPIO_PIN (21) + /* @brief Has external pin 22 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN22 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN22_GPIO_IDX (GPIOA_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN22_GPIO_PIN (10) + /* @brief Has external pin 23 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN23 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN23_GPIO_IDX (GPIOA_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN23_GPIO_PIN (11) + /* @brief Has external pin 24 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN24 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN24_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN24_GPIO_PIN (8) + /* @brief Has external pin 25 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN25 (1) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN25_GPIO_IDX (GPIOD_IDX) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN25_GPIO_PIN (11) + /* @brief Has external pin 26 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN26 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN26_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN26_GPIO_PIN (0) + /* @brief Has external pin 27 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN27 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN27_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN27_GPIO_PIN (0) + /* @brief Has external pin 28 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN28 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN28_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN28_GPIO_PIN (0) + /* @brief Has external pin 29 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN29 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN29_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN29_GPIO_PIN (0) + /* @brief Has external pin 30 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN30 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN30_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN30_GPIO_PIN (0) + /* @brief Has external pin 31 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN31 (0) + /* @brief Index of port of external pin. */ + #define FSL_FEATURE_LLWU_PIN31_GPIO_IDX (0) + /* @brief Number of external pin port on specified port. */ + #define FSL_FEATURE_LLWU_PIN31_GPIO_PIN (0) + /* @brief Has internal module 0 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE0 (1) + /* @brief Has internal module 1 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE1 (1) + /* @brief Has internal module 2 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE2 (1) + /* @brief Has internal module 3 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE3 (0) + /* @brief Has internal module 4 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE4 (1) + /* @brief Has internal module 5 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE5 (1) + /* @brief Has internal module 6 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE6 (0) + /* @brief Has internal module 7 connected to LLWU device. */ + #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE7 (1) + /* @brief Has Version ID Register (LLWU_VERID). */ + #define FSL_FEATURE_LLWU_HAS_VERID (0) + /* @brief Has Parameter Register (LLWU_PARAM). */ + #define FSL_FEATURE_LLWU_HAS_PARAM (0) + /* @brief Width of registers of the LLWU. */ + #define FSL_FEATURE_LLWU_REG_BITWIDTH (8) + /* @brief Has DMA Enable register (LLWU_DE). */ + #define FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG (0) +#endif /* defined(CPU_MK82FN256CAx15) || defined(CPU_MK82FN256VDC15) */ + +/* LMEM module features */ + +/* @brief Has process identifier support. */ +#define FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE (1) + +/* LPTMR module features */ + +/* @brief Has shared interrupt handler with another LPTMR module. */ +#define FSL_FEATURE_LPTMR_HAS_SHARED_IRQ_HANDLER (1) +/* @brief Whether LPTMR counter is 32 bits width. */ +#define FSL_FEATURE_LPTMR_CNR_WIDTH_IS_32B (0) + +/* LPUART module features */ + +/* @brief Has receive FIFO overflow detection (bit field CFIFO[RXOFE]). */ +#define FSL_FEATURE_LPUART_HAS_IRQ_EXTENDED_FUNCTIONS (0) +/* @brief Has low power features (can be enabled in wait mode via register bit C1[DOZEEN] or CTRL[DOZEEN] if the registers are 32-bit wide). */ +#define FSL_FEATURE_LPUART_HAS_LOW_POWER_UART_SUPPORT (1) +/* @brief Has extended data register ED (or extra flags in the DATA register if the registers are 32-bit wide). */ +#define FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS (1) +/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */ +#define FSL_FEATURE_LPUART_HAS_FIFO (1) +/* @brief Has 32-bit register MODIR */ +#define FSL_FEATURE_LPUART_HAS_MODIR (1) +/* @brief Hardware flow control (RTS, CTS) is supported. */ +#define FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT (1) +/* @brief Infrared (modulation) is supported. */ +#define FSL_FEATURE_LPUART_HAS_IR_SUPPORT (1) +/* @brief 2 bits long stop bit is available. */ +#define FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT (1) +/* @brief If 10-bit mode is supported. */ +#define FSL_FEATURE_LPUART_HAS_10BIT_DATA_SUPPORT (1) +/* @brief If 7-bit mode is supported. */ +#define FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT (0) +/* @brief Baud rate fine adjustment is available. */ +#define FSL_FEATURE_LPUART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT (0) +/* @brief Baud rate oversampling is available (has bit fields C4[OSR], C5[BOTHEDGE], C5[RESYNCDIS] or BAUD[OSR], BAUD[BOTHEDGE], BAUD[RESYNCDIS] if the registers are 32-bit wide). */ +#define FSL_FEATURE_LPUART_HAS_BAUD_RATE_OVER_SAMPLING_SUPPORT (1) +/* @brief Baud rate oversampling is available. */ +#define FSL_FEATURE_LPUART_HAS_RX_RESYNC_SUPPORT (1) +/* @brief Baud rate oversampling is available. */ +#define FSL_FEATURE_LPUART_HAS_BOTH_EDGE_SAMPLING_SUPPORT (1) +/* @brief Peripheral type. */ +#define FSL_FEATURE_LPUART_IS_SCI (1) +/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */ +#define FSL_FEATURE_LPUART_FIFO_SIZEn(x) \ + ((x) == LPUART0 ? (8) : \ + ((x) == LPUART1 ? (8) : \ + ((x) == LPUART2 ? (1) : \ + ((x) == LPUART3 ? (1) : \ + ((x) == LPUART4 ? (1) : (-1)))))) +/* @brief Maximal data width without parity bit. */ +#define FSL_FEATURE_LPUART_MAX_DATA_WIDTH_WITH_NO_PARITY (10) +/* @brief Maximal data width with parity bit. */ +#define FSL_FEATURE_LPUART_MAX_DATA_WIDTH_WITH_PARITY (9) +/* @brief Supports two match addresses to filter incoming frames. */ +#define FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING (1) +/* @brief Has transmitter/receiver DMA enable bits C5[TDMAE]/C5[RDMAE] (or BAUD[TDMAE]/BAUD[RDMAE] if the registers are 32-bit wide). */ +#define FSL_FEATURE_LPUART_HAS_DMA_ENABLE (1) +/* @brief Has transmitter/receiver DMA select bits C4[TDMAS]/C4[RDMAS], resp. C5[TDMAS]/C5[RDMAS] if IS_SCI = 0. */ +#define FSL_FEATURE_LPUART_HAS_DMA_SELECT (0) +/* @brief Data character bit order selection is supported (bit field S2[MSBF] or STAT[MSBF] if the registers are 32-bit wide). */ +#define FSL_FEATURE_LPUART_HAS_BIT_ORDER_SELECT (1) +/* @brief Has smart card (ISO7816 protocol) support and no improved smart card support. */ +#define FSL_FEATURE_LPUART_HAS_SMART_CARD_SUPPORT (0) +/* @brief Has improved smart card (ISO7816 protocol) support. */ +#define FSL_FEATURE_LPUART_HAS_IMPROVED_SMART_CARD_SUPPORT (0) +/* @brief Has local operation network (CEA709.1-B protocol) support. */ +#define FSL_FEATURE_LPUART_HAS_LOCAL_OPERATION_NETWORK_SUPPORT (0) +/* @brief Has 32-bit registers (BAUD, STAT, CTRL, DATA, MATCH, MODIR) instead of 8-bit (BDH, BDL, C1, S1, D, etc.). */ +#define FSL_FEATURE_LPUART_HAS_32BIT_REGISTERS (1) +/* @brief Lin break detect available (has bit BAUD[LBKDIE]). */ +#define FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT (1) +/* @brief UART stops in Wait mode available (has bit C1[UARTSWAI]). */ +#define FSL_FEATURE_LPUART_HAS_WAIT_MODE_OPERATION (0) +/* @brief Has separate DMA RX and TX requests. */ +#define FSL_FEATURE_LPUART_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1) +/* @brief Has separate RX and TX interrupts. */ +#define FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ (0) +/* @brief Has LPAURT_PARAM. */ +#define FSL_FEATURE_LPUART_HAS_PARAM (0) +/* @brief Has LPUART_VERID. */ +#define FSL_FEATURE_LPUART_HAS_VERID (0) +/* @brief Has LPUART_GLOBAL. */ +#define FSL_FEATURE_LPUART_HAS_GLOBAL (0) +/* @brief Has LPUART_PINCFG. */ +#define FSL_FEATURE_LPUART_HAS_PINCFG (0) + +/* LTC module features */ + +/* @brief LTC module supports DES algorithm. */ +#define FSL_FEATURE_LTC_HAS_DES (1) +/* @brief LTC module supports PKHA algorithm. */ +#define FSL_FEATURE_LTC_HAS_PKHA (1) +/* @brief LTC module supports SHA algorithm. */ +#define FSL_FEATURE_LTC_HAS_SHA (0) +/* @brief LTC module supports AES GCM mode. */ +#define FSL_FEATURE_LTC_HAS_GCM (1) +/* @brief LTC module supports DPAMS registers. */ +#define FSL_FEATURE_LTC_HAS_DPAMS (1) +/* @brief LTC module supports AES with 24 bytes key. */ +#define FSL_FEATURE_LTC_HAS_AES192 (1) +/* @brief LTC module supports AES with 32 bytes key. */ +#define FSL_FEATURE_LTC_HAS_AES256 (1) + +/* MCG module features */ + +/* @brief PRDIV base value (divider of register bit field [PRDIV] zero value). */ +#define FSL_FEATURE_MCG_PLL_PRDIV_BASE (1) +/* @brief Maximum PLL external reference divider value (max. value of register bit field C5[PRVDIV]). */ +#define FSL_FEATURE_MCG_PLL_PRDIV_MAX (7) +/* @brief VCO divider base value (multiply factor of register bit field C6[VDIV] zero value). */ +#define FSL_FEATURE_MCG_PLL_VDIV_BASE (16) +/* @brief PLL reference clock low range. OSCCLK/PLL_R. */ +#define FSL_FEATURE_MCG_PLL_REF_MIN (8000000) +/* @brief PLL reference clock high range. OSCCLK/PLL_R. */ +#define FSL_FEATURE_MCG_PLL_REF_MAX (16000000) +/* @brief The PLL clock is divided by 2 before VCO divider. */ +#define FSL_FEATURE_MCG_HAS_PLL_INTERNAL_DIV (1) +/* @brief FRDIV supports 1280. */ +#define FSL_FEATURE_MCG_FRDIV_SUPPORT_1280 (1) +/* @brief FRDIV supports 1536. */ +#define FSL_FEATURE_MCG_FRDIV_SUPPORT_1536 (1) +/* @brief MCGFFCLK divider. */ +#define FSL_FEATURE_MCG_FFCLK_DIV (1) +/* @brief Is PLL clock divided by 2 before MCG PLL/FLL clock selection in the SIM module. */ +#define FSL_FEATURE_MCG_HAS_PLL_EXTRA_DIV (0) +/* @brief Has 32kHz RTC external reference clock (register bits C8[LOCS1], C8[CME1], C8[LOCRE1] and RTC module are present). */ +#define FSL_FEATURE_MCG_HAS_RTC_32K (1) +/* @brief Has PLL1 external reference clock (registers C10, C11, C12, S2). */ +#define FSL_FEATURE_MCG_HAS_PLL1 (0) +/* @brief Has 48MHz internal oscillator. */ +#define FSL_FEATURE_MCG_HAS_IRC_48M (1) +/* @brief Has OSC1 external oscillator (registers C10, C11, C12, S2). */ +#define FSL_FEATURE_MCG_HAS_OSC1 (0) +/* @brief Has fast internal reference clock fine trim (register bit C2[FCFTRIM]). */ +#define FSL_FEATURE_MCG_HAS_FCFTRIM (1) +/* @brief Has PLL loss of lock reset (register bit C8[LOLRE]). */ +#define FSL_FEATURE_MCG_HAS_LOLRE (1) +/* @brief Has MCG OSC clock selection (register bit C7[OSCSEL]). */ +#define FSL_FEATURE_MCG_USE_OSCSEL (1) +/* @brief Has PLL external reference selection (register bits C5[PLLREFSEL0] and C11[PLLREFSEL1]). */ +#define FSL_FEATURE_MCG_USE_PLLREFSEL (0) +/* @brief TBD */ +#define FSL_FEATURE_MCG_USE_SYSTEM_CLOCK (0) +/* @brief Has phase-locked loop (PLL) (register C5 and bits C6[VDIV], C6[PLLS], C6[LOLIE0], S[PLLST], S[LOCK0], S[LOLS]). */ +#define FSL_FEATURE_MCG_HAS_PLL (1) +/* @brief Has phase-locked loop (PLL) PRDIV (register C5[PRDIV]. */ +#define FSL_FEATURE_MCG_HAS_PLL_PRDIV (1) +/* @brief Has phase-locked loop (PLL) VDIV (register C6[VDIV]. */ +#define FSL_FEATURE_MCG_HAS_PLL_VDIV (1) +/* @brief PLL/OSC related register bit fields have PLL/OSC index in their name. */ +#define FSL_FEATURE_MCG_HAS_PLL_OSC_INDEX (0) +/* @brief Has frequency-locked loop (FLL) (register ATCVH, ATCVL and bits C1[IREFS], C1[FRDIV]). */ +#define FSL_FEATURE_MCG_HAS_FLL (1) +/* @brief Has PLL external to MCG (C9[PLL_CME], C9[PLL_LOCRE], C9[EXT_PLL_LOCS]). */ +#define FSL_FEATURE_MCG_HAS_EXTERNAL_PLL (0) +/* @brief Has crystal oscillator or external reference clock low power controls (register bits C2[HGO], C2[RANGE]). */ +#define FSL_FEATURE_MCG_HAS_EXT_REF_LOW_POWER_CONTROL (1) +/* @brief Has PLL/FLL selection as MCG output (register bit C6[PLLS]). */ +#define FSL_FEATURE_MCG_HAS_PLL_FLL_SELECTION (1) +/* @brief Has PLL output selection (PLL0/PLL1, PLL/external PLL) (register bit C11[PLLCS]). */ +#define FSL_FEATURE_MCG_HAS_PLL_OUTPUT_SELECTION (0) +/* @brief Has automatic trim machine (registers ATCVH, ATCVL and bits SC[ATMF], SC[ATMS], SC[ATME]). */ +#define FSL_FEATURE_MCG_HAS_AUTO_TRIM_MACHINE (1) +/* @brief Has external clock monitor (register bit C6[CME]). */ +#define FSL_FEATURE_MCG_HAS_EXTERNAL_CLOCK_MONITOR (1) +/* @brief Has low frequency internal reference clock (IRC) (registers LTRIMRNG, LFRIM, LSTRIM and bit MC[LIRC_DIV2]). */ +#define FSL_FEATURE_MCG_HAS_LOW_FREQ_IRC (0) +/* @brief Has high frequency internal reference clock (IRC) (registers HCTRIM, HTTRIM, HFTRIM and bit MC[HIRCEN]). */ +#define FSL_FEATURE_MCG_HAS_HIGH_FREQ_IRC (0) +/* @brief Has PEI mode or PBI mode. */ +#define FSL_FEATURE_MCG_HAS_PLL_INTERNAL_MODE (0) +/* @brief Reset clock mode is BLPI. */ +#define FSL_FEATURE_MCG_RESET_IS_BLPI (0) + +/* MPU module features */ + +/* @brief Specifies number of descriptors available. */ +#define FSL_FEATURE_MPU_DESCRIPTOR_COUNT (12) +/* @brief Has process identifier support. */ +#define FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER (1) +/* @brief Total number of MPU master. */ +#define FSL_FEATURE_MPU_MASTER_COUNT (8) +/* @brief Total number of MPU master with privileged rights */ +#define FSL_FEATURE_MPU_PRIVILEGED_RIGHTS_MASTER_COUNT (4) +/* @brief Max index of used MPU master. */ +#define FSL_FEATURE_MPU_MASTER_MAX_INDEX (5) +/* @brief Has master 4 or 5 or 6 or 7. */ +#define FSL_FEATURE_MPU_HAS_MASTER_4_7 (1) + +/* interrupt module features */ + +/* @brief Lowest interrupt request number. */ +#define FSL_FEATURE_INTERRUPT_IRQ_MIN (-14) +/* @brief Highest interrupt request number. */ +#define FSL_FEATURE_INTERRUPT_IRQ_MAX (104) + +/* OSC module features */ + +/* @brief Has OSC1 external oscillator. */ +#define FSL_FEATURE_OSC_HAS_OSC1 (0) +/* @brief Has OSC0 external oscillator. */ +#define FSL_FEATURE_OSC_HAS_OSC0 (0) +/* @brief Has OSC external oscillator (without index). */ +#define FSL_FEATURE_OSC_HAS_OSC (1) +/* @brief Number of OSC external oscillators. */ +#define FSL_FEATURE_OSC_OSC_COUNT (1) +/* @brief Has external reference clock divider (register bit field DIV[ERPS]). */ +#define FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER (1) + +/* PDB module features */ + +/* @brief Define the count of supporting ADC pre-trigger for each channel. */ +#define FSL_FEATURE_PDB_ADC_PRE_CHANNEL_COUNT (2) +/* @brief Has DAC support. */ +#define FSL_FEATURE_PDB_HAS_DAC (1) +/* @brief Has shared interrupt handler (has not individual interrupt handler for each channel). */ +#define FSL_FEATURE_PDB_HAS_SHARED_IRQ_HANDLER (0) + +/* PIT module features */ + +/* @brief Number of channels (related to number of registers LDVALn, CVALn, TCTRLn, TFLGn). */ +#define FSL_FEATURE_PIT_TIMER_COUNT (4) +/* @brief Has lifetime timer (related to existence of registers LTMR64L and LTMR64H). */ +#define FSL_FEATURE_PIT_HAS_LIFETIME_TIMER (0) +/* @brief Has chain mode (related to existence of register bit field TCTRLn[CHN]). */ +#define FSL_FEATURE_PIT_HAS_CHAIN_MODE (1) +/* @brief Has shared interrupt handler (has not individual interrupt handler for each channel). */ +#define FSL_FEATURE_PIT_HAS_SHARED_IRQ_HANDLER (0) + +/* PMC module features */ + +/* @brief Has Bandgap Enable In VLPx Operation support. */ +#define FSL_FEATURE_PMC_HAS_BGEN (1) +/* @brief Has Bandgap Buffer Enable. */ +#define FSL_FEATURE_PMC_HAS_BGBE (1) +/* @brief Has Bandgap Buffer Drive Select. */ +#define FSL_FEATURE_PMC_HAS_BGBDS (0) +/* @brief Has Low-Voltage Detect Voltage Select support. */ +#define FSL_FEATURE_PMC_HAS_LVDV (1) +/* @brief Has Low-Voltage Warning Voltage Select support. */ +#define FSL_FEATURE_PMC_HAS_LVWV (1) +/* @brief Has LPO. */ +#define FSL_FEATURE_PMC_HAS_LPO (0) +/* @brief Has VLPx option PMC_REGSC[VLPO]. */ +#define FSL_FEATURE_PMC_HAS_VLPO (0) +/* @brief Has acknowledge isolation support. */ +#define FSL_FEATURE_PMC_HAS_ACKISO (1) +/* @brief Has Regulator In Full Performance Mode Status Bit PMC_REGSC[REGFPM]. */ +#define FSL_FEATURE_PMC_HAS_REGFPM (0) +/* @brief Has Regulator In Run Regulation Status Bit PMC_REGSC[REGONS]. */ +#define FSL_FEATURE_PMC_HAS_REGONS (1) +/* @brief Has PMC_HVDSC1. */ +#define FSL_FEATURE_PMC_HAS_HVDSC1 (1) +/* @brief Has PMC_PARAM. */ +#define FSL_FEATURE_PMC_HAS_PARAM (0) +/* @brief Has PMC_VERID. */ +#define FSL_FEATURE_PMC_HAS_VERID (0) + +/* PORT module features */ + +/* @brief Has control lock (register bit PCR[LK]). */ +#define FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK (1) +/* @brief Has open drain control (register bit PCR[ODE]). */ +#define FSL_FEATURE_PORT_HAS_OPEN_DRAIN (1) +/* @brief Has digital filter (registers DFER, DFCR and DFWR). */ +#define FSL_FEATURE_PORT_HAS_DIGITAL_FILTER (1) +/* @brief Has DMA request (register bit field PCR[IRQC] values). */ +#define FSL_FEATURE_PORT_HAS_DMA_REQUEST (1) +/* @brief Has pull resistor selection available. */ +#define FSL_FEATURE_PORT_HAS_PULL_SELECTION (1) +/* @brief Has pull resistor enable (register bit PCR[PE]). */ +#define FSL_FEATURE_PORT_HAS_PULL_ENABLE (1) +/* @brief Has slew rate control (register bit PCR[SRE]). */ +#define FSL_FEATURE_PORT_HAS_SLEW_RATE (1) +/* @brief Has passive filter (register bit field PCR[PFE]). */ +#define FSL_FEATURE_PORT_HAS_PASSIVE_FILTER (1) +/* @brief Has drive strength control (register bit PCR[DSE]). */ +#define FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH (1) +/* @brief Has separate drive strength register (HDRVE). */ +#define FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH_REGISTER (0) +/* @brief Has glitch filter (register IOFLT). */ +#define FSL_FEATURE_PORT_HAS_GLITCH_FILTER (0) +/* @brief Defines width of PCR[MUX] field. */ +#define FSL_FEATURE_PORT_PCR_MUX_WIDTH (3) +/* @brief Has dedicated interrupt vector. */ +#define FSL_FEATURE_PORT_HAS_INTERRUPT_VECTOR (1) +/* @brief Defines whether PCR[IRQC] bit-field has flag states. */ +#define FSL_FEATURE_PORT_HAS_IRQC_FLAG (0) +/* @brief Defines whether PCR[IRQC] bit-field has trigger states. */ +#define FSL_FEATURE_PORT_HAS_IRQC_TRIGGER (0) + +/* QSPI module features */ + +/* @brief QSPI lookup table depth. */ +#define FSL_FEATURE_QSPI_LUT_DEPTH (64) +/* @brief QSPI Tx FIFO depth. */ +#define FSL_FEATURE_QSPI_TXFIFO_DEPTH (16) +/* @brief QSPI Rx FIFO depth. */ +#define FSL_FEATURE_QSPI_RXFIFO_DEPTH (16) +/* @brief QSPI AHB buffer count. */ +#define FSL_FEATURE_QSPI_AHB_BUFFER_COUNT (4) +/* @brief QSPI AMBA base address. */ +#define FSL_FEATURE_QSPI_AMBA_BASE (0x68000000U) +/* @brief QSPI AHB buffer ARDB base address. */ +#define FSL_FEATURE_QSPI_ARDB_BASE (0x67000000U) +/* @brief QSPI has command usage error flag. */ +#define FSL_FEATURE_QSPI_HAS_IP_COMMAND_USAGE_ERROR (1) +/* @brief QSPI support parallel mode. */ +#define FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE (1) +/* @brief QSPI support dual die. */ +#define FSL_FEATURE_QSPI_SUPPORT_DUAL_DIE (1) + +/* RCM module features */ + +/* @brief Has Loss-of-Lock Reset support. */ +#define FSL_FEATURE_RCM_HAS_LOL (1) +/* @brief Has Loss-of-Clock Reset support. */ +#define FSL_FEATURE_RCM_HAS_LOC (1) +/* @brief Has JTAG generated Reset support. */ +#define FSL_FEATURE_RCM_HAS_JTAG (1) +/* @brief Has EzPort generated Reset support. */ +#define FSL_FEATURE_RCM_HAS_EZPORT (0) +/* @brief Has bit-field indicating EZP_MS_B pin state during last reset. */ +#define FSL_FEATURE_RCM_HAS_EZPMS (0) +/* @brief Has boot ROM configuration, MR[BOOTROM], FM[FORCEROM] */ +#define FSL_FEATURE_RCM_HAS_BOOTROM (1) +/* @brief Has sticky system reset status register RCM_SSRS0 and RCM_SSRS1. */ +#define FSL_FEATURE_RCM_HAS_SSRS (1) +/* @brief Has Version ID Register (RCM_VERID). */ +#define FSL_FEATURE_RCM_HAS_VERID (0) +/* @brief Has Parameter Register (RCM_PARAM). */ +#define FSL_FEATURE_RCM_HAS_PARAM (0) +/* @brief Has Reset Interrupt Enable Register RCM_SRIE. */ +#define FSL_FEATURE_RCM_HAS_SRIE (0) +/* @brief Width of registers of the RCM. */ +#define FSL_FEATURE_RCM_REG_WIDTH (8) +/* @brief Has Core 1 generated Reset support RCM_SRS[CORE1] */ +#define FSL_FEATURE_RCM_HAS_CORE1 (0) +/* @brief Has MDM-AP system reset support RCM_SRS1[MDM_AP] */ +#define FSL_FEATURE_RCM_HAS_MDM_AP (1) +/* @brief Has wakeup reset feature. Register bit SRS[WAKEUP]. */ +#define FSL_FEATURE_RCM_HAS_WAKEUP (1) + +/* RTC module features */ + +/* @brief Has wakeup pin. */ +#define FSL_FEATURE_RTC_HAS_WAKEUP_PIN (1) +/* @brief Has wakeup pin selection (bit field CR[WPS]). */ +#define FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION (1) +/* @brief Has low power features (registers MER, MCLR and MCHR). */ +#define FSL_FEATURE_RTC_HAS_MONOTONIC (0) +/* @brief Has read/write access control (registers WAR and RAR). */ +#define FSL_FEATURE_RTC_HAS_ACCESS_CONTROL (1) +/* @brief Has security features (registers TTSR, MER, MCLR and MCHR). */ +#define FSL_FEATURE_RTC_HAS_SECURITY (1) +/* @brief Has RTC_CLKIN available. */ +#define FSL_FEATURE_RTC_HAS_RTC_CLKIN (0) +/* @brief Has prescaler adjust for LPO. */ +#define FSL_FEATURE_RTC_HAS_LPO_ADJUST (0) +/* @brief Has Clock Pin Enable field. */ +#define FSL_FEATURE_RTC_HAS_CPE (0) +/* @brief Has Timer Seconds Interrupt Configuration field. */ +#define FSL_FEATURE_RTC_HAS_TSIC (0) +/* @brief Has OSC capacitor setting RTC_CR[SC2P ~ SC16P] */ +#define FSL_FEATURE_RTC_HAS_OSC_SCXP (1) + +/* SDHC module features */ + +/* @brief Has external DMA support (register bit VENDOR[EXTDMAEN]). */ +#define FSL_FEATURE_SDHC_HAS_EXTERNAL_DMA_SUPPORT (0) +/* @brief Has support of 3.0V voltage (register bit HTCAPBLT[VS30]). */ +#define FSL_FEATURE_SDHC_HAS_V300_SUPPORT (0) +/* @brief Has support of 1.8V voltage (register bit HTCAPBLT[VS18]). */ +#define FSL_FEATURE_SDHC_HAS_V180_SUPPORT (0) + +/* SIM module features */ + +/* @brief Has USB FS divider. */ +#define FSL_FEATURE_SIM_USBFS_USE_SPECIAL_DIVIDER (0) +/* @brief Is PLL clock divided by 2 before MCG PLL/FLL clock selection. */ +#define FSL_FEATURE_SIM_PLLCLK_USE_SPECIAL_DIVIDER (0) +/* @brief Has RAM size specification (register bit field SOPT1[RAMSIZE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_RAMSIZE (1) +/* @brief Has 32k oscillator clock output (register bit SOPT1[OSC32KOUT]). */ +#define FSL_FEATURE_SIM_OPT_HAS_OSC32K_OUT (0) +/* @brief Has 32k oscillator clock selection (register bit field SOPT1[OSC32KSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_OSC32K_SELECTION (1) +/* @brief 32k oscillator clock selection width (width of register bit field SOPT1[OSC32KSEL]). */ +#define FSL_FEATURE_SIM_OPT_OSC32K_SELECTION_WIDTH (2) +/* @brief Has RTC clock output selection (register bit SOPT2[RTCCLKOUTSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_RTC_CLOCK_OUT_SELECTION (1) +/* @brief Has USB voltage regulator (register bits SOPT1[USBVSTBY], SOPT1[USBSSTBY], SOPT1[USBREGEN], SOPT1CFG[URWE], SOPT1CFG[UVSWE], SOPT1CFG[USSWE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR (1) +/* @brief USB has integrated PHY (register bits USBPHYCTL[USBVREGSEL], USBPHYCTL[USBVREGPD], USBPHYCTL[USB3VOUTTRG], USBPHYCTL[USBDISILIM], SOPT2[USBSLSRC], SOPT2[USBREGEN]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USB_PHY (0) +/* @brief Has PTD7 pad drive strength control (register bit SOPT2[PTD7PAD]). */ +#define FSL_FEATURE_SIM_OPT_HAS_PTD7PAD (0) +/* @brief Has FlexBus security level selection (register bit SOPT2[FBSL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FBSL (1) +/* @brief Has number of FlexBus hold cycle before FlexBus can release bus (register bit SOPT6[PCR]). */ +#define FSL_FEATURE_SIM_OPT_HAS_PCR (0) +/* @brief Has number of NFC hold cycle in case of FlexBus request (register bit SOPT6[MCC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_MCC (0) +/* @brief Has UART open drain enable (register bits UARTnODE, where n is a number, in register SOPT5). */ +#define FSL_FEATURE_SIM_OPT_HAS_ODE (0) +/* @brief Number of LPUART modules (number of register bits LPUARTn, where n is a number, in register SCGC5). */ +#define FSL_FEATURE_SIM_OPT_LPUART_COUNT (5) +/* @brief Number of UART modules (number of register bits UARTn, where n is a number, in register SCGC4). */ +#define FSL_FEATURE_SIM_OPT_UART_COUNT (0) +/* @brief Has UART0 open drain enable (register bit SOPT5[UART0ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART0_ODE (0) +/* @brief Has UART1 open drain enable (register bit SOPT5[UART1ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART1_ODE (0) +/* @brief Has UART2 open drain enable (register bit SOPT5[UART2ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART2_ODE (0) +/* @brief Has LPUART0 open drain enable (register bit SOPT5[LPUART0ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART0_ODE (0) +/* @brief Has LPUART1 open drain enable (register bit SOPT5[LPUART1ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART1_ODE (0) +/* @brief Has CMT/UART pad drive strength control (register bit SOPT2[CMTUARTPAD]). */ +#define FSL_FEATURE_SIM_OPT_HAS_CMTUARTPAD (0) +/* @brief Has LPUART0 transmit data source selection (register bit SOPT5[LPUART0TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART0_TX_SRC (1) +/* @brief Has LPUART0 receive data source selection (register bit SOPT5[LPUART0RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART0_RX_SRC (1) +/* @brief Has LPUART1 transmit data source selection (register bit SOPT5[LPUART1TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART1_TX_SRC (1) +/* @brief Has LPUART1 receive data source selection (register bit SOPT5[LPUART1RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART1_RX_SRC (1) +/* @brief Has UART0 transmit data source selection (register bit SOPT5[UART0TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART0_TX_SRC (0) +/* @brief UART0 transmit data source selection width (width of register bit SOPT5[UART0TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_UART0_TX_SRC_WIDTH (0) +/* @brief Has UART0 receive data source selection (register bit SOPT5[UART0RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART0_RX_SRC (0) +/* @brief UART0 receive data source selection width (width of register bit SOPT5[UART0RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_UART0_RX_SRC_WIDTH (0) +/* @brief Has UART1 transmit data source selection (register bit SOPT5[UART1TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART1_TX_SRC (0) +/* @brief Has UART1 receive data source selection (register bit SOPT5[UART1RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART1_RX_SRC (0) +/* @brief UART1 receive data source selection width (width of register bit SOPT5[UART1RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_UART1_RX_SRC_WIDTH (0) +/* @brief Has FTM module(s) configuration. */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM (1) +/* @brief Number of FTM modules. */ +#define FSL_FEATURE_SIM_OPT_FTM_COUNT (4) +/* @brief Number of FTM triggers with selectable source. */ +#define FSL_FEATURE_SIM_OPT_FTM_TRIGGER_COUNT (2) +/* @brief Has FTM0 triggers source selection (register bits SOPT4[FTM0TRGnSRC], where n is a number). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM0_TRIGGER (1) +/* @brief Has FTM3 triggers source selection (register bits SOPT4[FTM3TRGnSRC], where n is a number). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM3_TRIGGER (1) +/* @brief Has FTM1 channel 0 input capture source selection (register bit SOPT4[FTM1CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM1_CHANNELS (1) +/* @brief Has FTM2 channel 0 input capture source selection (register bit SOPT4[FTM2CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM2_CHANNELS (1) +/* @brief Has FTM3 channel 0 input capture source selection (register bit SOPT4[FTM3CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM3_CHANNELS (0) +/* @brief Has FTM2 channel 1 input capture source selection (register bit SOPT4[FTM2CH1SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM2_CHANNEL1 (1) +/* @brief Number of configurable FTM0 fault detection input (number of register bits SOPT4[FTM0FLTn], where n is a number starting from zero). */ +#define FSL_FEATURE_SIM_OPT_FTM0_FAULT_COUNT (2) +/* @brief Number of configurable FTM1 fault detection input (number of register bits SOPT4[FTM1FLTn], where n is a number starting from zero). */ +#define FSL_FEATURE_SIM_OPT_FTM1_FAULT_COUNT (1) +/* @brief Number of configurable FTM2 fault detection input (number of register bits SOPT4[FTM2FLTn], where n is a number starting from zero). */ +#define FSL_FEATURE_SIM_OPT_FTM2_FAULT_COUNT (1) +/* @brief Number of configurable FTM3 fault detection input (number of register bits SOPT4[FTM3FLTn], where n is a number starting from zero). */ +#define FSL_FEATURE_SIM_OPT_FTM3_FAULT_COUNT (1) +/* @brief Has FTM hardware trigger 0 software synchronization (register bit SOPT8[FTMnSYNCBIT], where n is a module instance index). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM_TRIGGER_SYNC (1) +/* @brief Has FTM channels output source selection (register bit SOPT8[FTMxOCHnSRC], where x is a module instance index and n is a channel index). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM_CHANNELS_OUTPUT_SRC (1) +/* @brief Has TPM module(s) configuration. */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM (1) +/* @brief The highest TPM module index. */ +#define FSL_FEATURE_SIM_OPT_MAX_TPM_INDEX (2) +/* @brief Has TPM module with index 0. */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM0 (0) +/* @brief Has TPM0 clock selection (register bit field SOPT4[TPM0CLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM0_CLK_SEL (0) +/* @brief Is TPM channels configuration in the SOPT4 (not SOPT9) register (register bits TPMnCH0SRC, TPMnCLKSEL, where n is a module instance index). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM_CHANNELS_CONFIG_IN_SOPT4_REG (0) +/* @brief Has TPM1 channel 0 input capture source selection (register bit field SOPT4[TPM1CH0SRC] or SOPT9[TPM1CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM1_CH0_SRC_SELECTION (1) +/* @brief Has TPM1 clock selection (register bit field SOPT4[TPM1CLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM1_CLK_SEL (0) +/* @brief TPM1 channel 0 input capture source selection width (width of register bit field SOPT4[TPM1CH0SRC] or SOPT9[TPM1CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_TPM1_CH0_SRC_SELECTION_WIDTH (1) +/* @brief Has TPM2 channel 0 input capture source selection (register bit field SOPT4[TPM2CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM2_CH0_SRC_SELECTION (0) +/* @brief Has TPM2 clock selection (register bit field SOPT4[TPM2CLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM2_CLK_SEL (0) +/* @brief Has PLL/FLL clock selection (register bit field SOPT2[PLLFLLSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_PLL_FLL_SELECTION (1) +/* @brief PLL/FLL clock selection width (width of register bit field SOPT2[PLLFLLSEL]). */ +#define FSL_FEATURE_SIM_OPT_PLL_FLL_SELECTION_WIDTH (1) +/* @brief Has NFC clock source selection (register bit SOPT2[NFCSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_NFCSRC (0) +/* @brief Has eSDHC clock source selection (register bit SOPT2[ESDHCSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_ESDHCSRC (0) +/* @brief Has SDHC clock source selection (register bit SOPT2[SDHCSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_SDHCSRC (1) +/* @brief Has LCDC clock source selection (register bits SOPT2[LCDCSRC], SOPT2[LCDC_CLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LCDCSRC (0) +/* @brief Has ENET timestamp clock source selection (register bit SOPT2[TIMESRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TIMESRC (0) +/* @brief Has ENET RMII clock source selection (register bit SOPT2[RMIISRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_RMIISRC (0) +/* @brief Has USB clock source selection (register bit SOPT2[USBSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USBSRC (1) +/* @brief Has USB FS clock source selection (register bit SOPT2[USBFSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USBFSRC (0) +/* @brief Has USB HS clock source selection (register bit SOPT2[USBHSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USBHSRC (0) +/* @brief Has LPUART clock source selection (register bit SOPT2[LPUARTSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUARTSRC (1) +/* @brief Has LPUART0 clock source selection (register bit SOPT2[LPUART0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART0SRC (0) +/* @brief Has LPUART1 clock source selection (register bit SOPT2[LPUART1SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART1SRC (0) +/* @brief Has FLEXIOSRC clock source selection (register bit SOPT2[FLEXIOSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FLEXIOSRC (1) +/* @brief Has UART0 clock source selection (register bit SOPT2[UART0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART0SRC (0) +/* @brief Has TPM clock source selection (register bit SOPT2[TPMSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPMSRC (1) +/* @brief Has debug trace clock selection (register bit SOPT2[TRACECLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TRACE_CLKSEL (1) +/* @brief Number of ADC modules (register bits SOPT7[ADCnTRGSEL], SOPT7[ADCnPRETRGSEL], SOPT7[ADCnALTTRGSEL], where n is a module instance index). */ +#define FSL_FEATURE_SIM_OPT_ADC_COUNT (1) +/* @brief ADC0 alternate trigger enable width (width of bit field ADC0ALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_ADC0ALTTRGEN_WIDTH (1) +/* @brief ADC1 alternate trigger enable width (width of bit field ADC1ALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_ADC1ALTTRGEN_WIDTH (0) +/* @brief ADC2 alternate trigger enable width (width of bit field ADC2ALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_ADC2ALTTRGEN_WIDTH (0) +/* @brief ADC3 alternate trigger enable width (width of bit field ADC3ALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_ADC3ALTTRGEN_WIDTH (0) +/* @brief HSADC0 converter A alternate trigger enable width (width of bit field HSADC0AALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_HSADC0AALTTRGEN_WIDTH (0) +/* @brief HSADC1 converter A alternate trigger enable width (width of bit field HSADC1AALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_HSADC1AALTTRGEN_WIDTH (0) +/* @brief ADC converter A alternate trigger enable width (width of bit field ADCAALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_ADCAALTTRGEN_WIDTH (0) +/* @brief HSADC0 converter B alternate trigger enable width (width of bit field HSADC0BALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_HSADC0BALTTRGEN_WIDTH (0) +/* @brief HSADC1 converter B alternate trigger enable width (width of bit field HSADC1BALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_HSADC1BALTTRGEN_WIDTH (0) +/* @brief ADC converter B alternate trigger enable width (width of bit field ADCBALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_ADCBALTTRGEN_WIDTH (0) +/* @brief Has clock 2 output divider (register bit field CLKDIV1[OUTDIV2]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_OUTDIV2 (1) +/* @brief Has clock 3 output divider (register bit field CLKDIV1[OUTDIV3]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_OUTDIV3 (1) +/* @brief Has clock 4 output divider (register bit field CLKDIV1[OUTDIV4]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_OUTDIV4 (1) +/* @brief Clock 4 output divider width (width of register bit field CLKDIV1[OUTDIV4]). */ +#define FSL_FEATURE_SIM_DIVIDER_OUTDIV4_WIDTH (4) +/* @brief Has clock 5 output divider (register bit field CLKDIV1[OUTDIV5]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_OUTDIV5 (0) +/* @brief Has USB clock divider (register bit field CLKDIV2[USBDIV] and CLKDIV2[USBFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_USBDIV (1) +/* @brief Has USB FS clock divider (register bit field CLKDIV2[USBFSDIV] and CLKDIV2[USBFSFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_USBFSDIV (0) +/* @brief Has USB HS clock divider (register bit field CLKDIV2[USBHSDIV] and CLKDIV2[USBHSFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_USBHSDIV (0) +/* @brief Has PLL/FLL clock divider (register bit field CLKDIV3[PLLFLLDIV] and CLKDIV3[PLLFLLFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_PLLFLLDIV (1) +/* @brief Has LCDC clock divider (register bit field CLKDIV3[LCDCDIV] and CLKDIV3[LCDCFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_LCDCDIV (0) +/* @brief Has trace clock divider (register bit field CLKDIV4[TRACEDIV] and CLKDIV4[TRACEFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_TRACEDIV (1) +/* @brief Has NFC clock divider (register bit field CLKDIV4[NFCDIV] and CLKDIV4[NFCFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_NFCDIV (0) +/* @brief Has Kinetis family ID (register bit field SDID[FAMILYID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_FAMILYID (1) +/* @brief Has Kinetis family ID (register bit field SDID[FAMID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_FAMID (1) +/* @brief Has Kinetis sub-family ID (register bit field SDID[SUBFAMID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_SUBFAMID (1) +/* @brief Has Kinetis series ID (register bit field SDID[SERIESID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_SERIESID (1) +/* @brief Has device die ID (register bit field SDID[DIEID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_DIEID (1) +/* @brief Has system SRAM size specifier (register bit field SDID[SRAMSIZE]). */ +#define FSL_FEATURE_SIM_SDID_HAS_SRAMSIZE (0) +/* @brief Has flash mode (register bit FCFG1[FLASHDOZE]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_FLASHDOZE (1) +/* @brief Has flash disable (register bit FCFG1[FLASHDIS]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_FLASHDIS (1) +/* @brief Has FTFE disable (register bit FCFG1[FTFDIS]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_FTFDIS (0) +/* @brief Has FlexNVM size specifier (register bit field FCFG1[NVMSIZE]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_NVMSIZE (0) +/* @brief Has EEPROM size specifier (register bit field FCFG1[EESIZE]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_EESIZE (0) +/* @brief Has FlexNVM partition (register bit field FCFG1[DEPART]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_DEPART (0) +/* @brief Maximum flash address block 0 address specifier (register bit field FCFG2[MAXADDR0]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_MAXADDR0 (1) +/* @brief Maximum flash address block 1 address specifier (register bit field FCFG2[MAXADDR1]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_MAXADDR1 (1) +/* @brief Maximum flash address block 0 or 1 address specifier (register bit field FCFG2[MAXADDR01]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_MAXADDR01 (0) +/* @brief Maximum flash address block 2 or 3 address specifier (register bit field FCFG2[MAXADDR23]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_MAXADDR23 (0) +/* @brief Has program flash availability specifier (register bit FCFG2[PFLSH]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_PFLSH (0) +/* @brief Has program flash swapping (register bit FCFG2[SWAPPFLSH]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_PFLSH_SWAP (0) +/* @brief Has miscellanious control register (register MCR). */ +#define FSL_FEATURE_SIM_HAS_MISC_CONTROLS (0) +/* @brief Has COP watchdog (registers COPC and SRVCOP). */ +#define FSL_FEATURE_SIM_HAS_COP_WATCHDOG (0) +/* @brief Has COP watchdog stop (register bits COPC[COPSTPEN], COPC[COPDBGEN] and COPC[COPCLKSEL]). */ +#define FSL_FEATURE_SIM_HAS_COP_STOP (0) +/* @brief Has LLWU clock gate bit (e.g SIM_SCGC4). */ +#define FSL_FEATURE_SIM_HAS_SCGC_LLWU (0) + +/* SMC module features */ + +/* @brief Has partial stop option (register bit STOPCTRL[PSTOPO]). */ +#define FSL_FEATURE_SMC_HAS_PSTOPO (1) +/* @brief Has LPO power option (register bit STOPCTRL[LPOPO]). */ +#define FSL_FEATURE_SMC_HAS_LPOPO (1) +/* @brief Has POR power option (register bit STOPCTRL[PORPO] or VLLSCTRL[PORPO]). */ +#define FSL_FEATURE_SMC_HAS_PORPO (1) +/* @brief Has low power wakeup on interrupt (register bit PMCTRL[LPWUI]). */ +#define FSL_FEATURE_SMC_HAS_LPWUI (0) +/* @brief Has LLS or VLLS mode control (register bit STOPCTRL[LLSM]). */ +#define FSL_FEATURE_SMC_HAS_LLS_SUBMODE (1) +/* @brief Has VLLS mode control (register bit VLLSCTRL[VLLSM]). */ +#define FSL_FEATURE_SMC_USE_VLLSCTRL_REG (0) +/* @brief Has VLLS mode control (register bit STOPCTRL[VLLSM]). */ +#define FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM (0) +/* @brief Has RAM partition 2 power option (register bit STOPCTRL[RAM2PO]). */ +#define FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION (1) +/* @brief Has high speed run mode (register bit PMPROT[AHSRUN]). */ +#define FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE (1) +/* @brief Has low leakage stop mode (register bit PMPROT[ALLS]). */ +#define FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE (1) +/* @brief Has very low leakage stop mode (register bit PMPROT[AVLLS]). */ +#define FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE (1) +/* @brief Has stop submode. */ +#define FSL_FEATURE_SMC_HAS_SUB_STOP_MODE (1) +/* @brief Has stop submode 0(VLLS0). */ +#define FSL_FEATURE_SMC_HAS_STOP_SUBMODE0 (1) +/* @brief Has stop submode 2(VLLS2). */ +#define FSL_FEATURE_SMC_HAS_STOP_SUBMODE2 (1) +/* @brief Has SMC_PARAM. */ +#define FSL_FEATURE_SMC_HAS_PARAM (0) +/* @brief Has SMC_VERID. */ +#define FSL_FEATURE_SMC_HAS_VERID (0) + +/* DSPI module features */ + +/* @brief Receive/transmit FIFO size in number of items. */ +#define FSL_FEATURE_DSPI_FIFO_SIZEn(x) \ + ((x) == DSPI0 ? (4) : \ + ((x) == DSPI1 ? (1) : \ + ((x) == DSPI2 ? (1) : (-1)))) +/* @brief Maximum transfer data width in bits. */ +#define FSL_FEATURE_DSPI_MAX_DATA_WIDTH (16) +/* @brief Maximum number of chip select pins. (Reflects the width of register bit field PUSHR[PCS].) */ +#define FSL_FEATURE_DSPI_MAX_CHIP_SELECT_COUNT (6) +/* @brief Number of chip select pins. */ +#define FSL_FEATURE_DSPI_CHIP_SELECT_COUNT (6) +/* @brief Has chip select strobe capability on the PCS5 pin. */ +#define FSL_FEATURE_DSPI_HAS_CHIP_SELECT_STROBE (1) +/* @brief Has separated TXDATA and CMD FIFOs (register SREX). */ +#define FSL_FEATURE_DSPI_HAS_SEPARATE_TXDATA_CMD_FIFO (0) +/* @brief Has 16-bit data transfer support. */ +#define FSL_FEATURE_DSPI_16BIT_TRANSFERS (1) +/* @brief Has separate DMA RX and TX requests. */ +#define FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1) + +/* SysTick module features */ + +/* @brief Systick has external reference clock. */ +#define FSL_FEATURE_SYSTICK_HAS_EXT_REF (0) +/* @brief Systick external reference clock is core clock divided by this value. */ +#define FSL_FEATURE_SYSTICK_EXT_REF_CORE_DIV (0) + +/* TPM module features */ + +/* @brief Bus clock is the source clock for the module. */ +#define FSL_FEATURE_TPM_BUS_CLOCK (0) +/* @brief Number of channels. */ +#define FSL_FEATURE_TPM_CHANNEL_COUNTn(x) (2) +/* @brief Has counter reset by the selected input capture event (register bits C0SC[ICRST], C1SC[ICRST], ...). */ +#define FSL_FEATURE_TPM_HAS_COUNTER_RESET_BY_CAPTURE_EVENT (0) +/* @brief Has TPM_PARAM. */ +#define FSL_FEATURE_TPM_HAS_PARAM (0) +/* @brief Has TPM_VERID. */ +#define FSL_FEATURE_TPM_HAS_VERID (0) +/* @brief Has TPM_GLOBAL. */ +#define FSL_FEATURE_TPM_HAS_GLOBAL (0) +/* @brief Has TPM_TRIG. */ +#define FSL_FEATURE_TPM_HAS_TRIG (0) +/* @brief Has counter pause on trigger. */ +#define FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER (1) +/* @brief Has external trigger selection. */ +#define FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION (1) +/* @brief Has TPM_COMBINE. */ +#define FSL_FEATURE_TPM_HAS_COMBINE (1) +/* @brief Has TPM_POL. */ +#define FSL_FEATURE_TPM_HAS_POL (1) +/* @brief Has TPM_FILTER. */ +#define FSL_FEATURE_TPM_HAS_FILTER (1) +/* @brief Has TPM_QDCTRL. */ +#define FSL_FEATURE_TPM_HAS_QDCTRL (1) + +/* TSI module features */ + +/* @brief TSI module version. */ +#define FSL_FEATURE_TSI_VERSION (4) +/* @brief Has end-of-scan DMA transfer request enable (register bit GENCS[EOSDMEO]). */ +#define FSL_FEATURE_TSI_HAS_END_OF_SCAN_DMA_ENABLE (1) +/* @brief Number of TSI channels. */ +#define FSL_FEATURE_TSI_CHANNEL_COUNT (16) + +/* USB module features */ + +/* @brief HOST mode enabled */ +#define FSL_FEATURE_USB_KHCI_HOST_ENABLED (1) +/* @brief OTG mode enabled */ +#define FSL_FEATURE_USB_KHCI_OTG_ENABLED (1) +/* @brief Size of the USB dedicated RAM */ +#define FSL_FEATURE_USB_KHCI_USB_RAM (0) +/* @brief Has KEEP_ALIVE_CTRL register */ +#define FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED (0) +/* @brief Has the Dynamic SOF threshold compare support */ +#define FSL_FEATURE_USB_KHCI_DYNAMIC_SOF_THRESHOLD_COMPARE_ENABLED (1) +/* @brief Has the VBUS detect support */ +#define FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED (1) +/* @brief Has the IRC48M module clock support */ +#define FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED (1) +/* @brief Number of endpoints supported */ +#define FSL_FEATURE_USB_ENDPT_COUNT (16) + +/* VREF module features */ + +/* @brief Has chop oscillator (bit TRM[CHOPEN]) */ +#define FSL_FEATURE_VREF_HAS_CHOP_OSC (1) +/* @brief Has second order curvature compensation (bit SC[ICOMPEN]) */ +#define FSL_FEATURE_VREF_HAS_COMPENSATION (1) +/* @brief If high/low buffer mode supported */ +#define FSL_FEATURE_VREF_MODE_LV_TYPE (1) +/* @brief Module has also low reference (registers VREFL/VREFH) */ +#define FSL_FEATURE_VREF_HAS_LOW_REFERENCE (0) +/* @brief Has VREF_TRM4. */ +#define FSL_FEATURE_VREF_HAS_TRM4 (0) + +/* WDOG module features */ + +/* @brief Watchdog is available. */ +#define FSL_FEATURE_WDOG_HAS_WATCHDOG (1) +/* @brief Has Wait mode support. */ +#define FSL_FEATURE_WDOG_HAS_WAITEN (1) + +#endif /* _MK82F25615_FEATURES_H_ */ + diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_ARM_STD/MK82FN256xxx15.sct b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_ARM_STD/MK82FN256xxx15.sct new file mode 100644 index 00000000000..60da5f63a51 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_ARM_STD/MK82FN256xxx15.sct @@ -0,0 +1,127 @@ +#! armcc -E +/* +** ################################################################### +** Processors: MK82FN256CAx15 +** MK82FN256VDC15 +** MK82FN256VLL15 +** MK82FN256VLQ15 +** +** Compiler: Keil ARM C/C++ Compiler +** Reference manual: K82P121M150SF5RM, Rev. 0, May 2015 +** Version: rev. 1.2, 2015-07-29 +** Build: b160406 +** +** Abstract: +** Linker file for the Keil ARM C/C++ Compiler +** +** Copyright (c) 2016 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** ################################################################### +*/ + +#define __ram_vector_table__ 1 + +/* Heap 1/4 of ram and stack 1/8 */ +#define __stack_size__ 0x8000 +#define __heap_size__ 0x10000 + +#if (defined(__ram_vector_table__)) + #define __ram_vector_table_size__ 0x000003C0 +#else + #define __ram_vector_table_size__ 0x00000000 +#endif + +#define m_interrupts_start 0x00000000 +#define m_interrupts_size 0x000003C0 + +#define m_bootloader_config_start 0x000003C0 +#define m_bootloader_config_size 0x00000040 + +#define m_flash_config_start 0x00000400 +#define m_flash_config_size 0x00000010 + +#define m_text_start 0x00000410 +#define m_text_size 0x0003FBF0 + +#define m_interrupts_ram_start 0x1FFF0000 +#define m_interrupts_ram_size __ram_vector_table_size__ + +#define m_data_start (m_interrupts_ram_start + m_interrupts_ram_size) +#define m_data_size (0x00010000 - m_interrupts_ram_size) + +#define m_data_2_start 0x20000000 +#define m_data_2_size 0x00030000 + +/* Sizes */ +#if (defined(__stack_size__)) + #define Stack_Size __stack_size__ +#else + #define Stack_Size 0x0400 +#endif + +#if (defined(__heap_size__)) + #define Heap_Size __heap_size__ +#else + #define Heap_Size 0x0400 +#endif + +LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region + VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address + * (RESET,+FIRST) + } + ER_m_bootloader_config m_bootloader_config_start FIXED m_bootloader_config_size { ; load address = execution address + * (BootloaderConfig) + } + ER_m_flash_config m_flash_config_start FIXED m_flash_config_size { ; load address = execution address + * (FlashConfig) + } + ER_m_text m_text_start m_text_size { ; load address = execution address + * (InRoot$$Sections) + .ANY (+RO) + } + +#if (defined(__ram_vector_table__)) + VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size { + } +#else + VECTOR_RAM m_interrupts_start EMPTY 0 { + } +#endif + RW_m_data m_data_start m_data_size { ; RW data + .ANY (+RW +ZI) + } + RW_m_data_2 m_data_2_start m_data_2_size-Stack_Size-Heap_Size { ; RW data + .ANY (+RW +ZI) + } + RW_IRAM1 ImageLimit(RW_m_data_2) { ; Heap region growing up + } +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_ARM_STD/startup_MK82F25615.S b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_ARM_STD/startup_MK82F25615.S new file mode 100644 index 00000000000..83585b0e38f --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_ARM_STD/startup_MK82F25615.S @@ -0,0 +1,965 @@ +; * --------------------------------------------------------------------------------------- +; * @file: startup_MK82F25615.s +; * @purpose: CMSIS Cortex-M4 Core Device Startup File +; * MK82F25615 +; * @version: 1.0 +; * @date: 2015-4-9 +; * @build: b151210 +; * --------------------------------------------------------------------------------------- +; * +; * Copyright (c) 1997 - 2015 , Freescale Semiconductor, Inc. +; * All rights reserved. +; * +; * Redistribution and use in source and binary forms, with or without modification, +; * are permitted provided that the following conditions are met: +; * +; * o Redistributions of source code must retain the above copyright notice, this list +; * of conditions and the following disclaimer. +; * +; * o Redistributions in binary form must reproduce the above copyright notice, this +; * list of conditions and the following disclaimer in the documentation and/or +; * other materials provided with the distribution. +; * +; * o Neither the name of Freescale Semiconductor, Inc. nor the names of its +; * contributors may be used to endorse or promote products derived from this +; * software without specific prior written permission. +; * +; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +; * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +; * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +; * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; * +; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------ +; * +; *****************************************************************************/ + +__initial_sp EQU 0x20030000 ; Top of RAM + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ;NMI Handler + DCD HardFault_Handler ;Hard Fault Handler + DCD MemManage_Handler ;MPU Fault Handler + DCD BusFault_Handler ;Bus Fault Handler + DCD UsageFault_Handler ;Usage Fault Handler + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD SVC_Handler ;SVCall Handler + DCD DebugMon_Handler ;Debug Monitor Handler + DCD 0 ;Reserved + DCD PendSV_Handler ;PendSV Handler + DCD SysTick_Handler ;SysTick Handler + + ;External Interrupts + DCD DMA0_DMA16_IRQHandler ;DMA channel 0,16 transfer complete + DCD DMA1_DMA17_IRQHandler ;DMA channel 1,17 transfer complete + DCD DMA2_DMA18_IRQHandler ;DMA channel 2,18 transfer complete + DCD DMA3_DMA19_IRQHandler ;DMA channel 3,19 transfer complete + DCD DMA4_DMA20_IRQHandler ;DMA channel 4,20 transfer complete + DCD DMA5_DMA21_IRQHandler ;DMA channel 5,21 transfer complete + DCD DMA6_DMA22_IRQHandler ;DMA channel 6,22 transfer complete + DCD DMA7_DMA23_IRQHandler ;DMA channel 7,23 transfer complete + DCD DMA8_DMA24_IRQHandler ;DMA channel 8,24 transfer complete + DCD DMA9_DMA25_IRQHandler ;DMA channel 9,25 transfer complete + DCD DMA10_DMA26_IRQHandler ;DMA channel 10,26 transfer complete + DCD DMA11_DMA27_IRQHandler ;DMA channel 11,27 transfer complete + DCD DMA12_DMA28_IRQHandler ;DMA channel 12,28 transfer complete + DCD DMA13_DMA29_IRQHandler ;DMA channel 13,29 transfer complete + DCD DMA14_DMA30_IRQHandler ;DMA channel 14,30 transfer complete + DCD DMA15_DMA31_IRQHandler ;DMA channel 15,31 transfer complete + DCD DMA_Error_IRQHandler ;DMA channel 0 - 31 error + DCD MCM_IRQHandler ;MCM normal interrupt + DCD FTFA_IRQHandler ;FTFA command complete + DCD Read_Collision_IRQHandler ;FTFA read collision + DCD LVD_LVW_IRQHandler ;PMC controller low-voltage detect, low-voltage warning + DCD LLWU_IRQHandler ;Low leakage wakeup unit + DCD WDOG_EWM_IRQHandler ;Single interrupt vector for WDOG and EWM + DCD TRNG0_IRQHandler ;True randon number generator + DCD I2C0_IRQHandler ;Inter-integrated circuit 0 + DCD I2C1_IRQHandler ;Inter-integrated circuit 1 + DCD SPI0_IRQHandler ;Serial peripheral Interface 0 + DCD SPI1_IRQHandler ;Serial peripheral Interface 1 + DCD I2S0_Tx_IRQHandler ;Integrated interchip sound 0 transmit interrupt + DCD I2S0_Rx_IRQHandler ;Integrated interchip sound 0 receive interrupt + DCD LPUART0_IRQHandler ;LPUART0 receive/transmit/error interrupt + DCD LPUART1_IRQHandler ;LPUART1 receive/transmit/error interrupt + DCD LPUART2_IRQHandler ;LPUART2 receive/transmit/error interrupt + DCD LPUART3_IRQHandler ;LPUART3 receive/transmit/error interrupt + DCD LPUART4_IRQHandler ;LPUART4 receive/transmit/error interrupt + DCD Reserved51_IRQHandler ;Reserved interrupt + DCD Reserved52_IRQHandler ;Reserved interrupt + DCD EMVSIM0_IRQHandler ;EMVSIM0 common interrupt + DCD EMVSIM1_IRQHandler ;EMVSIM1 common interrupt + DCD ADC0_IRQHandler ;Analog-to-digital converter 0 + DCD CMP0_IRQHandler ;Comparator 0 + DCD CMP1_IRQHandler ;Comparator 1 + DCD FTM0_IRQHandler ;FlexTimer module 0 fault, overflow and channels interrupt + DCD FTM1_IRQHandler ;FlexTimer module 1 fault, overflow and channels interrupt + DCD FTM2_IRQHandler ;FlexTimer module 2 fault, overflow and channels interrupt + DCD CMT_IRQHandler ;Carrier modulator transmitter + DCD RTC_IRQHandler ;Real time clock + DCD RTC_Seconds_IRQHandler ;Real time clock seconds + DCD PIT0CH0_IRQHandler ;Periodic interrupt timer 0 channel 0 + DCD PIT0CH1_IRQHandler ;Periodic interrupt timer 0 channel 1 + DCD PIT0CH2_IRQHandler ;Periodic interrupt timer 0 channel 2 + DCD PIT0CH3_IRQHandler ;Periodic interrupt timer 0 channel 3 + DCD PDB0_IRQHandler ;Programmable delay block + DCD USB0_IRQHandler ;USB OTG interrupt + DCD USBDCD_IRQHandler ;USB charger detect + DCD Reserved71_IRQHandler ;Reserved interrupt + DCD DAC0_IRQHandler ;Digital-to-analog converter 0 + DCD MCG_IRQHandler ;Multipurpose clock generator + DCD LPTMR0_LPTMR1_IRQHandler ;Single interrupt vector for Low Power Timer 0 and 1 + DCD PORTA_IRQHandler ;Port A pin detect interrupt + DCD PORTB_IRQHandler ;Port B pin detect interrupt + DCD PORTC_IRQHandler ;Port C pin detect interrupt + DCD PORTD_IRQHandler ;Port D pin detect interrupt + DCD PORTE_IRQHandler ;Port E pin detect interrupt + DCD SWI_IRQHandler ;Software interrupt + DCD SPI2_IRQHandler ;Serial peripheral Interface 2 + DCD Reserved82_IRQHandler ;Reserved interrupt + DCD Reserved83_IRQHandler ;Reserved interrupt + DCD Reserved84_IRQHandler ;Reserved interrupt + DCD Reserved85_IRQHandler ;Reserved interrupt + DCD FLEXIO0_IRQHandler ;FLEXIO0 + DCD FTM3_IRQHandler ;FlexTimer module 3 fault, overflow and channels interrupt + DCD Reserved88_IRQHandler ;Reserved interrupt + DCD Reserved89_IRQHandler ;Reserved interrupt + DCD I2C2_IRQHandler ;Inter-integrated circuit 2 + DCD Reserved91_IRQHandler ;Reserved interrupt + DCD Reserved92_IRQHandler ;Reserved interrupt + DCD Reserved93_IRQHandler ;Reserved interrupt + DCD Reserved94_IRQHandler ;Reserved interrupt + DCD Reserved95_IRQHandler ;Reserved interrupt + DCD Reserved96_IRQHandler ;Reserved interrupt + DCD SDHC_IRQHandler ;Secured digital host controller + DCD Reserved98_IRQHandler ;Reserved interrupt + DCD Reserved99_IRQHandler ;Reserved interrupt + DCD Reserved100_IRQHandler ;Reserved interrupt + DCD Reserved101_IRQHandler ;Reserved interrupt + DCD Reserved102_IRQHandler ;Reserved interrupt + DCD TSI0_IRQHandler ;Touch Sensing Input + DCD TPM1_IRQHandler ;TPM1 single interrupt vector for all sources + DCD TPM2_IRQHandler ;TPM2 single interrupt vector for all sources + DCD Reserved106_IRQHandler ;Reserved interrupt + DCD I2C3_IRQHandler ;Inter-integrated circuit 3 + DCD Reserved108_IRQHandler ;Reserved interrupt + DCD Reserved109_IRQHandler ;Reserved interrupt + DCD Reserved110_IRQHandler ;Reserved interrupt + DCD Reserved111_IRQHandler ;Reserved interrupt + DCD Reserved112_IRQHandler ;Reserved interrupt + DCD Reserved113_IRQHandler ;Reserved interrupt + DCD Reserved114_IRQHandler ;Reserved interrupt + DCD Reserved115_IRQHandler ;Reserved interrupt + DCD QuadSPI0_IRQHandler ;qspi + DCD Reserved117_IRQHandler ;Reserved interrupt + DCD Reserved118_IRQHandler ;Reserved interrupt + DCD Reserved119_IRQHandler ;Reserved interrupt + DCD LTC0_IRQHandler ;LP Trusted Cryptography + DCD Reserved121_IRQHandler ;Reserved interrupt + DCD Reserved122_IRQHandler ;Reserved interrupt + DCD DefaultISR ;123 + DCD DefaultISR ;124 + DCD DefaultISR ;125 + DCD DefaultISR ;126 + DCD DefaultISR ;127 + DCD DefaultISR ;128 + DCD DefaultISR ;129 + DCD DefaultISR ;130 + DCD DefaultISR ;131 + DCD DefaultISR ;132 + DCD DefaultISR ;133 + DCD DefaultISR ;134 + DCD DefaultISR ;135 + DCD DefaultISR ;136 + DCD DefaultISR ;137 + DCD DefaultISR ;138 + DCD DefaultISR ;139 + DCD DefaultISR ;140 + DCD DefaultISR ;141 + DCD DefaultISR ;142 + DCD DefaultISR ;143 + DCD DefaultISR ;144 + DCD DefaultISR ;145 + DCD DefaultISR ;146 + DCD DefaultISR ;147 + DCD DefaultISR ;148 + DCD DefaultISR ;149 + DCD DefaultISR ;150 + DCD DefaultISR ;151 + DCD DefaultISR ;152 + DCD DefaultISR ;153 + DCD DefaultISR ;154 + DCD DefaultISR ;155 + DCD DefaultISR ;156 + DCD DefaultISR ;157 + DCD DefaultISR ;158 + DCD DefaultISR ;159 + DCD DefaultISR ;160 + DCD DefaultISR ;161 + DCD DefaultISR ;162 + DCD DefaultISR ;163 + DCD DefaultISR ;164 + DCD DefaultISR ;165 + DCD DefaultISR ;166 + DCD DefaultISR ;167 + DCD DefaultISR ;168 + DCD DefaultISR ;169 + DCD DefaultISR ;170 + DCD DefaultISR ;171 + DCD DefaultISR ;172 + DCD DefaultISR ;173 + DCD DefaultISR ;174 + DCD DefaultISR ;175 + DCD DefaultISR ;176 + DCD DefaultISR ;177 + DCD DefaultISR ;178 + DCD DefaultISR ;179 + DCD DefaultISR ;180 + DCD DefaultISR ;181 + DCD DefaultISR ;182 + DCD DefaultISR ;183 + DCD DefaultISR ;184 + DCD DefaultISR ;185 + DCD DefaultISR ;186 + DCD DefaultISR ;187 + DCD DefaultISR ;188 + DCD DefaultISR ;189 + DCD DefaultISR ;190 + DCD DefaultISR ;191 + DCD DefaultISR ;192 + DCD DefaultISR ;193 + DCD DefaultISR ;194 + DCD DefaultISR ;195 + DCD DefaultISR ;196 + DCD DefaultISR ;197 + DCD DefaultISR ;198 + DCD DefaultISR ;199 + DCD DefaultISR ;200 + DCD DefaultISR ;201 + DCD DefaultISR ;202 + DCD DefaultISR ;203 + DCD DefaultISR ;204 + DCD DefaultISR ;205 + DCD DefaultISR ;206 + DCD DefaultISR ;207 + DCD DefaultISR ;208 + DCD DefaultISR ;209 + DCD DefaultISR ;210 + DCD DefaultISR ;211 + DCD DefaultISR ;212 + DCD DefaultISR ;213 + DCD DefaultISR ;214 + DCD DefaultISR ;215 + DCD DefaultISR ;216 + DCD DefaultISR ;217 + DCD DefaultISR ;218 + DCD DefaultISR ;219 + DCD DefaultISR ;220 + DCD DefaultISR ;221 + DCD DefaultISR ;222 + DCD DefaultISR ;223 + DCD DefaultISR ;224 + DCD DefaultISR ;225 + DCD DefaultISR ;226 + DCD DefaultISR ;227 + DCD DefaultISR ;228 + DCD DefaultISR ;229 + DCD DefaultISR ;230 + DCD DefaultISR ;231 + DCD DefaultISR ;232 + DCD DefaultISR ;233 + DCD DefaultISR ;234 + DCD DefaultISR ;235 + DCD DefaultISR ;236 + DCD DefaultISR ;237 + DCD DefaultISR ;238 + DCD DefaultISR ;239 +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + +; Flash Configuration +; 16-byte flash configuration field that stores default protection settings (loaded on reset) +; and security information that allows the MCU to restrict access to the FTFL module. +; Backdoor Comparison Key +; Backdoor Comparison Key 0. <0x0-0xFF:2> +; Backdoor Comparison Key 1. <0x0-0xFF:2> +; Backdoor Comparison Key 2. <0x0-0xFF:2> +; Backdoor Comparison Key 3. <0x0-0xFF:2> +; Backdoor Comparison Key 4. <0x0-0xFF:2> +; Backdoor Comparison Key 5. <0x0-0xFF:2> +; Backdoor Comparison Key 6. <0x0-0xFF:2> +; Backdoor Comparison Key 7. <0x0-0xFF:2> +BackDoorK0 EQU 0xFF +BackDoorK1 EQU 0xFF +BackDoorK2 EQU 0xFF +BackDoorK3 EQU 0xFF +BackDoorK4 EQU 0xFF +BackDoorK5 EQU 0xFF +BackDoorK6 EQU 0xFF +BackDoorK7 EQU 0xFF +; +; Program flash protection bytes (FPROT) +; Each program flash region can be protected from program and erase operation by setting the associated PROT bit. +; Each bit protects a 1/32 region of the program flash memory. +; FPROT0 +; Program Flash Region Protect Register 0 +; 1/32 - 8/32 region +; FPROT0.0 +; FPROT0.1 +; FPROT0.2 +; FPROT0.3 +; FPROT0.4 +; FPROT0.5 +; FPROT0.6 +; FPROT0.7 +nFPROT0 EQU 0x00 +FPROT0 EQU nFPROT0:EOR:0xFF +; +; FPROT1 +; Program Flash Region Protect Register 1 +; 9/32 - 16/32 region +; FPROT1.0 +; FPROT1.1 +; FPROT1.2 +; FPROT1.3 +; FPROT1.4 +; FPROT1.5 +; FPROT1.6 +; FPROT1.7 +nFPROT1 EQU 0x00 +FPROT1 EQU nFPROT1:EOR:0xFF +; +; FPROT2 +; Program Flash Region Protect Register 2 +; 17/32 - 24/32 region +; FPROT2.0 +; FPROT2.1 +; FPROT2.2 +; FPROT2.3 +; FPROT2.4 +; FPROT2.5 +; FPROT2.6 +; FPROT2.7 +nFPROT2 EQU 0x00 +FPROT2 EQU nFPROT2:EOR:0xFF +; +; FPROT3 +; Program Flash Region Protect Register 3 +; 25/32 - 32/32 region +; FPROT3.0 +; FPROT3.1 +; FPROT3.2 +; FPROT3.3 +; FPROT3.4 +; FPROT3.5 +; FPROT3.6 +; FPROT3.7 +nFPROT3 EQU 0x00 +FPROT3 EQU nFPROT3:EOR:0xFF +; +; +; Flash nonvolatile option byte (FOPT) +; Allows the user to customize the operation of the MCU at boot time. +; LPBOOT +; <0=> Low-power boot +; <1=> Normal boot +; BOOTPIN_OPT +; <0=> Force Boot from ROM if BOOTCFG0 asserted, where BOOTCFG0 is the boot config function which is muxed with NMI pin +; <1=> Boot source configured by FOPT (BOOTSRC_SEL) bits +; NMI_DIS +; <0=> NMI interrupts are always blocked +; <1=> NMI_b pin/interrupts reset default to enabled +; FAST_INIT +; <0=> Slower initialization +; <1=> Fast Initialization +; BOOTSRC_SEL +; <0=> Boot from Flash +; <2=> Boot from ROM, configure QSPI0, and enter boot loader mode. +; <3=> Boot from ROM and enter boot loader mode. +; Boot source selection +FOPT EQU 0x3D +; +; Flash security byte (FSEC) +; WARNING: If SEC field is configured as "MCU security status is secure" and MEEN field is configured as "Mass erase is disabled", +; MCU's security status cannot be set back to unsecure state since Mass erase via the debugger is blocked !!! +; SEC +; <2=> MCU security status is unsecure +; <3=> MCU security status is secure +; Flash Security +; FSLACC +; <2=> Freescale factory access denied +; <3=> Freescale factory access granted +; Freescale Failure Analysis Access Code +; MEEN +; <2=> Mass erase is disabled +; <3=> Mass erase is enabled +; KEYEN +; <2=> Backdoor key access enabled +; <3=> Backdoor key access disabled +; Backdoor Key Security Enable +FSEC EQU 0xFE +; +; + IF :LNOT::DEF:RAM_TARGET + AREA FlashConfig, DATA, READONLY +__FlashConfig + DCB BackDoorK0, BackDoorK1, BackDoorK2, BackDoorK3 + DCB BackDoorK4, BackDoorK5, BackDoorK6, BackDoorK7 + DCB FPROT0 , FPROT1 , FPROT2 , FPROT3 + DCB FSEC , FOPT , 0xFF , 0xFF + ENDIF + + + AREA |.text|, CODE, READONLY + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + IF :LNOT::DEF:RAM_TARGET + REQUIRE FlashConfig + ENDIF + + CPSID I ; Mask interrupts + LDR R0, =0xE000ED08 + LDR R1, =__Vectors + STR R1, [R0] + LDR R0, =SystemInit + BLX R0 + CPSIE i ; Unmask interrupts + LDR R0, =__main + BX R0 + ENDP + + +; Dummy Exception Handlers (infinite loops which can be modified) +NMI_Handler\ + PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler\ + PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler\ + PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler\ + PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP +DMA0_DMA16_IRQHandler\ + PROC + EXPORT DMA0_DMA16_IRQHandler [WEAK] + LDR R0, =DMA0_DMA16_DriverIRQHandler + BX R0 + ENDP + +DMA1_DMA17_IRQHandler\ + PROC + EXPORT DMA1_DMA17_IRQHandler [WEAK] + LDR R0, =DMA1_DMA17_DriverIRQHandler + BX R0 + ENDP + +DMA2_DMA18_IRQHandler\ + PROC + EXPORT DMA2_DMA18_IRQHandler [WEAK] + LDR R0, =DMA2_DMA18_DriverIRQHandler + BX R0 + ENDP + +DMA3_DMA19_IRQHandler\ + PROC + EXPORT DMA3_DMA19_IRQHandler [WEAK] + LDR R0, =DMA3_DMA19_DriverIRQHandler + BX R0 + ENDP + +DMA4_DMA20_IRQHandler\ + PROC + EXPORT DMA4_DMA20_IRQHandler [WEAK] + LDR R0, =DMA4_DMA20_DriverIRQHandler + BX R0 + ENDP + +DMA5_DMA21_IRQHandler\ + PROC + EXPORT DMA5_DMA21_IRQHandler [WEAK] + LDR R0, =DMA5_DMA21_DriverIRQHandler + BX R0 + ENDP + +DMA6_DMA22_IRQHandler\ + PROC + EXPORT DMA6_DMA22_IRQHandler [WEAK] + LDR R0, =DMA6_DMA22_DriverIRQHandler + BX R0 + ENDP + +DMA7_DMA23_IRQHandler\ + PROC + EXPORT DMA7_DMA23_IRQHandler [WEAK] + LDR R0, =DMA7_DMA23_DriverIRQHandler + BX R0 + ENDP + +DMA8_DMA24_IRQHandler\ + PROC + EXPORT DMA8_DMA24_IRQHandler [WEAK] + LDR R0, =DMA8_DMA24_DriverIRQHandler + BX R0 + ENDP + +DMA9_DMA25_IRQHandler\ + PROC + EXPORT DMA9_DMA25_IRQHandler [WEAK] + LDR R0, =DMA9_DMA25_DriverIRQHandler + BX R0 + ENDP + +DMA10_DMA26_IRQHandler\ + PROC + EXPORT DMA10_DMA26_IRQHandler [WEAK] + LDR R0, =DMA10_DMA26_DriverIRQHandler + BX R0 + ENDP + +DMA11_DMA27_IRQHandler\ + PROC + EXPORT DMA11_DMA27_IRQHandler [WEAK] + LDR R0, =DMA11_DMA27_DriverIRQHandler + BX R0 + ENDP + +DMA12_DMA28_IRQHandler\ + PROC + EXPORT DMA12_DMA28_IRQHandler [WEAK] + LDR R0, =DMA12_DMA28_DriverIRQHandler + BX R0 + ENDP + +DMA13_DMA29_IRQHandler\ + PROC + EXPORT DMA13_DMA29_IRQHandler [WEAK] + LDR R0, =DMA13_DMA29_DriverIRQHandler + BX R0 + ENDP + +DMA14_DMA30_IRQHandler\ + PROC + EXPORT DMA14_DMA30_IRQHandler [WEAK] + LDR R0, =DMA14_DMA30_DriverIRQHandler + BX R0 + ENDP + +DMA15_DMA31_IRQHandler\ + PROC + EXPORT DMA15_DMA31_IRQHandler [WEAK] + LDR R0, =DMA15_DMA31_DriverIRQHandler + BX R0 + ENDP + +DMA_Error_IRQHandler\ + PROC + EXPORT DMA_Error_IRQHandler [WEAK] + LDR R0, =DMA_Error_DriverIRQHandler + BX R0 + ENDP + +I2C0_IRQHandler\ + PROC + EXPORT I2C0_IRQHandler [WEAK] + LDR R0, =I2C0_DriverIRQHandler + BX R0 + ENDP + +I2C1_IRQHandler\ + PROC + EXPORT I2C1_IRQHandler [WEAK] + LDR R0, =I2C1_DriverIRQHandler + BX R0 + ENDP + +SPI0_IRQHandler\ + PROC + EXPORT SPI0_IRQHandler [WEAK] + LDR R0, =SPI0_DriverIRQHandler + BX R0 + ENDP + +SPI1_IRQHandler\ + PROC + EXPORT SPI1_IRQHandler [WEAK] + LDR R0, =SPI1_DriverIRQHandler + BX R0 + ENDP + +I2S0_Tx_IRQHandler\ + PROC + EXPORT I2S0_Tx_IRQHandler [WEAK] + LDR R0, =I2S0_Tx_DriverIRQHandler + BX R0 + ENDP + +I2S0_Rx_IRQHandler\ + PROC + EXPORT I2S0_Rx_IRQHandler [WEAK] + LDR R0, =I2S0_Rx_DriverIRQHandler + BX R0 + ENDP + +LPUART0_IRQHandler\ + PROC + EXPORT LPUART0_IRQHandler [WEAK] + LDR R0, =LPUART0_DriverIRQHandler + BX R0 + ENDP + +LPUART1_IRQHandler\ + PROC + EXPORT LPUART1_IRQHandler [WEAK] + LDR R0, =LPUART1_DriverIRQHandler + BX R0 + ENDP + +LPUART2_IRQHandler\ + PROC + EXPORT LPUART2_IRQHandler [WEAK] + LDR R0, =LPUART2_DriverIRQHandler + BX R0 + ENDP + +LPUART3_IRQHandler\ + PROC + EXPORT LPUART3_IRQHandler [WEAK] + LDR R0, =LPUART3_DriverIRQHandler + BX R0 + ENDP + +LPUART4_IRQHandler\ + PROC + EXPORT LPUART4_IRQHandler [WEAK] + LDR R0, =LPUART4_DriverIRQHandler + BX R0 + ENDP + +SPI2_IRQHandler\ + PROC + EXPORT SPI2_IRQHandler [WEAK] + LDR R0, =SPI2_DriverIRQHandler + BX R0 + ENDP + +FLEXIO0_IRQHandler\ + PROC + EXPORT FLEXIO0_IRQHandler [WEAK] + LDR R0, =FLEXIO0_DriverIRQHandler + BX R0 + ENDP + +I2C2_IRQHandler\ + PROC + EXPORT I2C2_IRQHandler [WEAK] + LDR R0, =I2C2_DriverIRQHandler + BX R0 + ENDP + +SDHC_IRQHandler\ + PROC + EXPORT SDHC_IRQHandler [WEAK] + LDR R0, =SDHC_DriverIRQHandler + BX R0 + ENDP + +I2C3_IRQHandler\ + PROC + EXPORT I2C3_IRQHandler [WEAK] + LDR R0, =I2C3_DriverIRQHandler + BX R0 + ENDP + +QuadSPI0_IRQHandler\ + PROC + EXPORT QuadSPI0_IRQHandler [WEAK] + LDR R0, =QuadSPI0_DriverIRQHandler + BX R0 + ENDP + +Default_Handler\ + PROC + EXPORT DMA0_DMA16_DriverIRQHandler [WEAK] + EXPORT DMA1_DMA17_DriverIRQHandler [WEAK] + EXPORT DMA2_DMA18_DriverIRQHandler [WEAK] + EXPORT DMA3_DMA19_DriverIRQHandler [WEAK] + EXPORT DMA4_DMA20_DriverIRQHandler [WEAK] + EXPORT DMA5_DMA21_DriverIRQHandler [WEAK] + EXPORT DMA6_DMA22_DriverIRQHandler [WEAK] + EXPORT DMA7_DMA23_DriverIRQHandler [WEAK] + EXPORT DMA8_DMA24_DriverIRQHandler [WEAK] + EXPORT DMA9_DMA25_DriverIRQHandler [WEAK] + EXPORT DMA10_DMA26_DriverIRQHandler [WEAK] + EXPORT DMA11_DMA27_DriverIRQHandler [WEAK] + EXPORT DMA12_DMA28_DriverIRQHandler [WEAK] + EXPORT DMA13_DMA29_DriverIRQHandler [WEAK] + EXPORT DMA14_DMA30_DriverIRQHandler [WEAK] + EXPORT DMA15_DMA31_DriverIRQHandler [WEAK] + EXPORT DMA_Error_DriverIRQHandler [WEAK] + EXPORT MCM_IRQHandler [WEAK] + EXPORT FTFA_IRQHandler [WEAK] + EXPORT Read_Collision_IRQHandler [WEAK] + EXPORT LVD_LVW_IRQHandler [WEAK] + EXPORT LLWU_IRQHandler [WEAK] + EXPORT WDOG_EWM_IRQHandler [WEAK] + EXPORT TRNG0_IRQHandler [WEAK] + EXPORT I2C0_DriverIRQHandler [WEAK] + EXPORT I2C1_DriverIRQHandler [WEAK] + EXPORT SPI0_DriverIRQHandler [WEAK] + EXPORT SPI1_DriverIRQHandler [WEAK] + EXPORT I2S0_Tx_DriverIRQHandler [WEAK] + EXPORT I2S0_Rx_DriverIRQHandler [WEAK] + EXPORT LPUART0_DriverIRQHandler [WEAK] + EXPORT LPUART1_DriverIRQHandler [WEAK] + EXPORT LPUART2_DriverIRQHandler [WEAK] + EXPORT LPUART3_DriverIRQHandler [WEAK] + EXPORT LPUART4_DriverIRQHandler [WEAK] + EXPORT Reserved51_IRQHandler [WEAK] + EXPORT Reserved52_IRQHandler [WEAK] + EXPORT EMVSIM0_IRQHandler [WEAK] + EXPORT EMVSIM1_IRQHandler [WEAK] + EXPORT ADC0_IRQHandler [WEAK] + EXPORT CMP0_IRQHandler [WEAK] + EXPORT CMP1_IRQHandler [WEAK] + EXPORT FTM0_IRQHandler [WEAK] + EXPORT FTM1_IRQHandler [WEAK] + EXPORT FTM2_IRQHandler [WEAK] + EXPORT CMT_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT RTC_Seconds_IRQHandler [WEAK] + EXPORT PIT0CH0_IRQHandler [WEAK] + EXPORT PIT0CH1_IRQHandler [WEAK] + EXPORT PIT0CH2_IRQHandler [WEAK] + EXPORT PIT0CH3_IRQHandler [WEAK] + EXPORT PDB0_IRQHandler [WEAK] + EXPORT USB0_IRQHandler [WEAK] + EXPORT USBDCD_IRQHandler [WEAK] + EXPORT Reserved71_IRQHandler [WEAK] + EXPORT DAC0_IRQHandler [WEAK] + EXPORT MCG_IRQHandler [WEAK] + EXPORT LPTMR0_LPTMR1_IRQHandler [WEAK] + EXPORT PORTA_IRQHandler [WEAK] + EXPORT PORTB_IRQHandler [WEAK] + EXPORT PORTC_IRQHandler [WEAK] + EXPORT PORTD_IRQHandler [WEAK] + EXPORT PORTE_IRQHandler [WEAK] + EXPORT SWI_IRQHandler [WEAK] + EXPORT SPI2_DriverIRQHandler [WEAK] + EXPORT Reserved82_IRQHandler [WEAK] + EXPORT Reserved83_IRQHandler [WEAK] + EXPORT Reserved84_IRQHandler [WEAK] + EXPORT Reserved85_IRQHandler [WEAK] + EXPORT FLEXIO0_DriverIRQHandler [WEAK] + EXPORT FTM3_IRQHandler [WEAK] + EXPORT Reserved88_IRQHandler [WEAK] + EXPORT Reserved89_IRQHandler [WEAK] + EXPORT I2C2_DriverIRQHandler [WEAK] + EXPORT Reserved91_IRQHandler [WEAK] + EXPORT Reserved92_IRQHandler [WEAK] + EXPORT Reserved93_IRQHandler [WEAK] + EXPORT Reserved94_IRQHandler [WEAK] + EXPORT Reserved95_IRQHandler [WEAK] + EXPORT Reserved96_IRQHandler [WEAK] + EXPORT SDHC_DriverIRQHandler [WEAK] + EXPORT Reserved98_IRQHandler [WEAK] + EXPORT Reserved99_IRQHandler [WEAK] + EXPORT Reserved100_IRQHandler [WEAK] + EXPORT Reserved101_IRQHandler [WEAK] + EXPORT Reserved102_IRQHandler [WEAK] + EXPORT TSI0_IRQHandler [WEAK] + EXPORT TPM1_IRQHandler [WEAK] + EXPORT TPM2_IRQHandler [WEAK] + EXPORT Reserved106_IRQHandler [WEAK] + EXPORT I2C3_DriverIRQHandler [WEAK] + EXPORT Reserved108_IRQHandler [WEAK] + EXPORT Reserved109_IRQHandler [WEAK] + EXPORT Reserved110_IRQHandler [WEAK] + EXPORT Reserved111_IRQHandler [WEAK] + EXPORT Reserved112_IRQHandler [WEAK] + EXPORT Reserved113_IRQHandler [WEAK] + EXPORT Reserved114_IRQHandler [WEAK] + EXPORT Reserved115_IRQHandler [WEAK] + EXPORT QuadSPI0_DriverIRQHandler [WEAK] + EXPORT Reserved117_IRQHandler [WEAK] + EXPORT Reserved118_IRQHandler [WEAK] + EXPORT Reserved119_IRQHandler [WEAK] + EXPORT LTC0_IRQHandler [WEAK] + EXPORT Reserved121_IRQHandler [WEAK] + EXPORT Reserved122_IRQHandler [WEAK] + EXPORT DefaultISR [WEAK] +DMA0_DMA16_DriverIRQHandler +DMA1_DMA17_DriverIRQHandler +DMA2_DMA18_DriverIRQHandler +DMA3_DMA19_DriverIRQHandler +DMA4_DMA20_DriverIRQHandler +DMA5_DMA21_DriverIRQHandler +DMA6_DMA22_DriverIRQHandler +DMA7_DMA23_DriverIRQHandler +DMA8_DMA24_DriverIRQHandler +DMA9_DMA25_DriverIRQHandler +DMA10_DMA26_DriverIRQHandler +DMA11_DMA27_DriverIRQHandler +DMA12_DMA28_DriverIRQHandler +DMA13_DMA29_DriverIRQHandler +DMA14_DMA30_DriverIRQHandler +DMA15_DMA31_DriverIRQHandler +DMA_Error_DriverIRQHandler +MCM_IRQHandler +FTFA_IRQHandler +Read_Collision_IRQHandler +LVD_LVW_IRQHandler +LLWU_IRQHandler +WDOG_EWM_IRQHandler +TRNG0_IRQHandler +I2C0_DriverIRQHandler +I2C1_DriverIRQHandler +SPI0_DriverIRQHandler +SPI1_DriverIRQHandler +I2S0_Tx_DriverIRQHandler +I2S0_Rx_DriverIRQHandler +LPUART0_DriverIRQHandler +LPUART1_DriverIRQHandler +LPUART2_DriverIRQHandler +LPUART3_DriverIRQHandler +LPUART4_DriverIRQHandler +Reserved51_IRQHandler +Reserved52_IRQHandler +EMVSIM0_IRQHandler +EMVSIM1_IRQHandler +ADC0_IRQHandler +CMP0_IRQHandler +CMP1_IRQHandler +FTM0_IRQHandler +FTM1_IRQHandler +FTM2_IRQHandler +CMT_IRQHandler +RTC_IRQHandler +RTC_Seconds_IRQHandler +PIT0CH0_IRQHandler +PIT0CH1_IRQHandler +PIT0CH2_IRQHandler +PIT0CH3_IRQHandler +PDB0_IRQHandler +USB0_IRQHandler +USBDCD_IRQHandler +Reserved71_IRQHandler +DAC0_IRQHandler +MCG_IRQHandler +LPTMR0_LPTMR1_IRQHandler +PORTA_IRQHandler +PORTB_IRQHandler +PORTC_IRQHandler +PORTD_IRQHandler +PORTE_IRQHandler +SWI_IRQHandler +SPI2_DriverIRQHandler +Reserved82_IRQHandler +Reserved83_IRQHandler +Reserved84_IRQHandler +Reserved85_IRQHandler +FLEXIO0_DriverIRQHandler +FTM3_IRQHandler +Reserved88_IRQHandler +Reserved89_IRQHandler +I2C2_DriverIRQHandler +Reserved91_IRQHandler +Reserved92_IRQHandler +Reserved93_IRQHandler +Reserved94_IRQHandler +Reserved95_IRQHandler +Reserved96_IRQHandler +SDHC_DriverIRQHandler +Reserved98_IRQHandler +Reserved99_IRQHandler +Reserved100_IRQHandler +Reserved101_IRQHandler +Reserved102_IRQHandler +TSI0_IRQHandler +TPM1_IRQHandler +TPM2_IRQHandler +Reserved106_IRQHandler +I2C3_DriverIRQHandler +Reserved108_IRQHandler +Reserved109_IRQHandler +Reserved110_IRQHandler +Reserved111_IRQHandler +Reserved112_IRQHandler +Reserved113_IRQHandler +Reserved114_IRQHandler +Reserved115_IRQHandler +QuadSPI0_DriverIRQHandler +Reserved117_IRQHandler +Reserved118_IRQHandler +Reserved119_IRQHandler +LTC0_IRQHandler +Reserved121_IRQHandler +Reserved122_IRQHandler +DefaultISR + B DefaultISR + ENDP + ALIGN + + + END diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_ARM_STD/sys.cpp b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_ARM_STD/sys.cpp new file mode 100644 index 00000000000..b129b2c2a5b --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_ARM_STD/sys.cpp @@ -0,0 +1,31 @@ +/* mbed Microcontroller Library - stackheap + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * Setup a fixed single stack/heap memory model, + * between the top of the RW/ZI region and the stackpointer + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +extern char Image$$RW_IRAM1$$ZI$$Limit[]; + +extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { + uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit; + uint32_t sp_limit = __current_sp(); + + zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned + + struct __initial_stackheap r; + r.heap_base = zi_limit; + r.heap_limit = sp_limit; + return r; +} + +#ifdef __cplusplus +} +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_GCC_ARM/MK82FN256xxx15.ld b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_GCC_ARM/MK82FN256xxx15.ld new file mode 100644 index 00000000000..982f9a5528b --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_GCC_ARM/MK82FN256xxx15.ld @@ -0,0 +1,275 @@ +/* +** ################################################################### +** Processors: MK82FN256CAx15 +** MK82FN256VDC15 +** MK82FN256VLL15 +** MK82FN256VLQ15 +** +** Compiler: GNU C Compiler +** Reference manual: K82P121M150SF5RM, Rev. 0, May 2015 +** Version: rev. 1.2, 2015-07-29 +** Build: b160613 +** +** Abstract: +** Linker file for the GNU C Compiler +** +** Copyright (c) 2016 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** ################################################################### +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +__ram_vector_table__ = 1; + +/* Heap 1/4 of ram and stack 1/8 */ +__stack_size__ = 0x8000; +__heap_size__ = 0x10000; + +HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; +M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x03C0 : 0x0; + +/* Specify the memory areas */ +MEMORY +{ + m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000003C0 + m_bootloader_config (RX) : ORIGIN = 0x000003C0, LENGTH = 0x00000040 + m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010 + m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0003FBF0 + m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000 + m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into internal flash */ + .interrupts : + { + __VECTOR_TABLE = .; + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } > m_interrupts + + .bootloader_config : + { + . = ALIGN(4); + KEEP(*(.BootloaderConfig)) /* Bootloader Configuration Area (BCA) */ + . = ALIGN(4); + } > m_bootloader_config + + .flash_config : + { + . = ALIGN(4); + KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */ + . = ALIGN(4); + } > m_flash_config + + /* The program code and other data goes into internal flash */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(4); + } > m_text + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > m_text + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > m_text + + .ctors : + { + __CTOR_LIST__ = .; + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + } > m_text + + .dtors : + { + __DTOR_LIST__ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + } > m_text + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } > m_text + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } > m_text + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } > m_text + + __etext = .; /* define a global symbol at end of code */ + __DATA_ROM = .; /* Symbol is used by startup for data initialization */ + + .interrupts_ram : + { + . = ALIGN(4); + __VECTOR_RAM__ = .; + __interrupts_ram_start__ = .; /* Create a global symbol at data start */ + *(.m_interrupts_ram) /* This is a user defined section */ + . += M_VECTOR_RAM_SIZE; + . = ALIGN(4); + __interrupts_ram_end__ = .; /* Define a global symbol at data end */ + } > m_data + + __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts); + __RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0; + + .data : AT(__DATA_ROM) + { + . = ALIGN(4); + __DATA_RAM = .; + __data_start__ = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + KEEP(*(.jcr*)) + . = ALIGN(4); + __data_end__ = .; /* define a global symbol at data end */ + } > m_data + + __DATA_END = __DATA_ROM + (__data_end__ - __data_start__); + text_end = ORIGIN(m_text) + LENGTH(m_text); + ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") + + USB_RAM_GAP = DEFINED(__usb_ram_size__) ? __usb_ram_size__ : 0x00; + /* Uninitialized data section */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + . = ALIGN(4); + __START_BSS = .; + __bss_start__ = .; + *(.bss) + *(.bss*) + . = ALIGN(512); + USB_RAM_START = .; + . += USB_RAM_GAP; + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + __END_BSS = .; + } > m_data + + .heap : + { + . = ALIGN(8); + __end__ = .; + PROVIDE(end = .); + __HeapBase = .; + . += HEAP_SIZE; + __HeapLimit = .; + __heap_limit = .; /* Add for _sbrk */ + } > m_data_2 + + .stack : + { + . = ALIGN(8); + . += STACK_SIZE; + } > m_data_2 + + m_usb_bdt USB_RAM_START (NOLOAD) : + { + *(m_usb_bdt) + USB_RAM_BDT_END = .; + } + + m_usb_global USB_RAM_BDT_END (NOLOAD) : + { + *(m_usb_global) + } + + /* Initializes stack on the end of block */ + __StackTop = ORIGIN(m_data_2) + LENGTH(m_data_2); + __StackLimit = __StackTop - STACK_SIZE; + PROVIDE(__stack = __StackTop); + + .ARM.attributes 0 : { *(.ARM.attributes) } + + ASSERT(__StackLimit >= __HeapLimit, "region m_data_2 overflowed with stack and heap") +} + diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_GCC_ARM/startup_MK82F25615.S b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_GCC_ARM/startup_MK82F25615.S new file mode 100644 index 00000000000..4383a2af2aa --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_GCC_ARM/startup_MK82F25615.S @@ -0,0 +1,868 @@ +/* ---------------------------------------------------------------------------------------*/ +/* @file: startup_MK82F25615.s */ +/* @purpose: CMSIS Cortex-M4 Core Device Startup File */ +/* MK82F25615 */ +/* @version: 1.0 */ +/* @date: 2015-4-9 */ +/* @build: b151210 */ +/* ---------------------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 1997 - 2015 , Freescale Semiconductor, Inc. */ +/* All rights reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or without modification, */ +/* are permitted provided that the following conditions are met: */ +/* */ +/* o Redistributions of source code must retain the above copyright notice, this list */ +/* of conditions and the following disclaimer. */ +/* */ +/* o Redistributions in binary form must reproduce the above copyright notice, this */ +/* list of conditions and the following disclaimer in the documentation and/or */ +/* other materials provided with the distribution. */ +/* */ +/* o Neither the name of Freescale Semiconductor, Inc. nor the names of its */ +/* contributors may be used to endorse or promote products derived from this */ +/* software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ +/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ +/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ +/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ +/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ +/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ +/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ +/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/*****************************************************************************/ +/* Version: GCC for ARM Embedded Processors */ +/*****************************************************************************/ + .syntax unified + .arch armv7-m + + .section .isr_vector, "a" + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler /* Reset Handler */ + .long NMI_Handler /* NMI Handler*/ + .long HardFault_Handler /* Hard Fault Handler*/ + .long MemManage_Handler /* MPU Fault Handler*/ + .long BusFault_Handler /* Bus Fault Handler*/ + .long UsageFault_Handler /* Usage Fault Handler*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long SVC_Handler /* SVCall Handler*/ + .long DebugMon_Handler /* Debug Monitor Handler*/ + .long 0 /* Reserved*/ + .long PendSV_Handler /* PendSV Handler*/ + .long SysTick_Handler /* SysTick Handler*/ + + /* External Interrupts*/ + .long DMA0_DMA16_IRQHandler /* DMA channel 0,16 transfer complete*/ + .long DMA1_DMA17_IRQHandler /* DMA channel 1,17 transfer complete*/ + .long DMA2_DMA18_IRQHandler /* DMA channel 2,18 transfer complete*/ + .long DMA3_DMA19_IRQHandler /* DMA channel 3,19 transfer complete*/ + .long DMA4_DMA20_IRQHandler /* DMA channel 4,20 transfer complete*/ + .long DMA5_DMA21_IRQHandler /* DMA channel 5,21 transfer complete*/ + .long DMA6_DMA22_IRQHandler /* DMA channel 6,22 transfer complete*/ + .long DMA7_DMA23_IRQHandler /* DMA channel 7,23 transfer complete*/ + .long DMA8_DMA24_IRQHandler /* DMA channel 8,24 transfer complete*/ + .long DMA9_DMA25_IRQHandler /* DMA channel 9,25 transfer complete*/ + .long DMA10_DMA26_IRQHandler /* DMA channel 10,26 transfer complete*/ + .long DMA11_DMA27_IRQHandler /* DMA channel 11,27 transfer complete*/ + .long DMA12_DMA28_IRQHandler /* DMA channel 12,28 transfer complete*/ + .long DMA13_DMA29_IRQHandler /* DMA channel 13,29 transfer complete*/ + .long DMA14_DMA30_IRQHandler /* DMA channel 14,30 transfer complete*/ + .long DMA15_DMA31_IRQHandler /* DMA channel 15,31 transfer complete*/ + .long DMA_Error_IRQHandler /* DMA channel 0 - 31 error*/ + .long MCM_IRQHandler /* MCM normal interrupt*/ + .long FTFA_IRQHandler /* FTFA command complete*/ + .long Read_Collision_IRQHandler /* FTFA read collision*/ + .long LVD_LVW_IRQHandler /* PMC controller low-voltage detect, low-voltage warning*/ + .long LLWU_IRQHandler /* Low leakage wakeup unit*/ + .long WDOG_EWM_IRQHandler /* Single interrupt vector for WDOG and EWM*/ + .long TRNG0_IRQHandler /* True randon number generator*/ + .long I2C0_IRQHandler /* Inter-integrated circuit 0*/ + .long I2C1_IRQHandler /* Inter-integrated circuit 1*/ + .long SPI0_IRQHandler /* Serial peripheral Interface 0*/ + .long SPI1_IRQHandler /* Serial peripheral Interface 1*/ + .long I2S0_Tx_IRQHandler /* Integrated interchip sound 0 transmit interrupt*/ + .long I2S0_Rx_IRQHandler /* Integrated interchip sound 0 receive interrupt*/ + .long LPUART0_IRQHandler /* LPUART0 receive/transmit/error interrupt*/ + .long LPUART1_IRQHandler /* LPUART1 receive/transmit/error interrupt*/ + .long LPUART2_IRQHandler /* LPUART2 receive/transmit/error interrupt*/ + .long LPUART3_IRQHandler /* LPUART3 receive/transmit/error interrupt*/ + .long LPUART4_IRQHandler /* LPUART4 receive/transmit/error interrupt*/ + .long Reserved51_IRQHandler /* Reserved interrupt*/ + .long Reserved52_IRQHandler /* Reserved interrupt*/ + .long EMVSIM0_IRQHandler /* EMVSIM0 common interrupt*/ + .long EMVSIM1_IRQHandler /* EMVSIM1 common interrupt*/ + .long ADC0_IRQHandler /* Analog-to-digital converter 0*/ + .long CMP0_IRQHandler /* Comparator 0*/ + .long CMP1_IRQHandler /* Comparator 1*/ + .long FTM0_IRQHandler /* FlexTimer module 0 fault, overflow and channels interrupt*/ + .long FTM1_IRQHandler /* FlexTimer module 1 fault, overflow and channels interrupt*/ + .long FTM2_IRQHandler /* FlexTimer module 2 fault, overflow and channels interrupt*/ + .long CMT_IRQHandler /* Carrier modulator transmitter*/ + .long RTC_IRQHandler /* Real time clock*/ + .long RTC_Seconds_IRQHandler /* Real time clock seconds*/ + .long PIT0CH0_IRQHandler /* Periodic interrupt timer 0 channel 0*/ + .long PIT0CH1_IRQHandler /* Periodic interrupt timer 0 channel 1*/ + .long PIT0CH2_IRQHandler /* Periodic interrupt timer 0 channel 2*/ + .long PIT0CH3_IRQHandler /* Periodic interrupt timer 0 channel 3*/ + .long PDB0_IRQHandler /* Programmable delay block*/ + .long USB0_IRQHandler /* USB OTG interrupt*/ + .long USBDCD_IRQHandler /* USB charger detect*/ + .long Reserved71_IRQHandler /* Reserved interrupt*/ + .long DAC0_IRQHandler /* Digital-to-analog converter 0*/ + .long MCG_IRQHandler /* Multipurpose clock generator*/ + .long LPTMR0_LPTMR1_IRQHandler /* Single interrupt vector for Low Power Timer 0 and 1*/ + .long PORTA_IRQHandler /* Port A pin detect interrupt*/ + .long PORTB_IRQHandler /* Port B pin detect interrupt*/ + .long PORTC_IRQHandler /* Port C pin detect interrupt*/ + .long PORTD_IRQHandler /* Port D pin detect interrupt*/ + .long PORTE_IRQHandler /* Port E pin detect interrupt*/ + .long SWI_IRQHandler /* Software interrupt*/ + .long SPI2_IRQHandler /* Serial peripheral Interface 2*/ + .long Reserved82_IRQHandler /* Reserved interrupt*/ + .long Reserved83_IRQHandler /* Reserved interrupt*/ + .long Reserved84_IRQHandler /* Reserved interrupt*/ + .long Reserved85_IRQHandler /* Reserved interrupt*/ + .long FLEXIO0_IRQHandler /* FLEXIO0*/ + .long FTM3_IRQHandler /* FlexTimer module 3 fault, overflow and channels interrupt*/ + .long Reserved88_IRQHandler /* Reserved interrupt*/ + .long Reserved89_IRQHandler /* Reserved interrupt*/ + .long I2C2_IRQHandler /* Inter-integrated circuit 2*/ + .long Reserved91_IRQHandler /* Reserved interrupt*/ + .long Reserved92_IRQHandler /* Reserved interrupt*/ + .long Reserved93_IRQHandler /* Reserved interrupt*/ + .long Reserved94_IRQHandler /* Reserved interrupt*/ + .long Reserved95_IRQHandler /* Reserved interrupt*/ + .long Reserved96_IRQHandler /* Reserved interrupt*/ + .long SDHC_IRQHandler /* Secured digital host controller*/ + .long Reserved98_IRQHandler /* Reserved interrupt*/ + .long Reserved99_IRQHandler /* Reserved interrupt*/ + .long Reserved100_IRQHandler /* Reserved interrupt*/ + .long Reserved101_IRQHandler /* Reserved interrupt*/ + .long Reserved102_IRQHandler /* Reserved interrupt*/ + .long TSI0_IRQHandler /* Touch Sensing Input*/ + .long TPM1_IRQHandler /* TPM1 single interrupt vector for all sources*/ + .long TPM2_IRQHandler /* TPM2 single interrupt vector for all sources*/ + .long Reserved106_IRQHandler /* Reserved interrupt*/ + .long I2C3_IRQHandler /* Inter-integrated circuit 3*/ + .long Reserved108_IRQHandler /* Reserved interrupt*/ + .long Reserved109_IRQHandler /* Reserved interrupt*/ + .long Reserved110_IRQHandler /* Reserved interrupt*/ + .long Reserved111_IRQHandler /* Reserved interrupt*/ + .long Reserved112_IRQHandler /* Reserved interrupt*/ + .long Reserved113_IRQHandler /* Reserved interrupt*/ + .long Reserved114_IRQHandler /* Reserved interrupt*/ + .long Reserved115_IRQHandler /* Reserved interrupt*/ + .long QuadSPI0_IRQHandler /* qspi*/ + .long Reserved117_IRQHandler /* Reserved interrupt*/ + .long Reserved118_IRQHandler /* Reserved interrupt*/ + .long Reserved119_IRQHandler /* Reserved interrupt*/ + .long LTC0_IRQHandler /* LP Trusted Cryptography*/ + .long Reserved121_IRQHandler /* Reserved interrupt*/ + .long Reserved122_IRQHandler /* Reserved interrupt*/ + .long DefaultISR /* 123*/ + .long DefaultISR /* 124*/ + .long DefaultISR /* 125*/ + .long DefaultISR /* 126*/ + .long DefaultISR /* 127*/ + .long DefaultISR /* 128*/ + .long DefaultISR /* 129*/ + .long DefaultISR /* 130*/ + .long DefaultISR /* 131*/ + .long DefaultISR /* 132*/ + .long DefaultISR /* 133*/ + .long DefaultISR /* 134*/ + .long DefaultISR /* 135*/ + .long DefaultISR /* 136*/ + .long DefaultISR /* 137*/ + .long DefaultISR /* 138*/ + .long DefaultISR /* 139*/ + .long DefaultISR /* 140*/ + .long DefaultISR /* 141*/ + .long DefaultISR /* 142*/ + .long DefaultISR /* 143*/ + .long DefaultISR /* 144*/ + .long DefaultISR /* 145*/ + .long DefaultISR /* 146*/ + .long DefaultISR /* 147*/ + .long DefaultISR /* 148*/ + .long DefaultISR /* 149*/ + .long DefaultISR /* 150*/ + .long DefaultISR /* 151*/ + .long DefaultISR /* 152*/ + .long DefaultISR /* 153*/ + .long DefaultISR /* 154*/ + .long DefaultISR /* 155*/ + .long DefaultISR /* 156*/ + .long DefaultISR /* 157*/ + .long DefaultISR /* 158*/ + .long DefaultISR /* 159*/ + .long DefaultISR /* 160*/ + .long DefaultISR /* 161*/ + .long DefaultISR /* 162*/ + .long DefaultISR /* 163*/ + .long DefaultISR /* 164*/ + .long DefaultISR /* 165*/ + .long DefaultISR /* 166*/ + .long DefaultISR /* 167*/ + .long DefaultISR /* 168*/ + .long DefaultISR /* 169*/ + .long DefaultISR /* 170*/ + .long DefaultISR /* 171*/ + .long DefaultISR /* 172*/ + .long DefaultISR /* 173*/ + .long DefaultISR /* 174*/ + .long DefaultISR /* 175*/ + .long DefaultISR /* 176*/ + .long DefaultISR /* 177*/ + .long DefaultISR /* 178*/ + .long DefaultISR /* 179*/ + .long DefaultISR /* 180*/ + .long DefaultISR /* 181*/ + .long DefaultISR /* 182*/ + .long DefaultISR /* 183*/ + .long DefaultISR /* 184*/ + .long DefaultISR /* 185*/ + .long DefaultISR /* 186*/ + .long DefaultISR /* 187*/ + .long DefaultISR /* 188*/ + .long DefaultISR /* 189*/ + .long DefaultISR /* 190*/ + .long DefaultISR /* 191*/ + .long DefaultISR /* 192*/ + .long DefaultISR /* 193*/ + .long DefaultISR /* 194*/ + .long DefaultISR /* 195*/ + .long DefaultISR /* 196*/ + .long DefaultISR /* 197*/ + .long DefaultISR /* 198*/ + .long DefaultISR /* 199*/ + .long DefaultISR /* 200*/ + .long DefaultISR /* 201*/ + .long DefaultISR /* 202*/ + .long DefaultISR /* 203*/ + .long DefaultISR /* 204*/ + .long DefaultISR /* 205*/ + .long DefaultISR /* 206*/ + .long DefaultISR /* 207*/ + .long DefaultISR /* 208*/ + .long DefaultISR /* 209*/ + .long DefaultISR /* 210*/ + .long DefaultISR /* 211*/ + .long DefaultISR /* 212*/ + .long DefaultISR /* 213*/ + .long DefaultISR /* 214*/ + .long DefaultISR /* 215*/ + .long DefaultISR /* 216*/ + .long DefaultISR /* 217*/ + .long DefaultISR /* 218*/ + .long DefaultISR /* 219*/ + .long DefaultISR /* 220*/ + .long DefaultISR /* 221*/ + .long DefaultISR /* 222*/ + .long DefaultISR /* 223*/ + .long DefaultISR /* 224*/ + .long DefaultISR /* 225*/ + .long DefaultISR /* 226*/ + .long DefaultISR /* 227*/ + .long DefaultISR /* 228*/ + .long DefaultISR /* 229*/ + .long DefaultISR /* 230*/ + .long DefaultISR /* 231*/ + .long DefaultISR /* 232*/ + .long DefaultISR /* 233*/ + .long DefaultISR /* 234*/ + .long DefaultISR /* 235*/ + .long DefaultISR /* 236*/ + .long DefaultISR /* 237*/ + .long DefaultISR /* 238*/ + .long DefaultISR /* 239*/ + + .size __isr_vector, . - __isr_vector + +/* Flash Configuration */ + .section .FlashConfig, "a" + .long 0xFFFFFFFF + .long 0xFFFFFFFF + .long 0xFFFFFFFF + .long 0xFFFF3DFE + + .text + .thumb + +/* Reset Handler */ + + .thumb_func + .align 2 + .globl Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + cpsid i /* Mask interrupts */ + .equ VTOR, 0xE000ED08 + ldr r0, =VTOR + ldr r1, =__isr_vector + str r1, [r0] +#ifndef __NO_SYSTEM_INIT + ldr r0,=SystemInit + blx r0 +#endif +/* Loop to copy data from read only memory to RAM. The ranges + * of copy from/to are specified by following symbols evaluated in + * linker script. + * __etext: End of code section, i.e., begin of data sections to copy from. + * __data_start__/__data_end__: RAM address range that data should be + * copied to. Both must be aligned to 4 bytes boundary. */ + + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + +#if 1 +/* Here are two copies of loop implemenations. First one favors code size + * and the second one favors performance. Default uses the first one. + * Change to "#if 0" to use the second one */ +.LC0: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .LC0 +#else + subs r3, r2 + ble .LC1 +.LC0: + subs r3, #4 + ldr r0, [r1, r3] + str r0, [r2, r3] + bgt .LC0 +.LC1: +#endif + +#ifdef __STARTUP_CLEAR_BSS +/* This part of work usually is done in C library startup code. Otherwise, + * define this macro to enable it in this startup. + * + * Loop to zero out BSS section, which uses following symbols + * in linker script: + * __bss_start__: start of BSS section. Must align to 4 + * __bss_end__: end of BSS section. Must align to 4 + */ + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 +.LC2: + cmp r1, r2 + itt lt + strlt r0, [r1], #4 + blt .LC2 +#endif /* __STARTUP_CLEAR_BSS */ + + cpsie i /* Unmask interrupts */ +#ifndef __START +#define __START _start +#endif +#ifndef __ATOLLIC__ + ldr r0,=__START + blx r0 +#else + ldr r0,=__libc_init_array + blx r0 + ldr r0,=main + bx r0 +#endif + .pool + .size Reset_Handler, . - Reset_Handler + + .align 1 + .thumb_func + .weak DefaultISR + .type DefaultISR, %function +DefaultISR: + b DefaultISR + .size DefaultISR, . - DefaultISR + + .align 1 + .thumb_func + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + ldr r0,=NMI_Handler + bx r0 + .size NMI_Handler, . - NMI_Handler + + .align 1 + .thumb_func + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + ldr r0,=HardFault_Handler + bx r0 + .size HardFault_Handler, . - HardFault_Handler + + .align 1 + .thumb_func + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + ldr r0,=SVC_Handler + bx r0 + .size SVC_Handler, . - SVC_Handler + + .align 1 + .thumb_func + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + ldr r0,=PendSV_Handler + bx r0 + .size PendSV_Handler, . - PendSV_Handler + + .align 1 + .thumb_func + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + ldr r0,=SysTick_Handler + bx r0 + .size SysTick_Handler, . - SysTick_Handler + + .align 1 + .thumb_func + .weak DMA0_DMA16_IRQHandler + .type DMA0_DMA16_IRQHandler, %function +DMA0_DMA16_IRQHandler: + ldr r0,=DMA0_DMA16_DriverIRQHandler + bx r0 + .size DMA0_DMA16_IRQHandler, . - DMA0_DMA16_IRQHandler + + .align 1 + .thumb_func + .weak DMA1_DMA17_IRQHandler + .type DMA1_DMA17_IRQHandler, %function +DMA1_DMA17_IRQHandler: + ldr r0,=DMA1_DMA17_DriverIRQHandler + bx r0 + .size DMA1_DMA17_IRQHandler, . - DMA1_DMA17_IRQHandler + + .align 1 + .thumb_func + .weak DMA2_DMA18_IRQHandler + .type DMA2_DMA18_IRQHandler, %function +DMA2_DMA18_IRQHandler: + ldr r0,=DMA2_DMA18_DriverIRQHandler + bx r0 + .size DMA2_DMA18_IRQHandler, . - DMA2_DMA18_IRQHandler + + .align 1 + .thumb_func + .weak DMA3_DMA19_IRQHandler + .type DMA3_DMA19_IRQHandler, %function +DMA3_DMA19_IRQHandler: + ldr r0,=DMA3_DMA19_DriverIRQHandler + bx r0 + .size DMA3_DMA19_IRQHandler, . - DMA3_DMA19_IRQHandler + + .align 1 + .thumb_func + .weak DMA4_DMA20_IRQHandler + .type DMA4_DMA20_IRQHandler, %function +DMA4_DMA20_IRQHandler: + ldr r0,=DMA4_DMA20_DriverIRQHandler + bx r0 + .size DMA4_DMA20_IRQHandler, . - DMA4_DMA20_IRQHandler + + .align 1 + .thumb_func + .weak DMA5_DMA21_IRQHandler + .type DMA5_DMA21_IRQHandler, %function +DMA5_DMA21_IRQHandler: + ldr r0,=DMA5_DMA21_DriverIRQHandler + bx r0 + .size DMA5_DMA21_IRQHandler, . - DMA5_DMA21_IRQHandler + + .align 1 + .thumb_func + .weak DMA6_DMA22_IRQHandler + .type DMA6_DMA22_IRQHandler, %function +DMA6_DMA22_IRQHandler: + ldr r0,=DMA6_DMA22_DriverIRQHandler + bx r0 + .size DMA6_DMA22_IRQHandler, . - DMA6_DMA22_IRQHandler + + .align 1 + .thumb_func + .weak DMA7_DMA23_IRQHandler + .type DMA7_DMA23_IRQHandler, %function +DMA7_DMA23_IRQHandler: + ldr r0,=DMA7_DMA23_DriverIRQHandler + bx r0 + .size DMA7_DMA23_IRQHandler, . - DMA7_DMA23_IRQHandler + + .align 1 + .thumb_func + .weak DMA8_DMA24_IRQHandler + .type DMA8_DMA24_IRQHandler, %function +DMA8_DMA24_IRQHandler: + ldr r0,=DMA8_DMA24_DriverIRQHandler + bx r0 + .size DMA8_DMA24_IRQHandler, . - DMA8_DMA24_IRQHandler + + .align 1 + .thumb_func + .weak DMA9_DMA25_IRQHandler + .type DMA9_DMA25_IRQHandler, %function +DMA9_DMA25_IRQHandler: + ldr r0,=DMA9_DMA25_DriverIRQHandler + bx r0 + .size DMA9_DMA25_IRQHandler, . - DMA9_DMA25_IRQHandler + + .align 1 + .thumb_func + .weak DMA10_DMA26_IRQHandler + .type DMA10_DMA26_IRQHandler, %function +DMA10_DMA26_IRQHandler: + ldr r0,=DMA10_DMA26_DriverIRQHandler + bx r0 + .size DMA10_DMA26_IRQHandler, . - DMA10_DMA26_IRQHandler + + .align 1 + .thumb_func + .weak DMA11_DMA27_IRQHandler + .type DMA11_DMA27_IRQHandler, %function +DMA11_DMA27_IRQHandler: + ldr r0,=DMA11_DMA27_DriverIRQHandler + bx r0 + .size DMA11_DMA27_IRQHandler, . - DMA11_DMA27_IRQHandler + + .align 1 + .thumb_func + .weak DMA12_DMA28_IRQHandler + .type DMA12_DMA28_IRQHandler, %function +DMA12_DMA28_IRQHandler: + ldr r0,=DMA12_DMA28_DriverIRQHandler + bx r0 + .size DMA12_DMA28_IRQHandler, . - DMA12_DMA28_IRQHandler + + .align 1 + .thumb_func + .weak DMA13_DMA29_IRQHandler + .type DMA13_DMA29_IRQHandler, %function +DMA13_DMA29_IRQHandler: + ldr r0,=DMA13_DMA29_DriverIRQHandler + bx r0 + .size DMA13_DMA29_IRQHandler, . - DMA13_DMA29_IRQHandler + + .align 1 + .thumb_func + .weak DMA14_DMA30_IRQHandler + .type DMA14_DMA30_IRQHandler, %function +DMA14_DMA30_IRQHandler: + ldr r0,=DMA14_DMA30_DriverIRQHandler + bx r0 + .size DMA14_DMA30_IRQHandler, . - DMA14_DMA30_IRQHandler + + .align 1 + .thumb_func + .weak DMA15_DMA31_IRQHandler + .type DMA15_DMA31_IRQHandler, %function +DMA15_DMA31_IRQHandler: + ldr r0,=DMA15_DMA31_DriverIRQHandler + bx r0 + .size DMA15_DMA31_IRQHandler, . - DMA15_DMA31_IRQHandler + + .align 1 + .thumb_func + .weak DMA_Error_IRQHandler + .type DMA_Error_IRQHandler, %function +DMA_Error_IRQHandler: + ldr r0,=DMA_Error_DriverIRQHandler + bx r0 + .size DMA_Error_IRQHandler, . - DMA_Error_IRQHandler + + .align 1 + .thumb_func + .weak I2C0_IRQHandler + .type I2C0_IRQHandler, %function +I2C0_IRQHandler: + ldr r0,=I2C0_DriverIRQHandler + bx r0 + .size I2C0_IRQHandler, . - I2C0_IRQHandler + + .align 1 + .thumb_func + .weak I2C1_IRQHandler + .type I2C1_IRQHandler, %function +I2C1_IRQHandler: + ldr r0,=I2C1_DriverIRQHandler + bx r0 + .size I2C1_IRQHandler, . - I2C1_IRQHandler + + .align 1 + .thumb_func + .weak SPI0_IRQHandler + .type SPI0_IRQHandler, %function +SPI0_IRQHandler: + ldr r0,=SPI0_DriverIRQHandler + bx r0 + .size SPI0_IRQHandler, . - SPI0_IRQHandler + + .align 1 + .thumb_func + .weak SPI1_IRQHandler + .type SPI1_IRQHandler, %function +SPI1_IRQHandler: + ldr r0,=SPI1_DriverIRQHandler + bx r0 + .size SPI1_IRQHandler, . - SPI1_IRQHandler + + .align 1 + .thumb_func + .weak I2S0_Tx_IRQHandler + .type I2S0_Tx_IRQHandler, %function +I2S0_Tx_IRQHandler: + ldr r0,=I2S0_Tx_DriverIRQHandler + bx r0 + .size I2S0_Tx_IRQHandler, . - I2S0_Tx_IRQHandler + + .align 1 + .thumb_func + .weak I2S0_Rx_IRQHandler + .type I2S0_Rx_IRQHandler, %function +I2S0_Rx_IRQHandler: + ldr r0,=I2S0_Rx_DriverIRQHandler + bx r0 + .size I2S0_Rx_IRQHandler, . - I2S0_Rx_IRQHandler + + .align 1 + .thumb_func + .weak LPUART0_IRQHandler + .type LPUART0_IRQHandler, %function +LPUART0_IRQHandler: + ldr r0,=LPUART0_DriverIRQHandler + bx r0 + .size LPUART0_IRQHandler, . - LPUART0_IRQHandler + + .align 1 + .thumb_func + .weak LPUART1_IRQHandler + .type LPUART1_IRQHandler, %function +LPUART1_IRQHandler: + ldr r0,=LPUART1_DriverIRQHandler + bx r0 + .size LPUART1_IRQHandler, . - LPUART1_IRQHandler + + .align 1 + .thumb_func + .weak LPUART2_IRQHandler + .type LPUART2_IRQHandler, %function +LPUART2_IRQHandler: + ldr r0,=LPUART2_DriverIRQHandler + bx r0 + .size LPUART2_IRQHandler, . - LPUART2_IRQHandler + + .align 1 + .thumb_func + .weak LPUART3_IRQHandler + .type LPUART3_IRQHandler, %function +LPUART3_IRQHandler: + ldr r0,=LPUART3_DriverIRQHandler + bx r0 + .size LPUART3_IRQHandler, . - LPUART3_IRQHandler + + .align 1 + .thumb_func + .weak LPUART4_IRQHandler + .type LPUART4_IRQHandler, %function +LPUART4_IRQHandler: + ldr r0,=LPUART4_DriverIRQHandler + bx r0 + .size LPUART4_IRQHandler, . - LPUART4_IRQHandler + + .align 1 + .thumb_func + .weak SPI2_IRQHandler + .type SPI2_IRQHandler, %function +SPI2_IRQHandler: + ldr r0,=SPI2_DriverIRQHandler + bx r0 + .size SPI2_IRQHandler, . - SPI2_IRQHandler + + .align 1 + .thumb_func + .weak FLEXIO0_IRQHandler + .type FLEXIO0_IRQHandler, %function +FLEXIO0_IRQHandler: + ldr r0,=FLEXIO0_DriverIRQHandler + bx r0 + .size FLEXIO0_IRQHandler, . - FLEXIO0_IRQHandler + + .align 1 + .thumb_func + .weak I2C2_IRQHandler + .type I2C2_IRQHandler, %function +I2C2_IRQHandler: + ldr r0,=I2C2_DriverIRQHandler + bx r0 + .size I2C2_IRQHandler, . - I2C2_IRQHandler + + .align 1 + .thumb_func + .weak SDHC_IRQHandler + .type SDHC_IRQHandler, %function +SDHC_IRQHandler: + ldr r0,=SDHC_DriverIRQHandler + bx r0 + .size SDHC_IRQHandler, . - SDHC_IRQHandler + + .align 1 + .thumb_func + .weak I2C3_IRQHandler + .type I2C3_IRQHandler, %function +I2C3_IRQHandler: + ldr r0,=I2C3_DriverIRQHandler + bx r0 + .size I2C3_IRQHandler, . - I2C3_IRQHandler + + .align 1 + .thumb_func + .weak QuadSPI0_IRQHandler + .type QuadSPI0_IRQHandler, %function +QuadSPI0_IRQHandler: + ldr r0,=QuadSPI0_DriverIRQHandler + bx r0 + .size QuadSPI0_IRQHandler, . - QuadSPI0_IRQHandler + + +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_irq_handler handler_name + .weak \handler_name + .set \handler_name, DefaultISR + .endm + +/* Exception Handlers */ + def_irq_handler MemManage_Handler + def_irq_handler BusFault_Handler + def_irq_handler UsageFault_Handler + def_irq_handler DebugMon_Handler + def_irq_handler DMA0_DMA16_DriverIRQHandler + def_irq_handler DMA1_DMA17_DriverIRQHandler + def_irq_handler DMA2_DMA18_DriverIRQHandler + def_irq_handler DMA3_DMA19_DriverIRQHandler + def_irq_handler DMA4_DMA20_DriverIRQHandler + def_irq_handler DMA5_DMA21_DriverIRQHandler + def_irq_handler DMA6_DMA22_DriverIRQHandler + def_irq_handler DMA7_DMA23_DriverIRQHandler + def_irq_handler DMA8_DMA24_DriverIRQHandler + def_irq_handler DMA9_DMA25_DriverIRQHandler + def_irq_handler DMA10_DMA26_DriverIRQHandler + def_irq_handler DMA11_DMA27_DriverIRQHandler + def_irq_handler DMA12_DMA28_DriverIRQHandler + def_irq_handler DMA13_DMA29_DriverIRQHandler + def_irq_handler DMA14_DMA30_DriverIRQHandler + def_irq_handler DMA15_DMA31_DriverIRQHandler + def_irq_handler DMA_Error_DriverIRQHandler + def_irq_handler MCM_IRQHandler + def_irq_handler FTFA_IRQHandler + def_irq_handler Read_Collision_IRQHandler + def_irq_handler LVD_LVW_IRQHandler + def_irq_handler LLWU_IRQHandler + def_irq_handler WDOG_EWM_IRQHandler + def_irq_handler TRNG0_IRQHandler + def_irq_handler I2C0_DriverIRQHandler + def_irq_handler I2C1_DriverIRQHandler + def_irq_handler SPI0_DriverIRQHandler + def_irq_handler SPI1_DriverIRQHandler + def_irq_handler I2S0_Tx_DriverIRQHandler + def_irq_handler I2S0_Rx_DriverIRQHandler + def_irq_handler LPUART0_DriverIRQHandler + def_irq_handler LPUART1_DriverIRQHandler + def_irq_handler LPUART2_DriverIRQHandler + def_irq_handler LPUART3_DriverIRQHandler + def_irq_handler LPUART4_DriverIRQHandler + def_irq_handler Reserved51_IRQHandler + def_irq_handler Reserved52_IRQHandler + def_irq_handler EMVSIM0_IRQHandler + def_irq_handler EMVSIM1_IRQHandler + def_irq_handler ADC0_IRQHandler + def_irq_handler CMP0_IRQHandler + def_irq_handler CMP1_IRQHandler + def_irq_handler FTM0_IRQHandler + def_irq_handler FTM1_IRQHandler + def_irq_handler FTM2_IRQHandler + def_irq_handler CMT_IRQHandler + def_irq_handler RTC_IRQHandler + def_irq_handler RTC_Seconds_IRQHandler + def_irq_handler PIT0CH0_IRQHandler + def_irq_handler PIT0CH1_IRQHandler + def_irq_handler PIT0CH2_IRQHandler + def_irq_handler PIT0CH3_IRQHandler + def_irq_handler PDB0_IRQHandler + def_irq_handler USB0_IRQHandler + def_irq_handler USBDCD_IRQHandler + def_irq_handler Reserved71_IRQHandler + def_irq_handler DAC0_IRQHandler + def_irq_handler MCG_IRQHandler + def_irq_handler LPTMR0_LPTMR1_IRQHandler + def_irq_handler PORTA_IRQHandler + def_irq_handler PORTB_IRQHandler + def_irq_handler PORTC_IRQHandler + def_irq_handler PORTD_IRQHandler + def_irq_handler PORTE_IRQHandler + def_irq_handler SWI_IRQHandler + def_irq_handler SPI2_DriverIRQHandler + def_irq_handler Reserved82_IRQHandler + def_irq_handler Reserved83_IRQHandler + def_irq_handler Reserved84_IRQHandler + def_irq_handler Reserved85_IRQHandler + def_irq_handler FLEXIO0_DriverIRQHandler + def_irq_handler FTM3_IRQHandler + def_irq_handler Reserved88_IRQHandler + def_irq_handler Reserved89_IRQHandler + def_irq_handler I2C2_DriverIRQHandler + def_irq_handler Reserved91_IRQHandler + def_irq_handler Reserved92_IRQHandler + def_irq_handler Reserved93_IRQHandler + def_irq_handler Reserved94_IRQHandler + def_irq_handler Reserved95_IRQHandler + def_irq_handler Reserved96_IRQHandler + def_irq_handler SDHC_DriverIRQHandler + def_irq_handler Reserved98_IRQHandler + def_irq_handler Reserved99_IRQHandler + def_irq_handler Reserved100_IRQHandler + def_irq_handler Reserved101_IRQHandler + def_irq_handler Reserved102_IRQHandler + def_irq_handler TSI0_IRQHandler + def_irq_handler TPM1_IRQHandler + def_irq_handler TPM2_IRQHandler + def_irq_handler Reserved106_IRQHandler + def_irq_handler I2C3_DriverIRQHandler + def_irq_handler Reserved108_IRQHandler + def_irq_handler Reserved109_IRQHandler + def_irq_handler Reserved110_IRQHandler + def_irq_handler Reserved111_IRQHandler + def_irq_handler Reserved112_IRQHandler + def_irq_handler Reserved113_IRQHandler + def_irq_handler Reserved114_IRQHandler + def_irq_handler Reserved115_IRQHandler + def_irq_handler QuadSPI0_DriverIRQHandler + def_irq_handler Reserved117_IRQHandler + def_irq_handler Reserved118_IRQHandler + def_irq_handler Reserved119_IRQHandler + def_irq_handler LTC0_IRQHandler + def_irq_handler Reserved121_IRQHandler + def_irq_handler Reserved122_IRQHandler + + .end diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_IAR/MK82FN256xxx15.icf b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_IAR/MK82FN256xxx15.icf new file mode 100644 index 00000000000..61027df5866 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_IAR/MK82FN256xxx15.icf @@ -0,0 +1,124 @@ +/* +** ################################################################### +** Processors: MK82FN256CAx15 +** MK82FN256VDC15 +** MK82FN256VLL15 +** MK82FN256VLQ15 +** +** Compiler: IAR ANSI C/C++ Compiler for ARM +** Reference manual: K82P121M150SF5RM, Rev. 0, May 2015 +** Version: rev. 1.2, 2015-07-29 +** Build: b160406 +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright (c) 2016 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** ################################################################### +*/ + +define symbol __ram_vector_table__ = 1; + +/* Heap 1/4 of ram and stack 1/8 */ +define symbol __stack_size__=0x8000; +define symbol __heap_size__=0x10000; + +define symbol __ram_vector_table_size__ = isdefinedsymbol(__ram_vector_table__) ? 0x000003C0 : 0; +define symbol __ram_vector_table_offset__ = isdefinedsymbol(__ram_vector_table__) ? 0x000003BF : 0; + +define symbol m_interrupts_start = 0x00000000; +define symbol m_interrupts_end = 0x000003BF; + +define symbol m_bootloader_config_start = 0x000003C0; +define symbol m_bootloader_config_end = 0x000003FF; + +define symbol m_flash_config_start = 0x00000400; +define symbol m_flash_config_end = 0x0000040F; + +define symbol m_text_start = 0x00000410; +define symbol m_text_end = 0x0003FFFF; + +define symbol m_interrupts_ram_start = 0x1FFF0000; +define symbol m_interrupts_ram_end = 0x1FFF0000 + __ram_vector_table_offset__; + +define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__; +define symbol m_data_end = 0x1FFFFFFF; + +define symbol m_data_2_start = 0x20000000; +define symbol m_data_2_end = 0x2002FFFF; + +/* Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x0400; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x0400; +} + +define exported symbol __VECTOR_TABLE = m_interrupts_start; +define exported symbol __VECTOR_RAM = isdefinedsymbol(__ram_vector_table__) ? m_interrupts_ram_start : m_interrupts_start; +define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__; + +define memory mem with size = 4G; +define region m_bootloader_config_region = mem:[from m_bootloader_config_start to m_bootloader_config_end]; +define region m_flash_config_region = mem:[from m_flash_config_start to m_flash_config_end]; +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; +define region DATA_region = mem:[from m_data_start to m_data_end] + | mem:[from m_data_2_start to m_data_2_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_2_end-__size_cstack__+1 to m_data_2_end]; +define region m_interrupts_ram_region = mem:[from m_interrupts_ram_start to m_interrupts_ram_end]; + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +initialize by copy { readwrite, section .textrw }; +do not initialize { section .noinit }; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in m_bootloader_config_region { section BootloaderConfig }; +place in m_flash_config_region { section FlashConfig }; +place in TEXT_region { readonly }; +place in DATA_region { block RW }; +place in DATA_region { block ZI }; +place in DATA_region { last block HEAP }; +place in CSTACK_region { block CSTACK }; +place in m_interrupts_ram_region { section m_interrupts_ram }; + diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_IAR/startup_MK82F25615.S b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_IAR/startup_MK82F25615.S new file mode 100644 index 00000000000..1a5bba85437 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/TOOLCHAIN_IAR/startup_MK82F25615.S @@ -0,0 +1,816 @@ +; --------------------------------------------------------------------------------------- +; @file: startup_MK82F25615.s +; @purpose: CMSIS Cortex-M4 Core Device Startup File +; MK82F25615 +; @version: 1.0 +; @date: 2015-4-9 +; @build: b151210 +; --------------------------------------------------------------------------------------- +; +; Copyright (c) 1997 - 2015 , Freescale Semiconductor, Inc. +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without modification, +; are permitted provided that the following conditions are met: +; +; o Redistributions of source code must retain the above copyright notice, this list +; of conditions and the following disclaimer. +; +; o Redistributions in binary form must reproduce the above copyright notice, this +; list of conditions and the following disclaimer in the documentation and/or +; other materials provided with the distribution. +; +; o Neither the name of Freescale Semiconductor, Inc. nor the names of its +; contributors may be used to endorse or promote products derived from this +; software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +; ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +; ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __vector_table_0x1c + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + + DCD NMI_Handler ;NMI Handler + DCD HardFault_Handler ;Hard Fault Handler + DCD MemManage_Handler ;MPU Fault Handler + DCD BusFault_Handler ;Bus Fault Handler + DCD UsageFault_Handler ;Usage Fault Handler +__vector_table_0x1c + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD SVC_Handler ;SVCall Handler + DCD DebugMon_Handler ;Debug Monitor Handler + DCD 0 ;Reserved + DCD PendSV_Handler ;PendSV Handler + DCD SysTick_Handler ;SysTick Handler + + ;External Interrupts + DCD DMA0_DMA16_IRQHandler ;DMA channel 0,16 transfer complete + DCD DMA1_DMA17_IRQHandler ;DMA channel 1,17 transfer complete + DCD DMA2_DMA18_IRQHandler ;DMA channel 2,18 transfer complete + DCD DMA3_DMA19_IRQHandler ;DMA channel 3,19 transfer complete + DCD DMA4_DMA20_IRQHandler ;DMA channel 4,20 transfer complete + DCD DMA5_DMA21_IRQHandler ;DMA channel 5,21 transfer complete + DCD DMA6_DMA22_IRQHandler ;DMA channel 6,22 transfer complete + DCD DMA7_DMA23_IRQHandler ;DMA channel 7,23 transfer complete + DCD DMA8_DMA24_IRQHandler ;DMA channel 8,24 transfer complete + DCD DMA9_DMA25_IRQHandler ;DMA channel 9,25 transfer complete + DCD DMA10_DMA26_IRQHandler ;DMA channel 10,26 transfer complete + DCD DMA11_DMA27_IRQHandler ;DMA channel 11,27 transfer complete + DCD DMA12_DMA28_IRQHandler ;DMA channel 12,28 transfer complete + DCD DMA13_DMA29_IRQHandler ;DMA channel 13,29 transfer complete + DCD DMA14_DMA30_IRQHandler ;DMA channel 14,30 transfer complete + DCD DMA15_DMA31_IRQHandler ;DMA channel 15,31 transfer complete + DCD DMA_Error_IRQHandler ;DMA channel 0 - 31 error + DCD MCM_IRQHandler ;MCM normal interrupt + DCD FTFA_IRQHandler ;FTFA command complete + DCD Read_Collision_IRQHandler ;FTFA read collision + DCD LVD_LVW_IRQHandler ;PMC controller low-voltage detect, low-voltage warning + DCD LLWU_IRQHandler ;Low leakage wakeup unit + DCD WDOG_EWM_IRQHandler ;Single interrupt vector for WDOG and EWM + DCD TRNG0_IRQHandler ;True randon number generator + DCD I2C0_IRQHandler ;Inter-integrated circuit 0 + DCD I2C1_IRQHandler ;Inter-integrated circuit 1 + DCD SPI0_IRQHandler ;Serial peripheral Interface 0 + DCD SPI1_IRQHandler ;Serial peripheral Interface 1 + DCD I2S0_Tx_IRQHandler ;Integrated interchip sound 0 transmit interrupt + DCD I2S0_Rx_IRQHandler ;Integrated interchip sound 0 receive interrupt + DCD LPUART0_IRQHandler ;LPUART0 receive/transmit/error interrupt + DCD LPUART1_IRQHandler ;LPUART1 receive/transmit/error interrupt + DCD LPUART2_IRQHandler ;LPUART2 receive/transmit/error interrupt + DCD LPUART3_IRQHandler ;LPUART3 receive/transmit/error interrupt + DCD LPUART4_IRQHandler ;LPUART4 receive/transmit/error interrupt + DCD Reserved51_IRQHandler ;Reserved interrupt + DCD Reserved52_IRQHandler ;Reserved interrupt + DCD EMVSIM0_IRQHandler ;EMVSIM0 common interrupt + DCD EMVSIM1_IRQHandler ;EMVSIM1 common interrupt + DCD ADC0_IRQHandler ;Analog-to-digital converter 0 + DCD CMP0_IRQHandler ;Comparator 0 + DCD CMP1_IRQHandler ;Comparator 1 + DCD FTM0_IRQHandler ;FlexTimer module 0 fault, overflow and channels interrupt + DCD FTM1_IRQHandler ;FlexTimer module 1 fault, overflow and channels interrupt + DCD FTM2_IRQHandler ;FlexTimer module 2 fault, overflow and channels interrupt + DCD CMT_IRQHandler ;Carrier modulator transmitter + DCD RTC_IRQHandler ;Real time clock + DCD RTC_Seconds_IRQHandler ;Real time clock seconds + DCD PIT0CH0_IRQHandler ;Periodic interrupt timer 0 channel 0 + DCD PIT0CH1_IRQHandler ;Periodic interrupt timer 0 channel 1 + DCD PIT0CH2_IRQHandler ;Periodic interrupt timer 0 channel 2 + DCD PIT0CH3_IRQHandler ;Periodic interrupt timer 0 channel 3 + DCD PDB0_IRQHandler ;Programmable delay block + DCD USB0_IRQHandler ;USB OTG interrupt + DCD USBDCD_IRQHandler ;USB charger detect + DCD Reserved71_IRQHandler ;Reserved interrupt + DCD DAC0_IRQHandler ;Digital-to-analog converter 0 + DCD MCG_IRQHandler ;Multipurpose clock generator + DCD LPTMR0_LPTMR1_IRQHandler ;Single interrupt vector for Low Power Timer 0 and 1 + DCD PORTA_IRQHandler ;Port A pin detect interrupt + DCD PORTB_IRQHandler ;Port B pin detect interrupt + DCD PORTC_IRQHandler ;Port C pin detect interrupt + DCD PORTD_IRQHandler ;Port D pin detect interrupt + DCD PORTE_IRQHandler ;Port E pin detect interrupt + DCD SWI_IRQHandler ;Software interrupt + DCD SPI2_IRQHandler ;Serial peripheral Interface 2 + DCD Reserved82_IRQHandler ;Reserved interrupt + DCD Reserved83_IRQHandler ;Reserved interrupt + DCD Reserved84_IRQHandler ;Reserved interrupt + DCD Reserved85_IRQHandler ;Reserved interrupt + DCD FLEXIO0_IRQHandler ;FLEXIO0 + DCD FTM3_IRQHandler ;FlexTimer module 3 fault, overflow and channels interrupt + DCD Reserved88_IRQHandler ;Reserved interrupt + DCD Reserved89_IRQHandler ;Reserved interrupt + DCD I2C2_IRQHandler ;Inter-integrated circuit 2 + DCD Reserved91_IRQHandler ;Reserved interrupt + DCD Reserved92_IRQHandler ;Reserved interrupt + DCD Reserved93_IRQHandler ;Reserved interrupt + DCD Reserved94_IRQHandler ;Reserved interrupt + DCD Reserved95_IRQHandler ;Reserved interrupt + DCD Reserved96_IRQHandler ;Reserved interrupt + DCD SDHC_IRQHandler ;Secured digital host controller + DCD Reserved98_IRQHandler ;Reserved interrupt + DCD Reserved99_IRQHandler ;Reserved interrupt + DCD Reserved100_IRQHandler ;Reserved interrupt + DCD Reserved101_IRQHandler ;Reserved interrupt + DCD Reserved102_IRQHandler ;Reserved interrupt + DCD TSI0_IRQHandler ;Touch Sensing Input + DCD TPM1_IRQHandler ;TPM1 single interrupt vector for all sources + DCD TPM2_IRQHandler ;TPM2 single interrupt vector for all sources + DCD Reserved106_IRQHandler ;Reserved interrupt + DCD I2C3_IRQHandler ;Inter-integrated circuit 3 + DCD Reserved108_IRQHandler ;Reserved interrupt + DCD Reserved109_IRQHandler ;Reserved interrupt + DCD Reserved110_IRQHandler ;Reserved interrupt + DCD Reserved111_IRQHandler ;Reserved interrupt + DCD Reserved112_IRQHandler ;Reserved interrupt + DCD Reserved113_IRQHandler ;Reserved interrupt + DCD Reserved114_IRQHandler ;Reserved interrupt + DCD Reserved115_IRQHandler ;Reserved interrupt + DCD QuadSPI0_IRQHandler ;qspi + DCD Reserved117_IRQHandler ;Reserved interrupt + DCD Reserved118_IRQHandler ;Reserved interrupt + DCD Reserved119_IRQHandler ;Reserved interrupt + DCD LTC0_IRQHandler ;LP Trusted Cryptography + DCD Reserved121_IRQHandler ;Reserved interrupt + DCD Reserved122_IRQHandler ;Reserved interrupt + DCD DefaultISR ;123 + DCD DefaultISR ;124 + DCD DefaultISR ;125 + DCD DefaultISR ;126 + DCD DefaultISR ;127 + DCD DefaultISR ;128 + DCD DefaultISR ;129 + DCD DefaultISR ;130 + DCD DefaultISR ;131 + DCD DefaultISR ;132 + DCD DefaultISR ;133 + DCD DefaultISR ;134 + DCD DefaultISR ;135 + DCD DefaultISR ;136 + DCD DefaultISR ;137 + DCD DefaultISR ;138 + DCD DefaultISR ;139 + DCD DefaultISR ;140 + DCD DefaultISR ;141 + DCD DefaultISR ;142 + DCD DefaultISR ;143 + DCD DefaultISR ;144 + DCD DefaultISR ;145 + DCD DefaultISR ;146 + DCD DefaultISR ;147 + DCD DefaultISR ;148 + DCD DefaultISR ;149 + DCD DefaultISR ;150 + DCD DefaultISR ;151 + DCD DefaultISR ;152 + DCD DefaultISR ;153 + DCD DefaultISR ;154 + DCD DefaultISR ;155 + DCD DefaultISR ;156 + DCD DefaultISR ;157 + DCD DefaultISR ;158 + DCD DefaultISR ;159 + DCD DefaultISR ;160 + DCD DefaultISR ;161 + DCD DefaultISR ;162 + DCD DefaultISR ;163 + DCD DefaultISR ;164 + DCD DefaultISR ;165 + DCD DefaultISR ;166 + DCD DefaultISR ;167 + DCD DefaultISR ;168 + DCD DefaultISR ;169 + DCD DefaultISR ;170 + DCD DefaultISR ;171 + DCD DefaultISR ;172 + DCD DefaultISR ;173 + DCD DefaultISR ;174 + DCD DefaultISR ;175 + DCD DefaultISR ;176 + DCD DefaultISR ;177 + DCD DefaultISR ;178 + DCD DefaultISR ;179 + DCD DefaultISR ;180 + DCD DefaultISR ;181 + DCD DefaultISR ;182 + DCD DefaultISR ;183 + DCD DefaultISR ;184 + DCD DefaultISR ;185 + DCD DefaultISR ;186 + DCD DefaultISR ;187 + DCD DefaultISR ;188 + DCD DefaultISR ;189 + DCD DefaultISR ;190 + DCD DefaultISR ;191 + DCD DefaultISR ;192 + DCD DefaultISR ;193 + DCD DefaultISR ;194 + DCD DefaultISR ;195 + DCD DefaultISR ;196 + DCD DefaultISR ;197 + DCD DefaultISR ;198 + DCD DefaultISR ;199 + DCD DefaultISR ;200 + DCD DefaultISR ;201 + DCD DefaultISR ;202 + DCD DefaultISR ;203 + DCD DefaultISR ;204 + DCD DefaultISR ;205 + DCD DefaultISR ;206 + DCD DefaultISR ;207 + DCD DefaultISR ;208 + DCD DefaultISR ;209 + DCD DefaultISR ;210 + DCD DefaultISR ;211 + DCD DefaultISR ;212 + DCD DefaultISR ;213 + DCD DefaultISR ;214 + DCD DefaultISR ;215 + DCD DefaultISR ;216 + DCD DefaultISR ;217 + DCD DefaultISR ;218 + DCD DefaultISR ;219 + DCD DefaultISR ;220 + DCD DefaultISR ;221 + DCD DefaultISR ;222 + DCD DefaultISR ;223 + DCD DefaultISR ;224 + DCD DefaultISR ;225 + DCD DefaultISR ;226 + DCD DefaultISR ;227 + DCD DefaultISR ;228 + DCD DefaultISR ;229 + DCD DefaultISR ;230 + DCD DefaultISR ;231 + DCD DefaultISR ;232 + DCD DefaultISR ;233 + DCD DefaultISR ;234 + DCD DefaultISR ;235 + DCD DefaultISR ;236 + DCD DefaultISR ;237 + DCD DefaultISR ;238 + DCD DefaultISR ;239 +__Vectors_End + + SECTION FlashConfig:CODE +__FlashConfig + DCD 0xFFFFFFFF + DCD 0xFFFFFFFF + DCD 0xFFFFFFFF + DCD 0xFFFF3DFE +__FlashConfig_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + CPSID I ; Mask interrupts + LDR R0, =0xE000ED08 + LDR R1, =__vector_table + STR R1, [R0] + LDR R0, =SystemInit + BLX R0 + CPSIE I ; Unmask interrupts + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + PUBWEAK MemManage_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +MemManage_Handler + B . + + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +BusFault_Handler + B . + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +UsageFault_Handler + B . + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +DebugMon_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + PUBWEAK DMA0_DMA16_IRQHandler + PUBWEAK DMA0_DMA16_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA0_DMA16_IRQHandler + LDR R0, =DMA0_DMA16_DriverIRQHandler + BX R0 + + PUBWEAK DMA1_DMA17_IRQHandler + PUBWEAK DMA1_DMA17_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA1_DMA17_IRQHandler + LDR R0, =DMA1_DMA17_DriverIRQHandler + BX R0 + + PUBWEAK DMA2_DMA18_IRQHandler + PUBWEAK DMA2_DMA18_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA2_DMA18_IRQHandler + LDR R0, =DMA2_DMA18_DriverIRQHandler + BX R0 + + PUBWEAK DMA3_DMA19_IRQHandler + PUBWEAK DMA3_DMA19_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA3_DMA19_IRQHandler + LDR R0, =DMA3_DMA19_DriverIRQHandler + BX R0 + + PUBWEAK DMA4_DMA20_IRQHandler + PUBWEAK DMA4_DMA20_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA4_DMA20_IRQHandler + LDR R0, =DMA4_DMA20_DriverIRQHandler + BX R0 + + PUBWEAK DMA5_DMA21_IRQHandler + PUBWEAK DMA5_DMA21_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA5_DMA21_IRQHandler + LDR R0, =DMA5_DMA21_DriverIRQHandler + BX R0 + + PUBWEAK DMA6_DMA22_IRQHandler + PUBWEAK DMA6_DMA22_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA6_DMA22_IRQHandler + LDR R0, =DMA6_DMA22_DriverIRQHandler + BX R0 + + PUBWEAK DMA7_DMA23_IRQHandler + PUBWEAK DMA7_DMA23_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA7_DMA23_IRQHandler + LDR R0, =DMA7_DMA23_DriverIRQHandler + BX R0 + + PUBWEAK DMA8_DMA24_IRQHandler + PUBWEAK DMA8_DMA24_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA8_DMA24_IRQHandler + LDR R0, =DMA8_DMA24_DriverIRQHandler + BX R0 + + PUBWEAK DMA9_DMA25_IRQHandler + PUBWEAK DMA9_DMA25_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA9_DMA25_IRQHandler + LDR R0, =DMA9_DMA25_DriverIRQHandler + BX R0 + + PUBWEAK DMA10_DMA26_IRQHandler + PUBWEAK DMA10_DMA26_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA10_DMA26_IRQHandler + LDR R0, =DMA10_DMA26_DriverIRQHandler + BX R0 + + PUBWEAK DMA11_DMA27_IRQHandler + PUBWEAK DMA11_DMA27_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA11_DMA27_IRQHandler + LDR R0, =DMA11_DMA27_DriverIRQHandler + BX R0 + + PUBWEAK DMA12_DMA28_IRQHandler + PUBWEAK DMA12_DMA28_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA12_DMA28_IRQHandler + LDR R0, =DMA12_DMA28_DriverIRQHandler + BX R0 + + PUBWEAK DMA13_DMA29_IRQHandler + PUBWEAK DMA13_DMA29_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA13_DMA29_IRQHandler + LDR R0, =DMA13_DMA29_DriverIRQHandler + BX R0 + + PUBWEAK DMA14_DMA30_IRQHandler + PUBWEAK DMA14_DMA30_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA14_DMA30_IRQHandler + LDR R0, =DMA14_DMA30_DriverIRQHandler + BX R0 + + PUBWEAK DMA15_DMA31_IRQHandler + PUBWEAK DMA15_DMA31_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA15_DMA31_IRQHandler + LDR R0, =DMA15_DMA31_DriverIRQHandler + BX R0 + + PUBWEAK DMA_Error_IRQHandler + PUBWEAK DMA_Error_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA_Error_IRQHandler + LDR R0, =DMA_Error_DriverIRQHandler + BX R0 + + PUBWEAK MCM_IRQHandler + PUBWEAK FTFA_IRQHandler + PUBWEAK Read_Collision_IRQHandler + PUBWEAK LVD_LVW_IRQHandler + PUBWEAK LLWU_IRQHandler + PUBWEAK WDOG_EWM_IRQHandler + PUBWEAK TRNG0_IRQHandler + PUBWEAK I2C0_IRQHandler + PUBWEAK I2C0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +I2C0_IRQHandler + LDR R0, =I2C0_DriverIRQHandler + BX R0 + + PUBWEAK I2C1_IRQHandler + PUBWEAK I2C1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +I2C1_IRQHandler + LDR R0, =I2C1_DriverIRQHandler + BX R0 + + PUBWEAK SPI0_IRQHandler + PUBWEAK SPI0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SPI0_IRQHandler + LDR R0, =SPI0_DriverIRQHandler + BX R0 + + PUBWEAK SPI1_IRQHandler + PUBWEAK SPI1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SPI1_IRQHandler + LDR R0, =SPI1_DriverIRQHandler + BX R0 + + PUBWEAK I2S0_Tx_IRQHandler + PUBWEAK I2S0_Tx_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +I2S0_Tx_IRQHandler + LDR R0, =I2S0_Tx_DriverIRQHandler + BX R0 + + PUBWEAK I2S0_Rx_IRQHandler + PUBWEAK I2S0_Rx_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +I2S0_Rx_IRQHandler + LDR R0, =I2S0_Rx_DriverIRQHandler + BX R0 + + PUBWEAK LPUART0_IRQHandler + PUBWEAK LPUART0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +LPUART0_IRQHandler + LDR R0, =LPUART0_DriverIRQHandler + BX R0 + + PUBWEAK LPUART1_IRQHandler + PUBWEAK LPUART1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +LPUART1_IRQHandler + LDR R0, =LPUART1_DriverIRQHandler + BX R0 + + PUBWEAK LPUART2_IRQHandler + PUBWEAK LPUART2_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +LPUART2_IRQHandler + LDR R0, =LPUART2_DriverIRQHandler + BX R0 + + PUBWEAK LPUART3_IRQHandler + PUBWEAK LPUART3_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +LPUART3_IRQHandler + LDR R0, =LPUART3_DriverIRQHandler + BX R0 + + PUBWEAK LPUART4_IRQHandler + PUBWEAK LPUART4_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +LPUART4_IRQHandler + LDR R0, =LPUART4_DriverIRQHandler + BX R0 + + PUBWEAK Reserved51_IRQHandler + PUBWEAK Reserved52_IRQHandler + PUBWEAK EMVSIM0_IRQHandler + PUBWEAK EMVSIM1_IRQHandler + PUBWEAK ADC0_IRQHandler + PUBWEAK CMP0_IRQHandler + PUBWEAK CMP1_IRQHandler + PUBWEAK FTM0_IRQHandler + PUBWEAK FTM1_IRQHandler + PUBWEAK FTM2_IRQHandler + PUBWEAK CMT_IRQHandler + PUBWEAK RTC_IRQHandler + PUBWEAK RTC_Seconds_IRQHandler + PUBWEAK PIT0CH0_IRQHandler + PUBWEAK PIT0CH1_IRQHandler + PUBWEAK PIT0CH2_IRQHandler + PUBWEAK PIT0CH3_IRQHandler + PUBWEAK PDB0_IRQHandler + PUBWEAK USB0_IRQHandler + PUBWEAK USBDCD_IRQHandler + PUBWEAK Reserved71_IRQHandler + PUBWEAK DAC0_IRQHandler + PUBWEAK MCG_IRQHandler + PUBWEAK LPTMR0_LPTMR1_IRQHandler + PUBWEAK PORTA_IRQHandler + PUBWEAK PORTB_IRQHandler + PUBWEAK PORTC_IRQHandler + PUBWEAK PORTD_IRQHandler + PUBWEAK PORTE_IRQHandler + PUBWEAK SWI_IRQHandler + PUBWEAK SPI2_IRQHandler + PUBWEAK SPI2_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SPI2_IRQHandler + LDR R0, =SPI2_DriverIRQHandler + BX R0 + + PUBWEAK Reserved82_IRQHandler + PUBWEAK Reserved83_IRQHandler + PUBWEAK Reserved84_IRQHandler + PUBWEAK Reserved85_IRQHandler + PUBWEAK FLEXIO0_IRQHandler + PUBWEAK FLEXIO0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXIO0_IRQHandler + LDR R0, =FLEXIO0_DriverIRQHandler + BX R0 + + PUBWEAK FTM3_IRQHandler + PUBWEAK Reserved88_IRQHandler + PUBWEAK Reserved89_IRQHandler + PUBWEAK I2C2_IRQHandler + PUBWEAK I2C2_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +I2C2_IRQHandler + LDR R0, =I2C2_DriverIRQHandler + BX R0 + + PUBWEAK Reserved91_IRQHandler + PUBWEAK Reserved92_IRQHandler + PUBWEAK Reserved93_IRQHandler + PUBWEAK Reserved94_IRQHandler + PUBWEAK Reserved95_IRQHandler + PUBWEAK Reserved96_IRQHandler + PUBWEAK SDHC_IRQHandler + PUBWEAK SDHC_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SDHC_IRQHandler + LDR R0, =SDHC_DriverIRQHandler + BX R0 + + PUBWEAK Reserved98_IRQHandler + PUBWEAK Reserved99_IRQHandler + PUBWEAK Reserved100_IRQHandler + PUBWEAK Reserved101_IRQHandler + PUBWEAK Reserved102_IRQHandler + PUBWEAK TSI0_IRQHandler + PUBWEAK TPM1_IRQHandler + PUBWEAK TPM2_IRQHandler + PUBWEAK Reserved106_IRQHandler + PUBWEAK I2C3_IRQHandler + PUBWEAK I2C3_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +I2C3_IRQHandler + LDR R0, =I2C3_DriverIRQHandler + BX R0 + + PUBWEAK Reserved108_IRQHandler + PUBWEAK Reserved109_IRQHandler + PUBWEAK Reserved110_IRQHandler + PUBWEAK Reserved111_IRQHandler + PUBWEAK Reserved112_IRQHandler + PUBWEAK Reserved113_IRQHandler + PUBWEAK Reserved114_IRQHandler + PUBWEAK Reserved115_IRQHandler + PUBWEAK QuadSPI0_IRQHandler + PUBWEAK QuadSPI0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +QuadSPI0_IRQHandler + LDR R0, =QuadSPI0_DriverIRQHandler + BX R0 + + PUBWEAK Reserved117_IRQHandler + PUBWEAK Reserved118_IRQHandler + PUBWEAK Reserved119_IRQHandler + PUBWEAK LTC0_IRQHandler + PUBWEAK Reserved121_IRQHandler + PUBWEAK Reserved122_IRQHandler + PUBWEAK DefaultISR + SECTION .text:CODE:REORDER:NOROOT(1) +DMA0_DMA16_DriverIRQHandler +DMA1_DMA17_DriverIRQHandler +DMA2_DMA18_DriverIRQHandler +DMA3_DMA19_DriverIRQHandler +DMA4_DMA20_DriverIRQHandler +DMA5_DMA21_DriverIRQHandler +DMA6_DMA22_DriverIRQHandler +DMA7_DMA23_DriverIRQHandler +DMA8_DMA24_DriverIRQHandler +DMA9_DMA25_DriverIRQHandler +DMA10_DMA26_DriverIRQHandler +DMA11_DMA27_DriverIRQHandler +DMA12_DMA28_DriverIRQHandler +DMA13_DMA29_DriverIRQHandler +DMA14_DMA30_DriverIRQHandler +DMA15_DMA31_DriverIRQHandler +DMA_Error_DriverIRQHandler +MCM_IRQHandler +FTFA_IRQHandler +Read_Collision_IRQHandler +LVD_LVW_IRQHandler +LLWU_IRQHandler +WDOG_EWM_IRQHandler +TRNG0_IRQHandler +I2C0_DriverIRQHandler +I2C1_DriverIRQHandler +SPI0_DriverIRQHandler +SPI1_DriverIRQHandler +I2S0_Tx_DriverIRQHandler +I2S0_Rx_DriverIRQHandler +LPUART0_DriverIRQHandler +LPUART1_DriverIRQHandler +LPUART2_DriverIRQHandler +LPUART3_DriverIRQHandler +LPUART4_DriverIRQHandler +Reserved51_IRQHandler +Reserved52_IRQHandler +EMVSIM0_IRQHandler +EMVSIM1_IRQHandler +ADC0_IRQHandler +CMP0_IRQHandler +CMP1_IRQHandler +FTM0_IRQHandler +FTM1_IRQHandler +FTM2_IRQHandler +CMT_IRQHandler +RTC_IRQHandler +RTC_Seconds_IRQHandler +PIT0CH0_IRQHandler +PIT0CH1_IRQHandler +PIT0CH2_IRQHandler +PIT0CH3_IRQHandler +PDB0_IRQHandler +USB0_IRQHandler +USBDCD_IRQHandler +Reserved71_IRQHandler +DAC0_IRQHandler +MCG_IRQHandler +LPTMR0_LPTMR1_IRQHandler +PORTA_IRQHandler +PORTB_IRQHandler +PORTC_IRQHandler +PORTD_IRQHandler +PORTE_IRQHandler +SWI_IRQHandler +SPI2_DriverIRQHandler +Reserved82_IRQHandler +Reserved83_IRQHandler +Reserved84_IRQHandler +Reserved85_IRQHandler +FLEXIO0_DriverIRQHandler +FTM3_IRQHandler +Reserved88_IRQHandler +Reserved89_IRQHandler +I2C2_DriverIRQHandler +Reserved91_IRQHandler +Reserved92_IRQHandler +Reserved93_IRQHandler +Reserved94_IRQHandler +Reserved95_IRQHandler +Reserved96_IRQHandler +SDHC_DriverIRQHandler +Reserved98_IRQHandler +Reserved99_IRQHandler +Reserved100_IRQHandler +Reserved101_IRQHandler +Reserved102_IRQHandler +TSI0_IRQHandler +TPM1_IRQHandler +TPM2_IRQHandler +Reserved106_IRQHandler +I2C3_DriverIRQHandler +Reserved108_IRQHandler +Reserved109_IRQHandler +Reserved110_IRQHandler +Reserved111_IRQHandler +Reserved112_IRQHandler +Reserved113_IRQHandler +Reserved114_IRQHandler +Reserved115_IRQHandler +QuadSPI0_DriverIRQHandler +Reserved117_IRQHandler +Reserved118_IRQHandler +Reserved119_IRQHandler +LTC0_IRQHandler +Reserved121_IRQHandler +Reserved122_IRQHandler +DefaultISR + B DefaultISR + + END diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/cmsis.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/cmsis.h new file mode 100644 index 00000000000..7423a125ba6 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/cmsis.h @@ -0,0 +1,13 @@ +/* mbed Microcontroller Library - CMSIS + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * A generic CMSIS include header, pulling in LPC11U24 specifics + */ + +#ifndef MBED_CMSIS_H +#define MBED_CMSIS_H + +#include "fsl_device_registers.h" +#include "cmsis_nvic.h" + +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/cmsis_nvic.c new file mode 100644 index 00000000000..f3468ce0d09 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/cmsis_nvic.c @@ -0,0 +1,42 @@ +/* mbed Microcontroller Library + * CMSIS-style functionality to support dynamic vectors + ******************************************************************************* + * Copyright (c) 2011 ARM Limited. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of ARM Limited nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis_nvic.h" + +extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); + +void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { + InstallIRQHandler(IRQn, vector); +} + +uint32_t __NVIC_GetVector(IRQn_Type IRQn) { + uint32_t *vectors = (uint32_t*)SCB->VTOR; + return vectors[IRQn + 16]; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/cmsis_nvic.h new file mode 100644 index 00000000000..5b794a1cf11 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/cmsis_nvic.h @@ -0,0 +1,51 @@ +/* mbed Microcontroller Library + * CMSIS-style functionality to support dynamic vectors + ******************************************************************************* + * Copyright (c) 2011 ARM Limited. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of ARM Limited nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +#define NVIC_NUM_VECTORS (16 + 107) // CORE + MCU Peripherals +#define NVIC_USER_IRQ_OFFSET 16 + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t __NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/fsl_device_registers.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/fsl_device_registers.h new file mode 100644 index 00000000000..d764819338f --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/fsl_device_registers.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_DEVICE_REGISTERS_H__ +#define __FSL_DEVICE_REGISTERS_H__ + +/* + * Include the cpu specific register header files. + * + * The CPU macro should be declared in the project or makefile. + */ +#if (defined(CPU_MK82FN256CAx15) || defined(CPU_MK82FN256VDC15) || defined(CPU_MK82FN256VLL15) || \ + defined(CPU_MK82FN256VLQ15)) + +#define K82F25615_SERIES + +/* CMSIS-style register definitions */ +#include "MK82F25615.h" +/* CPU specific feature definitions */ +#include "MK82F25615_features.h" + +#else + #error "No valid CPU defined!" +#endif + +#endif /* __FSL_DEVICE_REGISTERS_H__ */ + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/system_MK82F25615.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/system_MK82F25615.c new file mode 100644 index 00000000000..c70283962bf --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/system_MK82F25615.c @@ -0,0 +1,221 @@ +/* +** ################################################################### +** Processors: MK82FN256CAx15 +** MK82FN256VDC15 +** MK82FN256VLL15 +** MK82FN256VLQ15 +** +** Compilers: Keil ARM C/C++ Compiler +** Freescale C/C++ for Embedded ARM +** GNU C Compiler +** IAR ANSI C/C++ Compiler for ARM +** +** Reference manual: K82P121M150SF5RM, Rev. 0, May 2015 +** Version: rev. 1.2, 2015-07-29 +** Build: b151216 +** +** Abstract: +** Provides a system configuration function and a global variable that +** contains the system frequency. It configures the device and initializes +** the oscillator (PLL) that is part of the microcontroller device. +** +** Copyright (c) 2015 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** Revisions: +** - rev. 1.0 (2015-04-09) +** Initial version +** - rev. 1.1 (2015-05-28) +** Update according to the reference manual Rev. 0. +** - rev. 1.2 (2015-07-29) +** Correction of backward compatibility. +** +** ################################################################### +*/ + +/*! + * @file MK82F25615 + * @version 1.2 + * @date 2015-07-29 + * @brief Device specific configuration file for MK82F25615 (implementation file) + * + * Provides a system configuration function and a global variable that contains + * the system frequency. It configures the device and initializes the oscillator + * (PLL) that is part of the microcontroller device. + */ + +#include +#include "fsl_device_registers.h" + + + +/* ---------------------------------------------------------------------------- + -- Core clock + ---------------------------------------------------------------------------- */ + +uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK; + +/* ---------------------------------------------------------------------------- + -- SystemInit() + ---------------------------------------------------------------------------- */ + +void SystemInit (void) { +#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) + SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); /* set CP10, CP11 Full Access */ +#endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */ + +#if (DISABLE_WDOG) + /* WDOG->UNLOCK: WDOGUNLOCK=0xC520 */ + WDOG->UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */ + /* WDOG->UNLOCK: WDOGUNLOCK=0xD928 */ + WDOG->UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928); /* Key 2 */ + /* WDOG->STCTRLH: ?=0,DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,?=0,?=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */ + WDOG->STCTRLH = WDOG_STCTRLH_BYTESEL(0x00) | + WDOG_STCTRLH_WAITEN_MASK | + WDOG_STCTRLH_STOPEN_MASK | + WDOG_STCTRLH_ALLOWUPDATE_MASK | + WDOG_STCTRLH_CLKSRC_MASK | + 0x0100U; +#endif /* (DISABLE_WDOG) */ + +} + +/* ---------------------------------------------------------------------------- + -- SystemCoreClockUpdate() + ---------------------------------------------------------------------------- */ + +void SystemCoreClockUpdate (void) { + + uint32_t MCGOUTClock; /* Variable to store output clock frequency of the MCG module */ + uint16_t Divider; + + if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x00U) { + /* Output of FLL or PLL is selected */ + if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U) { + /* FLL is selected */ + if ((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U) { + /* External reference clock is selected */ + switch (MCG->C7 & MCG_C7_OSCSEL_MASK) { + case 0x00U: + MCGOUTClock = CPU_XTAL_CLK_HZ; /* System oscillator drives MCG clock */ + break; + case 0x01U: + MCGOUTClock = CPU_XTAL32k_CLK_HZ; /* RTC 32 kHz oscillator drives MCG clock */ + break; + case 0x02U: + default: + MCGOUTClock = CPU_INT_IRC_CLK_HZ; /* IRC 48MHz oscillator drives MCG clock */ + break; + } + if (((MCG->C2 & MCG_C2_RANGE_MASK) != 0x00U) && ((MCG->C7 & MCG_C7_OSCSEL_MASK) != 0x01U)) { + switch (MCG->C1 & MCG_C1_FRDIV_MASK) { + case 0x38U: + Divider = 1536U; + break; + case 0x30U: + Divider = 1280U; + break; + default: + Divider = (uint16_t)(32LU << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT)); + break; + } + } else {/* ((MCG->C2 & MCG_C2_RANGE_MASK) != 0x00U) */ + Divider = (uint16_t)(1LU << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT)); + } + MCGOUTClock = (MCGOUTClock / Divider); /* Calculate the divided FLL reference clock */ + } else { /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U)) */ + MCGOUTClock = CPU_INT_SLOW_CLK_HZ; /* The slow internal reference clock is selected */ + } /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U)) */ + /* Select correct multiplier to calculate the MCG output clock */ + switch (MCG->C4 & (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) { + case 0x00U: + MCGOUTClock *= 640U; + break; + case 0x20U: + MCGOUTClock *= 1280U; + break; + case 0x40U: + MCGOUTClock *= 1920U; + break; + case 0x60U: + MCGOUTClock *= 2560U; + break; + case 0x80U: + MCGOUTClock *= 732U; + break; + case 0xA0U: + MCGOUTClock *= 1464U; + break; + case 0xC0U: + MCGOUTClock *= 2197U; + break; + case 0xE0U: + MCGOUTClock *= 2929U; + break; + default: + break; + } + } else { /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U)) */ + /* PLL is selected */ + Divider = (((uint16_t)MCG->C5 & MCG_C5_PRDIV_MASK) + 0x01U); + MCGOUTClock = (uint32_t)(CPU_XTAL_CLK_HZ / Divider); /* Calculate the PLL reference clock */ + Divider = (((uint16_t)MCG->C6 & MCG_C6_VDIV_MASK) + 16U); + MCGOUTClock *= Divider; /* Calculate the VCO output clock */ + MCGOUTClock /= 2; /* Calculate the MCG output clock */ + } /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U)) */ + } else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x40U) { + /* Internal reference clock is selected */ + if ((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U) { + MCGOUTClock = CPU_INT_SLOW_CLK_HZ; /* Slow internal reference clock selected */ + } else { /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U)) */ + Divider = (uint16_t)(0x01LU << ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT)); + MCGOUTClock = (uint32_t) (CPU_INT_FAST_CLK_HZ / Divider); /* Fast internal reference clock selected */ + } /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U)) */ + } else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U) { + /* External reference clock is selected */ + switch (MCG->C7 & MCG_C7_OSCSEL_MASK) { + case 0x00U: + MCGOUTClock = CPU_XTAL_CLK_HZ; /* System oscillator drives MCG clock */ + break; + case 0x01U: + MCGOUTClock = CPU_XTAL32k_CLK_HZ; /* RTC 32 kHz oscillator drives MCG clock */ + break; + case 0x02U: + default: + MCGOUTClock = CPU_INT_IRC_CLK_HZ; /* IRC 48MHz oscillator drives MCG clock */ + break; + } + } else { /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U)) */ + /* Reserved value */ + return; + } /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U)) */ + SystemCoreClock = (MCGOUTClock / (0x01U + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT))); +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/system_MK82F25615.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/system_MK82F25615.h new file mode 100644 index 00000000000..ef5372b7b5a --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/device/system_MK82F25615.h @@ -0,0 +1,141 @@ +/* +** ################################################################### +** Processors: MK82FN256CAx15 +** MK82FN256VDC15 +** MK82FN256VLL15 +** MK82FN256VLQ15 +** +** Compilers: Keil ARM C/C++ Compiler +** Freescale C/C++ for Embedded ARM +** GNU C Compiler +** IAR ANSI C/C++ Compiler for ARM +** +** Reference manual: K82P121M150SF5RM, Rev. 0, May 2015 +** Version: rev. 1.2, 2015-07-29 +** Build: b151216 +** +** Abstract: +** Provides a system configuration function and a global variable that +** contains the system frequency. It configures the device and initializes +** the oscillator (PLL) that is part of the microcontroller device. +** +** Copyright (c) 2015 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** Revisions: +** - rev. 1.0 (2015-04-09) +** Initial version +** - rev. 1.1 (2015-05-28) +** Update according to the reference manual Rev. 0. +** - rev. 1.2 (2015-07-29) +** Correction of backward compatibility. +** +** ################################################################### +*/ + +/*! + * @file MK82F25615 + * @version 1.2 + * @date 2015-07-29 + * @brief Device specific configuration file for MK82F25615 (header file) + * + * Provides a system configuration function and a global variable that contains + * the system frequency. It configures the device and initializes the oscillator + * (PLL) that is part of the microcontroller device. + */ + +#ifndef _SYSTEM_MK82F25615_H_ +#define _SYSTEM_MK82F25615_H_ /**< Symbol preventing repeated inclusion */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +#ifndef DISABLE_WDOG + #define DISABLE_WDOG 1 +#endif + +/* Define clock source values */ + +#define CPU_XTAL_CLK_HZ 12000000U /* Value of the external crystal or oscillator clock frequency of the system oscillator (OSC) in Hz */ +#define CPU_XTAL32k_CLK_HZ 32768U /* Value of the external 32k crystal or oscillator clock frequency of the RTC in Hz */ +#define CPU_INT_SLOW_CLK_HZ 32768U /* Value of the slow internal oscillator clock frequency in Hz */ +#define CPU_INT_FAST_CLK_HZ 4000000U /* Value of the fast internal oscillator clock frequency in Hz */ +#define CPU_INT_IRC_CLK_HZ 48000000U /* Value of the 48M internal oscillator clock frequency in Hz */ + +/* RTC oscillator setting */ +/* RTC_CR: SC2P=0,SC4P=0,SC8P=0,SC16P=0,CLKO=1,OSCE=1,WPS=0,UM=0,SUP=0,WPE=0,SWR=0 */ +#define SYSTEM_RTC_CR_VALUE 0x0300U /* RTC_CR */ + +/* Low power mode enable */ +/* SMC_PMPROT: AHSRUN=1,AVLP=1,ALLS=1,AVLLS=1 */ +#define SYSTEM_SMC_PMPROT_VALUE 0xAAU /* SMC_PMPROT */ + +#define DEFAULT_SYSTEM_CLOCK 20971520u + + +/** + * @brief System clock frequency (core clock) + * + * The system clock frequency supplied to the SysTick timer and the processor + * core clock. This variable can be used by the user application to setup the + * SysTick timer or configure other parameters. It may also be used by debugger to + * query the frequency of the debug timer or configure the trace clock speed + * SystemCoreClock is initialized with a correct predefined value. + */ +extern uint32_t SystemCoreClock; + +/** + * @brief Setup the microcontroller system. + * + * Typically this function configures the oscillator (PLL) that is part of the + * microcontroller device. For systems with variable clock speed it also updates + * the variable SystemCoreClock. SystemInit is called from startup_device file. + */ +void SystemInit (void); + +/** + * @brief Updates the SystemCoreClock variable. + * + * It must be called whenever the core clock is changed during program + * execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates + * the current core clock. + */ +void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYSTEM_MK82F25615_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_adc16.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_adc16.c new file mode 100644 index 00000000000..db5b03c2084 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_adc16.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_adc16.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get instance number for ADC16 module. + * + * @param base ADC16 peripheral base address + */ +static uint32_t ADC16_GetInstance(ADC_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to ADC16 bases for each instance. */ +static ADC_Type *const s_adc16Bases[] = ADC_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to ADC16 clocks for each instance. */ +static const clock_ip_name_t s_adc16Clocks[] = ADC16_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t ADC16_GetInstance(ADC_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_ADC16_COUNT; instance++) + { + if (s_adc16Bases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_ADC16_COUNT); + + return instance; +} + +void ADC16_Init(ADC_Type *base, const adc16_config_t *config) +{ + assert(NULL != config); + + uint32_t tmp32; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the clock. */ + CLOCK_EnableClock(s_adc16Clocks[ADC16_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* ADCx_CFG1. */ + tmp32 = ADC_CFG1_ADICLK(config->clockSource) | ADC_CFG1_MODE(config->resolution); + if (kADC16_LongSampleDisabled != config->longSampleMode) + { + tmp32 |= ADC_CFG1_ADLSMP_MASK; + } + tmp32 |= ADC_CFG1_ADIV(config->clockDivider); + if (config->enableLowPower) + { + tmp32 |= ADC_CFG1_ADLPC_MASK; + } + base->CFG1 = tmp32; + + /* ADCx_CFG2. */ + tmp32 = base->CFG2 & ~(ADC_CFG2_ADACKEN_MASK | ADC_CFG2_ADHSC_MASK | ADC_CFG2_ADLSTS_MASK); + if (kADC16_LongSampleDisabled != config->longSampleMode) + { + tmp32 |= ADC_CFG2_ADLSTS(config->longSampleMode); + } + if (config->enableHighSpeed) + { + tmp32 |= ADC_CFG2_ADHSC_MASK; + } + if (config->enableAsynchronousClock) + { + tmp32 |= ADC_CFG2_ADACKEN_MASK; + } + base->CFG2 = tmp32; + + /* ADCx_SC2. */ + tmp32 = base->SC2 & ~(ADC_SC2_REFSEL_MASK); + tmp32 |= ADC_SC2_REFSEL(config->referenceVoltageSource); + base->SC2 = tmp32; + + /* ADCx_SC3. */ + if (config->enableContinuousConversion) + { + base->SC3 |= ADC_SC3_ADCO_MASK; + } + else + { + base->SC3 &= ~ADC_SC3_ADCO_MASK; + } +} + +void ADC16_Deinit(ADC_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable the clock. */ + CLOCK_DisableClock(s_adc16Clocks[ADC16_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void ADC16_GetDefaultConfig(adc16_config_t *config) +{ + assert(NULL != config); + + config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; + config->clockSource = kADC16_ClockSourceAsynchronousClock; + config->enableAsynchronousClock = true; + config->clockDivider = kADC16_ClockDivider8; + config->resolution = kADC16_ResolutionSE12Bit; + config->longSampleMode = kADC16_LongSampleDisabled; + config->enableHighSpeed = false; + config->enableLowPower = false; + config->enableContinuousConversion = false; +} + +#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION +status_t ADC16_DoAutoCalibration(ADC_Type *base) +{ + bool bHWTrigger = false; + volatile uint32_t tmp32; /* 'volatile' here is for the dummy read of ADCx_R[0] register. */ + status_t status = kStatus_Success; + + /* The calibration would be failed when in hardwar mode. + * Remember the hardware trigger state here and restore it later if the hardware trigger is enabled.*/ + if (0U != (ADC_SC2_ADTRG_MASK & base->SC2)) + { + bHWTrigger = true; + base->SC2 &= ~ADC_SC2_ADTRG_MASK; + } + + /* Clear the CALF and launch the calibration. */ + base->SC3 |= ADC_SC3_CAL_MASK | ADC_SC3_CALF_MASK; + while (0U == (kADC16_ChannelConversionDoneFlag & ADC16_GetChannelStatusFlags(base, 0U))) + { + /* Check the CALF when the calibration is active. */ + if (0U != (kADC16_CalibrationFailedFlag & ADC16_GetStatusFlags(base))) + { + status = kStatus_Fail; + break; + } + } + tmp32 = base->R[0]; /* Dummy read to clear COCO caused by calibration. */ + + /* Restore the hardware trigger setting if it was enabled before. */ + if (bHWTrigger) + { + base->SC2 |= ADC_SC2_ADTRG_MASK; + } + /* Check the CALF at the end of calibration. */ + if (0U != (kADC16_CalibrationFailedFlag & ADC16_GetStatusFlags(base))) + { + status = kStatus_Fail; + } + if (kStatus_Success != status) /* Check if the calibration process is succeed. */ + { + return status; + } + + /* Calculate the calibration values. */ + tmp32 = base->CLP0 + base->CLP1 + base->CLP2 + base->CLP3 + base->CLP4 + base->CLPS; + tmp32 = 0x8000U | (tmp32 >> 1U); + base->PG = tmp32; + +#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE + tmp32 = base->CLM0 + base->CLM1 + base->CLM2 + base->CLM3 + base->CLM4 + base->CLMS; + tmp32 = 0x8000U | (tmp32 >> 1U); + base->MG = tmp32; +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ + + return kStatus_Success; +} +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ + +#if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT +void ADC16_SetChannelMuxMode(ADC_Type *base, adc16_channel_mux_mode_t mode) +{ + if (kADC16_ChannelMuxA == mode) + { + base->CFG2 &= ~ADC_CFG2_MUXSEL_MASK; + } + else /* kADC16_ChannelMuxB. */ + { + base->CFG2 |= ADC_CFG2_MUXSEL_MASK; + } +} +#endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */ + +void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config) +{ + uint32_t tmp32 = base->SC2 & ~(ADC_SC2_ACFE_MASK | ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK); + + if (!config) /* Pass "NULL" to disable the feature. */ + { + base->SC2 = tmp32; + return; + } + /* Enable the feature. */ + tmp32 |= ADC_SC2_ACFE_MASK; + + /* Select the hardware compare working mode. */ + switch (config->hardwareCompareMode) + { + case kADC16_HardwareCompareMode0: + break; + case kADC16_HardwareCompareMode1: + tmp32 |= ADC_SC2_ACFGT_MASK; + break; + case kADC16_HardwareCompareMode2: + tmp32 |= ADC_SC2_ACREN_MASK; + break; + case kADC16_HardwareCompareMode3: + tmp32 |= ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK; + break; + default: + break; + } + base->SC2 = tmp32; + + /* Load the compare values. */ + base->CV1 = ADC_CV1_CV(config->value1); + base->CV2 = ADC_CV2_CV(config->value2); +} + +#if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE +void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode) +{ + uint32_t tmp32 = base->SC3 & ~(ADC_SC3_AVGE_MASK | ADC_SC3_AVGS_MASK); + + if (kADC16_HardwareAverageDisabled != mode) + { + tmp32 |= ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(mode); + } + base->SC3 = tmp32; +} +#endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ + +#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA +void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config) +{ + uint32_t tmp32; + + if (!config) /* Passing "NULL" is to disable the feature. */ + { + base->PGA = 0U; + return; + } + + /* Enable the PGA and set the gain value. */ + tmp32 = ADC_PGA_PGAEN_MASK | ADC_PGA_PGAG(config->pgaGain); + + /* Configure the misc features for PGA. */ + if (config->enableRunInNormalMode) + { + tmp32 |= ADC_PGA_PGALPb_MASK; + } +#if defined(FSL_FEATURE_ADC16_HAS_PGA_CHOPPING) && FSL_FEATURE_ADC16_HAS_PGA_CHOPPING + if (config->disablePgaChopping) + { + tmp32 |= ADC_PGA_PGACHPb_MASK; + } +#endif /* FSL_FEATURE_ADC16_HAS_PGA_CHOPPING */ +#if defined(FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT) && FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT + if (config->enableRunInOffsetMeasurement) + { + tmp32 |= ADC_PGA_PGAOFSM_MASK; + } +#endif /* FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT */ + base->PGA = tmp32; +} +#endif /* FSL_FEATURE_ADC16_HAS_PGA */ + +uint32_t ADC16_GetStatusFlags(ADC_Type *base) +{ + uint32_t ret = 0; + + if (0U != (base->SC2 & ADC_SC2_ADACT_MASK)) + { + ret |= kADC16_ActiveFlag; + } +#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION + if (0U != (base->SC3 & ADC_SC3_CALF_MASK)) + { + ret |= kADC16_CalibrationFailedFlag; + } +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ + return ret; +} + +void ADC16_ClearStatusFlags(ADC_Type *base, uint32_t mask) +{ +#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION + if (0U != (mask & kADC16_CalibrationFailedFlag)) + { + base->SC3 |= ADC_SC3_CALF_MASK; + } +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ +} + +void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config) +{ + assert(channelGroup < ADC_SC1_COUNT); + assert(NULL != config); + + uint32_t sc1 = ADC_SC1_ADCH(config->channelNumber); /* Set the channel number. */ + +#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE + /* Enable the differential conversion. */ + if (config->enableDifferentialConversion) + { + sc1 |= ADC_SC1_DIFF_MASK; + } +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ + /* Enable the interrupt when the conversion is done. */ + if (config->enableInterruptOnConversionCompleted) + { + sc1 |= ADC_SC1_AIEN_MASK; + } + base->SC1[channelGroup] = sc1; +} + +uint32_t ADC16_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup) +{ + assert(channelGroup < ADC_SC1_COUNT); + + uint32_t ret = 0U; + + if (0U != (base->SC1[channelGroup] & ADC_SC1_COCO_MASK)) + { + ret |= kADC16_ChannelConversionDoneFlag; + } + return ret; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_adc16.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_adc16.h new file mode 100644 index 00000000000..166e0a5f680 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_adc16.h @@ -0,0 +1,525 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_ADC16_H_ +#define _FSL_ADC16_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup adc16 + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief ADC16 driver version 2.0.0. */ +#define FSL_ADC16_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! + * @brief Channel status flags. + */ +enum _adc16_channel_status_flags +{ + kADC16_ChannelConversionDoneFlag = ADC_SC1_COCO_MASK, /*!< Conversion done. */ +}; + +/*! + * @brief Converter status flags. + */ +enum _adc16_status_flags +{ + kADC16_ActiveFlag = ADC_SC2_ADACT_MASK, /*!< Converter is active. */ +#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION + kADC16_CalibrationFailedFlag = ADC_SC3_CALF_MASK, /*!< Calibration is failed. */ +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ +}; + +#if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT +/*! + * @brief Channel multiplexer mode for each channel. + * + * For some ADC16 channels, there are two pin selections in channel multiplexer. For example, ADC0_SE4a and ADC0_SE4b + * are the different channels that share the same channel number. + */ +typedef enum _adc_channel_mux_mode +{ + kADC16_ChannelMuxA = 0U, /*!< For channel with channel mux a. */ + kADC16_ChannelMuxB = 1U, /*!< For channel with channel mux b. */ +} adc16_channel_mux_mode_t; +#endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */ + +/*! + * @brief Clock divider for the converter. + */ +typedef enum _adc16_clock_divider +{ + kADC16_ClockDivider1 = 0U, /*!< For divider 1 from the input clock to the module. */ + kADC16_ClockDivider2 = 1U, /*!< For divider 2 from the input clock to the module. */ + kADC16_ClockDivider4 = 2U, /*!< For divider 4 from the input clock to the module. */ + kADC16_ClockDivider8 = 3U, /*!< For divider 8 from the input clock to the module. */ +} adc16_clock_divider_t; + +/*! + *@brief Converter's resolution. + */ +typedef enum _adc16_resolution +{ + /* This group of enumeration is for internal use which is related to register setting. */ + kADC16_Resolution8or9Bit = 0U, /*!< Single End 8-bit or Differential Sample 9-bit. */ + kADC16_Resolution12or13Bit = 1U, /*!< Single End 12-bit or Differential Sample 13-bit. */ + kADC16_Resolution10or11Bit = 2U, /*!< Single End 10-bit or Differential Sample 11-bit. */ + + /* This group of enumeration is for a public user. */ + kADC16_ResolutionSE8Bit = kADC16_Resolution8or9Bit, /*!< Single End 8-bit. */ + kADC16_ResolutionSE12Bit = kADC16_Resolution12or13Bit, /*!< Single End 12-bit. */ + kADC16_ResolutionSE10Bit = kADC16_Resolution10or11Bit, /*!< Single End 10-bit. */ +#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE + kADC16_ResolutionDF9Bit = kADC16_Resolution8or9Bit, /*!< Differential Sample 9-bit. */ + kADC16_ResolutionDF13Bit = kADC16_Resolution12or13Bit, /*!< Differential Sample 13-bit. */ + kADC16_ResolutionDF11Bit = kADC16_Resolution10or11Bit, /*!< Differential Sample 11-bit. */ +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ + +#if defined(FSL_FEATURE_ADC16_MAX_RESOLUTION) && (FSL_FEATURE_ADC16_MAX_RESOLUTION >= 16U) + /* 16-bit is supported by default. */ + kADC16_Resolution16Bit = 3U, /*!< Single End 16-bit or Differential Sample 16-bit. */ + kADC16_ResolutionSE16Bit = kADC16_Resolution16Bit, /*!< Single End 16-bit. */ +#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE + kADC16_ResolutionDF16Bit = kADC16_Resolution16Bit, /*!< Differential Sample 16-bit. */ +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ +#endif /* FSL_FEATURE_ADC16_MAX_RESOLUTION >= 16U */ +} adc16_resolution_t; + +/*! + * @brief Clock source. + */ +typedef enum _adc16_clock_source +{ + kADC16_ClockSourceAlt0 = 0U, /*!< Selection 0 of the clock source. */ + kADC16_ClockSourceAlt1 = 1U, /*!< Selection 1 of the clock source. */ + kADC16_ClockSourceAlt2 = 2U, /*!< Selection 2 of the clock source. */ + kADC16_ClockSourceAlt3 = 3U, /*!< Selection 3 of the clock source. */ + + /* Chip defined clock source */ + kADC16_ClockSourceAsynchronousClock = kADC16_ClockSourceAlt3, /*!< Using internal asynchronous clock. */ +} adc16_clock_source_t; + +/*! + * @brief Long sample mode. + */ +typedef enum _adc16_long_sample_mode +{ + kADC16_LongSampleCycle24 = 0U, /*!< 20 extra ADCK cycles, 24 ADCK cycles total. */ + kADC16_LongSampleCycle16 = 1U, /*!< 12 extra ADCK cycles, 16 ADCK cycles total. */ + kADC16_LongSampleCycle10 = 2U, /*!< 6 extra ADCK cycles, 10 ADCK cycles total. */ + kADC16_LongSampleCycle6 = 3U, /*!< 2 extra ADCK cycles, 6 ADCK cycles total. */ + kADC16_LongSampleDisabled = 4U, /*!< Disable the long sample feature. */ +} adc16_long_sample_mode_t; + +/*! + * @brief Reference voltage source. + */ +typedef enum _adc16_reference_voltage_source +{ + kADC16_ReferenceVoltageSourceVref = 0U, /*!< For external pins pair of VrefH and VrefL. */ + kADC16_ReferenceVoltageSourceValt = 1U, /*!< For alternate reference pair of ValtH and ValtL. */ +} adc16_reference_voltage_source_t; + +#if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE +/*! + * @brief Hardware average mode. + */ +typedef enum _adc16_hardware_average_mode +{ + kADC16_HardwareAverageCount4 = 0U, /*!< For hardware average with 4 samples. */ + kADC16_HardwareAverageCount8 = 1U, /*!< For hardware average with 8 samples. */ + kADC16_HardwareAverageCount16 = 2U, /*!< For hardware average with 16 samples. */ + kADC16_HardwareAverageCount32 = 3U, /*!< For hardware average with 32 samples. */ + kADC16_HardwareAverageDisabled = 4U, /*!< Disable the hardware average feature.*/ +} adc16_hardware_average_mode_t; +#endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ + +/*! + * @brief Hardware compare mode. + */ +typedef enum _adc16_hardware_compare_mode +{ + kADC16_HardwareCompareMode0 = 0U, /*!< x < value1. */ + kADC16_HardwareCompareMode1 = 1U, /*!< x > value1. */ + kADC16_HardwareCompareMode2 = 2U, /*!< if value1 <= value2, then x < value1 || x > value2; + else, value1 > x > value2. */ + kADC16_HardwareCompareMode3 = 3U, /*!< if value1 <= value2, then value1 <= x <= value2; + else x >= value1 || x <= value2. */ +} adc16_hardware_compare_mode_t; + +#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA +/*! + * @brief PGA's Gain mode. + */ +typedef enum _adc16_pga_gain +{ + kADC16_PGAGainValueOf1 = 0U, /*!< For amplifier gain of 1. */ + kADC16_PGAGainValueOf2 = 1U, /*!< For amplifier gain of 2. */ + kADC16_PGAGainValueOf4 = 2U, /*!< For amplifier gain of 4. */ + kADC16_PGAGainValueOf8 = 3U, /*!< For amplifier gain of 8. */ + kADC16_PGAGainValueOf16 = 4U, /*!< For amplifier gain of 16. */ + kADC16_PGAGainValueOf32 = 5U, /*!< For amplifier gain of 32. */ + kADC16_PGAGainValueOf64 = 6U, /*!< For amplifier gain of 64. */ +} adc16_pga_gain_t; +#endif /* FSL_FEATURE_ADC16_HAS_PGA */ + +/*! + * @brief ADC16 converter configuration. + */ +typedef struct _adc16_config +{ + adc16_reference_voltage_source_t referenceVoltageSource; /*!< Select the reference voltage source. */ + adc16_clock_source_t clockSource; /*!< Select the input clock source to converter. */ + bool enableAsynchronousClock; /*!< Enable the asynchronous clock output. */ + adc16_clock_divider_t clockDivider; /*!< Select the divider of input clock source. */ + adc16_resolution_t resolution; /*!< Select the sample resolution mode. */ + adc16_long_sample_mode_t longSampleMode; /*!< Select the long sample mode. */ + bool enableHighSpeed; /*!< Enable the high-speed mode. */ + bool enableLowPower; /*!< Enable low power. */ + bool enableContinuousConversion; /*!< Enable continuous conversion mode. */ +} adc16_config_t; + +/*! + * @brief ADC16 Hardware comparison configuration. + */ +typedef struct _adc16_hardware_compare_config +{ + adc16_hardware_compare_mode_t hardwareCompareMode; /*!< Select the hardware compare mode. + See "adc16_hardware_compare_mode_t". */ + int16_t value1; /*!< Setting value1 for hardware compare mode. */ + int16_t value2; /*!< Setting value2 for hardware compare mode. */ +} adc16_hardware_compare_config_t; + +/*! + * @brief ADC16 channel conversion configuration. + */ +typedef struct _adc16_channel_config +{ + uint32_t channelNumber; /*!< Setting the conversion channel number. The available range is 0-31. + See channel connection information for each chip in Reference + Manual document. */ + bool enableInterruptOnConversionCompleted; /*!< Generate an interrupt request once the conversion is completed. */ +#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE + bool enableDifferentialConversion; /*!< Using Differential sample mode. */ +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ +} adc16_channel_config_t; + +#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA +/*! + * @brief ADC16 programmable gain amplifier configuration. + */ +typedef struct _adc16_pga_config +{ + adc16_pga_gain_t pgaGain; /*!< Setting PGA gain. */ + bool enableRunInNormalMode; /*!< Enable PGA working in normal mode, or low power mode by default. */ +#if defined(FSL_FEATURE_ADC16_HAS_PGA_CHOPPING) && FSL_FEATURE_ADC16_HAS_PGA_CHOPPING + bool disablePgaChopping; /*!< Disable the PGA chopping function. + The PGA employs chopping to remove/reduce offset and 1/f noise and offers + an offset measurement configuration that aids the offset calibration. */ +#endif /* FSL_FEATURE_ADC16_HAS_PGA_CHOPPING */ +#if defined(FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT) && FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT + bool enableRunInOffsetMeasurement; /*!< Enable the PGA working in offset measurement mode. + When this feature is enabled, the PGA disconnects itself from the external + inputs and auto-configures into offset measurement mode. With this field + set, run the ADC in the recommended settings and enable the maximum hardware + averaging to get the PGA offset number. The output is the + (PGA offset * (64+1)) for the given PGA setting. */ +#endif /* FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT */ +} adc16_pga_config_t; +#endif /* FSL_FEATURE_ADC16_HAS_PGA */ + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @name Initialization + * @{ + */ + +/*! + * @brief Initializes the ADC16 module. + * + * @param base ADC16 peripheral base address. + * @param config Pointer to configuration structure. See "adc16_config_t". + */ +void ADC16_Init(ADC_Type *base, const adc16_config_t *config); + +/*! + * @brief De-initializes the ADC16 module. + * + * @param base ADC16 peripheral base address. + */ +void ADC16_Deinit(ADC_Type *base); + +/*! + * @brief Gets an available pre-defined settings for the converter's configuration. + * + * This function initializes the converter configuration structure with available settings. The default values are as follows. + * @code + * config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; + * config->clockSource = kADC16_ClockSourceAsynchronousClock; + * config->enableAsynchronousClock = true; + * config->clockDivider = kADC16_ClockDivider8; + * config->resolution = kADC16_ResolutionSE12Bit; + * config->longSampleMode = kADC16_LongSampleDisabled; + * config->enableHighSpeed = false; + * config->enableLowPower = false; + * config->enableContinuousConversion = false; + * @endcode + * @param config Pointer to the configuration structure. + */ +void ADC16_GetDefaultConfig(adc16_config_t *config); + +#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION +/*! + * @brief Automates the hardware calibration. + * + * This auto calibration helps to adjust the plus/minus side gain automatically. + * Execute the calibration before using the converter. Note that the hardware trigger should be used + * during the calibration. + * + * @param base ADC16 peripheral base address. + * + * @return Execution status. + * @retval kStatus_Success Calibration is done successfully. + * @retval kStatus_Fail Calibration has failed. + */ +status_t ADC16_DoAutoCalibration(ADC_Type *base); +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ + +#if defined(FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION) && FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION +/*! + * @brief Sets the offset value for the conversion result. + * + * This offset value takes effect on the conversion result. If the offset value is not zero, the reading result + * is subtracted by it. Note, the hardware calibration fills the offset value automatically. + * + * @param base ADC16 peripheral base address. + * @param value Setting offset value. + */ +static inline void ADC16_SetOffsetValue(ADC_Type *base, int16_t value) +{ + base->OFS = (uint32_t)(value); +} +#endif /* FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION */ + +/* @} */ + +/*! + * @name Advanced Features + * @{ + */ + +#if defined(FSL_FEATURE_ADC16_HAS_DMA) && FSL_FEATURE_ADC16_HAS_DMA +/*! + * @brief Enables generating the DMA trigger when the conversion is complete. + * + * @param base ADC16 peripheral base address. + * @param enable Switcher of the DMA feature. "true" means enabled, "false" means not enabled. + */ +static inline void ADC16_EnableDMA(ADC_Type *base, bool enable) +{ + if (enable) + { + base->SC2 |= ADC_SC2_DMAEN_MASK; + } + else + { + base->SC2 &= ~ADC_SC2_DMAEN_MASK; + } +} +#endif /* FSL_FEATURE_ADC16_HAS_DMA */ + +/*! + * @brief Enables the hardware trigger mode. + * + * @param base ADC16 peripheral base address. + * @param enable Switcher of the hardware trigger feature. "true" means enabled, "false" means not enabled. + */ +static inline void ADC16_EnableHardwareTrigger(ADC_Type *base, bool enable) +{ + if (enable) + { + base->SC2 |= ADC_SC2_ADTRG_MASK; + } + else + { + base->SC2 &= ~ADC_SC2_ADTRG_MASK; + } +} + +#if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT +/*! + * @brief Sets the channel mux mode. + * + * Some sample pins share the same channel index. The channel mux mode decides which pin is used for an + * indicated channel. + * + * @param base ADC16 peripheral base address. + * @param mode Setting channel mux mode. See "adc16_channel_mux_mode_t". + */ +void ADC16_SetChannelMuxMode(ADC_Type *base, adc16_channel_mux_mode_t mode); +#endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */ + +/*! + * @brief Configures the hardware compare mode. + * + * The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the result + * in the compare range is available. To compare the range, see "adc16_hardware_compare_mode_t" or the appopriate reference + * manual for more information. + * + * @param base ADC16 peripheral base address. + * @param config Pointer to the "adc16_hardware_compare_config_t" structure. Passing "NULL" disables the feature. + */ +void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config); + +#if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE +/*! + * @brief Sets the hardware average mode. + * + * The hardware average mode provides a way to process the conversion result automatically by using hardware. The multiple + * conversion results are accumulated and averaged internally making them easier to read. + * + * @param base ADC16 peripheral base address. + * @param mode Setting the hardware average mode. See "adc16_hardware_average_mode_t". + */ +void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode); +#endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ + +#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA +/*! + * @brief Configures the PGA for the converter's front end. + * + * @param base ADC16 peripheral base address. + * @param config Pointer to the "adc16_pga_config_t" structure. Passing "NULL" disables the feature. + */ +void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config); +#endif /* FSL_FEATURE_ADC16_HAS_PGA */ + +/*! + * @brief Gets the status flags of the converter. + * + * @param base ADC16 peripheral base address. + * + * @return Flags' mask if indicated flags are asserted. See "_adc16_status_flags". + */ +uint32_t ADC16_GetStatusFlags(ADC_Type *base); + +/*! + * @brief Clears the status flags of the converter. + * + * @param base ADC16 peripheral base address. + * @param mask Mask value for the cleared flags. See "_adc16_status_flags". + */ +void ADC16_ClearStatusFlags(ADC_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name Conversion Channel + * @{ + */ + +/*! + * @brief Configures the conversion channel. + * + * This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API + * configures the channel while the external trigger source helps to trigger the conversion. + * + * Note that the "Channel Group" has a detailed description. + * To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one + * group of status and control registers, one for each conversion. The channel group parameter indicates which group of + * registers are used, for example, channel group 0 is for Group A registers and channel group 1 is for Group B registers. The + * channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of + * the channel groups is actively controlling ADC conversions. The channel group 0 is used for both software and hardware + * trigger modes. Channel group 1 and greater indicates multiple channel group registers for + * use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual for the + * number of SC1n registers (channel groups) specific to this device. Channel group 1 or greater are not used + * for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion. + * Updating the channel group 0 while a different channel group is actively controlling a conversion is allowed and + * vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a + * conversion aborts the current conversion. + * + * @param base ADC16 peripheral base address. + * @param channelGroup Channel group index. + * @param config Pointer to the "adc16_channel_config_t" structure for the conversion channel. + */ +void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config); + +/*! + * @brief Gets the conversion value. + * + * @param base ADC16 peripheral base address. + * @param channelGroup Channel group index. + * + * @return Conversion value. + */ +static inline uint32_t ADC16_GetChannelConversionValue(ADC_Type *base, uint32_t channelGroup) +{ + assert(channelGroup < ADC_R_COUNT); + + return base->R[channelGroup]; +} + +/*! + * @brief Gets the status flags of channel. + * + * @param base ADC16 peripheral base address. + * @param channelGroup Channel group index. + * + * @return Flags' mask if indicated flags are asserted. See "_adc16_channel_status_flags". + */ +uint32_t ADC16_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup); + +/* @} */ + +#if defined(__cplusplus) +} +#endif +/*! + * @} + */ +#endif /* _FSL_ADC16_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_clock.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_clock.c new file mode 100644 index 00000000000..b70bff9fb37 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_clock.c @@ -0,0 +1,1797 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_clock.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Macro definition remap workaround. */ +#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) +#define MCG_C2_EREFS0_MASK MCG_C2_EREFS_MASK +#endif +#if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK))) +#define MCG_C2_HGO0_MASK MCG_C2_HGO_MASK +#endif +#if (defined(MCG_C2_RANGE_MASK) && !(defined(MCG_C2_RANGE0_MASK))) +#define MCG_C2_RANGE0_MASK MCG_C2_RANGE_MASK +#endif +#if (defined(MCG_C6_CME_MASK) && !(defined(MCG_C6_CME0_MASK))) +#define MCG_C6_CME0_MASK MCG_C6_CME_MASK +#endif + +/* PLL fixed multiplier when there is not PRDIV and VDIV. */ +#define PLL_FIXED_MULT (375U) +/* Max frequency of the reference clock used for internal clock trim. */ +#define TRIM_REF_CLK_MIN (8000000U) +/* Min frequency of the reference clock used for internal clock trim. */ +#define TRIM_REF_CLK_MAX (16000000U) +/* Max trim value of fast internal reference clock. */ +#define TRIM_FIRC_MAX (5000000U) +/* Min trim value of fast internal reference clock. */ +#define TRIM_FIRC_MIN (3000000U) +/* Max trim value of fast internal reference clock. */ +#define TRIM_SIRC_MAX (39063U) +/* Min trim value of fast internal reference clock. */ +#define TRIM_SIRC_MIN (31250U) + +#define MCG_S_IRCST_VAL ((MCG->S & MCG_S_IRCST_MASK) >> MCG_S_IRCST_SHIFT) +#define MCG_S_CLKST_VAL ((MCG->S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) +#define MCG_S_IREFST_VAL ((MCG->S & MCG_S_IREFST_MASK) >> MCG_S_IREFST_SHIFT) +#define MCG_S_PLLST_VAL ((MCG->S & MCG_S_PLLST_MASK) >> MCG_S_PLLST_SHIFT) +#define MCG_C1_FRDIV_VAL ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT) +#define MCG_C2_LP_VAL ((MCG->C2 & MCG_C2_LP_MASK) >> MCG_C2_LP_SHIFT) +#define MCG_C2_RANGE_VAL ((MCG->C2 & MCG_C2_RANGE_MASK) >> MCG_C2_RANGE_SHIFT) +#define MCG_SC_FCRDIV_VAL ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT) +#define MCG_S2_PLLCST_VAL ((MCG->S2 & MCG_S2_PLLCST_MASK) >> MCG_S2_PLLCST_SHIFT) +#define MCG_C7_OSCSEL_VAL ((MCG->C7 & MCG_C7_OSCSEL_MASK) >> MCG_C7_OSCSEL_SHIFT) +#define MCG_C4_DMX32_VAL ((MCG->C4 & MCG_C4_DMX32_MASK) >> MCG_C4_DMX32_SHIFT) +#define MCG_C4_DRST_DRS_VAL ((MCG->C4 & MCG_C4_DRST_DRS_MASK) >> MCG_C4_DRST_DRS_SHIFT) +#define MCG_C7_PLL32KREFSEL_VAL ((MCG->C7 & MCG_C7_PLL32KREFSEL_MASK) >> MCG_C7_PLL32KREFSEL_SHIFT) +#define MCG_C5_PLLREFSEL0_VAL ((MCG->C5 & MCG_C5_PLLREFSEL0_MASK) >> MCG_C5_PLLREFSEL0_SHIFT) +#define MCG_C11_PLLREFSEL1_VAL ((MCG->C11 & MCG_C11_PLLREFSEL1_MASK) >> MCG_C11_PLLREFSEL1_SHIFT) +#define MCG_C11_PRDIV1_VAL ((MCG->C11 & MCG_C11_PRDIV1_MASK) >> MCG_C11_PRDIV1_SHIFT) +#define MCG_C12_VDIV1_VAL ((MCG->C12 & MCG_C12_VDIV1_MASK) >> MCG_C12_VDIV1_SHIFT) +#define MCG_C5_PRDIV0_VAL ((MCG->C5 & MCG_C5_PRDIV0_MASK) >> MCG_C5_PRDIV0_SHIFT) +#define MCG_C6_VDIV0_VAL ((MCG->C6 & MCG_C6_VDIV0_MASK) >> MCG_C6_VDIV0_SHIFT) + +#define OSC_MODE_MASK (MCG_C2_EREFS0_MASK | MCG_C2_HGO0_MASK | MCG_C2_RANGE0_MASK) + +#define SIM_CLKDIV1_OUTDIV1_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT) +#define SIM_CLKDIV1_OUTDIV2_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV2_MASK) >> SIM_CLKDIV1_OUTDIV2_SHIFT) +#define SIM_CLKDIV1_OUTDIV3_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV3_MASK) >> SIM_CLKDIV1_OUTDIV3_SHIFT) +#define SIM_CLKDIV1_OUTDIV4_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) +#define SIM_SOPT1_OSC32KSEL_VAL ((SIM->SOPT1 & SIM_SOPT1_OSC32KSEL_MASK) >> SIM_SOPT1_OSC32KSEL_SHIFT) +#define SIM_SOPT2_PLLFLLSEL_VAL ((SIM->SOPT2 & SIM_SOPT2_PLLFLLSEL_MASK) >> SIM_SOPT2_PLLFLLSEL_SHIFT) +#define SIM_CLKDIV3_PLLFLLDIV_VAL ((SIM->CLKDIV3 & SIM_CLKDIV3_PLLFLLDIV_MASK) >> SIM_CLKDIV3_PLLFLLDIV_SHIFT) +#define SIM_CLKDIV3_PLLFLLFRAC_VAL ((SIM->CLKDIV3 & SIM_CLKDIV3_PLLFLLFRAC_MASK) >> SIM_CLKDIV3_PLLFLLFRAC_SHIFT) + +/* MCG_S_CLKST definition. */ +enum _mcg_clkout_stat +{ + kMCG_ClkOutStatFll, /* FLL. */ + kMCG_ClkOutStatInt, /* Internal clock. */ + kMCG_ClkOutStatExt, /* External clock. */ + kMCG_ClkOutStatPll /* PLL. */ +}; + +/* MCG_S_PLLST definition. */ +enum _mcg_pllst +{ + kMCG_PllstFll, /* FLL is used. */ + kMCG_PllstPll /* PLL is used. */ +}; + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Slow internal reference clock frequency. */ +static uint32_t s_slowIrcFreq = 32768U; +/* Fast internal reference clock frequency. */ +static uint32_t s_fastIrcFreq = 4000000U; + +/* External XTAL0 (OSC0) clock frequency. */ +uint32_t g_xtal0Freq; +/* External XTAL32K clock frequency. */ +uint32_t g_xtal32Freq; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get the MCG external reference clock frequency. + * + * Get the current MCG external reference clock frequency in Hz. It is + * the frequency select by MCG_C7[OSCSEL]. This is an internal function. + * + * @return MCG external reference clock frequency in Hz. + */ +static uint32_t CLOCK_GetMcgExtClkFreq(void); + +/*! + * @brief Get the MCG FLL external reference clock frequency. + * + * Get the current MCG FLL external reference clock frequency in Hz. It is + * the frequency after by MCG_C1[FRDIV]. This is an internal function. + * + * @return MCG FLL external reference clock frequency in Hz. + */ +static uint32_t CLOCK_GetFllExtRefClkFreq(void); + +/*! + * @brief Get the MCG FLL reference clock frequency. + * + * Get the current MCG FLL reference clock frequency in Hz. It is + * the frequency select by MCG_C1[IREFS]. This is an internal function. + * + * @return MCG FLL reference clock frequency in Hz. + */ +static uint32_t CLOCK_GetFllRefClkFreq(void); + +/*! + * @brief Get the frequency of clock selected by MCG_C2[IRCS]. + * + * This clock's two output: + * 1. MCGOUTCLK when MCG_S[CLKST]=0. + * 2. MCGIRCLK when MCG_C1[IRCLKEN]=1. + * + * @return The frequency in Hz. + */ +static uint32_t CLOCK_GetInternalRefClkSelectFreq(void); + +/*! + * @brief Get the MCG PLL/PLL0 reference clock frequency. + * + * Get the current MCG PLL/PLL0 reference clock frequency in Hz. + * This is an internal function. + * + * @return MCG PLL/PLL0 reference clock frequency in Hz. + */ +static uint32_t CLOCK_GetPll0RefFreq(void); + +/*! + * @brief Calculate the RANGE value base on crystal frequency. + * + * To setup external crystal oscillator, must set the register bits RANGE + * base on the crystal frequency. This function returns the RANGE base on the + * input frequency. This is an internal function. + * + * @param freq Crystal frequency in Hz. + * @return The RANGE value. + */ +static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq); + +/*! + * @brief Delay function to wait FLL stable. + * + * Delay function to wait FLL stable in FEI mode or FEE mode, should wait at least + * 1ms. Every time changes FLL setting, should wait this time for FLL stable. + */ +static void CLOCK_FllStableDelay(void); + +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t CLOCK_GetMcgExtClkFreq(void) +{ + uint32_t freq; + + switch (MCG_C7_OSCSEL_VAL) + { + case 0U: + /* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. */ + assert(g_xtal0Freq); + freq = g_xtal0Freq; + break; + case 1U: + /* Please call CLOCK_SetXtal32Freq base on board setting before using XTAL32K/RTC_CLKIN clock. */ + assert(g_xtal32Freq); + freq = g_xtal32Freq; + break; + case 2U: + freq = MCG_INTERNAL_IRC_48M; + break; + default: + freq = 0U; + break; + } + + return freq; +} + +static uint32_t CLOCK_GetFllExtRefClkFreq(void) +{ + /* FllExtRef = McgExtRef / FllExtRefDiv */ + uint8_t frdiv; + uint8_t range; + uint8_t oscsel; + + uint32_t freq = CLOCK_GetMcgExtClkFreq(); + + if (!freq) + { + return freq; + } + + frdiv = MCG_C1_FRDIV_VAL; + freq >>= frdiv; + + range = MCG_C2_RANGE_VAL; + oscsel = MCG_C7_OSCSEL_VAL; + + /* + When should use divider 32, 64, 128, 256, 512, 1024, 1280, 1536. + 1. MCG_C7[OSCSEL] selects IRC48M. + 2. MCG_C7[OSCSEL] selects OSC0 and MCG_C2[RANGE] is not 0. + */ + if (((0U != range) && (kMCG_OscselOsc == oscsel)) || (kMCG_OscselIrc == oscsel)) + { + switch (frdiv) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + freq >>= 5u; + break; + case 6: + /* 64*20=1280 */ + freq /= 20u; + break; + case 7: + /* 128*12=1536 */ + freq /= 12u; + break; + default: + freq = 0u; + break; + } + } + + return freq; +} + +static uint32_t CLOCK_GetInternalRefClkSelectFreq(void) +{ + if (kMCG_IrcSlow == MCG_S_IRCST_VAL) + { + /* Slow internal reference clock selected*/ + return s_slowIrcFreq; + } + else + { + /* Fast internal reference clock selected*/ + return s_fastIrcFreq >> MCG_SC_FCRDIV_VAL; + } +} + +static uint32_t CLOCK_GetFllRefClkFreq(void) +{ + /* If use external reference clock. */ + if (kMCG_FllSrcExternal == MCG_S_IREFST_VAL) + { + return CLOCK_GetFllExtRefClkFreq(); + } + /* If use internal reference clock. */ + else + { + return s_slowIrcFreq; + } +} + +static uint32_t CLOCK_GetPll0RefFreq(void) +{ + /* MCG external reference clock. */ + return CLOCK_GetMcgExtClkFreq(); +} + +static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq) +{ + uint8_t range; + + if (freq <= 39063U) + { + range = 0U; + } + else if (freq <= 8000000U) + { + range = 1U; + } + else + { + range = 2U; + } + + return range; +} + +static void CLOCK_FllStableDelay(void) +{ + /* + Should wait at least 1ms. Because in these modes, the core clock is 100MHz + at most, so this function could obtain the 1ms delay. + */ + volatile uint32_t i = 30000U; + while (i--) + { + __NOP(); + } +} + +uint32_t CLOCK_GetOsc0ErClkUndivFreq(void) +{ + if (OSC0->CR & OSC_CR_ERCLKEN_MASK) + { + /* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. */ + assert(g_xtal0Freq); + return g_xtal0Freq; + } + else + { + return 0U; + } +} + +uint32_t CLOCK_GetOsc0ErClkDivFreq(void) +{ + if (OSC0->CR & OSC_CR_ERCLKEN_MASK) + { + /* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. */ + assert(g_xtal0Freq); + return g_xtal0Freq >> ((OSC0->DIV & OSC_DIV_ERPS_MASK) >> OSC_DIV_ERPS_SHIFT); + } + else + { + return 0U; + } +} + +uint32_t CLOCK_GetEr32kClkFreq(void) +{ + uint32_t freq; + + switch (SIM_SOPT1_OSC32KSEL_VAL) + { + case 0U: /* OSC 32k clock */ + freq = (CLOCK_GetOsc0ErClkUndivFreq() == 32768U) ? 32768U : 0U; + break; + case 2U: /* RTC 32k clock */ + /* Please call CLOCK_SetXtal32Freq base on board setting before using XTAL32K/RTC_CLKIN clock. */ + assert(g_xtal32Freq); + freq = g_xtal32Freq; + break; + case 3U: /* LPO clock */ + freq = LPO_CLK_FREQ; + break; + default: + freq = 0U; + break; + } + return freq; +} + +uint32_t CLOCK_GetPllFllSelClkFreq(void) +{ + uint32_t freq; + + switch (SIM_SOPT2_PLLFLLSEL_VAL) + { + case 0U: /* FLL. */ + freq = CLOCK_GetFllFreq(); + break; + case 1U: /* PLL. */ + freq = CLOCK_GetPll0Freq(); + break; + case 3U: /* MCG IRC48M. */ + freq = MCG_INTERNAL_IRC_48M; + break; + default: + freq = 0U; + break; + } + + freq *= (SIM_CLKDIV3_PLLFLLFRAC_VAL + 1U); + freq /= (SIM_CLKDIV3_PLLFLLDIV_VAL + 1U); + return freq; +} + +uint32_t CLOCK_GetOsc0ErClkFreq(void) +{ + return CLOCK_GetOsc0ErClkUndivFreq(); +} + +uint32_t CLOCK_GetPlatClkFreq(void) +{ + return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); +} + +uint32_t CLOCK_GetFlashClkFreq(void) +{ + return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV4_VAL + 1); +} + +uint32_t CLOCK_GetFlexBusClkFreq(void) +{ + return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV3_VAL + 1); +} + +uint32_t CLOCK_GetBusClkFreq(void) +{ + return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV2_VAL + 1); +} + +uint32_t CLOCK_GetCoreSysClkFreq(void) +{ + return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); +} + +uint32_t CLOCK_GetFreq(clock_name_t clockName) +{ + uint32_t freq; + + switch (clockName) + { + case kCLOCK_CoreSysClk: + case kCLOCK_PlatClk: + freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); + break; + case kCLOCK_BusClk: + freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV2_VAL + 1); + break; + case kCLOCK_FlexBusClk: + freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV3_VAL + 1); + break; + case kCLOCK_FlashClk: + freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV4_VAL + 1); + break; + case kCLOCK_PllFllSelClk: + freq = CLOCK_GetPllFllSelClkFreq(); + break; + case kCLOCK_Er32kClk: + freq = CLOCK_GetEr32kClkFreq(); + break; + case kCLOCK_McgFixedFreqClk: + freq = CLOCK_GetFixedFreqClkFreq(); + break; + case kCLOCK_McgInternalRefClk: + freq = CLOCK_GetInternalRefClkFreq(); + break; + case kCLOCK_McgFllClk: + freq = CLOCK_GetFllFreq(); + break; + case kCLOCK_McgPll0Clk: + freq = CLOCK_GetPll0Freq(); + break; + case kCLOCK_McgIrc48MClk: + freq = MCG_INTERNAL_IRC_48M; + break; + case kCLOCK_LpoClk: + freq = LPO_CLK_FREQ; + break; + case kCLOCK_Osc0ErClkUndiv: + freq = CLOCK_GetOsc0ErClkDivFreq(); + break; + case kCLOCK_Osc0ErClk: + freq = CLOCK_GetOsc0ErClkUndivFreq(); + break; + default: + freq = 0U; + break; + } + + return freq; +} + +void CLOCK_SetSimConfig(sim_clock_config_t const *config) +{ + SIM->CLKDIV1 = config->clkdiv1; + CLOCK_SetPllFllSelClock(config->pllFllSel, config->pllFllDiv, config->pllFllFrac); + CLOCK_SetEr32kClock(config->er32kSrc); +} + +bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq) +{ + bool ret = true; + + CLOCK_DisableClock(kCLOCK_Usbfs0); + + if (kCLOCK_UsbSrcExt == src) + { + SIM->SOPT2 &= ~SIM_SOPT2_USBSRC_MASK; + } + else + { + switch (freq) + { + case 120000000U: + SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(4) | SIM_CLKDIV2_USBFRAC(1); + break; + case 96000000U: + SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(1) | SIM_CLKDIV2_USBFRAC(0); + break; + case 72000000U: + SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC(1); + break; + case 48000000U: + SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0) | SIM_CLKDIV2_USBFRAC(0); + break; + default: + ret = false; + break; + } + + SIM->SOPT2 = ((SIM->SOPT2 & ~(SIM_SOPT2_PLLFLLSEL_MASK | SIM_SOPT2_USBSRC_MASK)) | (uint32_t)src); + } + + CLOCK_EnableClock(kCLOCK_Usbfs0); + + if (kCLOCK_UsbSrcIrc48M == src) + { + USB0->CLK_RECOVER_IRC_EN = 0x03U; + USB0->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK; + } + return ret; +} + +uint32_t CLOCK_GetOutClkFreq(void) +{ + uint32_t mcgoutclk; + uint32_t clkst = MCG_S_CLKST_VAL; + + switch (clkst) + { + case kMCG_ClkOutStatPll: + mcgoutclk = CLOCK_GetPll0Freq(); + break; + case kMCG_ClkOutStatFll: + mcgoutclk = CLOCK_GetFllFreq(); + break; + case kMCG_ClkOutStatInt: + mcgoutclk = CLOCK_GetInternalRefClkSelectFreq(); + break; + case kMCG_ClkOutStatExt: + mcgoutclk = CLOCK_GetMcgExtClkFreq(); + break; + default: + mcgoutclk = 0U; + break; + } + return mcgoutclk; +} + +uint32_t CLOCK_GetFllFreq(void) +{ + static const uint16_t fllFactorTable[4][2] = {{640, 732}, {1280, 1464}, {1920, 2197}, {2560, 2929}}; + + uint8_t drs, dmx32; + uint32_t freq; + + /* If FLL is not enabled currently, then return 0U. */ + if ((MCG->C2 & MCG_C2_LP_MASK) || (MCG->S & MCG_S_PLLST_MASK)) + { + return 0U; + } + + /* Get FLL reference clock frequency. */ + freq = CLOCK_GetFllRefClkFreq(); + if (!freq) + { + return freq; + } + + drs = MCG_C4_DRST_DRS_VAL; + dmx32 = MCG_C4_DMX32_VAL; + + return freq * fllFactorTable[drs][dmx32]; +} + +uint32_t CLOCK_GetInternalRefClkFreq(void) +{ + /* If MCGIRCLK is gated. */ + if (!(MCG->C1 & MCG_C1_IRCLKEN_MASK)) + { + return 0U; + } + + return CLOCK_GetInternalRefClkSelectFreq(); +} + +uint32_t CLOCK_GetFixedFreqClkFreq(void) +{ + uint32_t freq = CLOCK_GetFllRefClkFreq(); + + /* MCGFFCLK must be no more than MCGOUTCLK/8. */ + if ((freq) && (freq <= (CLOCK_GetOutClkFreq() / 8U))) + { + return freq; + } + else + { + return 0U; + } +} + +uint32_t CLOCK_GetPll0Freq(void) +{ + uint32_t mcgpll0clk; + + /* If PLL0 is not enabled, return 0. */ + if (!(MCG->S & MCG_S_LOCK0_MASK)) + { + return 0U; + } + + mcgpll0clk = CLOCK_GetPll0RefFreq(); + + /* + * Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. + * Please call CLOCK_SetXtal1Freq base on board setting before using OSC1 clock. + */ + assert(mcgpll0clk); + + mcgpll0clk /= (FSL_FEATURE_MCG_PLL_PRDIV_BASE + MCG_C5_PRDIV0_VAL); + mcgpll0clk *= (FSL_FEATURE_MCG_PLL_VDIV_BASE + MCG_C6_VDIV0_VAL); + + mcgpll0clk >>= 1U; + return mcgpll0clk; +} + +status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel) +{ + bool needDelay; + uint32_t i; + +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + /* If change MCG_C7[OSCSEL] and external reference clock is system clock source, return error. */ + if ((MCG_C7_OSCSEL_VAL != oscsel) && (!(MCG->S & MCG_S_IREFST_MASK))) + { + return kStatus_MCG_SourceUsed; + } +#endif /* MCG_CONFIG_CHECK_PARAM */ + + if (MCG_C7_OSCSEL_VAL != oscsel) + { + /* If change OSCSEL, need to delay, ERR009878. */ + needDelay = true; + } + else + { + needDelay = false; + } + + MCG->C7 = (MCG->C7 & ~MCG_C7_OSCSEL_MASK) | MCG_C7_OSCSEL(oscsel); + if (kMCG_OscselOsc == oscsel) + { + if (MCG->C2 & MCG_C2_EREFS_MASK) + { + while (!(MCG->S & MCG_S_OSCINIT0_MASK)) + { + } + } + } + + if (needDelay) + { + /* ERR009878 Delay at least 50 micro-seconds for external clock change valid. */ + i = 1500U; + while (i--) + { + __NOP(); + } + } + + return kStatus_Success; +} + +status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv) +{ + uint32_t mcgOutClkState = MCG_S_CLKST_VAL; + mcg_irc_mode_t curIrcs = (mcg_irc_mode_t)MCG_S_IRCST_VAL; + uint8_t curFcrdiv = MCG_SC_FCRDIV_VAL; + +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + /* If MCGIRCLK is used as system clock source. */ + if (kMCG_ClkOutStatInt == mcgOutClkState) + { + /* If need to change MCGIRCLK source or driver, return error. */ + if (((kMCG_IrcFast == curIrcs) && (fcrdiv != curFcrdiv)) || (ircs != curIrcs)) + { + return kStatus_MCG_SourceUsed; + } + } +#endif + + /* If need to update the FCRDIV. */ + if (fcrdiv != curFcrdiv) + { + /* If fast IRC is in use currently, change to slow IRC. */ + if ((kMCG_IrcFast == curIrcs) && ((mcgOutClkState == kMCG_ClkOutStatInt) || (MCG->C1 & MCG_C1_IRCLKEN_MASK))) + { + MCG->C2 = ((MCG->C2 & ~MCG_C2_IRCS_MASK) | (MCG_C2_IRCS(kMCG_IrcSlow))); + while (MCG_S_IRCST_VAL != kMCG_IrcSlow) + { + } + } + /* Update FCRDIV. */ + MCG->SC = (MCG->SC & ~(MCG_SC_FCRDIV_MASK | MCG_SC_ATMF_MASK | MCG_SC_LOCS0_MASK)) | MCG_SC_FCRDIV(fcrdiv); + } + + /* Set internal reference clock selection. */ + MCG->C2 = (MCG->C2 & ~MCG_C2_IRCS_MASK) | (MCG_C2_IRCS(ircs)); + MCG->C1 = (MCG->C1 & ~(MCG_C1_IRCLKEN_MASK | MCG_C1_IREFSTEN_MASK)) | (uint8_t)enableMode; + + /* If MCGIRCLK is used, need to wait for MCG_S_IRCST. */ + if ((mcgOutClkState == kMCG_ClkOutStatInt) || (enableMode & kMCG_IrclkEnable)) + { + while (MCG_S_IRCST_VAL != ircs) + { + } + } + + return kStatus_Success; +} + +uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv) +{ + uint8_t ret_prdiv; /* PRDIV to return. */ + uint8_t ret_vdiv; /* VDIV to return. */ + uint8_t prdiv_min; /* Min PRDIV value to make reference clock in allowed range. */ + uint8_t prdiv_max; /* Max PRDIV value to make reference clock in allowed range. */ + uint8_t prdiv_cur; /* PRDIV value for iteration. */ + uint8_t vdiv_cur; /* VDIV value for iteration. */ + uint32_t ret_freq = 0U; /* PLL output fequency to return. */ + uint32_t diff = 0xFFFFFFFFU; /* Difference between desireFreq and return frequency. */ + uint32_t ref_div; /* Reference frequency after PRDIV. */ + + /* + Steps: + 1. Get allowed prdiv with such rules: + 1). refFreq / prdiv >= FSL_FEATURE_MCG_PLL_REF_MIN. + 2). refFreq / prdiv <= FSL_FEATURE_MCG_PLL_REF_MAX. + 2. For each allowed prdiv, there are two candidate vdiv values: + 1). (desireFreq / (refFreq / prdiv)). + 2). (desireFreq / (refFreq / prdiv)) + 1. + If could get the precise desired frequency, return current prdiv and + vdiv directly. Otherwise choose the one which is closer to desired + frequency. + */ + + /* Reference frequency is out of range. */ + if ((refFreq < FSL_FEATURE_MCG_PLL_REF_MIN) || + (refFreq > (FSL_FEATURE_MCG_PLL_REF_MAX * (FSL_FEATURE_MCG_PLL_PRDIV_MAX + FSL_FEATURE_MCG_PLL_PRDIV_BASE)))) + { + return 0U; + } + + /* refFreq/PRDIV must in a range. First get the allowed PRDIV range. */ + prdiv_max = refFreq / FSL_FEATURE_MCG_PLL_REF_MIN; + prdiv_min = (refFreq + FSL_FEATURE_MCG_PLL_REF_MAX - 1U) / FSL_FEATURE_MCG_PLL_REF_MAX; + + desireFreq *= 2U; + + /* PRDIV traversal. */ + for (prdiv_cur = prdiv_max; prdiv_cur >= prdiv_min; prdiv_cur--) + { + /* Reference frequency after PRDIV. */ + ref_div = refFreq / prdiv_cur; + + vdiv_cur = desireFreq / ref_div; + + if ((vdiv_cur < FSL_FEATURE_MCG_PLL_VDIV_BASE - 1U) || (vdiv_cur > FSL_FEATURE_MCG_PLL_VDIV_BASE + 31U)) + { + /* No VDIV is available with this PRDIV. */ + continue; + } + + ret_freq = vdiv_cur * ref_div; + + if (vdiv_cur >= FSL_FEATURE_MCG_PLL_VDIV_BASE) + { + if (ret_freq == desireFreq) /* If desire frequency is got. */ + { + *prdiv = prdiv_cur - FSL_FEATURE_MCG_PLL_PRDIV_BASE; + *vdiv = vdiv_cur - FSL_FEATURE_MCG_PLL_VDIV_BASE; + return ret_freq / 2U; + } + /* New PRDIV/VDIV is closer. */ + if (diff > desireFreq - ret_freq) + { + diff = desireFreq - ret_freq; + ret_prdiv = prdiv_cur; + ret_vdiv = vdiv_cur; + } + } + vdiv_cur++; + if (vdiv_cur <= (FSL_FEATURE_MCG_PLL_VDIV_BASE + 31U)) + { + ret_freq += ref_div; + /* New PRDIV/VDIV is closer. */ + if (diff > ret_freq - desireFreq) + { + diff = ret_freq - desireFreq; + ret_prdiv = prdiv_cur; + ret_vdiv = vdiv_cur; + } + } + } + + if (0xFFFFFFFFU != diff) + { + /* PRDIV/VDIV found. */ + *prdiv = ret_prdiv - FSL_FEATURE_MCG_PLL_PRDIV_BASE; + *vdiv = ret_vdiv - FSL_FEATURE_MCG_PLL_VDIV_BASE; + ret_freq = (refFreq / ret_prdiv) * ret_vdiv; + return ret_freq / 2U; + } + else + { + /* No proper PRDIV/VDIV found. */ + return 0U; + } +} + +void CLOCK_EnablePll0(mcg_pll_config_t const *config) +{ + assert(config); + + uint8_t mcg_c5 = 0U; + + mcg_c5 |= MCG_C5_PRDIV0(config->prdiv); + MCG->C5 = mcg_c5; /* Disable the PLL first. */ + + MCG->C6 = (MCG->C6 & ~MCG_C6_VDIV0_MASK) | MCG_C6_VDIV0(config->vdiv); + + /* Set enable mode. */ + MCG->C5 |= ((uint32_t)kMCG_PllEnableIndependent | (uint32_t)config->enableMode); + + /* Wait for PLL lock. */ + while (!(MCG->S & MCG_S_LOCK0_MASK)) + { + } +} + +void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode) +{ + /* Clear the previous flag, MCG_SC[LOCS0]. */ + MCG->SC &= ~MCG_SC_ATMF_MASK; + + if (kMCG_MonitorNone == mode) + { + MCG->C6 &= ~MCG_C6_CME0_MASK; + } + else + { + if (kMCG_MonitorInt == mode) + { + MCG->C2 &= ~MCG_C2_LOCRE0_MASK; + } + else + { + MCG->C2 |= MCG_C2_LOCRE0_MASK; + } + MCG->C6 |= MCG_C6_CME0_MASK; + } +} + +void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode) +{ + uint8_t mcg_c8 = MCG->C8; + + mcg_c8 &= ~(MCG_C8_CME1_MASK | MCG_C8_LOCRE1_MASK); + + if (kMCG_MonitorNone != mode) + { + if (kMCG_MonitorReset == mode) + { + mcg_c8 |= MCG_C8_LOCRE1_MASK; + } + mcg_c8 |= MCG_C8_CME1_MASK; + } + MCG->C8 = mcg_c8; +} + +void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode) +{ + uint8_t mcg_c8; + + /* Clear previous flag. */ + MCG->S = MCG_S_LOLS0_MASK; + + if (kMCG_MonitorNone == mode) + { + MCG->C6 &= ~MCG_C6_LOLIE0_MASK; + } + else + { + mcg_c8 = MCG->C8; + + mcg_c8 &= ~MCG_C8_LOCS1_MASK; + + if (kMCG_MonitorInt == mode) + { + mcg_c8 &= ~MCG_C8_LOLRE_MASK; + } + else + { + mcg_c8 |= MCG_C8_LOLRE_MASK; + } + MCG->C8 = mcg_c8; + MCG->C6 |= MCG_C6_LOLIE0_MASK; + } +} + +uint32_t CLOCK_GetStatusFlags(void) +{ + uint32_t ret = 0U; + uint8_t mcg_s = MCG->S; + + if (MCG->SC & MCG_SC_LOCS0_MASK) + { + ret |= kMCG_Osc0LostFlag; + } + if (mcg_s & MCG_S_OSCINIT0_MASK) + { + ret |= kMCG_Osc0InitFlag; + } + if (MCG->C8 & MCG_C8_LOCS1_MASK) + { + ret |= kMCG_RtcOscLostFlag; + } + if (mcg_s & MCG_S_LOLS0_MASK) + { + ret |= kMCG_Pll0LostFlag; + } + if (mcg_s & MCG_S_LOCK0_MASK) + { + ret |= kMCG_Pll0LockFlag; + } + return ret; +} + +void CLOCK_ClearStatusFlags(uint32_t mask) +{ + uint8_t reg; + + if (mask & kMCG_Osc0LostFlag) + { + MCG->SC &= ~MCG_SC_ATMF_MASK; + } + if (mask & kMCG_RtcOscLostFlag) + { + reg = MCG->C8; + MCG->C8 = reg; + } + if (mask & kMCG_Pll0LostFlag) + { + MCG->S = MCG_S_LOLS0_MASK; + } +} + +void CLOCK_InitOsc0(osc_config_t const *config) +{ + uint8_t range = CLOCK_GetOscRangeFromFreq(config->freq); + + OSC_SetCapLoad(OSC0, config->capLoad); + OSC_SetExtRefClkConfig(OSC0, &config->oscerConfig); + + MCG->C2 = ((MCG->C2 & ~OSC_MODE_MASK) | MCG_C2_RANGE(range) | (uint8_t)config->workMode); + + if ((kOSC_ModeExt != config->workMode) && (OSC0->CR & OSC_CR_ERCLKEN_MASK)) + { + /* Wait for stable. */ + while (!(MCG->S & MCG_S_OSCINIT0_MASK)) + { + } + } +} + +void CLOCK_DeinitOsc0(void) +{ + OSC0->CR = 0U; + MCG->C2 &= ~OSC_MODE_MASK; +} + +status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_t *actualFreq, mcg_atm_select_t atms) +{ + uint32_t multi; /* extFreq / desireFreq */ + uint32_t actv; /* Auto trim value. */ + uint8_t mcg_sc; + + static const uint32_t trimRange[2][2] = { + /* Min Max */ + {TRIM_SIRC_MIN, TRIM_SIRC_MAX}, /* Slow IRC. */ + {TRIM_FIRC_MIN, TRIM_FIRC_MAX} /* Fast IRC. */ + }; + + if ((extFreq > TRIM_REF_CLK_MAX) || (extFreq < TRIM_REF_CLK_MIN)) + { + return kStatus_MCG_AtmBusClockInvalid; + } + + /* Check desired frequency range. */ + if ((desireFreq < trimRange[atms][0]) || (desireFreq > trimRange[atms][1])) + { + return kStatus_MCG_AtmDesiredFreqInvalid; + } + + /* + Make sure internal reference clock is not used to generate bus clock. + Here only need to check (MCG_S_IREFST == 1). + */ + if (MCG_S_IREFST(kMCG_FllSrcInternal) == (MCG->S & MCG_S_IREFST_MASK)) + { + return kStatus_MCG_AtmIrcUsed; + } + + multi = extFreq / desireFreq; + actv = multi * 21U; + + if (kMCG_AtmSel4m == atms) + { + actv *= 128U; + } + + /* Now begin to start trim. */ + MCG->ATCVL = (uint8_t)actv; + MCG->ATCVH = (uint8_t)(actv >> 8U); + + mcg_sc = MCG->SC; + mcg_sc &= ~(MCG_SC_ATMS_MASK | MCG_SC_LOCS0_MASK); + mcg_sc |= (MCG_SC_ATMF_MASK | MCG_SC_ATMS(atms)); + MCG->SC = (mcg_sc | MCG_SC_ATME_MASK); + + /* Wait for finished. */ + while (MCG->SC & MCG_SC_ATME_MASK) + { + } + + /* Error occurs? */ + if (MCG->SC & MCG_SC_ATMF_MASK) + { + /* Clear the failed flag. */ + MCG->SC = mcg_sc; + return kStatus_MCG_AtmHardwareFail; + } + + *actualFreq = extFreq / multi; + + if (kMCG_AtmSel4m == atms) + { + s_fastIrcFreq = *actualFreq; + } + else + { + s_slowIrcFreq = *actualFreq; + } + + return kStatus_Success; +} + +mcg_mode_t CLOCK_GetMode(void) +{ + mcg_mode_t mode = kMCG_ModeError; + uint32_t clkst = MCG_S_CLKST_VAL; + uint32_t irefst = MCG_S_IREFST_VAL; + uint32_t lp = MCG_C2_LP_VAL; + uint32_t pllst = MCG_S_PLLST_VAL; + + /*------------------------------------------------------------------ + Mode and Registers + ____________________________________________________________________ + + Mode | CLKST | IREFST | PLLST | LP + ____________________________________________________________________ + + FEI | 00(FLL) | 1(INT) | 0(FLL) | X + ____________________________________________________________________ + + FEE | 00(FLL) | 0(EXT) | 0(FLL) | X + ____________________________________________________________________ + + FBE | 10(EXT) | 0(EXT) | 0(FLL) | 0(NORMAL) + ____________________________________________________________________ + + FBI | 01(INT) | 1(INT) | 0(FLL) | 0(NORMAL) + ____________________________________________________________________ + + BLPI | 01(INT) | 1(INT) | 0(FLL) | 1(LOW POWER) + ____________________________________________________________________ + + BLPE | 10(EXT) | 0(EXT) | X | 1(LOW POWER) + ____________________________________________________________________ + + PEE | 11(PLL) | 0(EXT) | 1(PLL) | X + ____________________________________________________________________ + + PBE | 10(EXT) | 0(EXT) | 1(PLL) | O(NORMAL) + ____________________________________________________________________ + + PBI | 01(INT) | 1(INT) | 1(PLL) | 0(NORMAL) + ____________________________________________________________________ + + PEI | 11(PLL) | 1(INT) | 1(PLL) | X + ____________________________________________________________________ + + ----------------------------------------------------------------------*/ + + switch (clkst) + { + case kMCG_ClkOutStatFll: + if (kMCG_FllSrcExternal == irefst) + { + mode = kMCG_ModeFEE; + } + else + { + mode = kMCG_ModeFEI; + } + break; + case kMCG_ClkOutStatInt: + if (lp) + { + mode = kMCG_ModeBLPI; + } + else + { + { + mode = kMCG_ModeFBI; + } + } + break; + case kMCG_ClkOutStatExt: + if (lp) + { + mode = kMCG_ModeBLPE; + } + else + { + if (kMCG_PllstPll == pllst) + { + mode = kMCG_ModePBE; + } + else + { + mode = kMCG_ModeFBE; + } + } + break; + case kMCG_ClkOutStatPll: + { + mode = kMCG_ModePEE; + } + break; + default: + break; + } + + return mode; +} + +status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) +{ + uint8_t mcg_c4; + bool change_drs = false; + +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + mcg_mode_t mode = CLOCK_GetMode(); + if (!((kMCG_ModeFEI == mode) || (kMCG_ModeFBI == mode) || (kMCG_ModeFBE == mode) || (kMCG_ModeFEE == mode))) + { + return kStatus_MCG_ModeUnreachable; + } +#endif + mcg_c4 = MCG->C4; + + /* + Errata: ERR007993 + Workaround: Invert MCG_C4[DMX32] or change MCG_C4[DRST_DRS] before + reference clock source changes, then reset to previous value after + reference clock changes. + */ + if (kMCG_FllSrcExternal == MCG_S_IREFST_VAL) + { + change_drs = true; + /* Change the LSB of DRST_DRS. */ + MCG->C4 ^= (1U << MCG_C4_DRST_DRS_SHIFT); + } + + /* Set CLKS and IREFS. */ + MCG->C1 = + ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK))) | (MCG_C1_CLKS(kMCG_ClkOutSrcOut) /* CLKS = 0 */ + | MCG_C1_IREFS(kMCG_FllSrcInternal)); /* IREFS = 1 */ + + /* Wait and check status. */ + while (kMCG_FllSrcInternal != MCG_S_IREFST_VAL) + { + } + + /* Errata: ERR007993 */ + if (change_drs) + { + MCG->C4 = mcg_c4; + } + + /* In FEI mode, the MCG_C4[DMX32] is set to 0U. */ + MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs)); + + /* Check MCG_S[CLKST] */ + while (kMCG_ClkOutStatFll != MCG_S_CLKST_VAL) + { + } + + /* Wait for FLL stable time. */ + if (fllStableDelay) + { + fllStableDelay(); + } + + return kStatus_Success; +} + +status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) +{ + uint8_t mcg_c4; + bool change_drs = false; + +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + mcg_mode_t mode = CLOCK_GetMode(); + if (!((kMCG_ModeFEE == mode) || (kMCG_ModeFBI == mode) || (kMCG_ModeFBE == mode) || (kMCG_ModeFEI == mode))) + { + return kStatus_MCG_ModeUnreachable; + } +#endif + mcg_c4 = MCG->C4; + + /* + Errata: ERR007993 + Workaround: Invert MCG_C4[DMX32] or change MCG_C4[DRST_DRS] before + reference clock source changes, then reset to previous value after + reference clock changes. + */ + if (kMCG_FllSrcInternal == MCG_S_IREFST_VAL) + { + change_drs = true; + /* Change the LSB of DRST_DRS. */ + MCG->C4 ^= (1U << MCG_C4_DRST_DRS_SHIFT); + } + + /* Set CLKS and IREFS. */ + MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK)) | + (MCG_C1_CLKS(kMCG_ClkOutSrcOut) /* CLKS = 0 */ + | MCG_C1_FRDIV(frdiv) /* FRDIV */ + | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ + + /* Wait and check status. */ + while (kMCG_FllSrcExternal != MCG_S_IREFST_VAL) + { + } + + /* Errata: ERR007993 */ + if (change_drs) + { + MCG->C4 = mcg_c4; + } + + /* Set DRS and DMX32. */ + mcg_c4 = ((mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs))); + MCG->C4 = mcg_c4; + + /* Wait for DRST_DRS update. */ + while (MCG->C4 != mcg_c4) + { + } + + /* Check MCG_S[CLKST] */ + while (kMCG_ClkOutStatFll != MCG_S_CLKST_VAL) + { + } + + /* Wait for FLL stable time. */ + if (fllStableDelay) + { + fllStableDelay(); + } + + return kStatus_Success; +} + +status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) +{ + uint8_t mcg_c4; + bool change_drs = false; + +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + mcg_mode_t mode = CLOCK_GetMode(); + + if (!((kMCG_ModeFEE == mode) || (kMCG_ModeFBI == mode) || (kMCG_ModeFBE == mode) || (kMCG_ModeFEI == mode) || + (kMCG_ModeBLPI == mode))) + + { + return kStatus_MCG_ModeUnreachable; + } +#endif + + mcg_c4 = MCG->C4; + + MCG->C2 &= ~MCG_C2_LP_MASK; /* Disable lowpower. */ + + /* + Errata: ERR007993 + Workaround: Invert MCG_C4[DMX32] or change MCG_C4[DRST_DRS] before + reference clock source changes, then reset to previous value after + reference clock changes. + */ + if (kMCG_FllSrcExternal == MCG_S_IREFST_VAL) + { + change_drs = true; + /* Change the LSB of DRST_DRS. */ + MCG->C4 ^= (1U << MCG_C4_DRST_DRS_SHIFT); + } + + /* Set CLKS and IREFS. */ + MCG->C1 = + ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | (MCG_C1_CLKS(kMCG_ClkOutSrcInternal) /* CLKS = 1 */ + | MCG_C1_IREFS(kMCG_FllSrcInternal))); /* IREFS = 1 */ + + /* Wait and check status. */ + while (kMCG_FllSrcInternal != MCG_S_IREFST_VAL) + { + } + + /* Errata: ERR007993 */ + if (change_drs) + { + MCG->C4 = mcg_c4; + } + + while (kMCG_ClkOutStatInt != MCG_S_CLKST_VAL) + { + } + + MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs)); + + /* Wait for FLL stable time. */ + if (fllStableDelay) + { + fllStableDelay(); + } + + return kStatus_Success; +} + +status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) +{ + uint8_t mcg_c4; + bool change_drs = false; + +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + mcg_mode_t mode = CLOCK_GetMode(); + if (!((kMCG_ModeFEE == mode) || (kMCG_ModeFBI == mode) || (kMCG_ModeFBE == mode) || (kMCG_ModeFEI == mode) || + (kMCG_ModePBE == mode) || (kMCG_ModeBLPE == mode))) + { + return kStatus_MCG_ModeUnreachable; + } +#endif + + /* Change to FLL mode. */ + MCG->C6 &= ~MCG_C6_PLLS_MASK; + while (MCG->S & MCG_S_PLLST_MASK) + { + } + + /* Set LP bit to enable the FLL */ + MCG->C2 &= ~MCG_C2_LP_MASK; + + mcg_c4 = MCG->C4; + + /* + Errata: ERR007993 + Workaround: Invert MCG_C4[DMX32] or change MCG_C4[DRST_DRS] before + reference clock source changes, then reset to previous value after + reference clock changes. + */ + if (kMCG_FllSrcInternal == MCG_S_IREFST_VAL) + { + change_drs = true; + /* Change the LSB of DRST_DRS. */ + MCG->C4 ^= (1U << MCG_C4_DRST_DRS_SHIFT); + } + + /* Set CLKS and IREFS. */ + MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK)) | + (MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */ + | MCG_C1_FRDIV(frdiv) /* FRDIV = frdiv */ + | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ + + /* Wait for Reference clock Status bit to clear */ + while (kMCG_FllSrcExternal != MCG_S_IREFST_VAL) + { + } + + /* Errata: ERR007993 */ + if (change_drs) + { + MCG->C4 = mcg_c4; + } + + /* Set DRST_DRS and DMX32. */ + mcg_c4 = ((mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs))); + + /* Wait for clock status bits to show clock source is ext ref clk */ + while (kMCG_ClkOutStatExt != MCG_S_CLKST_VAL) + { + } + + /* Wait for fll stable time. */ + if (fllStableDelay) + { + fllStableDelay(); + } + + return kStatus_Success; +} + +status_t CLOCK_SetBlpiMode(void) +{ +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + if (MCG_S_CLKST_VAL != kMCG_ClkOutStatInt) + { + return kStatus_MCG_ModeUnreachable; + } +#endif /* MCG_CONFIG_CHECK_PARAM */ + + /* Set LP. */ + MCG->C2 |= MCG_C2_LP_MASK; + + return kStatus_Success; +} + +status_t CLOCK_SetBlpeMode(void) +{ +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + if (MCG_S_CLKST_VAL != kMCG_ClkOutStatExt) + { + return kStatus_MCG_ModeUnreachable; + } +#endif + + /* Set LP bit to enter BLPE mode. */ + MCG->C2 |= MCG_C2_LP_MASK; + + return kStatus_Success; +} + +status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config) +{ + assert(config); + + /* + This function is designed to change MCG to PBE mode from PEE/BLPE/FBE, + but with this workflow, the source mode could be all modes except PEI/PBI. + */ + MCG->C2 &= ~MCG_C2_LP_MASK; /* Disable lowpower. */ + + /* Change to use external clock first. */ + MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | MCG_C1_CLKS(kMCG_ClkOutSrcExternal)); + + /* Wait for CLKST clock status bits to show clock source is ext ref clk */ + while ((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) != + (MCG_S_IREFST(kMCG_FllSrcExternal) | MCG_S_CLKST(kMCG_ClkOutStatExt))) + { + } + + /* Disable PLL first, then configure PLL. */ + MCG->C6 &= ~MCG_C6_PLLS_MASK; + while (MCG->S & MCG_S_PLLST_MASK) + { + } + + /* Configure the PLL. */ + { + CLOCK_EnablePll0(config); + } + + /* Change to PLL mode. */ + MCG->C6 |= MCG_C6_PLLS_MASK; + + /* Wait for PLL mode changed. */ + while (!(MCG->S & MCG_S_PLLST_MASK)) + { + } + + return kStatus_Success; +} + +status_t CLOCK_SetPeeMode(void) +{ +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + mcg_mode_t mode = CLOCK_GetMode(); + if (kMCG_ModePBE != mode) + { + return kStatus_MCG_ModeUnreachable; + } +#endif + + /* Change to use PLL/FLL output clock first. */ + MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcOut); + + /* Wait for clock status bits to update */ + while (MCG_S_CLKST_VAL != kMCG_ClkOutStatPll) + { + } + + return kStatus_Success; +} + +status_t CLOCK_ExternalModeToFbeModeQuick(void) +{ +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + if (MCG->S & MCG_S_IREFST_MASK) + { + return kStatus_MCG_ModeInvalid; + } +#endif /* MCG_CONFIG_CHECK_PARAM */ + + /* Disable low power */ + MCG->C2 &= ~MCG_C2_LP_MASK; + + MCG->C1 = ((MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcExternal)); + while (MCG_S_CLKST_VAL != kMCG_ClkOutStatExt) + { + } + + /* Disable PLL. */ + MCG->C6 &= ~MCG_C6_PLLS_MASK; + while (MCG->S & MCG_S_PLLST_MASK) + { + } + + return kStatus_Success; +} + +status_t CLOCK_InternalModeToFbiModeQuick(void) +{ +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + if (!(MCG->S & MCG_S_IREFST_MASK)) + { + return kStatus_MCG_ModeInvalid; + } +#endif + + /* Disable low power */ + MCG->C2 &= ~MCG_C2_LP_MASK; + + MCG->C1 = ((MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcInternal)); + while (MCG_S_CLKST_VAL != kMCG_ClkOutStatInt) + { + } + + return kStatus_Success; +} + +status_t CLOCK_BootToFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) +{ + return CLOCK_SetFeiMode(dmx32, drs, fllStableDelay); +} + +status_t CLOCK_BootToFeeMode( + mcg_oscsel_t oscsel, uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) +{ + CLOCK_SetExternalRefClkConfig(oscsel); + + return CLOCK_SetFeeMode(frdiv, dmx32, drs, fllStableDelay); +} + +status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode) +{ + /* If reset mode is FEI mode, set MCGIRCLK and always success. */ + CLOCK_SetInternalRefClkConfig(ircEnableMode, ircs, fcrdiv); + + /* If reset mode is not BLPI, first enter FBI mode. */ + MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcInternal); + while (MCG_S_CLKST_VAL != kMCG_ClkOutStatInt) + { + } + + /* Enter BLPI mode. */ + MCG->C2 |= MCG_C2_LP_MASK; + + return kStatus_Success; +} + +status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel) +{ + CLOCK_SetExternalRefClkConfig(oscsel); + + /* Set to FBE mode. */ + MCG->C1 = + ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | (MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */ + | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ + + /* Wait for MCG_S[CLKST] and MCG_S[IREFST]. */ + while ((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) != + (MCG_S_IREFST(kMCG_FllSrcExternal) | MCG_S_CLKST(kMCG_ClkOutStatExt))) + { + } + + /* In FBE now, start to enter BLPE. */ + MCG->C2 |= MCG_C2_LP_MASK; + + return kStatus_Success; +} + +status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config) +{ + assert(config); + + CLOCK_SetExternalRefClkConfig(oscsel); + + CLOCK_SetPbeMode(pllcs, config); + + /* Change to use PLL output clock. */ + MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcOut); + while (MCG_S_CLKST_VAL != kMCG_ClkOutStatPll) + { + } + + return kStatus_Success; +} + +/* + The transaction matrix. It defines the path for mode switch, the row is for + current mode and the column is target mode. + For example, switch from FEI to PEE: + 1. Current mode FEI, next mode is mcgModeMatrix[FEI][PEE] = FBE, so swith to FBE. + 2. Current mode FBE, next mode is mcgModeMatrix[FBE][PEE] = PBE, so swith to PBE. + 3. Current mode PBE, next mode is mcgModeMatrix[PBE][PEE] = PEE, so swith to PEE. + Thus the MCG mode has changed from FEI to PEE. + */ +static const mcg_mode_t mcgModeMatrix[8][8] = { + {kMCG_ModeFEI, kMCG_ModeFBI, kMCG_ModeFBI, kMCG_ModeFEE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, + kMCG_ModeFBE}, /* FEI */ + {kMCG_ModeFEI, kMCG_ModeFBI, kMCG_ModeBLPI, kMCG_ModeFEE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, + kMCG_ModeFBE}, /* FBI */ + {kMCG_ModeFBI, kMCG_ModeFBI, kMCG_ModeBLPI, kMCG_ModeFBI, kMCG_ModeFBI, kMCG_ModeFBI, kMCG_ModeFBI, + kMCG_ModeFBI}, /* BLPI */ + {kMCG_ModeFEI, kMCG_ModeFBI, kMCG_ModeFBI, kMCG_ModeFEE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, + kMCG_ModeFBE}, /* FEE */ + {kMCG_ModeFEI, kMCG_ModeFBI, kMCG_ModeFBI, kMCG_ModeFEE, kMCG_ModeFBE, kMCG_ModeBLPE, kMCG_ModePBE, + kMCG_ModePBE}, /* FBE */ + {kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeBLPE, kMCG_ModePBE, + kMCG_ModePBE}, /* BLPE */ + {kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeBLPE, kMCG_ModePBE, + kMCG_ModePEE}, /* PBE */ + {kMCG_ModePBE, kMCG_ModePBE, kMCG_ModePBE, kMCG_ModePBE, kMCG_ModePBE, kMCG_ModePBE, kMCG_ModePBE, + kMCG_ModePBE} /* PEE */ + /* FEI FBI BLPI FEE FBE BLPE PBE PEE */ +}; + +status_t CLOCK_SetMcgConfig(const mcg_config_t *config) +{ + mcg_mode_t next_mode; + status_t status = kStatus_Success; + + mcg_pll_clk_select_t pllcs = kMCG_PllClkSelPll0; + + /* If need to change external clock, MCG_C7[OSCSEL]. */ + if (MCG_C7_OSCSEL_VAL != config->oscsel) + { + /* If external clock is in use, change to FEI first. */ + if (!(MCG->S & MCG_S_IRCST_MASK)) + { + CLOCK_ExternalModeToFbeModeQuick(); + CLOCK_SetFeiMode(config->dmx32, config->drs, (void (*)(void))0); + } + + CLOCK_SetExternalRefClkConfig(config->oscsel); + } + + /* Re-configure MCGIRCLK, if MCGIRCLK is used as system clock source, then change to FEI/PEI first. */ + if (MCG_S_CLKST_VAL == kMCG_ClkOutStatInt) + { + MCG->C2 &= ~MCG_C2_LP_MASK; /* Disable lowpower. */ + + { + CLOCK_SetFeiMode(config->dmx32, config->drs, CLOCK_FllStableDelay); + } + } + + /* Configure MCGIRCLK. */ + CLOCK_SetInternalRefClkConfig(config->irclkEnableMode, config->ircs, config->fcrdiv); + + next_mode = CLOCK_GetMode(); + + do + { + next_mode = mcgModeMatrix[next_mode][config->mcgMode]; + + switch (next_mode) + { + case kMCG_ModeFEI: + status = CLOCK_SetFeiMode(config->dmx32, config->drs, CLOCK_FllStableDelay); + break; + case kMCG_ModeFEE: + status = CLOCK_SetFeeMode(config->frdiv, config->dmx32, config->drs, CLOCK_FllStableDelay); + break; + case kMCG_ModeFBI: + status = CLOCK_SetFbiMode(config->dmx32, config->drs, (void (*)(void))0); + break; + case kMCG_ModeFBE: + status = CLOCK_SetFbeMode(config->frdiv, config->dmx32, config->drs, (void (*)(void))0); + break; + case kMCG_ModeBLPI: + status = CLOCK_SetBlpiMode(); + break; + case kMCG_ModeBLPE: + status = CLOCK_SetBlpeMode(); + break; + case kMCG_ModePBE: + /* If target mode is not PBE or PEE, then only need to set CLKS = EXT here. */ + if ((kMCG_ModePEE == config->mcgMode) || (kMCG_ModePBE == config->mcgMode)) + { + { + status = CLOCK_SetPbeMode(pllcs, &config->pll0Config); + } + } + else + { + MCG->C1 = ((MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcExternal)); + while (MCG_S_CLKST_VAL != kMCG_ClkOutStatExt) + { + } + } + break; + case kMCG_ModePEE: + status = CLOCK_SetPeeMode(); + break; + default: + break; + } + if (kStatus_Success != status) + { + return status; + } + } while (next_mode != config->mcgMode); + + if (config->pll0Config.enableMode & kMCG_PllEnableIndependent) + { + CLOCK_EnablePll0(&config->pll0Config); + } + else + { + MCG->C5 &= ~(uint32_t)kMCG_PllEnableIndependent; + } + return kStatus_Success; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_clock.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_clock.h new file mode 100644 index 00000000000..1dbfa263a49 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_clock.h @@ -0,0 +1,1608 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_CLOCK_H_ +#define _FSL_CLOCK_H_ + +#include "fsl_common.h" + +/*! @addtogroup clock */ +/*! @{ */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Configure whether driver controls clock + * + * When set to 0, peripheral drivers will enable clock in initialize function + * and disable clock in de-initialize function. When set to 1, peripheral + * driver will not control the clock, application could contol the clock out of + * the driver. + * + * @note All drivers share this feature switcher. If it is set to 1, application + * should handle clock enable and disable for all drivers. + */ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)) +#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0 +#endif + +/*! @name Driver version */ +/*@{*/ +/*! @brief CLOCK driver version 2.2.0. */ +#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 0)) +/*@}*/ + +/*! @brief External XTAL0 (OSC0) clock frequency. + * + * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the + * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example, + * if XTAL0 is 8 MHz: + * @code + * CLOCK_InitOsc0(...); // Set up the OSC0 + * CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to the clock driver. + * @endcode + * + * This is important for the multicore platforms where only one core needs to set up the + * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq + * to get a valid clock frequency. + */ +extern uint32_t g_xtal0Freq; + +/*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. + * + * The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz. When the clock is set up, use the + * function CLOCK_SetXtal32Freq to set the value in the clock driver. + * + * This is important for the multicore platforms where only one core needs to set up + * the clock. All other cores need to call the CLOCK_SetXtal32Freq + * to get a valid clock frequency. + */ +extern uint32_t g_xtal32Freq; + +/*! @brief IRC48M clock frequency in Hz. */ +#define MCG_INTERNAL_IRC_48M 48000000U + +#if (defined(OSC) && !(defined(OSC0))) +#define OSC0 OSC +#endif + +/*! @brief Clock ip name array for DMAMUX. */ +#define DMAMUX_CLOCKS \ + { \ + kCLOCK_Dmamux0 \ + } + +/*! @brief Clock ip name array for RTC. */ +#define RTC_CLOCKS \ + { \ + kCLOCK_Rtc0 \ + } + +/*! @brief Clock ip name array for SAI. */ +#define SAI_CLOCKS \ + { \ + kCLOCK_Sai0 \ + } + +/*! @brief Clock ip name array for PORT. */ +#define PORT_CLOCKS \ + { \ + kCLOCK_PortA, kCLOCK_PortB, kCLOCK_PortC, kCLOCK_PortD, kCLOCK_PortE \ + } + +/*! @brief Clock ip name array for FLEXBUS. */ +#define FLEXBUS_CLOCKS \ + { \ + kCLOCK_Flexbus0 \ + } + +/*! @brief Clock ip name array for EWM. */ +#define EWM_CLOCKS \ + { \ + kCLOCK_Ewm0 \ + } + +/*! @brief Clock ip name array for PIT. */ +#define PIT_CLOCKS \ + { \ + kCLOCK_Pit0 \ + } + +/*! @brief Clock ip name array for DSPI. */ +#define DSPI_CLOCKS \ + { \ + kCLOCK_Spi0, kCLOCK_Spi1, kCLOCK_Spi2 \ + } + +/*! @brief Clock ip name array for EMVSIM. */ +#define EMVSIM_CLOCKS \ + { \ + kCLOCK_Emvsim0, kCLOCK_Emvsim1 \ + } + +/*! @brief Clock ip name array for QSPI. */ +#define QSPI_CLOCKS \ + { \ + kCLOCK_Qspi0 \ + } + +/*! @brief Clock ip name array for SDHC. */ +#define SDHC_CLOCKS \ + { \ + kCLOCK_Sdhc0 \ + } + +/*! @brief Clock ip name array for FTM. */ +#define FTM_CLOCKS \ + { \ + kCLOCK_Ftm0, kCLOCK_Ftm1, kCLOCK_Ftm2, kCLOCK_Ftm3 \ + } + +/*! @brief Clock ip name array for EDMA. */ +#define EDMA_CLOCKS \ + { \ + kCLOCK_Dma0 \ + } + +/*! @brief Clock ip name array for LPUART. */ +#define LPUART_CLOCKS \ + { \ + kCLOCK_Lpuart0, kCLOCK_Lpuart1, kCLOCK_Lpuart2, kCLOCK_Lpuart3, kCLOCK_Lpuart4 \ + } + +/*! @brief Clock ip name array for DAC. */ +#define DAC_CLOCKS \ + { \ + kCLOCK_Dac0 \ + } + +/*! @brief Clock ip name array for LPTMR. */ +#define LPTMR_CLOCKS \ + { \ + kCLOCK_Lptmr0, kCLOCK_Lptmr1 \ + } + +/*! @brief Clock ip name array for ADC16. */ +#define ADC16_CLOCKS \ + { \ + kCLOCK_Adc0 \ + } + +/*! @brief Clock ip name array for SDRAM. */ +#define SDRAM_CLOCKS \ + { \ + kCLOCK_Sdramc0 \ + } + +/*! @brief Clock ip name array for TRNG. */ +#define TRNG_CLOCKS \ + { \ + kCLOCK_Trng0 \ + } + +/*! @brief Clock ip name array for MPU. */ +#define MPU_CLOCKS \ + { \ + kCLOCK_Mpu0 \ + } + +/*! @brief Clock ip name array for FLEXIO. */ +#define FLEXIO_CLOCKS \ + { \ + kCLOCK_Flexio0 \ + } + +/*! @brief Clock ip name array for VREF. */ +#define VREF_CLOCKS \ + { \ + kCLOCK_Vref0 \ + } + +/*! @brief Clock ip name array for CMT. */ +#define CMT_CLOCKS \ + { \ + kCLOCK_Cmt0 \ + } + +/*! @brief Clock ip name array for TPM. */ +#define TPM_CLOCKS \ + { \ + kCLOCK_IpInvalid, kCLOCK_Tpm1, kCLOCK_Tpm2 \ + } + +/*! @brief Clock ip name array for TSI. */ +#define TSI_CLOCKS \ + { \ + kCLOCK_Tsi0 \ + } + +/*! @brief Clock ip name array for LTC. */ +#define LTC_CLOCKS \ + { \ + kCLOCK_Ltc0 \ + } + +/*! @brief Clock ip name array for CRC. */ +#define CRC_CLOCKS \ + { \ + kCLOCK_Crc0 \ + } + +/*! @brief Clock ip name array for I2C. */ +#define I2C_CLOCKS \ + { \ + kCLOCK_I2c0, kCLOCK_I2c1, kCLOCK_I2c2, kCLOCK_I2c3 \ + } + +/*! @brief Clock ip name array for PDB. */ +#define PDB_CLOCKS \ + { \ + kCLOCK_Pdb0 \ + } + +/*! @brief Clock ip name array for FTF. */ +#define FTF_CLOCKS \ + { \ + kCLOCK_Ftf0 \ + } + +/*! @brief Clock ip name array for CMP. */ +#define CMP_CLOCKS \ + { \ + kCLOCK_Cmp0, kCLOCK_Cmp1 \ + } + +/*! + * @brief LPO clock frequency. + */ +#define LPO_CLK_FREQ 1000U + +/*! @brief Peripherals clock source definition. */ +#define SYS_CLK kCLOCK_CoreSysClk +#define BUS_CLK kCLOCK_BusClk + +#define I2C0_CLK_SRC BUS_CLK +#define I2C1_CLK_SRC BUS_CLK +#define I2C2_CLK_SRC BUS_CLK +#define I2C3_CLK_SRC BUS_CLK +#define DSPI0_CLK_SRC BUS_CLK +#define DSPI1_CLK_SRC BUS_CLK +#define DSPI2_CLK_SRC BUS_CLK + +/*! @brief Clock name used to get clock frequency. */ +typedef enum _clock_name +{ + + /* ----------------------------- System layer clock -------------------------------*/ + kCLOCK_CoreSysClk, /*!< Core/system clock */ + kCLOCK_PlatClk, /*!< Platform clock */ + kCLOCK_BusClk, /*!< Bus clock */ + kCLOCK_FlexBusClk, /*!< FlexBus clock */ + kCLOCK_FlashClk, /*!< Flash clock */ + kCLOCK_FastPeriphClk, /*!< Fast peripheral clock */ + kCLOCK_PllFllSelClk, /*!< The clock after SIM[PLLFLLSEL]. */ + + /* ---------------------------------- OSC clock -----------------------------------*/ + kCLOCK_Er32kClk, /*!< External reference 32K clock (ERCLK32K) */ + kCLOCK_Osc0ErClk, /*!< OSC0 external reference clock (OSC0ERCLK) */ + kCLOCK_Osc1ErClk, /*!< OSC1 external reference clock (OSC1ERCLK) */ + kCLOCK_Osc0ErClkUndiv, /*!< OSC0 external reference undivided clock(OSC0ERCLK_UNDIV). */ + + /* ----------------------------- MCG and MCG-Lite clock ---------------------------*/ + kCLOCK_McgFixedFreqClk, /*!< MCG fixed frequency clock (MCGFFCLK) */ + kCLOCK_McgInternalRefClk, /*!< MCG internal reference clock (MCGIRCLK) */ + kCLOCK_McgFllClk, /*!< MCGFLLCLK */ + kCLOCK_McgPll0Clk, /*!< MCGPLL0CLK */ + kCLOCK_McgPll1Clk, /*!< MCGPLL1CLK */ + kCLOCK_McgExtPllClk, /*!< EXT_PLLCLK */ + kCLOCK_McgPeriphClk, /*!< MCG peripheral clock (MCGPCLK) */ + kCLOCK_McgIrc48MClk, /*!< MCG IRC48M clock */ + + /* --------------------------------- Other clock ----------------------------------*/ + kCLOCK_LpoClk, /*!< LPO clock */ + +} clock_name_t; + +/*! @brief USB clock source definition. */ +typedef enum _clock_usb_src +{ + kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */ + kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(3U), /*!< Use IRC48M. */ + kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */ +} clock_usb_src_t; +/*------------------------------------------------------------------------------ + + clock_gate_t definition: + + 31 16 0 + ----------------------------------------------------------------- + | SIM_SCGC register offset | control bit offset in SCGC | + ----------------------------------------------------------------- + + For example, the SDHC clock gate is controlled by SIM_SCGC3[17], the + SIM_SCGC3 offset in SIM is 0x1030, then kClockGateSdhc0 is defined as + + kClockGateSdhc0 = (0x1030 << 16) | 17; + +------------------------------------------------------------------------------*/ + +#define CLK_GATE_REG_OFFSET_SHIFT 16U +#define CLK_GATE_REG_OFFSET_MASK 0xFFFF0000U +#define CLK_GATE_BIT_SHIFT_SHIFT 0U +#define CLK_GATE_BIT_SHIFT_MASK 0x0000FFFFU + +#define CLK_GATE_DEFINE(reg_offset, bit_shift) \ + ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \ + (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK)) + +#define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT) +#define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT) + +/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */ +typedef enum _clock_ip_name +{ + kCLOCK_IpInvalid = 0U, + kCLOCK_I2c2 = CLK_GATE_DEFINE(0x1028U, 6U), + kCLOCK_I2c3 = CLK_GATE_DEFINE(0x1028U, 7U), + + kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x102CU, 4U), + kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x102CU, 5U), + kCLOCK_Lpuart2 = CLK_GATE_DEFINE(0x102CU, 6U), + kCLOCK_Lpuart3 = CLK_GATE_DEFINE(0x102CU, 7U), + kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x102CU, 9U), + kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x102CU, 10U), + kCLOCK_Dac0 = CLK_GATE_DEFINE(0x102CU, 12U), + kCLOCK_Ltc0 = CLK_GATE_DEFINE(0x102CU, 17U), + kCLOCK_Emvsim0 = CLK_GATE_DEFINE(0x102CU, 20U), + kCLOCK_Emvsim1 = CLK_GATE_DEFINE(0x102CU, 21U), + kCLOCK_Lpuart4 = CLK_GATE_DEFINE(0x102CU, 22U), + kCLOCK_Qspi0 = CLK_GATE_DEFINE(0x102CU, 26U), + kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x102CU, 31U), + + kCLOCK_Trng0 = CLK_GATE_DEFINE(0x1030U, 0U), + kCLOCK_Spi2 = CLK_GATE_DEFINE(0x1030U, 12U), + kCLOCK_Sdhc0 = CLK_GATE_DEFINE(0x1030U, 17U), + kCLOCK_Ftm3 = CLK_GATE_DEFINE(0x1030U, 25U), + + kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U), + kCLOCK_Cmt0 = CLK_GATE_DEFINE(0x1034U, 2U), + kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U), + kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U), + kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U), + kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U), + kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U), + kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U), + + kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U), + kCLOCK_Lptmr1 = CLK_GATE_DEFINE(0x1038U, 4U), + kCLOCK_Tsi0 = CLK_GATE_DEFINE(0x1038U, 5U), + kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U), + kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U), + kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U), + kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U), + kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U), + + kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U), + kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U), + kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U), + kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U), + kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U), + kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U), + kCLOCK_Usbdcd0 = CLK_GATE_DEFINE(0x103CU, 21U), + kCLOCK_Pdb0 = CLK_GATE_DEFINE(0x103CU, 22U), + kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U), + kCLOCK_Ftm0 = CLK_GATE_DEFINE(0x103CU, 24U), + kCLOCK_Ftm1 = CLK_GATE_DEFINE(0x103CU, 25U), + kCLOCK_Ftm2 = CLK_GATE_DEFINE(0x103CU, 26U), + kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U), + kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U), + + kCLOCK_Flexbus0 = CLK_GATE_DEFINE(0x1040U, 0U), + kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U), + kCLOCK_Mpu0 = CLK_GATE_DEFINE(0x1040U, 2U), + kCLOCK_Sdramc0 = CLK_GATE_DEFINE(0x1040U, 3U), +} clock_ip_name_t; + +/*!@brief SIM configuration structure for clock setting. */ +typedef struct _sim_clock_config +{ + uint8_t pllFllSel; /*!< PLL/FLL/IRC48M selection. */ + uint8_t pllFllDiv; /*!< PLLFLLSEL clock divider divisor. */ + uint8_t pllFllFrac; /*!< PLLFLLSEL clock divider fraction. */ + uint8_t er32kSrc; /*!< ERCLK32K source selection. */ + uint32_t clkdiv1; /*!< SIM_CLKDIV1. */ +} sim_clock_config_t; + +/*! @brief OSC work mode. */ +typedef enum _osc_mode +{ + kOSC_ModeExt = 0U, /*!< Use an external clock. */ +#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) + kOSC_ModeOscLowPower = MCG_C2_EREFS_MASK, /*!< Oscillator low power. */ +#else + kOSC_ModeOscLowPower = MCG_C2_EREFS0_MASK, /*!< Oscillator low power. */ +#endif + kOSC_ModeOscHighGain = 0U +#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) + | + MCG_C2_EREFS_MASK +#else + | + MCG_C2_EREFS0_MASK +#endif +#if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK))) + | + MCG_C2_HGO_MASK, /*!< Oscillator high gain. */ +#else + | + MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */ +#endif +} osc_mode_t; + +/*! @brief Oscillator capacitor load setting.*/ +enum _osc_cap_load +{ + kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */ + kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */ + kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */ + kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */ +}; + +/*! @brief OSCERCLK enable mode. */ +enum _oscer_enable_mode +{ + kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */ + kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */ +}; + +/*! @brief OSC configuration for OSCERCLK. */ +typedef struct _oscer_config +{ + uint8_t enableMode; /*!< OSCERCLK enable mode. OR'ed value of @ref _oscer_enable_mode. */ + + uint8_t erclkDiv; /*!< Divider for OSCERCLK.*/ +} oscer_config_t; + +/*! + * @brief OSC Initialization Configuration Structure + * + * Defines the configuration data structure to initialize the OSC. + * When porting to a new board, set the following members + * according to the board setting: + * 1. freq: The external frequency. + * 2. workMode: The OSC module mode. + */ +typedef struct _osc_config +{ + uint32_t freq; /*!< External clock frequency. */ + uint8_t capLoad; /*!< Capacitor load setting. */ + osc_mode_t workMode; /*!< OSC work mode setting. */ + oscer_config_t oscerConfig; /*!< Configuration for OSCERCLK. */ +} osc_config_t; + +/*! @brief MCG FLL reference clock source select. */ +typedef enum _mcg_fll_src +{ + kMCG_FllSrcExternal, /*!< External reference clock is selected */ + kMCG_FllSrcInternal /*!< The slow internal reference clock is selected */ +} mcg_fll_src_t; + +/*! @brief MCG internal reference clock select */ +typedef enum _mcg_irc_mode +{ + kMCG_IrcSlow, /*!< Slow internal reference clock selected */ + kMCG_IrcFast /*!< Fast internal reference clock selected */ +} mcg_irc_mode_t; + +/*! @brief MCG DCO Maximum Frequency with 32.768 kHz Reference */ +typedef enum _mcg_dmx32 +{ + kMCG_Dmx32Default, /*!< DCO has a default range of 25% */ + kMCG_Dmx32Fine /*!< DCO is fine-tuned for maximum frequency with 32.768 kHz reference */ +} mcg_dmx32_t; + +/*! @brief MCG DCO range select */ +typedef enum _mcg_drs +{ + kMCG_DrsLow, /*!< Low frequency range */ + kMCG_DrsMid, /*!< Mid frequency range */ + kMCG_DrsMidHigh, /*!< Mid-High frequency range */ + kMCG_DrsHigh /*!< High frequency range */ +} mcg_drs_t; + +/*! @brief MCG PLL reference clock select */ +typedef enum _mcg_pll_ref_src +{ + kMCG_PllRefOsc0, /*!< Selects OSC0 as PLL reference clock */ + kMCG_PllRefOsc1 /*!< Selects OSC1 as PLL reference clock */ +} mcg_pll_ref_src_t; + +/*! @brief MCGOUT clock source. */ +typedef enum _mcg_clkout_src +{ + kMCG_ClkOutSrcOut, /*!< Output of the FLL is selected (reset default) */ + kMCG_ClkOutSrcInternal, /*!< Internal reference clock is selected */ + kMCG_ClkOutSrcExternal, /*!< External reference clock is selected */ +} mcg_clkout_src_t; + +/*! @brief MCG Automatic Trim Machine Select */ +typedef enum _mcg_atm_select +{ + kMCG_AtmSel32k, /*!< 32 kHz Internal Reference Clock selected */ + kMCG_AtmSel4m /*!< 4 MHz Internal Reference Clock selected */ +} mcg_atm_select_t; + +/*! @brief MCG OSC Clock Select */ +typedef enum _mcg_oscsel +{ + kMCG_OscselOsc, /*!< Selects System Oscillator (OSCCLK) */ + kMCG_OscselRtc, /*!< Selects 32 kHz RTC Oscillator */ + kMCG_OscselIrc /*!< Selects 48 MHz IRC Oscillator */ +} mcg_oscsel_t; + +/*! @brief MCG PLLCS select */ +typedef enum _mcg_pll_clk_select +{ + kMCG_PllClkSelPll0, /*!< PLL0 output clock is selected */ + kMCG_PllClkSelPll1 /* PLL1 output clock is selected */ +} mcg_pll_clk_select_t; + +/*! @brief MCG clock monitor mode. */ +typedef enum _mcg_monitor_mode +{ + kMCG_MonitorNone, /*!< Clock monitor is disabled. */ + kMCG_MonitorInt, /*!< Trigger interrupt when clock lost. */ + kMCG_MonitorReset /*!< System reset when clock lost. */ +} mcg_monitor_mode_t; + +/*! @brief MCG status. */ +enum _mcg_status +{ + kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */ + kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific + function. */ + kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */ + kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */ + kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */ + kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */ + kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because + it is in use. */ +}; + +/*! @brief MCG status flags. */ +enum _mcg_status_flags_t +{ + kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */ + kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */ + kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost. */ + kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost. */ + kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked. */ +}; + +/*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */ +enum _mcg_irclk_enable_mode +{ + kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */ + kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */ +}; + +/*! @brief MCG PLL clock enable mode definition. */ +enum _mcg_pll_enable_mode +{ + kMCG_PllEnableIndependent = MCG_C5_PLLCLKEN0_MASK, /*!< MCGPLLCLK enable independent of the + MCG clock mode. Generally, the PLL + is disabled in FLL modes + (FEI/FBI/FEE/FBE). Setting the PLL clock + enable independent, enables the + PLL in the FLL modes. */ + kMCG_PllEnableInStop = MCG_C5_PLLSTEN0_MASK /*!< MCGPLLCLK enable in STOP mode. */ +}; + +/*! @brief MCG mode definitions */ +typedef enum _mcg_mode +{ + kMCG_ModeFEI = 0U, /*!< FEI - FLL Engaged Internal */ + kMCG_ModeFBI, /*!< FBI - FLL Bypassed Internal */ + kMCG_ModeBLPI, /*!< BLPI - Bypassed Low Power Internal */ + kMCG_ModeFEE, /*!< FEE - FLL Engaged External */ + kMCG_ModeFBE, /*!< FBE - FLL Bypassed External */ + kMCG_ModeBLPE, /*!< BLPE - Bypassed Low Power External */ + kMCG_ModePBE, /*!< PBE - PLL Bypassed External */ + kMCG_ModePEE, /*!< PEE - PLL Engaged External */ + kMCG_ModeError /*!< Unknown mode */ +} mcg_mode_t; + +/*! @brief MCG PLL configuration. */ +typedef struct _mcg_pll_config +{ + uint8_t enableMode; /*!< Enable mode. OR'ed value of @ref _mcg_pll_enable_mode. */ + uint8_t prdiv; /*!< Reference divider PRDIV. */ + uint8_t vdiv; /*!< VCO divider VDIV. */ +} mcg_pll_config_t; + +/*! @brief MCG mode change configuration structure + * + * When porting to a new board, set the following members + * according to the board setting: + * 1. frdiv: If the FLL uses the external reference clock, set this + * value to ensure that the external reference clock divided by frdiv is + * in the 31.25 kHz to 39.0625 kHz range. + * 2. The PLL reference clock divider PRDIV: PLL reference clock frequency after + * PRDIV should be in the FSL_FEATURE_MCG_PLL_REF_MIN to + * FSL_FEATURE_MCG_PLL_REF_MAX range. + */ +typedef struct _mcg_config +{ + mcg_mode_t mcgMode; /*!< MCG mode. */ + + /* ----------------------- MCGIRCCLK settings ------------------------ */ + uint8_t irclkEnableMode; /*!< MCGIRCLK enable mode. */ + mcg_irc_mode_t ircs; /*!< Source, MCG_C2[IRCS]. */ + uint8_t fcrdiv; /*!< Divider, MCG_SC[FCRDIV]. */ + + /* ------------------------ MCG FLL settings ------------------------- */ + uint8_t frdiv; /*!< Divider MCG_C1[FRDIV]. */ + mcg_drs_t drs; /*!< DCO range MCG_C4[DRST_DRS]. */ + mcg_dmx32_t dmx32; /*!< MCG_C4[DMX32]. */ + mcg_oscsel_t oscsel; /*!< OSC select MCG_C7[OSCSEL]. */ + + /* ------------------------ MCG PLL settings ------------------------- */ + mcg_pll_config_t pll0Config; /*!< MCGPLL0CLK configuration. */ + +} mcg_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @brief Enable the clock for specific IP. + * + * @param name Which clock to enable, see \ref clock_ip_name_t. + */ +static inline void CLOCK_EnableClock(clock_ip_name_t name) +{ + uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name); + (*(volatile uint32_t *)regAddr) |= (1U << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name)); +} + +/*! + * @brief Disable the clock for specific IP. + * + * @param name Which clock to disable, see \ref clock_ip_name_t. + */ +static inline void CLOCK_DisableClock(clock_ip_name_t name) +{ + uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name); + (*(volatile uint32_t *)regAddr) &= ~(1U << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name)); +} + +/*! + * @brief Set ERCLK32K source. + * + * @param src The value to set ERCLK32K clock source. + */ +static inline void CLOCK_SetEr32kClock(uint32_t src) +{ + SIM->SOPT1 = ((SIM->SOPT1 & ~SIM_SOPT1_OSC32KSEL_MASK) | SIM_SOPT1_OSC32KSEL(src)); +} + +/*! + * @brief Set SDHC0 clock source. + * + * @param src The value to set SDHC0 clock source. + */ +static inline void CLOCK_SetSdhc0Clock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_SDHCSRC_MASK) | SIM_SOPT2_SDHCSRC(src)); +} + +/*! + * @brief Set EMVSIM clock source. + * + * @param src The value to set EMVSIM clock source. + */ +static inline void CLOCK_SetEmvsimClock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_EMVSIMSRC_MASK) | SIM_SOPT2_EMVSIMSRC(src)); +} + +/*! + * @brief Set LPUART clock source. + * + * @param src The value to set LPUART clock source. + */ +static inline void CLOCK_SetLpuartClock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_LPUARTSRC_MASK) | SIM_SOPT2_LPUARTSRC(src)); +} + +/*! + * @brief Set TPM clock source. + * + * @param src The value to set TPM clock source. + */ +static inline void CLOCK_SetTpmClock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TPMSRC_MASK) | SIM_SOPT2_TPMSRC(src)); +} + +/*! + * @brief Set FLEXIO clock source. + * + * @param src The value to set FLEXIO clock source. + */ +static inline void CLOCK_SetFlexio0Clock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_FLEXIOSRC_MASK) | SIM_SOPT2_FLEXIOSRC(src)); +} + +/*! + * @brief Set debug trace clock source. + * + * @param src The value to set debug trace clock source. + */ +static inline void CLOCK_SetTraceClock(uint32_t src, uint32_t divValue, uint32_t fracValue) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TRACECLKSEL_MASK) | SIM_SOPT2_TRACECLKSEL(src)); + SIM->CLKDIV4 = SIM_CLKDIV4_TRACEDIV(divValue) | SIM_CLKDIV4_TRACEFRAC(fracValue); +} + +/*! + * @brief Set PLLFLLSEL clock source. + * + * @param src The value to set PLLFLLSEL clock source. + */ +static inline void CLOCK_SetPllFllSelClock(uint32_t src, uint32_t divValue, uint32_t fracValue) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_PLLFLLSEL_MASK) | SIM_SOPT2_PLLFLLSEL(src)); + SIM->CLKDIV3 = SIM_CLKDIV3_PLLFLLDIV(divValue) | SIM_CLKDIV3_PLLFLLFRAC(fracValue); +} + +/*! + * @brief Set CLKOUT source. + * + * @param src The value to set CLKOUT source. + */ +static inline void CLOCK_SetClkOutClock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_CLKOUTSEL_MASK) | SIM_SOPT2_CLKOUTSEL(src)); +} + +/*! + * @brief Set RTC_CLKOUT source. + * + * @param src The value to set RTC_CLKOUT source. + */ +static inline void CLOCK_SetRtcClkOutClock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_RTCCLKOUTSEL_MASK) | SIM_SOPT2_RTCCLKOUTSEL(src)); +} + +/*! @brief Enable USB FS clock. + * + * @param src USB FS clock source. + * @param freq The frequency specified by src. + * @retval true The clock is set successfully. + * @retval false The clock source is invalid to get proper USB FS clock. + */ +bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq); + +/*! @brief Disable USB FS clock. + * + * Disable USB FS clock. + */ +static inline void CLOCK_DisableUsbfs0Clock(void) +{ + CLOCK_DisableClock(kCLOCK_Usbfs0); +} + +/*! + * @brief System clock divider + * + * Set the SIM_CLKDIV1[OUTDIV1], SIM_CLKDIV1[OUTDIV2], SIM_CLKDIV1[OUTDIV3], SIM_CLKDIV1[OUTDIV4]. + * + * @param outdiv1 Clock 1 output divider value. + * + * @param outdiv2 Clock 2 output divider value. + * + * @param outdiv3 Clock 3 output divider value. + * + * @param outdiv4 Clock 4 output divider value. + */ +static inline void CLOCK_SetOutDiv(uint32_t outdiv1, uint32_t outdiv2, uint32_t outdiv3, uint32_t outdiv4) +{ + SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV2(outdiv2) | SIM_CLKDIV1_OUTDIV3(outdiv3) | + SIM_CLKDIV1_OUTDIV4(outdiv4); +} + +/*! + * @brief Gets the clock frequency for a specific clock name. + * + * This function checks the current clock configurations and then calculates + * the clock frequency for a specific clock name defined in clock_name_t. + * The MCG must be properly configured before using this function. + * + * @param clockName Clock names defined in clock_name_t + * @return Clock frequency value in Hertz + */ +uint32_t CLOCK_GetFreq(clock_name_t clockName); + +/*! + * @brief Get the core clock or system clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetCoreSysClkFreq(void); + +/*! + * @brief Get the platform clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetPlatClkFreq(void); + +/*! + * @brief Get the bus clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetBusClkFreq(void); + +/*! + * @brief Get the flexbus clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetFlexBusClkFreq(void); + +/*! + * @brief Get the flash clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetFlashClkFreq(void); + +/*! + * @brief Get the output clock frequency selected by SIM[PLLFLLSEL]. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetPllFllSelClkFreq(void); + +/*! + * @brief Get the external reference 32K clock frequency (ERCLK32K). + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetEr32kClkFreq(void); + +/*! + * @brief Get the OSC0 external reference undivided clock frequency (OSC0ERCLK_UNDIV). + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetOsc0ErClkUndivFreq(void); + +/*! + * @brief Get the OSC0 external reference clock frequency (OSC0ERCLK). + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetOsc0ErClkFreq(void); + +/*! + * @brief Set the clock configure in SIM module. + * + * This function sets system layer clock settings in SIM module. + * + * @param config Pointer to the configure structure. + */ +void CLOCK_SetSimConfig(sim_clock_config_t const *config); + +/*! + * @brief Set the system clock dividers in SIM to safe value. + * + * The system level clocks (core clock, bus clock, flexbus clock and flash clock) + * must be in allowed ranges. During MCG clock mode switch, the MCG output clock + * changes then the system level clocks may be out of range. This function could + * be used before MCG mode change, to make sure system level clocks are in allowed + * range. + * + * @param config Pointer to the configure structure. + */ +static inline void CLOCK_SetSimSafeDivs(void) +{ + SIM->CLKDIV1 = 0x01140000U; +} + +/*! @name MCG frequency functions. */ +/*@{*/ + +/*! + * @brief Gets the MCG output clock (MCGOUTCLK) frequency. + * + * This function gets the MCG output clock frequency in Hz based on the current MCG + * register value. + * + * @return The frequency of MCGOUTCLK. + */ +uint32_t CLOCK_GetOutClkFreq(void); + +/*! + * @brief Gets the MCG FLL clock (MCGFLLCLK) frequency. + * + * This function gets the MCG FLL clock frequency in Hz based on the current MCG + * register value. The FLL is enabled in FEI/FBI/FEE/FBE mode and + * disabled in low power state in other modes. + * + * @return The frequency of MCGFLLCLK. + */ +uint32_t CLOCK_GetFllFreq(void); + +/*! + * @brief Gets the MCG internal reference clock (MCGIRCLK) frequency. + * + * This function gets the MCG internal reference clock frequency in Hz based + * on the current MCG register value. + * + * @return The frequency of MCGIRCLK. + */ +uint32_t CLOCK_GetInternalRefClkFreq(void); + +/*! + * @brief Gets the MCG fixed frequency clock (MCGFFCLK) frequency. + * + * This function gets the MCG fixed frequency clock frequency in Hz based + * on the current MCG register value. + * + * @return The frequency of MCGFFCLK. + */ +uint32_t CLOCK_GetFixedFreqClkFreq(void); + +/*! + * @brief Gets the MCG PLL0 clock (MCGPLL0CLK) frequency. + * + * This function gets the MCG PLL0 clock frequency in Hz based on the current MCG + * register value. + * + * @return The frequency of MCGPLL0CLK. + */ +uint32_t CLOCK_GetPll0Freq(void); + +/*@}*/ + +/*! @name MCG clock configuration. */ +/*@{*/ + +/*! + * @brief Enables or disables the MCG low power. + * + * Enabling the MCG low power disables the PLL and FLL in bypass modes. In other words, + * in FBE and PBE modes, enabling low power sets the MCG to BLPE mode. In FBI and + * PBI modes, enabling low power sets the MCG to BLPI mode. + * When disabling the MCG low power, the PLL or FLL are enabled based on MCG settings. + * + * @param enable True to enable MCG low power, false to disable MCG low power. + */ +static inline void CLOCK_SetLowPowerEnable(bool enable) +{ + if (enable) + { + MCG->C2 |= MCG_C2_LP_MASK; + } + else + { + MCG->C2 &= ~MCG_C2_LP_MASK; + } +} + +/*! + * @brief Configures the Internal Reference clock (MCGIRCLK). + * + * This function sets the \c MCGIRCLK base on parameters. It also selects the IRC + * source. If the fast IRC is used, this function sets the fast IRC divider. + * This function also sets whether the \c MCGIRCLK is enabled in stop mode. + * Calling this function in FBI/PBI/BLPI modes may change the system clock. As a result, + * using the function in these modes it is not allowed. + * + * @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. + * @param ircs MCGIRCLK clock source, choose fast or slow. + * @param fcrdiv Fast IRC divider setting (\c FCRDIV). + * @retval kStatus_MCG_SourceUsed Because the internall reference clock is used as a clock source, + * the confuration should not be changed. Otherwise, a glitch occurs. + * @retval kStatus_Success MCGIRCLK configuration finished successfully. + */ +status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv); + +/*! + * @brief Selects the MCG external reference clock. + * + * Selects the MCG external reference clock source, changes the MCG_C7[OSCSEL], + * and waits for the clock source to be stable. Because the external reference + * clock should not be changed in FEE/FBE/BLPE/PBE/PEE modes, do not call this function in these modes. + * + * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL]. + * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source, + * the confuration should not be changed. Otherwise, a glitch occurs. + * @retval kStatus_Success External reference clock set successfully. + */ +status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel); + +/*! + * @brief Set the FLL external reference clock divider value. + * + * Sets the FLL external reference clock divider value, the register MCG_C1[FRDIV]. + * + * @param frdiv The FLL external reference clock divider value, MCG_C1[FRDIV]. + */ +static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv) +{ + MCG->C1 = (MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv); +} + +/*! + * @brief Enables the PLL0 in FLL mode. + * + * This function sets us the PLL0 in FLL mode and reconfigures + * the PLL0. Ensure that the PLL reference + * clock is enabled before calling this function and that the PLL0 is not used as a clock source. + * The function CLOCK_CalcPllDiv gets the correct PLL + * divider values. + * + * @param config Pointer to the configuration structure. + */ +void CLOCK_EnablePll0(mcg_pll_config_t const *config); + +/*! + * @brief Disables the PLL0 in FLL mode. + * + * This function disables the PLL0 in FLL mode. It should be used together with the + * @ref CLOCK_EnablePll0. + */ +static inline void CLOCK_DisablePll0(void) +{ + MCG->C5 &= ~(MCG_C5_PLLCLKEN0_MASK | MCG_C5_PLLSTEN0_MASK); +} + +/*! + * @brief Calculates the PLL divider setting for a desired output frequency. + * + * This function calculates the correct reference clock divider (\c PRDIV) and + * VCO divider (\c VDIV) to generate a desired PLL output frequency. It returns the + * closest frequency match with the corresponding \c PRDIV/VDIV + * returned from parameters. If a desired frequency is not valid, this function + * returns 0. + * + * @param refFreq PLL reference clock frequency. + * @param desireFreq Desired PLL output frequency. + * @param prdiv PRDIV value to generate desired PLL frequency. + * @param vdiv VDIV value to generate desired PLL frequency. + * @return Closest frequency match that the PLL was able generate. + */ +uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv); + +/*@}*/ + +/*! @name MCG clock lock monitor functions. */ +/*@{*/ + +/*! + * @brief Sets the OSC0 clock monitor mode. + * + * This function sets the OSC0 clock monitor mode. See @ref mcg_monitor_mode_t for details. + * + * @param mode Monitor mode to set. + */ +void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode); + +/*! + * @brief Sets the RTC OSC clock monitor mode. + * + * This function sets the RTC OSC clock monitor mode. See @ref mcg_monitor_mode_t for details. + * + * @param mode Monitor mode to set. + */ +void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode); + +/*! + * @brief Sets the PLL0 clock monitor mode. + * + * This function sets the PLL0 clock monitor mode. See @ref mcg_monitor_mode_t for details. + * + * @param mode Monitor mode to set. + */ +void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode); + +/*! + * @brief Gets the MCG status flags. + * + * This function gets the MCG clock status flags. All status flags are + * returned as a logical OR of the enumeration @ref _mcg_status_flags_t. To + * check a specific flag, compare the return value with the flag. + * + * Example: + * @code + // To check the clock lost lock status of OSC0 and PLL0. + uint32_t mcgFlags; + + mcgFlags = CLOCK_GetStatusFlags(); + + if (mcgFlags & kMCG_Osc0LostFlag) + { + // OSC0 clock lock lost. Do something. + } + if (mcgFlags & kMCG_Pll0LostFlag) + { + // PLL0 clock lock lost. Do something. + } + @endcode + * + * @return Logical OR value of the @ref _mcg_status_flags_t. + */ +uint32_t CLOCK_GetStatusFlags(void); + +/*! + * @brief Clears the MCG status flags. + * + * This function clears the MCG clock lock lost status. The parameter is a logical + * OR value of the flags to clear. See @ref _mcg_status_flags_t. + * + * Example: + * @code + // To clear the clock lost lock status flags of OSC0 and PLL0. + + CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag); + @endcode + * + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration @ref _mcg_status_flags_t. + */ +void CLOCK_ClearStatusFlags(uint32_t mask); + +/*@}*/ + +/*! + * @name OSC configuration + * @{ + */ + +/*! + * @brief Configures the OSC external reference clock (OSCERCLK). + * + * This function configures the OSC external reference clock (OSCERCLK). + * This is an example to enable the OSCERCLK in normal and stop modes and also set + * the output divider to 1: + * + @code + oscer_config_t config = + { + .enableMode = kOSC_ErClkEnable | kOSC_ErClkEnableInStop, + .erclkDiv = 1U, + }; + + OSC_SetExtRefClkConfig(OSC, &config); + @endcode + * + * @param base OSC peripheral address. + * @param config Pointer to the configuration structure. + */ +static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *config) +{ + uint8_t reg = base->CR; + + reg &= ~(OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK); + reg |= config->enableMode; + + base->CR = reg; + + base->DIV = OSC_DIV_ERPS(config->erclkDiv); +} + +/*! + * @brief Sets the capacitor load configuration for the oscillator. + * + * This function sets the specified capacitors configuration for the oscillator. + * This should be done in the early system level initialization function call + * based on the system configuration. + * + * @param base OSC peripheral address. + * @param capLoad OR'ed value for the capacitor load option, see \ref _osc_cap_load. + * + * Example: + @code + // To enable only 2 pF and 8 pF capacitor load, please use like this. + OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P); + @endcode + */ +static inline void OSC_SetCapLoad(OSC_Type *base, uint8_t capLoad) +{ + uint8_t reg = base->CR; + + reg &= ~(OSC_CR_SC2P_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK | OSC_CR_SC16P_MASK); + reg |= capLoad; + + base->CR = reg; +} + +/*! + * @brief Initializes the OSC0. + * + * This function initializes the OSC0 according to the board configuration. + * + * @param config Pointer to the OSC0 configuration structure. + */ +void CLOCK_InitOsc0(osc_config_t const *config); + +/*! + * @brief Deinitializes the OSC0. + * + * This function deinitializes the OSC0. + */ +void CLOCK_DeinitOsc0(void); + +/* @} */ + +/*! + * @name External clock frequency + * @{ + */ + +/*! + * @brief Sets the XTAL0 frequency based on board settings. + * + * @param freq The XTAL0/EXTAL0 input clock frequency in Hz. + */ +static inline void CLOCK_SetXtal0Freq(uint32_t freq) +{ + g_xtal0Freq = freq; +} + +/*! + * @brief Sets the XTAL32/RTC_CLKIN frequency based on board settings. + * + * @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz. + */ +static inline void CLOCK_SetXtal32Freq(uint32_t freq) +{ + g_xtal32Freq = freq; +} +/* @} */ + +/*! + * @name MCG auto-trim machine. + * @{ + */ + +/*! + * @brief Auto trims the internal reference clock. + * + * This function trims the internal reference clock by using the external clock. If + * successful, it returns the kStatus_Success and the frequency after + * trimming is received in the parameter @p actualFreq. If an error occurs, + * the error code is returned. + * + * @param extFreq External clock frequency, which should be a bus clock. + * @param desireFreq Frequency to trim to. + * @param actualFreq Actual frequency after trimming. + * @param atms Trim fast or slow internal reference clock. + * @retval kStatus_Success ATM success. + * @retval kStatus_MCG_AtmBusClockInvalid The bus clock is not in allowed range for the ATM. + * @retval kStatus_MCG_AtmDesiredFreqInvalid MCGIRCLK could not be trimmed to the desired frequency. + * @retval kStatus_MCG_AtmIrcUsed Could not trim because MCGIRCLK is used as a bus clock source. + * @retval kStatus_MCG_AtmHardwareFail Hardware fails while trimming. + */ +status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_t *actualFreq, mcg_atm_select_t atms); +/* @} */ + +/*! @name MCG mode functions. */ +/*@{*/ + +/*! + * @brief Gets the current MCG mode. + * + * This function checks the MCG registers and determines the current MCG mode. + * + * @return Current MCG mode or error code; See @ref mcg_mode_t. + */ +mcg_mode_t CLOCK_GetMode(void); + +/*! + * @brief Sets the MCG to FEI mode. + * + * This function sets the MCG to FEI mode. If setting to FEI mode fails + * from the current mode, this function returns an error. + * + * @param dmx32 DMX32 in FEI mode. + * @param drs The DCO range selection. + * @param fllStableDelay Delay function to ensure that the FLL is stable. Passing + * NULL does not cause a delay. + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed + * to a frequency above 32768 Hz. + */ +status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); + +/*! + * @brief Sets the MCG to FEE mode. + * + * This function sets the MCG to FEE mode. If setting to FEE mode fails + * from the current mode, this function returns an error. + * + * @param frdiv FLL reference clock divider setting, FRDIV. + * @param dmx32 DMX32 in FEE mode. + * @param drs The DCO range selection. + * @param fllStableDelay Delay function to make sure FLL is stable. Passing + * NULL does not cause a delay. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); + +/*! + * @brief Sets the MCG to FBI mode. + * + * This function sets the MCG to FBI mode. If setting to FBI mode fails + * from the current mode, this function returns an error. + * + * @param dmx32 DMX32 in FBI mode. + * @param drs The DCO range selection. + * @param fllStableDelay Delay function to make sure FLL is stable. If the FLL + * is not used in FBI mode, this parameter can be NULL. Passing + * NULL does not cause a delay. + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed + * to frequency above 32768 Hz. + */ +status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); + +/*! + * @brief Sets the MCG to FBE mode. + * + * This function sets the MCG to FBE mode. If setting to FBE mode fails + * from the current mode, this function returns an error. + * + * @param frdiv FLL reference clock divider setting, FRDIV. + * @param dmx32 DMX32 in FBE mode. + * @param drs The DCO range selection. + * @param fllStableDelay Delay function to make sure FLL is stable. If the FLL + * is not used in FBE mode, this parameter can be NULL. Passing NULL + * does not cause a delay. + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); + +/*! + * @brief Sets the MCG to BLPI mode. + * + * This function sets the MCG to BLPI mode. If setting to BLPI mode fails + * from the current mode, this function returns an error. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_SetBlpiMode(void); + +/*! + * @brief Sets the MCG to BLPE mode. + * + * This function sets the MCG to BLPE mode. If setting to BLPE mode fails + * from the current mode, this function returns an error. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_SetBlpeMode(void); + +/*! + * @brief Sets the MCG to PBE mode. + * + * This function sets the MCG to PBE mode. If setting to PBE mode fails + * from the current mode, this function returns an error. + * + * @param pllcs The PLL selection, PLLCS. + * @param config Pointer to the PLL configuration. + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + * + * @note + * 1. The parameter \c pllcs selects the PLL. For platforms with + * only one PLL, the parameter pllcs is kept for interface compatibility. + * 2. The parameter \c config is the PLL configuration structure. On some + * platforms, it is possible to choose the external PLL directly, which renders the + * configuration structure not necessary. In this case, pass in NULL. + * For example: CLOCK_SetPbeMode(kMCG_OscselOsc, kMCG_PllClkSelExtPll, NULL); + */ +status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config); + +/*! + * @brief Sets the MCG to PEE mode. + * + * This function sets the MCG to PEE mode. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + * + * @note This function only changes the CLKS to use the PLL/FLL output. If the + * PRDIV/VDIV are different than in the PBE mode, set them up + * in PBE mode and wait. When the clock is stable, switch to PEE mode. + */ +status_t CLOCK_SetPeeMode(void); + +/*! + * @brief Switches the MCG to FBE mode from the external mode. + * + * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly. + * The external clock is used as the system clock souce and PLL is disabled. However, + * the FLL settings are not configured. This is a lite function with a small code size, which is useful + * during the mode switch. For example, to switch from PEE mode to FEI mode: + * + * @code + * CLOCK_ExternalModeToFbeModeQuick(); + * CLOCK_SetFeiMode(...); + * @endcode + * + * @retval kStatus_Success Switched successfully. + * @retval kStatus_MCG_ModeInvalid If the current mode is not an external mode, do not call this function. + */ +status_t CLOCK_ExternalModeToFbeModeQuick(void); + +/*! + * @brief Switches the MCG to FBI mode from internal modes. + * + * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly. + * The MCGIRCLK is used as the system clock souce and PLL is disabled. However, + * FLL settings are not configured. This is a lite function with a small code size, which is useful + * during the mode switch. For example, to switch from PEI mode to FEE mode: + * + * @code + * CLOCK_InternalModeToFbiModeQuick(); + * CLOCK_SetFeeMode(...); + * @endcode + * + * @retval kStatus_Success Switched successfully. + * @retval kStatus_MCG_ModeInvalid If the current mode is not an internal mode, do not call this function. + */ +status_t CLOCK_InternalModeToFbiModeQuick(void); + +/*! + * @brief Sets the MCG to FEI mode during system boot up. + * + * This function sets the MCG to FEI mode from the reset mode. It can also be used to + * set up MCG during system boot up. + * + * @param dmx32 DMX32 in FEI mode. + * @param drs The DCO range selection. + * @param fllStableDelay Delay function to ensure that the FLL is stable. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed + * to frequency above 32768 Hz. + */ +status_t CLOCK_BootToFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); + +/*! + * @brief Sets the MCG to FEE mode during system bootup. + * + * This function sets MCG to FEE mode from the reset mode. It can also be used to + * set up the MCG during system boot up. + * + * @param oscsel OSC clock select, OSCSEL. + * @param frdiv FLL reference clock divider setting, FRDIV. + * @param dmx32 DMX32 in FEE mode. + * @param drs The DCO range selection. + * @param fllStableDelay Delay function to ensure that the FLL is stable. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_BootToFeeMode( + mcg_oscsel_t oscsel, uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); + +/*! + * @brief Sets the MCG to BLPI mode during system boot up. + * + * This function sets the MCG to BLPI mode from the reset mode. It can also be used to + * set up the MCG during sytem boot up. + * + * @param fcrdiv Fast IRC divider, FCRDIV. + * @param ircs The internal reference clock to select, IRCS. + * @param ircEnableMode The MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. + * + * @retval kStatus_MCG_SourceUsed Could not change MCGIRCLK setting. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode); + +/*! + * @brief Sets the MCG to BLPE mode during sytem boot up. + * + * This function sets the MCG to BLPE mode from the reset mode. It can also be used to + * set up the MCG during sytem boot up. + * + * @param oscsel OSC clock select, MCG_C7[OSCSEL]. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel); + +/*! + * @brief Sets the MCG to PEE mode during system boot up. + * + * This function sets the MCG to PEE mode from reset mode. It can also be used to + * set up the MCG during system boot up. + * + * @param oscsel OSC clock select, MCG_C7[OSCSEL]. + * @param pllcs The PLL selection, PLLCS. + * @param config Pointer to the PLL configuration. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config); + +/*! + * @brief Sets the MCG to a target mode. + * + * This function sets MCG to a target mode defined by the configuration + * structure. If switching to the target mode fails, this function + * chooses the correct path. + * + * @param config Pointer to the target MCG mode configuration structure. + * @return Return kStatus_Success if switched successfully; Otherwise, it returns an error code #_mcg_status. + * + * @note If the external clock is used in the target mode, ensure that it is + * enabled. For example, if the OSC0 is used, set up OSC0 correctly before calling this + * function. + */ +status_t CLOCK_SetMcgConfig(mcg_config_t const *config); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @} */ + +#endif /* _FSL_CLOCK_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmp.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmp.c new file mode 100644 index 00000000000..d960936f246 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmp.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_cmp.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get instance number for CMP module. + * + * @param base CMP peripheral base address + */ +static uint32_t CMP_GetInstance(CMP_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to CMP bases for each instance. */ +static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to CMP clocks for each instance. */ +static const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Codes + ******************************************************************************/ +static uint32_t CMP_GetInstance(CMP_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_CMP_COUNT; instance++) + { + if (s_cmpBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_CMP_COUNT); + + return instance; +} + +void CMP_Init(CMP_Type *base, const cmp_config_t *config) +{ + assert(NULL != config); + + uint8_t tmp8; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the clock. */ + CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Configure. */ + CMP_Enable(base, false); /* Disable the CMP module during configuring. */ + /* CMPx_CR1. */ + tmp8 = base->CR1 & ~(CMP_CR1_PMODE_MASK | CMP_CR1_INV_MASK | CMP_CR1_COS_MASK | CMP_CR1_OPE_MASK); + if (config->enableHighSpeed) + { + tmp8 |= CMP_CR1_PMODE_MASK; + } + if (config->enableInvertOutput) + { + tmp8 |= CMP_CR1_INV_MASK; + } + if (config->useUnfilteredOutput) + { + tmp8 |= CMP_CR1_COS_MASK; + } + if (config->enablePinOut) + { + tmp8 |= CMP_CR1_OPE_MASK; + } +#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE + if (config->enableTriggerMode) + { + tmp8 |= CMP_CR1_TRIGM_MASK; + } + else + { + tmp8 &= ~CMP_CR1_TRIGM_MASK; + } +#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */ + base->CR1 = tmp8; + + /* CMPx_CR0. */ + tmp8 = base->CR0 & ~CMP_CR0_HYSTCTR_MASK; + tmp8 |= CMP_CR0_HYSTCTR(config->hysteresisMode); + base->CR0 = tmp8; + + CMP_Enable(base, config->enableCmp); /* Enable the CMP module after configured or not. */ +} + +void CMP_Deinit(CMP_Type *base) +{ + /* Disable the CMP module. */ + CMP_Enable(base, false); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable the clock. */ + CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void CMP_GetDefaultConfig(cmp_config_t *config) +{ + assert(NULL != config); + + config->enableCmp = true; /* Enable the CMP module after initialization. */ + config->hysteresisMode = kCMP_HysteresisLevel0; + config->enableHighSpeed = false; + config->enableInvertOutput = false; + config->useUnfilteredOutput = false; + config->enablePinOut = false; +#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE + config->enableTriggerMode = false; +#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */ +} + +void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel) +{ + uint8_t tmp8 = base->MUXCR; + + tmp8 &= ~(CMP_MUXCR_PSEL_MASK | CMP_MUXCR_MSEL_MASK); + tmp8 |= CMP_MUXCR_PSEL(positiveChannel) | CMP_MUXCR_MSEL(negativeChannel); + base->MUXCR = tmp8; +} + +#if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA +void CMP_EnableDMA(CMP_Type *base, bool enable) +{ + uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */ + + if (enable) + { + tmp8 |= CMP_SCR_DMAEN_MASK; + } + else + { + tmp8 &= ~CMP_SCR_DMAEN_MASK; + } + base->SCR = tmp8; +} +#endif /* FSL_FEATURE_CMP_HAS_DMA */ + +void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config) +{ + assert(NULL != config); + + uint8_t tmp8; + +#if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT + /* Choose the clock source for sampling. */ + if (config->enableSample) + { + base->CR1 |= CMP_CR1_SE_MASK; /* Choose the external SAMPLE clock. */ + } + else + { + base->CR1 &= ~CMP_CR1_SE_MASK; /* Choose the internal divided bus clock. */ + } +#endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */ + /* Set the filter count. */ + tmp8 = base->CR0 & ~CMP_CR0_FILTER_CNT_MASK; + tmp8 |= CMP_CR0_FILTER_CNT(config->filterCount); + base->CR0 = tmp8; + /* Set the filter period. It is used as the divider to bus clock. */ + base->FPR = CMP_FPR_FILT_PER(config->filterPeriod); +} + +void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config) +{ + uint8_t tmp8 = 0U; + + if (NULL == config) + { + /* Passing "NULL" as input parameter means no available configuration. So the DAC feature is disabled.*/ + base->DACCR = 0U; + return; + } + /* CMPx_DACCR. */ + tmp8 |= CMP_DACCR_DACEN_MASK; /* Enable the internal DAC. */ + if (kCMP_VrefSourceVin2 == config->referenceVoltageSource) + { + tmp8 |= CMP_DACCR_VRSEL_MASK; + } + tmp8 |= CMP_DACCR_VOSEL(config->DACValue); + + base->DACCR = tmp8; +} + +void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask) +{ + uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */ + + if (0U != (kCMP_OutputRisingInterruptEnable & mask)) + { + tmp8 |= CMP_SCR_IER_MASK; + } + if (0U != (kCMP_OutputFallingInterruptEnable & mask)) + { + tmp8 |= CMP_SCR_IEF_MASK; + } + base->SCR = tmp8; +} + +void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask) +{ + uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */ + + if (0U != (kCMP_OutputRisingInterruptEnable & mask)) + { + tmp8 &= ~CMP_SCR_IER_MASK; + } + if (0U != (kCMP_OutputFallingInterruptEnable & mask)) + { + tmp8 &= ~CMP_SCR_IEF_MASK; + } + base->SCR = tmp8; +} + +uint32_t CMP_GetStatusFlags(CMP_Type *base) +{ + uint32_t ret32 = 0U; + + if (0U != (CMP_SCR_CFR_MASK & base->SCR)) + { + ret32 |= kCMP_OutputRisingEventFlag; + } + if (0U != (CMP_SCR_CFF_MASK & base->SCR)) + { + ret32 |= kCMP_OutputFallingEventFlag; + } + if (0U != (CMP_SCR_COUT_MASK & base->SCR)) + { + ret32 |= kCMP_OutputAssertEventFlag; + } + return ret32; +} + +void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask) +{ + uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */ + + if (0U != (kCMP_OutputRisingEventFlag & mask)) + { + tmp8 |= CMP_SCR_CFR_MASK; + } + if (0U != (kCMP_OutputFallingEventFlag & mask)) + { + tmp8 |= CMP_SCR_CFF_MASK; + } + base->SCR = tmp8; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmp.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmp.h new file mode 100644 index 00000000000..0b3a5afbe5f --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmp.h @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_CMP_H_ +#define _FSL_CMP_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup cmp + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief CMP driver version 2.0.0. */ +#define FSL_CMP_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! +* @brief Interrupt enable/disable mask. +*/ +enum _cmp_interrupt_enable +{ + kCMP_OutputRisingInterruptEnable = CMP_SCR_IER_MASK, /*!< Comparator interrupt enable rising. */ + kCMP_OutputFallingInterruptEnable = CMP_SCR_IEF_MASK, /*!< Comparator interrupt enable falling. */ +}; + +/*! + * @brief Status flags' mask. + */ +enum _cmp_status_flags +{ + kCMP_OutputRisingEventFlag = CMP_SCR_CFR_MASK, /*!< Rising-edge on the comparison output has occurred. */ + kCMP_OutputFallingEventFlag = CMP_SCR_CFF_MASK, /*!< Falling-edge on the comparison output has occurred. */ + kCMP_OutputAssertEventFlag = CMP_SCR_COUT_MASK, /*!< Return the current value of the analog comparator output. */ +}; + +/*! + * @brief CMP Hysteresis mode. + */ +typedef enum _cmp_hysteresis_mode +{ + kCMP_HysteresisLevel0 = 0U, /*!< Hysteresis level 0. */ + kCMP_HysteresisLevel1 = 1U, /*!< Hysteresis level 1. */ + kCMP_HysteresisLevel2 = 2U, /*!< Hysteresis level 2. */ + kCMP_HysteresisLevel3 = 3U, /*!< Hysteresis level 3. */ +} cmp_hysteresis_mode_t; + +/*! + * @brief CMP Voltage Reference source. + */ +typedef enum _cmp_reference_voltage_source +{ + kCMP_VrefSourceVin1 = 0U, /*!< Vin1 is selected as a resistor ladder network supply reference Vin. */ + kCMP_VrefSourceVin2 = 1U, /*!< Vin2 is selected as a resistor ladder network supply reference Vin. */ +} cmp_reference_voltage_source_t; + +/*! + * @brief Configures the comparator. + */ +typedef struct _cmp_config +{ + bool enableCmp; /*!< Enable the CMP module. */ + cmp_hysteresis_mode_t hysteresisMode; /*!< CMP Hysteresis mode. */ + bool enableHighSpeed; /*!< Enable High-speed (HS) comparison mode. */ + bool enableInvertOutput; /*!< Enable the inverted comparator output. */ + bool useUnfilteredOutput; /*!< Set the compare output(COUT) to equal COUTA(true) or COUT(false). */ + bool enablePinOut; /*!< The comparator output is available on the associated pin. */ +#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE + bool enableTriggerMode; /*!< Enable the trigger mode. */ +#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */ +} cmp_config_t; + +/*! + * @brief Configures the filter. + */ +typedef struct _cmp_filter_config +{ +#if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT + bool enableSample; /*!< Using the external SAMPLE as a sampling clock input or using a divided bus clock. */ +#endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */ + uint8_t filterCount; /*!< Filter Sample Count. Available range is 1-7; 0 disables the filter.*/ + uint8_t filterPeriod; /*!< Filter Sample Period. The divider to the bus clock. Available range is 0-255. */ +} cmp_filter_config_t; + +/*! + * @brief Configures the internal DAC. + */ +typedef struct _cmp_dac_config +{ + cmp_reference_voltage_source_t referenceVoltageSource; /*!< Supply voltage reference source. */ + uint8_t DACValue; /*!< Value for the DAC Output Voltage. Available range is 0-63.*/ +} cmp_dac_config_t; + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @name Initialization + * @{ + */ + +/*! + * @brief Initializes the CMP. + * + * This function initializes the CMP module. The operations included are as follows. + * - Enabling the clock for CMP module. + * - Configuring the comparator. + * - Enabling the CMP module. + * Note that for some devices, multiple CMP instances share the same clock gate. In this case, to enable the clock for + * any instance enables all CMPs. See the appropriate MCU reference manual for the clock assignment of the CMP. + * + * @param base CMP peripheral base address. + * @param config Pointer to the configuration structure. + */ +void CMP_Init(CMP_Type *base, const cmp_config_t *config); + +/*! + * @brief De-initializes the CMP module. + * + * This function de-initializes the CMP module. The operations included are as follows. + * - Disabling the CMP module. + * - Disabling the clock for CMP module. + * + * This function disables the clock for the CMP. + * Note that for some devices, multiple CMP instances share the same clock gate. In this case, before disabling the + * clock for the CMP, ensure that all the CMP instances are not used. + * + * @param base CMP peripheral base address. + */ +void CMP_Deinit(CMP_Type *base); + +/*! + * @brief Enables/disables the CMP module. + * + * @param base CMP peripheral base address. + * @param enable Enables or disables the module. + */ +static inline void CMP_Enable(CMP_Type *base, bool enable) +{ + if (enable) + { + base->CR1 |= CMP_CR1_EN_MASK; + } + else + { + base->CR1 &= ~CMP_CR1_EN_MASK; + } +} + +/*! +* @brief Initializes the CMP user configuration structure. +* +* This function initializes the user configuration structure to these default values. +* @code +* config->enableCmp = true; +* config->hysteresisMode = kCMP_HysteresisLevel0; +* config->enableHighSpeed = false; +* config->enableInvertOutput = false; +* config->useUnfilteredOutput = false; +* config->enablePinOut = false; +* config->enableTriggerMode = false; +* @endcode +* @param config Pointer to the configuration structure. +*/ +void CMP_GetDefaultConfig(cmp_config_t *config); + +/*! + * @brief Sets the input channels for the comparator. + * + * This function sets the input channels for the comparator. + * Note that two input channels cannot be set the same way in the application. When the user selects the same input + * from the analog mux to the positive and negative port, the comparator is disabled automatically. + * + * @param base CMP peripheral base address. + * @param positiveChannel Positive side input channel number. Available range is 0-7. + * @param negativeChannel Negative side input channel number. Available range is 0-7. + */ +void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel); + +/* @} */ + +/*! + * @name Advanced Features + * @{ + */ + +#if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA +/*! + * @brief Enables/disables the DMA request for rising/falling events. + * + * This function enables/disables the DMA request for rising/falling events. Either event triggers the generation of + * the DMA request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from the CMP + * if the DMA is disabled. + * + * @param base CMP peripheral base address. + * @param enable Enables or disables the feature. + */ +void CMP_EnableDMA(CMP_Type *base, bool enable); +#endif /* FSL_FEATURE_CMP_HAS_DMA */ + +#if defined(FSL_FEATURE_CMP_HAS_WINDOW_MODE) && FSL_FEATURE_CMP_HAS_WINDOW_MODE +/*! + * @brief Enables/disables the window mode. + * + * @param base CMP peripheral base address. + * @param enable Enables or disables the feature. + */ +static inline void CMP_EnableWindowMode(CMP_Type *base, bool enable) +{ + if (enable) + { + base->CR1 |= CMP_CR1_WE_MASK; + } + else + { + base->CR1 &= ~CMP_CR1_WE_MASK; + } +} +#endif /* FSL_FEATURE_CMP_HAS_WINDOW_MODE */ + +#if defined(FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE) && FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE +/*! + * @brief Enables/disables the pass through mode. + * + * @param base CMP peripheral base address. + * @param enable Enables or disables the feature. + */ +static inline void CMP_EnablePassThroughMode(CMP_Type *base, bool enable) +{ + if (enable) + { + base->MUXCR |= CMP_MUXCR_PSTM_MASK; + } + else + { + base->MUXCR &= ~CMP_MUXCR_PSTM_MASK; + } +} +#endif /* FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE */ + +/*! + * @brief Configures the filter. + * + * @param base CMP peripheral base address. + * @param config Pointer to the configuration structure. + */ +void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config); + +/*! + * @brief Configures the internal DAC. + * + * @param base CMP peripheral base address. + * @param config Pointer to the configuration structure. "NULL" disables the feature. + */ +void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config); + +/*! + * @brief Enables the interrupts. + * + * @param base CMP peripheral base address. + * @param mask Mask value for interrupts. See "_cmp_interrupt_enable". + */ +void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask); + +/*! + * @brief Disables the interrupts. + * + * @param base CMP peripheral base address. + * @param mask Mask value for interrupts. See "_cmp_interrupt_enable". + */ +void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name Results + * @{ + */ + +/*! + * @brief Gets the status flags. + * + * @param base CMP peripheral base address. + * + * @return Mask value for the asserted flags. See "_cmp_status_flags". + */ +uint32_t CMP_GetStatusFlags(CMP_Type *base); + +/*! + * @brief Clears the status flags. + * + * @param base CMP peripheral base address. + * @param mask Mask value for the flags. See "_cmp_status_flags". + */ +void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask); + +/* @} */ +#if defined(__cplusplus) +} +#endif +/*! + * @} + */ +#endif /* _FSL_CMP_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmt.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmt.c new file mode 100644 index 00000000000..4818644c71e --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmt.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_cmt.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* The standard intermediate frequency (IF). */ +#define CMT_INTERMEDIATEFREQUENCY_8MHZ (8000000U) +/* CMT data modulate mask. */ +#define CMT_MODULATE_COUNT_WIDTH (8U) +/* CMT diver 1. */ +#define CMT_CMTDIV_ONE (1) +/* CMT diver 2. */ +#define CMT_CMTDIV_TWO (2) +/* CMT diver 4. */ +#define CMT_CMTDIV_FOUR (4) +/* CMT diver 8. */ +#define CMT_CMTDIV_EIGHT (8) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get instance number for CMT module. + * + * @param base CMT peripheral base address. + */ +static uint32_t CMT_GetInstance(CMT_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to cmt clocks for each instance. */ +static const clock_ip_name_t s_cmtClock[FSL_FEATURE_SOC_CMT_COUNT] = CMT_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Pointers to cmt bases for each instance. */ +static CMT_Type *const s_cmtBases[] = CMT_BASE_PTRS; + +/*! @brief Pointers to cmt IRQ number for each instance. */ +static const IRQn_Type s_cmtIrqs[] = CMT_IRQS; + +/******************************************************************************* + * Codes + ******************************************************************************/ + +static uint32_t CMT_GetInstance(CMT_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_CMT_COUNT; instance++) + { + if (s_cmtBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_CMT_COUNT); + + return instance; +} + +void CMT_GetDefaultConfig(cmt_config_t *config) +{ + assert(config); + + /* Default infrared output is enabled and set with high active, the divider is set to 1. */ + config->isInterruptEnabled = false; + config->isIroEnabled = true; + config->iroPolarity = kCMT_IROActiveHigh; + config->divider = kCMT_SecondClkDiv1; +} + +void CMT_Init(CMT_Type *base, const cmt_config_t *config, uint32_t busClock_Hz) +{ + assert(config); + assert(busClock_Hz >= CMT_INTERMEDIATEFREQUENCY_8MHZ); + + uint8_t divider; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate clock. */ + CLOCK_EnableClock(s_cmtClock[CMT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Sets clock divider. The divider set in pps should be set + to make sycClock_Hz/divder = 8MHz */ + base->PPS = CMT_PPS_PPSDIV(busClock_Hz / CMT_INTERMEDIATEFREQUENCY_8MHZ - 1); + divider = base->MSC; + divider &= ~CMT_MSC_CMTDIV_MASK; + divider |= CMT_MSC_CMTDIV(config->divider); + base->MSC = divider; + + /* Set the IRO signal. */ + base->OC = CMT_OC_CMTPOL(config->iroPolarity) | CMT_OC_IROPEN(config->isIroEnabled); + + /* Set interrupt. */ + if (config->isInterruptEnabled) + { + CMT_EnableInterrupts(base, kCMT_EndOfCycleInterruptEnable); + EnableIRQ(s_cmtIrqs[CMT_GetInstance(base)]); + } +} + +void CMT_Deinit(CMT_Type *base) +{ + /*Disable the CMT modulator. */ + base->MSC = 0; + + /* Disable the interrupt. */ + CMT_DisableInterrupts(base, kCMT_EndOfCycleInterruptEnable); + DisableIRQ(s_cmtIrqs[CMT_GetInstance(base)]); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate the clock. */ + CLOCK_DisableClock(s_cmtClock[CMT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void CMT_SetMode(CMT_Type *base, cmt_mode_t mode, cmt_modulate_config_t *modulateConfig) +{ + uint8_t mscReg = base->MSC; + + /* Judge the mode. */ + if (mode != kCMT_DirectIROCtl) + { + assert(modulateConfig); + + /* Set carrier generator. */ + CMT_SetCarrirGenerateCountOne(base, modulateConfig->highCount1, modulateConfig->lowCount1); + if (mode == kCMT_FSKMode) + { + CMT_SetCarrirGenerateCountTwo(base, modulateConfig->highCount2, modulateConfig->lowCount2); + } + + /* Set carrier modulator. */ + CMT_SetModulateMarkSpace(base, modulateConfig->markCount, modulateConfig->spaceCount); + mscReg &= ~ (CMT_MSC_FSK_MASK | CMT_MSC_BASE_MASK); + mscReg |= mode; + } + else + { + mscReg &= ~CMT_MSC_MCGEN_MASK; + } + /* Set the CMT mode. */ + base->MSC = mscReg; +} + +cmt_mode_t CMT_GetMode(CMT_Type *base) +{ + uint8_t mode = base->MSC; + + if (!(mode & CMT_MSC_MCGEN_MASK)) + { /* Carrier modulator disabled and the IRO signal is in direct software control. */ + return kCMT_DirectIROCtl; + } + else + { + /* Carrier modulator is enabled. */ + if (mode & CMT_MSC_BASE_MASK) + { + /* Base band mode. */ + return kCMT_BasebandMode; + } + else if (mode & CMT_MSC_FSK_MASK) + { + /* FSK mode. */ + return kCMT_FSKMode; + } + else + { + /* Time mode. */ + return kCMT_TimeMode; + } + } +} + +uint32_t CMT_GetCMTFrequency(CMT_Type *base, uint32_t busClock_Hz) +{ + uint32_t frequency; + uint32_t divider; + + /* Get intermediate frequency. */ + frequency = busClock_Hz / ((base->PPS & CMT_PPS_PPSDIV_MASK) + 1); + + /* Get the second divider. */ + divider = ((base->MSC & CMT_MSC_CMTDIV_MASK) >> CMT_MSC_CMTDIV_SHIFT); + /* Get CMT frequency. */ + switch ((cmt_second_clkdiv_t)divider) + { + case kCMT_SecondClkDiv1: + frequency = frequency / CMT_CMTDIV_ONE; + break; + case kCMT_SecondClkDiv2: + frequency = frequency / CMT_CMTDIV_TWO; + break; + case kCMT_SecondClkDiv4: + frequency = frequency / CMT_CMTDIV_FOUR; + break; + case kCMT_SecondClkDiv8: + frequency = frequency / CMT_CMTDIV_EIGHT; + break; + default: + frequency = frequency / CMT_CMTDIV_ONE; + break; + } + + return frequency; +} + +void CMT_SetModulateMarkSpace(CMT_Type *base, uint32_t markCount, uint32_t spaceCount) +{ + /* Set modulate mark. */ + base->CMD1 = (markCount >> CMT_MODULATE_COUNT_WIDTH) & CMT_CMD1_MB_MASK; + base->CMD2 = (markCount & CMT_CMD2_MB_MASK); + /* Set modulate space. */ + base->CMD3 = (spaceCount >> CMT_MODULATE_COUNT_WIDTH) & CMT_CMD3_SB_MASK; + base->CMD4 = spaceCount & CMT_CMD4_SB_MASK; +} + +void CMT_SetIroState(CMT_Type *base, cmt_infrared_output_state_t state) +{ + uint8_t ocReg = base->OC; + + ocReg &= ~CMT_OC_IROL_MASK; + ocReg |= CMT_OC_IROL(state); + + /* Set the infrared output signal control. */ + base->OC = ocReg; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmt.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmt.h new file mode 100644 index 00000000000..3d30a6dbfa6 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_cmt.h @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_CMT_H_ +#define _FSL_CMT_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup cmt + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief CMT driver version 2.0.1. */ +#define FSL_CMT_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! + * @brief The modes of CMT. + */ +typedef enum _cmt_mode +{ + kCMT_DirectIROCtl = 0x00U, /*!< Carrier modulator is disabled and the IRO signal is directly in software control */ + kCMT_TimeMode = 0x01U, /*!< Carrier modulator is enabled in time mode. */ + kCMT_FSKMode = 0x05U, /*!< Carrier modulator is enabled in FSK mode. */ + kCMT_BasebandMode = 0x09U /*!< Carrier modulator is enabled in baseband mode. */ +} cmt_mode_t; + +/*! + * @brief The CMT clock divide primary prescaler. + * The primary clock divider is used to divider the bus clock to + * get the intermediate frequency to approximately equal to 8 MHZ. + * When the bus clock is 8 MHZ, set primary prescaler to "kCMT_PrimaryClkDiv1". + */ +typedef enum _cmt_primary_clkdiv +{ + kCMT_PrimaryClkDiv1 = 0U, /*!< The intermediate frequency is the bus clock divided by 1. */ + kCMT_PrimaryClkDiv2 = 1U, /*!< The intermediate frequency is the bus clock divided by 2. */ + kCMT_PrimaryClkDiv3 = 2U, /*!< The intermediate frequency is the bus clock divided by 3. */ + kCMT_PrimaryClkDiv4 = 3U, /*!< The intermediate frequency is the bus clock divided by 4. */ + kCMT_PrimaryClkDiv5 = 4U, /*!< The intermediate frequency is the bus clock divided by 5. */ + kCMT_PrimaryClkDiv6 = 5U, /*!< The intermediate frequency is the bus clock divided by 6. */ + kCMT_PrimaryClkDiv7 = 6U, /*!< The intermediate frequency is the bus clock divided by 7. */ + kCMT_PrimaryClkDiv8 = 7U, /*!< The intermediate frequency is the bus clock divided by 8. */ + kCMT_PrimaryClkDiv9 = 8U, /*!< The intermediate frequency is the bus clock divided by 9. */ + kCMT_PrimaryClkDiv10 = 9U, /*!< The intermediate frequency is the bus clock divided by 10. */ + kCMT_PrimaryClkDiv11 = 10U, /*!< The intermediate frequency is the bus clock divided by 11. */ + kCMT_PrimaryClkDiv12 = 11U, /*!< The intermediate frequency is the bus clock divided by 12. */ + kCMT_PrimaryClkDiv13 = 12U, /*!< The intermediate frequency is the bus clock divided by 13. */ + kCMT_PrimaryClkDiv14 = 13U, /*!< The intermediate frequency is the bus clock divided by 14. */ + kCMT_PrimaryClkDiv15 = 14U, /*!< The intermediate frequency is the bus clock divided by 15. */ + kCMT_PrimaryClkDiv16 = 15U /*!< The intermediate frequency is the bus clock divided by 16. */ +} cmt_primary_clkdiv_t; + +/*! + * @brief The CMT clock divide secondary prescaler. + * The second prescaler can be used to divide the 8 MHZ CMT clock + * by 1, 2, 4, or 8 according to the specification. + */ +typedef enum _cmt_second_clkdiv +{ + kCMT_SecondClkDiv1 = 0U, /*!< The CMT clock is the intermediate frequency frequency divided by 1. */ + kCMT_SecondClkDiv2 = 1U, /*!< The CMT clock is the intermediate frequency frequency divided by 2. */ + kCMT_SecondClkDiv4 = 2U, /*!< The CMT clock is the intermediate frequency frequency divided by 4. */ + kCMT_SecondClkDiv8 = 3U /*!< The CMT clock is the intermediate frequency frequency divided by 8. */ +} cmt_second_clkdiv_t; + +/*! + * @brief The CMT infrared output polarity. + */ +typedef enum _cmt_infrared_output_polarity +{ + kCMT_IROActiveLow = 0U, /*!< The CMT infrared output signal polarity is active-low. */ + kCMT_IROActiveHigh = 1U /*!< The CMT infrared output signal polarity is active-high. */ +} cmt_infrared_output_polarity_t; + +/*! + * @brief The CMT infrared output signal state control. + */ +typedef enum _cmt_infrared_output_state +{ + kCMT_IROCtlLow = 0U, /*!< The CMT Infrared output signal state is controlled to low. */ + kCMT_IROCtlHigh = 1U /*!< The CMT Infrared output signal state is controlled to high. */ +} cmt_infrared_output_state_t; + +/*! + * @brief CMT interrupt configuration structure, default settings all disabled. + * + * This structure contains the settings for all of the CMT interrupt configurations. + */ +enum _cmt_interrupt_enable +{ + kCMT_EndOfCycleInterruptEnable = CMT_MSC_EOCIE_MASK, /*!< CMT end of cycle interrupt. */ +}; + +/*! + * @brief CMT carrier generator and modulator configuration structure + * + */ +typedef struct _cmt_modulate_config +{ + uint8_t highCount1; /*!< The high-time for carrier generator first register. */ + uint8_t lowCount1; /*!< The low-time for carrier generator first register. */ + uint8_t highCount2; /*!< The high-time for carrier generator second register for FSK mode. */ + uint8_t lowCount2; /*!< The low-time for carrier generator second register for FSK mode. */ + uint16_t markCount; /*!< The mark time for the modulator gate. */ + uint16_t spaceCount; /*!< The space time for the modulator gate. */ +} cmt_modulate_config_t; + +/*! @brief CMT basic configuration structure. */ +typedef struct _cmt_config +{ + bool isInterruptEnabled; /*!< Timer interrupt 0-disable, 1-enable. */ + bool isIroEnabled; /*!< The IRO output 0-disabled, 1-enabled. */ + cmt_infrared_output_polarity_t iroPolarity; /*!< The IRO polarity. */ + cmt_second_clkdiv_t divider; /*!< The CMT clock divide prescaler. */ +} cmt_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Gets the CMT default configuration structure. This API + * gets the default configuration structure for the CMT_Init(). + * Use the initialized structure unchanged in CMT_Init() or modify + * fields of the structure before calling the CMT_Init(). + * + * @param config The CMT configuration structure pointer. + */ +void CMT_GetDefaultConfig(cmt_config_t *config); + +/*! + * @brief Initializes the CMT module. + * + * This function ungates the module clock and sets the CMT internal clock, + * interrupt, and infrared output signal for the CMT module. + * + * @param base CMT peripheral base address. + * @param config The CMT basic configuration structure. + * @param busClock_Hz The CMT module input clock - bus clock frequency. + */ +void CMT_Init(CMT_Type *base, const cmt_config_t *config, uint32_t busClock_Hz); + +/*! + * @brief Disables the CMT module and gate control. + * + * This function disables CMT modulator, interrupts, and gates the + * CMT clock control. CMT_Init must be called to use the CMT again. + * + * @param base CMT peripheral base address. + */ +void CMT_Deinit(CMT_Type *base); + +/*! @}*/ + +/*! + * @name Basic Control Operations + * @{ + */ + +/*! + * @brief Selects the mode for CMT. + * + * @param base CMT peripheral base address. + * @param mode The CMT feature mode enumeration. See "cmt_mode_t". + * @param modulateConfig The carrier generation and modulator configuration. + */ +void CMT_SetMode(CMT_Type *base, cmt_mode_t mode, cmt_modulate_config_t *modulateConfig); + +/*! + * @brief Gets the mode of the CMT module. + * + * @param base CMT peripheral base address. + * @return The CMT mode. + * kCMT_DirectIROCtl Carrier modulator is disabled; the IRO signal is directly in software control. + * kCMT_TimeMode Carrier modulator is enabled in time mode. + * kCMT_FSKMode Carrier modulator is enabled in FSK mode. + * kCMT_BasebandMode Carrier modulator is enabled in baseband mode. + */ +cmt_mode_t CMT_GetMode(CMT_Type *base); + +/*! + * @brief Gets the actual CMT clock frequency. + * + * @param base CMT peripheral base address. + * @param busClock_Hz CMT module input clock - bus clock frequency. + * @return The CMT clock frequency. + */ +uint32_t CMT_GetCMTFrequency(CMT_Type *base, uint32_t busClock_Hz); + +/*! + * @brief Sets the primary data set for the CMT carrier generator counter. + * + * This function sets the high-time and low-time of the primary data set for the + * CMT carrier generator counter to control the period and the duty cycle of the + * output carrier signal. + * If the CMT clock period is Tcmt, the period of the carrier generator signal equals + * (highCount + lowCount) * Tcmt. The duty cycle equals to highCount / (highCount + lowCount). + * + * @param base CMT peripheral base address. + * @param highCount The number of CMT clocks for carrier generator signal high time, + * integer in the range of 1 ~ 0xFF. + * @param lowCount The number of CMT clocks for carrier generator signal low time, + * integer in the range of 1 ~ 0xFF. + */ +static inline void CMT_SetCarrirGenerateCountOne(CMT_Type *base, uint32_t highCount, uint32_t lowCount) +{ + assert(highCount <= CMT_CGH1_PH_MASK); + assert(highCount); + assert(lowCount <= CMT_CGL1_PL_MASK); + assert(lowCount); + + base->CGH1 = highCount; + base->CGL1 = lowCount; +} + +/*! + * @brief Sets the secondary data set for the CMT carrier generator counter. + * + * This function is used for FSK mode setting the high-time and low-time of the secondary + * data set CMT carrier generator counter to control the period and the duty cycle + * of the output carrier signal. + * If the CMT clock period is Tcmt, the period of the carrier generator signal equals + * (highCount + lowCount) * Tcmt. The duty cycle equals highCount / (highCount + lowCount). + * + * @param base CMT peripheral base address. + * @param highCount The number of CMT clocks for carrier generator signal high time, + * integer in the range of 1 ~ 0xFF. + * @param lowCount The number of CMT clocks for carrier generator signal low time, + * integer in the range of 1 ~ 0xFF. + */ +static inline void CMT_SetCarrirGenerateCountTwo(CMT_Type *base, uint32_t highCount, uint32_t lowCount) +{ + assert(highCount <= CMT_CGH2_SH_MASK); + assert(highCount); + assert(lowCount <= CMT_CGL2_SL_MASK); + assert(lowCount); + + base->CGH2 = highCount; + base->CGL2 = lowCount; +} + +/*! + * @brief Sets the modulation mark and space time period for the CMT modulator. + * + * This function sets the mark time period of the CMT modulator counter + * to control the mark time of the output modulated signal from the carrier generator output signal. + * If the CMT clock frequency is Fcmt and the carrier out signal frequency is fcg: + * - In Time and Baseband mode: The mark period of the generated signal equals (markCount + 1) / (Fcmt/8). + * The space period of the generated signal equals spaceCount / (Fcmt/8). + * - In FSK mode: The mark period of the generated signal equals (markCount + 1)/fcg. + * The space period of the generated signal equals spaceCount / fcg. + * + * @param base Base address for current CMT instance. + * @param markCount The number of clock period for CMT modulator signal mark period, + * in the range of 0 ~ 0xFFFF. + * @param spaceCount The number of clock period for CMT modulator signal space period, + * in the range of the 0 ~ 0xFFFF. + */ +void CMT_SetModulateMarkSpace(CMT_Type *base, uint32_t markCount, uint32_t spaceCount); + +/*! + * @brief Enables or disables the extended space operation. + * + * This function is used to make the space period longer + * for time, baseband, and FSK modes. + * + * @param base CMT peripheral base address. + * @param enable True enable the extended space, false disable the extended space. + */ +static inline void CMT_EnableExtendedSpace(CMT_Type *base, bool enable) +{ + if (enable) + { + base->MSC |= CMT_MSC_EXSPC_MASK; + } + else + { + base->MSC &= ~CMT_MSC_EXSPC_MASK; + } +} + +/*! + * @brief Sets the IRO (infrared output) signal state. + * + * Changes the states of the IRO signal when the kCMT_DirectIROMode mode is set + * and the IRO signal is enabled. + * + * @param base CMT peripheral base address. + * @param state The control of the IRO signal. See "cmt_infrared_output_state_t" + */ +void CMT_SetIroState(CMT_Type *base, cmt_infrared_output_state_t state); + +/*! + * @brief Enables the CMT interrupt. + * + * This function enables the CMT interrupts according to the provided mask if enabled. + * The CMT only has the end of the cycle interrupt - an interrupt occurs at the end + * of the modulator cycle. This interrupt provides a means for the user + * to reload the new mark/space values into the CMT modulator data registers + * and verify the modulator mark and space. + * For example, to enable the end of cycle, do the following. + * @code + * CMT_EnableInterrupts(CMT, kCMT_EndOfCycleInterruptEnable); + * @endcode + * @param base CMT peripheral base address. + * @param mask The interrupts to enable. Logical OR of @ref _cmt_interrupt_enable. + */ +static inline void CMT_EnableInterrupts(CMT_Type *base, uint32_t mask) +{ + base->MSC |= mask; +} + +/*! + * @brief Disables the CMT interrupt. + * + * This function disables the CMT interrupts according to the provided maskIf enabled. + * The CMT only has the end of the cycle interrupt. + * For example, to disable the end of cycle, do the following. + * @code + * CMT_DisableInterrupts(CMT, kCMT_EndOfCycleInterruptEnable); + * @endcode + * + * @param base CMT peripheral base address. + * @param mask The interrupts to enable. Logical OR of @ref _cmt_interrupt_enable. + */ +static inline void CMT_DisableInterrupts(CMT_Type *base, uint32_t mask) +{ + base->MSC &= ~mask; +} + +/*! + * @brief Gets the end of the cycle status flag. + * + * The flag is set: + * - When the modulator is not currently active and carrier and modulator + * are set to start the initial CMT transmission. + * - At the end of each modulation cycle when the counter is reloaded and + * the carrier and modulator are enabled. + * @param base CMT peripheral base address. + * @return Current status of the end of cycle status flag + * @arg non-zero: End-of-cycle has occurred. + * @arg zero: End-of-cycle has not yet occurred since the flag last cleared. + */ +static inline uint32_t CMT_GetStatusFlags(CMT_Type *base) +{ + return base->MSC & CMT_MSC_EOCF_MASK; +} + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_CMT_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_common.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_common.c new file mode 100644 index 00000000000..2d4a3b28e9d --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_common.c @@ -0,0 +1,161 @@ +/* +* Copyright (c) 2015-2016, Freescale Semiconductor, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "fsl_common.h" +/* This is not needed for mbed */ +#if 0 +#include "fsl_debug_console.h" + +#ifndef NDEBUG +#if (defined(__CC_ARM)) || (defined(__ICCARM__)) +void __aeabi_assert(const char *failedExpr, const char *file, int line) +{ + PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" \n", failedExpr, file, line); + for (;;) + { + __asm("bkpt #0"); + } +} +#elif(defined(__GNUC__)) +void __assert_func(const char *file, int line, const char *func, const char *failedExpr) +{ + PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" function name \"%s\" \n", failedExpr, file, line, func); + for (;;) + { + __asm("bkpt #0"); + } +} +#endif /* (defined(__CC_ARM)) || (defined (__ICCARM__)) */ +#endif /* NDEBUG */ +#endif +void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler) +{ +/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */ +#if defined(__CC_ARM) + extern uint32_t Image$$VECTOR_ROM$$Base[]; + extern uint32_t Image$$VECTOR_RAM$$Base[]; + extern uint32_t Image$$RW_m_data$$Base[]; + +#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base)) +#elif defined(__ICCARM__) + extern uint32_t __RAM_VECTOR_TABLE_SIZE[]; + extern uint32_t __VECTOR_TABLE[]; + extern uint32_t __VECTOR_RAM[]; +#elif defined(__GNUC__) + extern uint32_t __VECTOR_TABLE[]; + extern uint32_t __VECTOR_RAM[]; + extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[]; + uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES); +#endif /* defined(__CC_ARM) */ + uint32_t n; + uint32_t interrupts_disabled; + + interrupts_disabled = __get_PRIMASK(); + __disable_irq(); + if (SCB->VTOR != (uint32_t)__VECTOR_RAM) + { + /* Copy the vector table from ROM to RAM */ + for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++) + { + __VECTOR_RAM[n] = __VECTOR_TABLE[n]; + } + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_RAM; + } + + /* make sure the __VECTOR_RAM is noncachable */ + __VECTOR_RAM[irq + 16] = irqHandler; + + if (!interrupts_disabled) { + __enable_irq(); + } +} +#ifndef CPU_QN908X +#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) + +void EnableDeepSleepIRQ(IRQn_Type interrupt) +{ + uint32_t index = 0; + uint32_t intNumber = (uint32_t)interrupt; + while (intNumber >= 32u) + { + index++; + intNumber -= 32u; + } + + SYSCON->STARTERSET[index] = 1u << intNumber; + EnableIRQ(interrupt); /* also enable interrupt at NVIC */ +} + +void DisableDeepSleepIRQ(IRQn_Type interrupt) +{ + uint32_t index = 0; + uint32_t intNumber = (uint32_t)interrupt; + while (intNumber >= 32u) + { + index++; + intNumber -= 32u; + } + + DisableIRQ(interrupt); /* also disable interrupt at NVIC */ + SYSCON->STARTERCLR[index] = 1u << intNumber; +} +#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */ +#else +void EnableDeepSleepIRQ(IRQn_Type interrupt) +{ + uint32_t index = 0; + uint32_t intNumber = (uint32_t)interrupt; + while (intNumber >= 32u) + { + index++; + intNumber -= 32u; + } + + /* SYSCON->STARTERSET[index] = 1u << intNumber; */ + EnableIRQ(interrupt); /* also enable interrupt at NVIC */ +} + +void DisableDeepSleepIRQ(IRQn_Type interrupt) +{ + uint32_t index = 0; + uint32_t intNumber = (uint32_t)interrupt; + while (intNumber >= 32u) + { + index++; + intNumber -= 32u; + } + + DisableIRQ(interrupt); /* also disable interrupt at NVIC */ + /* SYSCON->STARTERCLR[index] = 1u << intNumber; */ +} +#endif /*CPU_QN908X */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_common.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_common.h new file mode 100644 index 00000000000..d9d74b95ba0 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_common.h @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_COMMON_H_ +#define _FSL_COMMON_H_ + +#include +#include +#include +#include +#include "fsl_device_registers.h" + +/*! + * @addtogroup ksdk_common + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Construct a status code value from a group and code number. */ +#define MAKE_STATUS(group, code) ((((group)*100) + (code))) + +/*! @brief Construct the version number for drivers. */ +#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) + +/* Debug console type definition. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console base on UART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console base on LPUART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console base on LPSCI. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console base on USBCDC. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console base on USBCDC. */ + +/*! @brief Status group numbers. */ +enum _status_groups +{ + kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */ + kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */ + kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */ + kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */ + kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */ + kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */ + kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */ + kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */ + kStatusGroup_UART = 10, /*!< Group number for UART status codes. */ + kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */ + kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */ + kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */ + kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/ + kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/ + kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/ + kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */ + kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */ + kStatusGroup_SAI = 19, /*!< Group number for SAI status code */ + kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */ + kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */ + kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */ + kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */ + kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */ + kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */ + kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */ + kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */ + kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */ + kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */ + kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */ + kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */ + kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */ + kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */ + kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */ + kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */ + kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */ + kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */ + kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */ + kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */ + kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */ + kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */ + kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */ + kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */ + kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */ + kStatusGroup_ApplicationRangeStart = 100, /*!< Starting number for application groups. */ +}; + +/*! @brief Generic status return codes. */ +enum _generic_status +{ + kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0), + kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1), + kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2), + kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3), + kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), + kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5), + kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6), +}; + +/*! @brief Type used for all status and error return values. */ +typedef int32_t status_t; + +/* + * The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t + * defined in previous of this file. + */ +#include "fsl_clock.h" + +/* + * Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral + */ +#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \ + (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0))) +#include "fsl_reset.h" +#endif + +/*! @name Min/max macros */ +/* @{ */ +#if !defined(MIN) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#if !defined(MAX) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +/* @} */ + +/*! @brief Computes the number of elements in an array. */ +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +/*! @name UINT16_MAX/UINT32_MAX value */ +/* @{ */ +#if !defined(UINT16_MAX) +#define UINT16_MAX ((uint16_t)-1) +#endif + +#if !defined(UINT32_MAX) +#define UINT32_MAX ((uint32_t)-1) +#endif +/* @} */ + +/*! @name Timer utilities */ +/* @{ */ +/*! Macro to convert a microsecond period to raw count value */ +#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)((uint64_t)us * clockFreqInHz / 1000000U) +/*! Macro to convert a raw count value to microsecond */ +#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000000U / clockFreqInHz) + +/*! Macro to convert a millisecond period to raw count value */ +#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)ms * clockFreqInHz / 1000U) +/*! Macro to convert a raw count value to millisecond */ +#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000U / clockFreqInHz) +/* @} */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Enable specific interrupt. + * + * Enable the interrupt not routed from intmux. + * + * @param interrupt The IRQ number. + */ +static inline void EnableIRQ(IRQn_Type interrupt) +{ + if (NotAvail_IRQn == interrupt) + { + return; + } + +#if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0) + if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX) +#endif + { + NVIC_EnableIRQ(interrupt); + } +} + +/*! + * @brief Disable specific interrupt. + * + * Disable the interrupt not routed from intmux. + * + * @param interrupt The IRQ number. + */ +static inline void DisableIRQ(IRQn_Type interrupt) +{ + if (NotAvail_IRQn == interrupt) + { + return; + } + +#if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0) + if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX) +#endif + { + NVIC_DisableIRQ(interrupt); + } +} + +/*! + * @brief Disable the global IRQ + * + * Disable the global interrupt and return the current primask register. User is required to provided the primask + * register for the EnableGlobalIRQ(). + * + * @return Current primask value. + */ +static inline uint32_t DisableGlobalIRQ(void) +{ + uint32_t regPrimask = __get_PRIMASK(); + + __disable_irq(); + + return regPrimask; +} + +/*! + * @brief Enaable the global IRQ + * + * Set the primask register with the provided primask value but not just enable the primask. The idea is for the + * convinience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to + * use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair. + * + * @param primask value of primask register to be restored. The primask value is supposed to be provided by the + * DisableGlobalIRQ(). + */ +static inline void EnableGlobalIRQ(uint32_t primask) +{ + __set_PRIMASK(primask); +} + +/*! + * @brief install IRQ handler + * + * @param irq IRQ number + * @param irqHandler IRQ handler address + */ +void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); + +#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) +/*! + * @brief Enable specific interrupt for wake-up from deep-sleep mode. + * + * Enable the interrupt for wake-up from deep sleep mode. + * Some interrupts are typically used in sleep mode only and will not occur during + * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable + * those clocks (significantly increasing power consumption in the reduced power mode), + * making these wake-ups possible. + * + * @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internally). + * + * @param interrupt The IRQ number. + */ +void EnableDeepSleepIRQ(IRQn_Type interrupt); + +/*! + * @brief Disable specific interrupt for wake-up from deep-sleep mode. + * + * Disable the interrupt for wake-up from deep sleep mode. + * Some interrupts are typically used in sleep mode only and will not occur during + * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable + * those clocks (significantly increasing power consumption in the reduced power mode), + * making these wake-ups possible. + * + * @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internally). + * + * @param interrupt The IRQ number. + */ +void DisableDeepSleepIRQ(IRQn_Type interrupt); +#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* _FSL_COMMON_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_crc.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_crc.c new file mode 100644 index 00000000000..e0313fcc5fd --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_crc.c @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_crc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @internal @brief Has data register with name CRC. */ +#if defined(FSL_FEATURE_CRC_HAS_CRC_REG) && FSL_FEATURE_CRC_HAS_CRC_REG +#define DATA CRC +#define DATALL CRCLL +#endif + +#if defined(CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT) && CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT +/* @brief Default user configuration structure for CRC-16-CCITT */ +#define CRC_DRIVER_DEFAULT_POLYNOMIAL 0x1021U +/*< CRC-16-CCIT polynomial x**16 + x**12 + x**5 + x**0 */ +#define CRC_DRIVER_DEFAULT_SEED 0xFFFFU +/*< Default initial checksum */ +#define CRC_DRIVER_DEFAULT_REFLECT_IN false +/*< Default is no transpose */ +#define CRC_DRIVER_DEFAULT_REFLECT_OUT false +/*< Default is transpose bytes */ +#define CRC_DRIVER_DEFAULT_COMPLEMENT_CHECKSUM false +/*< Default is without complement of CRC data register read data */ +#define CRC_DRIVER_DEFAULT_CRC_BITS kCrcBits16 +/*< Default is 16-bit CRC protocol */ +#define CRC_DRIVER_DEFAULT_CRC_RESULT kCrcFinalChecksum +/*< Default is resutl type is final checksum */ +#endif /* CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT */ + +/*! @brief CRC type of transpose of read write data */ +typedef enum _crc_transpose_type +{ + kCrcTransposeNone = 0U, /*! No transpose */ + kCrcTransposeBits = 1U, /*! Tranpose bits in bytes */ + kCrcTransposeBitsAndBytes = 2U, /*! Transpose bytes and bits in bytes */ + kCrcTransposeBytes = 3U, /*! Transpose bytes */ +} crc_transpose_type_t; + +/*! +* @brief CRC module configuration. +* +* This structure holds the configuration for the CRC module. +*/ +typedef struct _crc_module_config +{ + uint32_t polynomial; /*!< CRC Polynomial, MSBit first.@n + Example polynomial: 0x1021 = 1_0000_0010_0001 = x^12+x^5+1 */ + uint32_t seed; /*!< Starting checksum value */ + crc_transpose_type_t readTranspose; /*!< Type of transpose when reading CRC result. */ + crc_transpose_type_t writeTranspose; /*!< Type of transpose when writing CRC input data. */ + bool complementChecksum; /*!< True if the result shall be complement of the actual checksum. */ + crc_bits_t crcBits; /*!< Selects 16- or 32- bit CRC protocol. */ +} crc_module_config_t; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Returns transpose type for CRC protocol reflect in parameter. + * + * This functions helps to set writeTranspose member of crc_config_t structure. Reflect in is CRC protocol parameter. + * + * @param enable True or false for the selected CRC protocol Reflect In (refin) parameter. + */ +static inline crc_transpose_type_t CRC_GetTransposeTypeFromReflectIn(bool enable) +{ + return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeBytes); +} + +/*! + * @brief Returns transpose type for CRC protocol reflect out parameter. + * + * This functions helps to set readTranspose member of crc_config_t structure. Reflect out is CRC protocol parameter. + * + * @param enable True or false for the selected CRC protocol Reflect Out (refout) parameter. + */ +static inline crc_transpose_type_t CRC_GetTransposeTypeFromReflectOut(bool enable) +{ + return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeNone); +} + +/*! + * @brief Starts checksum computation. + * + * Configures the CRC module for the specified CRC protocol. @n + * Starts the checksum computation by writing the seed value + * + * @param base CRC peripheral address. + * @param config Pointer to protocol configuration structure. + */ +static void CRC_ConfigureAndStart(CRC_Type *base, const crc_module_config_t *config) +{ + uint32_t crcControl; + + /* pre-compute value for CRC control registger based on user configuraton without WAS field */ + crcControl = 0 | CRC_CTRL_TOT(config->writeTranspose) | CRC_CTRL_TOTR(config->readTranspose) | + CRC_CTRL_FXOR(config->complementChecksum) | CRC_CTRL_TCRC(config->crcBits); + + /* make sure the control register is clear - WAS is deasserted, and protocol is set */ + base->CTRL = crcControl; + + /* write polynomial register */ + base->GPOLY = config->polynomial; + + /* write pre-computed control register value along with WAS to start checksum computation */ + base->CTRL = crcControl | CRC_CTRL_WAS(true); + + /* write seed (initial checksum) */ + base->DATA = config->seed; + + /* deassert WAS by writing pre-computed CRC control register value */ + base->CTRL = crcControl; +} + +/*! + * @brief Starts final checksum computation. + * + * Configures the CRC module for the specified CRC protocol. @n + * Starts final checksum computation by writing the seed value. + * @note CRC_Get16bitResult() or CRC_Get32bitResult() return final checksum + * (output reflection and xor functions are applied). + * + * @param base CRC peripheral address. + * @param protocolConfig Pointer to protocol configuration structure. + */ +static void CRC_SetProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig) +{ + crc_module_config_t moduleConfig; + /* convert protocol to CRC peripheral module configuration, prepare for final checksum */ + moduleConfig.polynomial = protocolConfig->polynomial; + moduleConfig.seed = protocolConfig->seed; + moduleConfig.readTranspose = CRC_GetTransposeTypeFromReflectOut(protocolConfig->reflectOut); + moduleConfig.writeTranspose = CRC_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn); + moduleConfig.complementChecksum = protocolConfig->complementChecksum; + moduleConfig.crcBits = protocolConfig->crcBits; + + CRC_ConfigureAndStart(base, &moduleConfig); +} + +/*! + * @brief Starts intermediate checksum computation. + * + * Configures the CRC module for the specified CRC protocol. @n + * Starts intermediate checksum computation by writing the seed value. + * @note CRC_Get16bitResult() or CRC_Get32bitResult() return intermediate checksum (raw data register value). + * + * @param base CRC peripheral address. + * @param protocolConfig Pointer to protocol configuration structure. + */ +static void CRC_SetRawProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig) +{ + crc_module_config_t moduleConfig; + /* convert protocol to CRC peripheral module configuration, prepare for intermediate checksum */ + moduleConfig.polynomial = protocolConfig->polynomial; + moduleConfig.seed = protocolConfig->seed; + moduleConfig.readTranspose = + kCrcTransposeNone; /* intermediate checksum does no transpose of data register read value */ + moduleConfig.writeTranspose = CRC_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn); + moduleConfig.complementChecksum = false; /* intermediate checksum does no xor of data register read value */ + moduleConfig.crcBits = protocolConfig->crcBits; + + CRC_ConfigureAndStart(base, &moduleConfig); +} + +void CRC_Init(CRC_Type *base, const crc_config_t *config) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* ungate clock */ + CLOCK_EnableClock(kCLOCK_Crc0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + /* configure CRC module and write the seed */ + if (config->crcResult == kCrcFinalChecksum) + { + CRC_SetProtocolConfig(base, config); + } + else + { + CRC_SetRawProtocolConfig(base, config); + } +} + +void CRC_GetDefaultConfig(crc_config_t *config) +{ + static const crc_config_t crc16ccit = { + CRC_DRIVER_DEFAULT_POLYNOMIAL, CRC_DRIVER_DEFAULT_SEED, + CRC_DRIVER_DEFAULT_REFLECT_IN, CRC_DRIVER_DEFAULT_REFLECT_OUT, + CRC_DRIVER_DEFAULT_COMPLEMENT_CHECKSUM, CRC_DRIVER_DEFAULT_CRC_BITS, + CRC_DRIVER_DEFAULT_CRC_RESULT, + }; + + *config = crc16ccit; +} + +void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize) +{ + const uint32_t *data32; + + /* 8-bit reads and writes till source address is aligned 4 bytes */ + while ((dataSize) && ((uint32_t)data & 3U)) + { + base->ACCESS8BIT.DATALL = *data; + data++; + dataSize--; + } + + /* use 32-bit reads and writes as long as possible */ + data32 = (const uint32_t *)data; + while (dataSize >= sizeof(uint32_t)) + { + base->DATA = *data32; + data32++; + dataSize -= sizeof(uint32_t); + } + + data = (const uint8_t *)data32; + + /* 8-bit reads and writes till end of data buffer */ + while (dataSize) + { + base->ACCESS8BIT.DATALL = *data; + data++; + dataSize--; + } +} + +uint32_t CRC_Get32bitResult(CRC_Type *base) +{ + return base->DATA; +} + +uint16_t CRC_Get16bitResult(CRC_Type *base) +{ + uint32_t retval; + uint32_t totr; /* type of transpose read bitfield */ + + retval = base->DATA; + totr = (base->CTRL & CRC_CTRL_TOTR_MASK) >> CRC_CTRL_TOTR_SHIFT; + + /* check transpose type to get 16-bit out of 32-bit register */ + if (totr >= 2U) + { + /* transpose of bytes for read is set, the result CRC is in CRC_DATA[HU:HL] */ + retval &= 0xFFFF0000U; + retval = retval >> 16U; + } + else + { + /* no transpose of bytes for read, the result CRC is in CRC_DATA[LU:LL] */ + retval &= 0x0000FFFFU; + } + return (uint16_t)retval; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_crc.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_crc.h new file mode 100644 index 00000000000..aa52c4ec2cd --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_crc.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_CRC_H_ +#define _FSL_CRC_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup crc + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief CRC driver version. Version 2.0.1. + * + * Current version: 2.0.1 + * + * Change log: + * - Version 2.0.1 + * - move DATA and DATALL macro definition from header file to source file + */ +#define FSL_CRC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +#ifndef CRC_DRIVER_CUSTOM_DEFAULTS +/*! @brief Default configuration structure filled by CRC_GetDefaultConfig(). Use CRC16-CCIT-FALSE as defeault. */ +#define CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT 1 +#endif + +/*! @brief CRC bit width */ +typedef enum _crc_bits +{ + kCrcBits16 = 0U, /*!< Generate 16-bit CRC code */ + kCrcBits32 = 1U /*!< Generate 32-bit CRC code */ +} crc_bits_t; + +/*! @brief CRC result type */ +typedef enum _crc_result +{ + kCrcFinalChecksum = 0U, /*!< CRC data register read value is the final checksum. + Reflect out and final xor protocol features are applied. */ + kCrcIntermediateChecksum = 1U /*!< CRC data register read value is intermediate checksum (raw value). + Reflect out and final xor protocol feature are not applied. + Intermediate checksum can be used as a seed for CRC_Init() + to continue adding data to this checksum. */ +} crc_result_t; + +/*! +* @brief CRC protocol configuration. +* +* This structure holds the configuration for the CRC protocol. +* +*/ +typedef struct _crc_config +{ + uint32_t polynomial; /*!< CRC Polynomial, MSBit first. + Example polynomial: 0x1021 = 1_0000_0010_0001 = x^12+x^5+1 */ + uint32_t seed; /*!< Starting checksum value */ + bool reflectIn; /*!< Reflect bits on input. */ + bool reflectOut; /*!< Reflect bits on output. */ + bool complementChecksum; /*!< True if the result shall be complement of the actual checksum. */ + crc_bits_t crcBits; /*!< Selects 16- or 32- bit CRC protocol. */ + crc_result_t crcResult; /*!< Selects final or intermediate checksum return from CRC_Get16bitResult() or + CRC_Get32bitResult() */ +} crc_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Enables and configures the CRC peripheral module. + * + * This function enables the clock gate in the Kinetis SIM module for the CRC peripheral. + * It also configures the CRC module and starts a checksum computation by writing the seed. + * + * @param base CRC peripheral address. + * @param config CRC module configuration structure. + */ +void CRC_Init(CRC_Type *base, const crc_config_t *config); + +/*! + * @brief Disables the CRC peripheral module. + * + * This function disables the clock gate in the Kinetis SIM module for the CRC peripheral. + * + * @param base CRC peripheral address. + */ +static inline void CRC_Deinit(CRC_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* gate clock */ + CLOCK_DisableClock(kCLOCK_Crc0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * @brief Loads default values to the CRC protocol configuration structure. + * + * Loads default values to the CRC protocol configuration structure. The default values are as follows. + * @code + * config->polynomial = 0x1021; + * config->seed = 0xFFFF; + * config->reflectIn = false; + * config->reflectOut = false; + * config->complementChecksum = false; + * config->crcBits = kCrcBits16; + * config->crcResult = kCrcFinalChecksum; + * @endcode + * + * @param config CRC protocol configuration structure. + */ +void CRC_GetDefaultConfig(crc_config_t *config); + +/*! + * @brief Writes data to the CRC module. + * + * Writes input data buffer bytes to the CRC data register. + * The configured type of transpose is applied. + * + * @param base CRC peripheral address. + * @param data Input data stream, MSByte in data[0]. + * @param dataSize Size in bytes of the input data buffer. + */ +void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize); + +/*! + * @brief Reads the 32-bit checksum from the CRC module. + * + * Reads the CRC data register (either an intermediate or the final checksum). + * The configured type of transpose and complement is applied. + * + * @param base CRC peripheral address. + * @return An intermediate or the final 32-bit checksum, after configured transpose and complement operations. + */ +uint32_t CRC_Get32bitResult(CRC_Type *base); + +/*! + * @brief Reads a 16-bit checksum from the CRC module. + * + * Reads the CRC data register (either an intermediate or the final checksum). + * The configured type of transpose and complement is applied. + * + * @param base CRC peripheral address. + * @return An intermediate or the final 16-bit checksum, after configured transpose and complement operations. + */ +uint16_t CRC_Get16bitResult(CRC_Type *base); + +#if defined(__cplusplus) +} +#endif + +/*! + *@} + */ + +#endif /* _FSL_CRC_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dac.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dac.c new file mode 100644 index 00000000000..43290dbfbcd --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dac.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_dac.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get instance number for DAC module. + * + * @param base DAC peripheral base address + */ +static uint32_t DAC_GetInstance(DAC_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to DAC bases for each instance. */ +static DAC_Type *const s_dacBases[] = DAC_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to DAC clocks for each instance. */ +static const clock_ip_name_t s_dacClocks[] = DAC_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Codes + ******************************************************************************/ +static uint32_t DAC_GetInstance(DAC_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_DAC_COUNT; instance++) + { + if (s_dacBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_DAC_COUNT); + + return instance; +} + +void DAC_Init(DAC_Type *base, const dac_config_t *config) +{ + assert(NULL != config); + + uint8_t tmp8; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the clock. */ + CLOCK_EnableClock(s_dacClocks[DAC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Configure. */ + /* DACx_C0. */ + tmp8 = base->C0 & ~(DAC_C0_DACRFS_MASK | DAC_C0_LPEN_MASK); + if (kDAC_ReferenceVoltageSourceVref2 == config->referenceVoltageSource) + { + tmp8 |= DAC_C0_DACRFS_MASK; + } + if (config->enableLowPowerMode) + { + tmp8 |= DAC_C0_LPEN_MASK; + } + base->C0 = tmp8; + + /* DAC_Enable(base, true); */ + /* Tip: The DAC output can be enabled till then after user sets their own available data in application. */ +} + +void DAC_Deinit(DAC_Type *base) +{ + DAC_Enable(base, false); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable the clock. */ + CLOCK_DisableClock(s_dacClocks[DAC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void DAC_GetDefaultConfig(dac_config_t *config) +{ + assert(NULL != config); + + config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2; + config->enableLowPowerMode = false; +} + +void DAC_SetBufferConfig(DAC_Type *base, const dac_buffer_config_t *config) +{ + assert(NULL != config); + + uint8_t tmp8; + + /* DACx_C0. */ + tmp8 = base->C0 & ~(DAC_C0_DACTRGSEL_MASK); + if (kDAC_BufferTriggerBySoftwareMode == config->triggerMode) + { + tmp8 |= DAC_C0_DACTRGSEL_MASK; + } + base->C0 = tmp8; + + /* DACx_C1. */ + tmp8 = base->C1 & + ~( +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION + DAC_C1_DACBFWM_MASK | +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + DAC_C1_DACBFMD_MASK); +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION + tmp8 |= DAC_C1_DACBFWM(config->watermark); +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + tmp8 |= DAC_C1_DACBFMD(config->workMode); + base->C1 = tmp8; + + /* DACx_C2. */ + tmp8 = base->C2 & ~DAC_C2_DACBFUP_MASK; + tmp8 |= DAC_C2_DACBFUP(config->upperLimit); + base->C2 = tmp8; +} + +void DAC_GetDefaultBufferConfig(dac_buffer_config_t *config) +{ + assert(NULL != config); + + config->triggerMode = kDAC_BufferTriggerBySoftwareMode; +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION + config->watermark = kDAC_BufferWatermark1Word; +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + config->workMode = kDAC_BufferWorkAsNormalMode; + config->upperLimit = DAC_DATL_COUNT - 1U; +} + +void DAC_SetBufferValue(DAC_Type *base, uint8_t index, uint16_t value) +{ + assert(index < DAC_DATL_COUNT); + + base->DAT[index].DATL = (uint8_t)(0xFFU & value); /* Low 8-bit. */ + base->DAT[index].DATH = (uint8_t)((0xF00U & value) >> 8); /* High 4-bit. */ +} + +void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index) +{ + assert(index < DAC_DATL_COUNT); + + uint8_t tmp8 = base->C2 & ~DAC_C2_DACBFRP_MASK; + + tmp8 |= DAC_C2_DACBFRP(index); + base->C2 = tmp8; +} + +void DAC_EnableBufferInterrupts(DAC_Type *base, uint32_t mask) +{ + mask &= ( +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION + DAC_C0_DACBWIEN_MASK | +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ + DAC_C0_DACBTIEN_MASK | DAC_C0_DACBBIEN_MASK); + base->C0 |= ((uint8_t)mask); /* Write 1 to enable. */ +} + +void DAC_DisableBufferInterrupts(DAC_Type *base, uint32_t mask) +{ + mask &= ( +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION + DAC_C0_DACBWIEN_MASK | +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ + DAC_C0_DACBTIEN_MASK | DAC_C0_DACBBIEN_MASK); + base->C0 &= (uint8_t)(~((uint8_t)mask)); /* Write 0 to disable. */ +} + +uint32_t DAC_GetBufferStatusFlags(DAC_Type *base) +{ + return (uint32_t)(base->SR & ( +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION + DAC_SR_DACBFWMF_MASK | +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ + DAC_SR_DACBFRPTF_MASK | DAC_SR_DACBFRPBF_MASK)); +} + +void DAC_ClearBufferStatusFlags(DAC_Type *base, uint32_t mask) +{ + mask &= ( +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION + DAC_SR_DACBFWMF_MASK | +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ + DAC_SR_DACBFRPTF_MASK | DAC_SR_DACBFRPBF_MASK); + base->SR &= (uint8_t)(~((uint8_t)mask)); /* Write 0 to clear flags. */ +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dac.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dac.h new file mode 100644 index 00000000000..a49c5b98955 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dac.h @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_DAC_H_ +#define _FSL_DAC_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup dac + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief DAC driver version 2.0.1. */ +#define FSL_DAC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! + * @brief DAC buffer flags. + */ +enum _dac_buffer_status_flags +{ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION + kDAC_BufferWatermarkFlag = DAC_SR_DACBFWMF_MASK, /*!< DAC Buffer Watermark Flag. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ + kDAC_BufferReadPointerTopPositionFlag = DAC_SR_DACBFRPTF_MASK, /*!< DAC Buffer Read Pointer Top Position Flag. */ + kDAC_BufferReadPointerBottomPositionFlag = DAC_SR_DACBFRPBF_MASK, /*!< DAC Buffer Read Pointer Bottom Position + Flag. */ +}; + +/*! + * @brief DAC buffer interrupts. + */ +enum _dac_buffer_interrupt_enable +{ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION + kDAC_BufferWatermarkInterruptEnable = DAC_C0_DACBWIEN_MASK, /*!< DAC Buffer Watermark Interrupt Enable. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ + kDAC_BufferReadPointerTopInterruptEnable = DAC_C0_DACBTIEN_MASK, /*!< DAC Buffer Read Pointer Top Flag Interrupt + Enable. */ + kDAC_BufferReadPointerBottomInterruptEnable = DAC_C0_DACBBIEN_MASK, /*!< DAC Buffer Read Pointer Bottom Flag + Interrupt Enable */ +}; + +/*! + * @brief DAC reference voltage source. + */ +typedef enum _dac_reference_voltage_source +{ + kDAC_ReferenceVoltageSourceVref1 = 0U, /*!< The DAC selects DACREF_1 as the reference voltage. */ + kDAC_ReferenceVoltageSourceVref2 = 1U, /*!< The DAC selects DACREF_2 as the reference voltage. */ +} dac_reference_voltage_source_t; + +/*! + * @brief DAC buffer trigger mode. + */ +typedef enum _dac_buffer_trigger_mode +{ + kDAC_BufferTriggerByHardwareMode = 0U, /*!< The DAC hardware trigger is selected. */ + kDAC_BufferTriggerBySoftwareMode = 1U, /*!< The DAC software trigger is selected. */ +} dac_buffer_trigger_mode_t; + +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION +/*! + * @brief DAC buffer watermark. + */ +typedef enum _dac_buffer_watermark +{ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD + kDAC_BufferWatermark1Word = 0U, /*!< 1 word away from the upper limit. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD */ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS) && FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS + kDAC_BufferWatermark2Word = 1U, /*!< 2 words away from the upper limit. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS */ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS) && FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS + kDAC_BufferWatermark3Word = 2U, /*!< 3 words away from the upper limit. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS */ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS) && FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS + kDAC_BufferWatermark4Word = 3U, /*!< 4 words away from the upper limit. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS */ +} dac_buffer_watermark_t; +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + +/*! + * @brief DAC buffer work mode. + */ +typedef enum _dac_buffer_work_mode +{ + kDAC_BufferWorkAsNormalMode = 0U, /*!< Normal mode. */ +#if defined(FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE) && FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE + kDAC_BufferWorkAsSwingMode, /*!< Swing mode. */ +#endif /* FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE */ + kDAC_BufferWorkAsOneTimeScanMode, /*!< One-Time Scan mode. */ +#if defined(FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE) && FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE + kDAC_BufferWorkAsFIFOMode, /*!< FIFO mode. */ +#endif /* FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE */ +} dac_buffer_work_mode_t; + +/*! + * @brief DAC module configuration. + */ +typedef struct _dac_config +{ + dac_reference_voltage_source_t referenceVoltageSource; /*!< Select the DAC reference voltage source. */ + bool enableLowPowerMode; /*!< Enable the low-power mode. */ +} dac_config_t; + +/*! + * @brief DAC buffer configuration. + */ +typedef struct _dac_buffer_config +{ + dac_buffer_trigger_mode_t triggerMode; /*!< Select the buffer's trigger mode. */ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION + dac_buffer_watermark_t watermark; /*!< Select the buffer's watermark. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + dac_buffer_work_mode_t workMode; /*!< Select the buffer's work mode. */ + uint8_t upperLimit; /*!< Set the upper limit for the buffer index. + Normally, 0-15 is available for a buffer with 16 items. */ +} dac_buffer_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization + * @{ + */ + +/*! + * @brief Initializes the DAC module. + * + * This function initializes the DAC module including the following operations. + * - Enabling the clock for DAC module. + * - Configuring the DAC converter with a user configuration. + * - Enabling the DAC module. + * + * @param base DAC peripheral base address. + * @param config Pointer to the configuration structure. See "dac_config_t". + */ +void DAC_Init(DAC_Type *base, const dac_config_t *config); + +/*! + * @brief De-initializes the DAC module. + * + * This function de-initializes the DAC module including the following operations. + * - Disabling the DAC module. + * - Disabling the clock for the DAC module. + * + * @param base DAC peripheral base address. + */ +void DAC_Deinit(DAC_Type *base); + +/*! + * @brief Initializes the DAC user configuration structure. + * + * This function initializes the user configuration structure to a default value. The default values are as follows. + * @code + * config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2; + * config->enableLowPowerMode = false; + * @endcode + * @param config Pointer to the configuration structure. See "dac_config_t". + */ +void DAC_GetDefaultConfig(dac_config_t *config); + +/*! + * @brief Enables the DAC module. + * + * @param base DAC peripheral base address. + * @param enable Enables or disables the feature. + */ +static inline void DAC_Enable(DAC_Type *base, bool enable) +{ + if (enable) + { + base->C0 |= DAC_C0_DACEN_MASK; + } + else + { + base->C0 &= ~DAC_C0_DACEN_MASK; + } +} + +/* @} */ + +/*! + * @name Buffer + * @{ + */ + +/*! + * @brief Enables the DAC buffer. + * + * @param base DAC peripheral base address. + * @param enable Enables or disables the feature. + */ +static inline void DAC_EnableBuffer(DAC_Type *base, bool enable) +{ + if (enable) + { + base->C1 |= DAC_C1_DACBFEN_MASK; + } + else + { + base->C1 &= ~DAC_C1_DACBFEN_MASK; + } +} + +/*! + * @brief Configures the CMP buffer. + * + * @param base DAC peripheral base address. + * @param config Pointer to the configuration structure. See "dac_buffer_config_t". + */ +void DAC_SetBufferConfig(DAC_Type *base, const dac_buffer_config_t *config); + +/*! + * @brief Initializes the DAC buffer configuration structure. + * + * This function initializes the DAC buffer configuration structure to default values. The default values are as follows. + * @code + * config->triggerMode = kDAC_BufferTriggerBySoftwareMode; + * config->watermark = kDAC_BufferWatermark1Word; + * config->workMode = kDAC_BufferWorkAsNormalMode; + * config->upperLimit = DAC_DATL_COUNT - 1U; + * @endcode + * @param config Pointer to the configuration structure. See "dac_buffer_config_t". + */ +void DAC_GetDefaultBufferConfig(dac_buffer_config_t *config); + +/*! + * @brief Enables the DMA for DAC buffer. + * + * @param base DAC peripheral base address. + * @param enable Enables or disables the feature. + */ +static inline void DAC_EnableBufferDMA(DAC_Type *base, bool enable) +{ + if (enable) + { + base->C1 |= DAC_C1_DMAEN_MASK; + } + else + { + base->C1 &= ~DAC_C1_DMAEN_MASK; + } +} + +/*! + * @brief Sets the value for items in the buffer. + * + * @param base DAC peripheral base address. + * @param index Setting the index for items in the buffer. The available index should not exceed the size of the DAC buffer. + * @param value Setting the value for items in the buffer. 12-bits are available. + */ +void DAC_SetBufferValue(DAC_Type *base, uint8_t index, uint16_t value); + +/*! + * @brief Triggers the buffer using software and updates the read pointer of the DAC buffer. + * + * This function triggers the function using software. The read pointer of the DAC buffer is updated with one step + * after this function is called. Changing the read pointer depends on the buffer's work mode. + * + * @param base DAC peripheral base address. + */ +static inline void DAC_DoSoftwareTriggerBuffer(DAC_Type *base) +{ + base->C0 |= DAC_C0_DACSWTRG_MASK; +} + +/*! + * @brief Gets the current read pointer of the DAC buffer. + * + * This function gets the current read pointer of the DAC buffer. + * The current output value depends on the item indexed by the read pointer. It is updated either + * by a software trigger or a hardware trigger. + * + * @param base DAC peripheral base address. + * + * @return The current read pointer of the DAC buffer. + */ +static inline uint8_t DAC_GetBufferReadPointer(DAC_Type *base) +{ + return ((base->C2 & DAC_C2_DACBFRP_MASK) >> DAC_C2_DACBFRP_SHIFT); +} + +/*! + * @brief Sets the current read pointer of the DAC buffer. + * + * This function sets the current read pointer of the DAC buffer. + * The current output value depends on the item indexed by the read pointer. It is updated either by a + * software trigger or a hardware trigger. After the read pointer changes, the DAC output value also changes. + * + * @param base DAC peripheral base address. + * @param index Setting an index value for the pointer. + */ +void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index); + +/*! + * @brief Enables interrupts for the DAC buffer. + * + * @param base DAC peripheral base address. + * @param mask Mask value for interrupts. See "_dac_buffer_interrupt_enable". + */ +void DAC_EnableBufferInterrupts(DAC_Type *base, uint32_t mask); + +/*! + * @brief Disables interrupts for the DAC buffer. + * + * @param base DAC peripheral base address. + * @param mask Mask value for interrupts. See "_dac_buffer_interrupt_enable". + */ +void DAC_DisableBufferInterrupts(DAC_Type *base, uint32_t mask); + +/*! + * @brief Gets the flags of events for the DAC buffer. + * + * @param base DAC peripheral base address. + * + * @return Mask value for the asserted flags. See "_dac_buffer_status_flags". + */ +uint32_t DAC_GetBufferStatusFlags(DAC_Type *base); + +/*! + * @brief Clears the flags of events for the DAC buffer. + * + * @param base DAC peripheral base address. + * @param mask Mask value for flags. See "_dac_buffer_status_flags_t". + */ +void DAC_ClearBufferStatusFlags(DAC_Type *base, uint32_t mask); + +/* @} */ + +#if defined(__cplusplus) +} +#endif +/*! + * @} + */ +#endif /* _FSL_DAC_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dmamux.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dmamux.c new file mode 100644 index 00000000000..76c559ba0fb --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dmamux.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_dmamux.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get instance number for DMAMUX. + * + * @param base DMAMUX peripheral base address. + */ +static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Array to map DMAMUX instance number to base pointer. */ +static DMAMUX_Type *const s_dmamuxBases[] = DMAMUX_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Array to map DMAMUX instance number to clock name. */ +static const clock_ip_name_t s_dmamuxClockName[] = DMAMUX_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_DMAMUX_COUNT; instance++) + { + if (s_dmamuxBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_DMAMUX_COUNT); + + return instance; +} + +void DMAMUX_Init(DMAMUX_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void DMAMUX_Deinit(DMAMUX_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dmamux.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dmamux.h new file mode 100644 index 00000000000..c0bdd7becfd --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dmamux.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_DMAMUX_H_ +#define _FSL_DMAMUX_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup dmamux + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief DMAMUX driver version 2.0.2. */ +#define FSL_DMAMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) +/*@}*/ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name DMAMUX Initialization and de-initialization + * @{ + */ + +/*! + * @brief Initializes the DMAMUX peripheral. + * + * This function ungates the DMAMUX clock. + * + * @param base DMAMUX peripheral base address. + * + */ +void DMAMUX_Init(DMAMUX_Type *base); + +/*! + * @brief Deinitializes the DMAMUX peripheral. + * + * This function gates the DMAMUX clock. + * + * @param base DMAMUX peripheral base address. + */ +void DMAMUX_Deinit(DMAMUX_Type *base); + +/* @} */ +/*! + * @name DMAMUX Channel Operation + * @{ + */ + +/*! + * @brief Enables the DMAMUX channel. + * + * This function enables the DMAMUX channel. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + */ +static inline void DMAMUX_EnableChannel(DMAMUX_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] |= DMAMUX_CHCFG_ENBL_MASK; +} + +/*! + * @brief Disables the DMAMUX channel. + * + * This function disables the DMAMUX channel. + * + * @note The user must disable the DMAMUX channel before configuring it. + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + */ +static inline void DMAMUX_DisableChannel(DMAMUX_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] &= ~DMAMUX_CHCFG_ENBL_MASK; +} + +/*! + * @brief Configures the DMAMUX channel source. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + * @param source Channel source, which is used to trigger the DMA transfer. + */ +static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint32_t source) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] = ((base->CHCFG[channel] & ~DMAMUX_CHCFG_SOURCE_MASK) | DMAMUX_CHCFG_SOURCE(source)); +} + +#if defined(FSL_FEATURE_DMAMUX_HAS_TRIG) && FSL_FEATURE_DMAMUX_HAS_TRIG > 0U +/*! + * @brief Enables the DMAMUX period trigger. + * + * This function enables the DMAMUX period trigger feature. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + */ +static inline void DMAMUX_EnablePeriodTrigger(DMAMUX_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] |= DMAMUX_CHCFG_TRIG_MASK; +} + +/*! + * @brief Disables the DMAMUX period trigger. + * + * This function disables the DMAMUX period trigger. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + */ +static inline void DMAMUX_DisablePeriodTrigger(DMAMUX_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] &= ~DMAMUX_CHCFG_TRIG_MASK; +} +#endif /* FSL_FEATURE_DMAMUX_HAS_TRIG */ + +#if (defined(FSL_FEATURE_DMAMUX_HAS_A_ON) && FSL_FEATURE_DMAMUX_HAS_A_ON) +/*! + * @brief Enables the DMA channel to be always ON. + * + * This function enables the DMAMUX channel always ON feature. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + * @param enable Switcher of the always ON feature. "true" means enabled, "false" means disabled. + */ +static inline void DMAMUX_EnableAlwaysOn(DMAMUX_Type *base, uint32_t channel, bool enable) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + if (enable) + { + base->CHCFG[channel] |= DMAMUX_CHCFG_A_ON_MASK; + } + else + { + base->CHCFG[channel] &= ~DMAMUX_CHCFG_A_ON_MASK; + } +} +#endif /* FSL_FEATURE_DMAMUX_HAS_A_ON */ + +/* @} */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/* @} */ + +#endif /* _FSL_DMAMUX_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi.c new file mode 100644 index 00000000000..4bc67d7ad37 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi.c @@ -0,0 +1,1670 @@ +/* +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "fsl_dspi.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Typedef for master interrupt handler. */ +typedef void (*dspi_master_isr_t)(SPI_Type *base, dspi_master_handle_t *handle); + +/*! @brief Typedef for slave interrupt handler. */ +typedef void (*dspi_slave_isr_t)(SPI_Type *base, dspi_slave_handle_t *handle); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get instance number for DSPI module. + * + * @param base DSPI peripheral base address. + */ +uint32_t DSPI_GetInstance(SPI_Type *base); + +/*! + * @brief Configures the DSPI peripheral chip select polarity. + * + * This function takes in the desired peripheral chip select (Pcs) and it's corresponding desired polarity and + * configures the Pcs signal to operate with the desired characteristic. + * + * @param base DSPI peripheral address. + * @param pcs The particular peripheral chip select (parameter value is of type dspi_which_pcs_t) for which we wish to + * apply the active high or active low characteristic. + * @param activeLowOrHigh The setting for either "active high, inactive low (0)" or "active low, inactive high(1)" of + * type dspi_pcs_polarity_config_t. + */ +static void DSPI_SetOnePcsPolarity(SPI_Type *base, dspi_which_pcs_t pcs, dspi_pcs_polarity_config_t activeLowOrHigh); + +/*! + * @brief Master fill up the TX FIFO with data. + * This is not a public API as it is called from other driver functions. + */ +static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t *handle); + +/*! + * @brief Master finish up a transfer. + * It would call back if there is callback function and set the state to idle. + * This is not a public API as it is called from other driver functions. + */ +static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *handle); + +/*! + * @brief Slave fill up the TX FIFO with data. + * This is not a public API as it is called from other driver functions. + */ +static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *handle); + +/*! + * @brief Slave finish up a transfer. + * It would call back if there is callback function and set the state to idle. + * This is not a public API as it is called from other driver functions. + */ +static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *handle); + +/*! + * @brief DSPI common interrupt handler. + * + * @param base DSPI peripheral address. + * @param handle pointer to g_dspiHandle which stores the transfer state. + */ +static void DSPI_CommonIRQHandler(SPI_Type *base, void *param); + +/*! + * @brief Master prepare the transfer. + * Basically it set up dspi_master_handle . + * This is not a public API as it is called from other driver functions. fsl_dspi_edma.c also call this function. + */ +static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Defines constant value arrays for the baud rate pre-scalar and scalar divider values.*/ +static const uint32_t s_baudratePrescaler[] = {2, 3, 5, 7}; +static const uint32_t s_baudrateScaler[] = {2, 4, 6, 8, 16, 32, 64, 128, + 256, 512, 1024, 2048, 4096, 8192, 16384, 32768}; + +static const uint32_t s_delayPrescaler[] = {1, 3, 5, 7}; +static const uint32_t s_delayScaler[] = {2, 4, 8, 16, 32, 64, 128, 256, + 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536}; + +/*! @brief Pointers to dspi bases for each instance. */ +static SPI_Type *const s_dspiBases[] = SPI_BASE_PTRS; + +/*! @brief Pointers to dspi IRQ number for each instance. */ +static IRQn_Type const s_dspiIRQ[] = SPI_IRQS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to dspi clocks for each instance. */ +static clock_ip_name_t const s_dspiClock[] = DSPI_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Pointers to dspi handles for each instance. */ +static void *g_dspiHandle[FSL_FEATURE_SOC_DSPI_COUNT]; + +/*! @brief Pointer to master IRQ handler for each instance. */ +static dspi_master_isr_t s_dspiMasterIsr; + +/*! @brief Pointer to slave IRQ handler for each instance. */ +static dspi_slave_isr_t s_dspiSlaveIsr; + +/********************************************************************************************************************** +* Code +*********************************************************************************************************************/ +uint32_t DSPI_GetInstance(SPI_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_DSPI_COUNT; instance++) + { + if (s_dspiBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_DSPI_COUNT); + + return instance; +} + +void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz) +{ + assert(masterConfig); + + uint32_t temp; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* enable DSPI clock */ + CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + DSPI_Enable(base, true); + DSPI_StopTransfer(base); + + DSPI_SetMasterSlaveMode(base, kDSPI_Master); + + temp = base->MCR & (~(SPI_MCR_CONT_SCKE_MASK | SPI_MCR_MTFE_MASK | SPI_MCR_ROOE_MASK | SPI_MCR_SMPL_PT_MASK | + SPI_MCR_DIS_TXF_MASK | SPI_MCR_DIS_RXF_MASK)); + + base->MCR = temp | SPI_MCR_CONT_SCKE(masterConfig->enableContinuousSCK) | + SPI_MCR_MTFE(masterConfig->enableModifiedTimingFormat) | + SPI_MCR_ROOE(masterConfig->enableRxFifoOverWrite) | SPI_MCR_SMPL_PT(masterConfig->samplePoint) | + SPI_MCR_DIS_TXF(false) | SPI_MCR_DIS_RXF(false); + + DSPI_SetOnePcsPolarity(base, masterConfig->whichPcs, masterConfig->pcsActiveHighOrLow); + + if (0 == DSPI_MasterSetBaudRate(base, masterConfig->whichCtar, masterConfig->ctarConfig.baudRate, srcClock_Hz)) + { + assert(false); + } + + temp = base->CTAR[masterConfig->whichCtar] & + ~(SPI_CTAR_FMSZ_MASK | SPI_CTAR_CPOL_MASK | SPI_CTAR_CPHA_MASK | SPI_CTAR_LSBFE_MASK); + + base->CTAR[masterConfig->whichCtar] = + temp | SPI_CTAR_FMSZ(masterConfig->ctarConfig.bitsPerFrame - 1) | SPI_CTAR_CPOL(masterConfig->ctarConfig.cpol) | + SPI_CTAR_CPHA(masterConfig->ctarConfig.cpha) | SPI_CTAR_LSBFE(masterConfig->ctarConfig.direction); + + DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_PcsToSck, srcClock_Hz, + masterConfig->ctarConfig.pcsToSckDelayInNanoSec); + DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_LastSckToPcs, srcClock_Hz, + masterConfig->ctarConfig.lastSckToPcsDelayInNanoSec); + DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_BetweenTransfer, srcClock_Hz, + masterConfig->ctarConfig.betweenTransferDelayInNanoSec); + + DSPI_StartTransfer(base); +} + +void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig) +{ + assert(masterConfig); + + masterConfig->whichCtar = kDSPI_Ctar0; + masterConfig->ctarConfig.baudRate = 500000; + masterConfig->ctarConfig.bitsPerFrame = 8; + masterConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh; + masterConfig->ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge; + masterConfig->ctarConfig.direction = kDSPI_MsbFirst; + + masterConfig->ctarConfig.pcsToSckDelayInNanoSec = 1000; + masterConfig->ctarConfig.lastSckToPcsDelayInNanoSec = 1000; + masterConfig->ctarConfig.betweenTransferDelayInNanoSec = 1000; + + masterConfig->whichPcs = kDSPI_Pcs0; + masterConfig->pcsActiveHighOrLow = kDSPI_PcsActiveLow; + + masterConfig->enableContinuousSCK = false; + masterConfig->enableRxFifoOverWrite = false; + masterConfig->enableModifiedTimingFormat = false; + masterConfig->samplePoint = kDSPI_SckToSin0Clock; +} + +void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig) +{ + assert(slaveConfig); + + uint32_t temp = 0; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* enable DSPI clock */ + CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + DSPI_Enable(base, true); + DSPI_StopTransfer(base); + + DSPI_SetMasterSlaveMode(base, kDSPI_Slave); + + temp = base->MCR & (~(SPI_MCR_CONT_SCKE_MASK | SPI_MCR_MTFE_MASK | SPI_MCR_ROOE_MASK | SPI_MCR_SMPL_PT_MASK | + SPI_MCR_DIS_TXF_MASK | SPI_MCR_DIS_RXF_MASK)); + + base->MCR = temp | SPI_MCR_CONT_SCKE(slaveConfig->enableContinuousSCK) | + SPI_MCR_MTFE(slaveConfig->enableModifiedTimingFormat) | + SPI_MCR_ROOE(slaveConfig->enableRxFifoOverWrite) | SPI_MCR_SMPL_PT(slaveConfig->samplePoint) | + SPI_MCR_DIS_TXF(false) | SPI_MCR_DIS_RXF(false); + + DSPI_SetOnePcsPolarity(base, kDSPI_Pcs0, kDSPI_PcsActiveLow); + + temp = base->CTAR[slaveConfig->whichCtar] & + ~(SPI_CTAR_FMSZ_MASK | SPI_CTAR_CPOL_MASK | SPI_CTAR_CPHA_MASK | SPI_CTAR_LSBFE_MASK); + + base->CTAR[slaveConfig->whichCtar] = temp | SPI_CTAR_SLAVE_FMSZ(slaveConfig->ctarConfig.bitsPerFrame - 1) | + SPI_CTAR_SLAVE_CPOL(slaveConfig->ctarConfig.cpol) | + SPI_CTAR_SLAVE_CPHA(slaveConfig->ctarConfig.cpha); + + DSPI_StartTransfer(base); +} + +void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig) +{ + assert(slaveConfig); + + slaveConfig->whichCtar = kDSPI_Ctar0; + slaveConfig->ctarConfig.bitsPerFrame = 8; + slaveConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh; + slaveConfig->ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge; + + slaveConfig->enableContinuousSCK = false; + slaveConfig->enableRxFifoOverWrite = false; + slaveConfig->enableModifiedTimingFormat = false; + slaveConfig->samplePoint = kDSPI_SckToSin0Clock; +} + +void DSPI_Deinit(SPI_Type *base) +{ + DSPI_StopTransfer(base); + DSPI_Enable(base, false); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* disable DSPI clock */ + CLOCK_DisableClock(s_dspiClock[DSPI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +static void DSPI_SetOnePcsPolarity(SPI_Type *base, dspi_which_pcs_t pcs, dspi_pcs_polarity_config_t activeLowOrHigh) +{ + uint32_t temp; + + temp = base->MCR; + + if (activeLowOrHigh == kDSPI_PcsActiveLow) + { + temp |= SPI_MCR_PCSIS(pcs); + } + else + { + temp &= ~SPI_MCR_PCSIS(pcs); + } + + base->MCR = temp; +} + +uint32_t DSPI_MasterSetBaudRate(SPI_Type *base, + dspi_ctar_selection_t whichCtar, + uint32_t baudRate_Bps, + uint32_t srcClock_Hz) +{ + /* for master mode configuration, if slave mode detected, return 0*/ + if (!DSPI_IsMaster(base)) + { + return 0; + } + uint32_t temp; + uint32_t prescaler, bestPrescaler; + uint32_t scaler, bestScaler; + uint32_t dbr, bestDbr; + uint32_t realBaudrate, bestBaudrate; + uint32_t diff, min_diff; + uint32_t baudrate = baudRate_Bps; + + /* find combination of prescaler and scaler resulting in baudrate closest to the requested value */ + min_diff = 0xFFFFFFFFU; + bestPrescaler = 0; + bestScaler = 0; + bestDbr = 1; + bestBaudrate = 0; /* required to avoid compilation warning */ + + /* In all for loops, if min_diff = 0, the exit for loop*/ + for (prescaler = 0; (prescaler < 4) && min_diff; prescaler++) + { + for (scaler = 0; (scaler < 16) && min_diff; scaler++) + { + for (dbr = 1; (dbr < 3) && min_diff; dbr++) + { + realBaudrate = ((srcClock_Hz * dbr) / (s_baudratePrescaler[prescaler] * (s_baudrateScaler[scaler]))); + + /* calculate the baud rate difference based on the conditional statement that states that the calculated + * baud rate must not exceed the desired baud rate. + */ + if (baudrate >= realBaudrate) + { + diff = baudrate - realBaudrate; + if (min_diff > diff) + { + /* a better match found */ + min_diff = diff; + bestPrescaler = prescaler; + bestScaler = scaler; + bestBaudrate = realBaudrate; + bestDbr = dbr; + } + } + } + } + } + + /* write the best dbr, prescalar, and baud rate scalar to the CTAR */ + temp = base->CTAR[whichCtar] & ~(SPI_CTAR_DBR_MASK | SPI_CTAR_PBR_MASK | SPI_CTAR_BR_MASK); + + base->CTAR[whichCtar] = temp | ((bestDbr - 1) << SPI_CTAR_DBR_SHIFT) | (bestPrescaler << SPI_CTAR_PBR_SHIFT) | + (bestScaler << SPI_CTAR_BR_SHIFT); + + /* return the actual calculated baud rate */ + return bestBaudrate; +} + +void DSPI_MasterSetDelayScaler( + SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay) +{ + /* these settings are only relevant in master mode */ + if (DSPI_IsMaster(base)) + { + switch (whichDelay) + { + case kDSPI_PcsToSck: + base->CTAR[whichCtar] = (base->CTAR[whichCtar] & (~SPI_CTAR_PCSSCK_MASK) & (~SPI_CTAR_CSSCK_MASK)) | + SPI_CTAR_PCSSCK(prescaler) | SPI_CTAR_CSSCK(scaler); + break; + case kDSPI_LastSckToPcs: + base->CTAR[whichCtar] = (base->CTAR[whichCtar] & (~SPI_CTAR_PASC_MASK) & (~SPI_CTAR_ASC_MASK)) | + SPI_CTAR_PASC(prescaler) | SPI_CTAR_ASC(scaler); + break; + case kDSPI_BetweenTransfer: + base->CTAR[whichCtar] = (base->CTAR[whichCtar] & (~SPI_CTAR_PDT_MASK) & (~SPI_CTAR_DT_MASK)) | + SPI_CTAR_PDT(prescaler) | SPI_CTAR_DT(scaler); + break; + default: + break; + } + } +} + +uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base, + dspi_ctar_selection_t whichCtar, + dspi_delay_type_t whichDelay, + uint32_t srcClock_Hz, + uint32_t delayTimeInNanoSec) +{ + /* for master mode configuration, if slave mode detected, return 0 */ + if (!DSPI_IsMaster(base)) + { + return 0; + } + + uint32_t prescaler, bestPrescaler; + uint32_t scaler, bestScaler; + uint32_t realDelay, bestDelay; + uint32_t diff, min_diff; + uint32_t initialDelayNanoSec; + + /* find combination of prescaler and scaler resulting in the delay closest to the + * requested value + */ + min_diff = 0xFFFFFFFFU; + /* Initialize prescaler and scaler to their max values to generate the max delay */ + bestPrescaler = 0x3; + bestScaler = 0xF; + bestDelay = (((1000000000U * 4) / srcClock_Hz) * s_delayPrescaler[bestPrescaler] * s_delayScaler[bestScaler]) / 4; + + /* First calculate the initial, default delay */ + initialDelayNanoSec = 1000000000U / srcClock_Hz * 2; + + /* If the initial, default delay is already greater than the desired delay, then + * set the delays to their initial value (0) and return the delay. In other words, + * there is no way to decrease the delay value further. + */ + if (initialDelayNanoSec >= delayTimeInNanoSec) + { + DSPI_MasterSetDelayScaler(base, whichCtar, 0, 0, whichDelay); + return initialDelayNanoSec; + } + + /* In all for loops, if min_diff = 0, the exit for loop */ + for (prescaler = 0; (prescaler < 4) && min_diff; prescaler++) + { + for (scaler = 0; (scaler < 16) && min_diff; scaler++) + { + realDelay = ((4000000000U / srcClock_Hz) * s_delayPrescaler[prescaler] * s_delayScaler[scaler]) / 4; + + /* calculate the delay difference based on the conditional statement + * that states that the calculated delay must not be less then the desired delay + */ + if (realDelay >= delayTimeInNanoSec) + { + diff = realDelay - delayTimeInNanoSec; + if (min_diff > diff) + { + /* a better match found */ + min_diff = diff; + bestPrescaler = prescaler; + bestScaler = scaler; + bestDelay = realDelay; + } + } + } + } + + /* write the best dbr, prescalar, and baud rate scalar to the CTAR */ + DSPI_MasterSetDelayScaler(base, whichCtar, bestPrescaler, bestScaler, whichDelay); + + /* return the actual calculated baud rate */ + return bestDelay; +} + +void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command) +{ + assert(command); + + command->isPcsContinuous = false; + command->whichCtar = kDSPI_Ctar0; + command->whichPcs = kDSPI_Pcs0; + command->isEndOfQueue = false; + command->clearTransferCount = false; +} + +void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data) +{ + assert(command); + + /* First, clear Transmit Complete Flag (TCF) */ + DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag); + + while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)) + { + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + } + + base->PUSHR = SPI_PUSHR_CONT(command->isPcsContinuous) | SPI_PUSHR_CTAS(command->whichCtar) | + SPI_PUSHR_PCS(command->whichPcs) | SPI_PUSHR_EOQ(command->isEndOfQueue) | + SPI_PUSHR_CTCNT(command->clearTransferCount) | SPI_PUSHR_TXDATA(data); + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + + /* Wait till TCF sets */ + while (!(DSPI_GetStatusFlags(base) & kDSPI_TxCompleteFlag)) + { + } +} + +void DSPI_MasterWriteCommandDataBlocking(SPI_Type *base, uint32_t data) +{ + /* First, clear Transmit Complete Flag (TCF) */ + DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag); + + while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)) + { + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + } + + base->PUSHR = data; + + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + + /* Wait till TCF sets */ + while (!(DSPI_GetStatusFlags(base) & kDSPI_TxCompleteFlag)) + { + } +} + +void DSPI_SlaveWriteDataBlocking(SPI_Type *base, uint32_t data) +{ + /* First, clear Transmit Complete Flag (TCF) */ + DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag); + + while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)) + { + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + } + + base->PUSHR_SLAVE = data; + + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + + /* Wait till TCF sets */ + while (!(DSPI_GetStatusFlags(base) & kDSPI_TxCompleteFlag)) + { + } +} + +void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask) +{ + if (mask & SPI_RSER_TFFF_RE_MASK) + { + base->RSER &= ~SPI_RSER_TFFF_DIRS_MASK; + } + if (mask & SPI_RSER_RFDF_RE_MASK) + { + base->RSER &= ~SPI_RSER_RFDF_DIRS_MASK; + } + base->RSER |= mask; +} + +/*Transactional APIs -- Master*/ + +void DSPI_MasterTransferCreateHandle(SPI_Type *base, + dspi_master_handle_t *handle, + dspi_master_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + g_dspiHandle[DSPI_GetInstance(base)] = handle; + + handle->callback = callback; + handle->userData = userData; +} + +status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer) +{ + assert(transfer); + + uint16_t wordToSend = 0; + uint16_t wordReceived = 0; + uint8_t dummyData = DSPI_DUMMY_DATA; + uint8_t bitsPerFrame; + + uint32_t command; + uint32_t lastCommand; + + uint8_t *txData; + uint8_t *rxData; + uint32_t remainingSendByteCount; + uint32_t remainingReceiveByteCount; + + uint32_t fifoSize; + dspi_command_data_config_t commandStruct; + + /* If the transfer count is zero, then return immediately.*/ + if (transfer->dataSize == 0) + { + return kStatus_InvalidArgument; + } + + DSPI_StopTransfer(base); + DSPI_DisableInterrupts(base, kDSPI_AllInterruptEnable); + DSPI_FlushFifo(base, true, true); + DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag); + + /*Calculate the command and lastCommand*/ + commandStruct.whichPcs = + (dspi_which_pcs_t)(1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT)); + commandStruct.isEndOfQueue = false; + commandStruct.clearTransferCount = false; + commandStruct.whichCtar = + (dspi_ctar_selection_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT); + commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous); + + command = DSPI_MasterGetFormattedCommand(&(commandStruct)); + + commandStruct.isEndOfQueue = true; + commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer); + lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct)); + + /*Calculate the bitsPerFrame*/ + bitsPerFrame = ((base->CTAR[commandStruct.whichCtar] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1; + + txData = transfer->txData; + rxData = transfer->rxData; + remainingSendByteCount = transfer->dataSize; + remainingReceiveByteCount = transfer->dataSize; + + if ((base->MCR & SPI_MCR_DIS_RXF_MASK) || (base->MCR & SPI_MCR_DIS_TXF_MASK)) + { + fifoSize = 1; + } + else + { + fifoSize = FSL_FEATURE_DSPI_FIFO_SIZEn(base); + } + + DSPI_StartTransfer(base); + + if (bitsPerFrame <= 8) + { + while (remainingSendByteCount > 0) + { + if (remainingSendByteCount == 1) + { + while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)) + { + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + } + + if (txData != NULL) + { + base->PUSHR = (*txData) | (lastCommand); + txData++; + } + else + { + base->PUSHR = (lastCommand) | (dummyData); + } + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + remainingSendByteCount--; + + while (remainingReceiveByteCount > 0) + { + if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) + { + if (rxData != NULL) + { + /* Read data from POPR*/ + *(rxData) = DSPI_ReadData(base); + rxData++; + } + else + { + DSPI_ReadData(base); + } + remainingReceiveByteCount--; + + DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); + } + } + } + else + { + /*Wait until Tx Fifo is not full*/ + while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)) + { + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + } + if (txData != NULL) + { + base->PUSHR = command | (uint16_t)(*txData); + txData++; + } + else + { + base->PUSHR = command | dummyData; + } + remainingSendByteCount--; + + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + + while ((remainingReceiveByteCount - remainingSendByteCount) >= fifoSize) + { + if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) + { + if (rxData != NULL) + { + *(rxData) = DSPI_ReadData(base); + rxData++; + } + else + { + DSPI_ReadData(base); + } + remainingReceiveByteCount--; + + DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); + } + } + } + } + } + else + { + while (remainingSendByteCount > 0) + { + if (remainingSendByteCount <= 2) + { + while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)) + { + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + } + + if (txData != NULL) + { + wordToSend = *(txData); + ++txData; + + if (remainingSendByteCount > 1) + { + wordToSend |= (unsigned)(*(txData)) << 8U; + ++txData; + } + } + else + { + wordToSend = dummyData; + } + + base->PUSHR = lastCommand | wordToSend; + + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + remainingSendByteCount = 0; + + while (remainingReceiveByteCount > 0) + { + if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) + { + wordReceived = DSPI_ReadData(base); + + if (remainingReceiveByteCount != 1) + { + if (rxData != NULL) + { + *(rxData) = wordReceived; + ++rxData; + *(rxData) = wordReceived >> 8; + ++rxData; + } + remainingReceiveByteCount -= 2; + } + else + { + if (rxData != NULL) + { + *(rxData) = wordReceived; + ++rxData; + } + remainingReceiveByteCount--; + } + DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); + } + } + } + else + { + /*Wait until Tx Fifo is not full*/ + while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)) + { + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + } + + if (txData != NULL) + { + wordToSend = *(txData); + ++txData; + wordToSend |= (unsigned)(*(txData)) << 8U; + ++txData; + } + else + { + wordToSend = dummyData; + } + base->PUSHR = command | wordToSend; + remainingSendByteCount -= 2; + + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + + while (((remainingReceiveByteCount - remainingSendByteCount) / 2) >= fifoSize) + { + if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) + { + wordReceived = DSPI_ReadData(base); + + if (rxData != NULL) + { + *rxData = wordReceived; + ++rxData; + *rxData = wordReceived >> 8; + ++rxData; + } + remainingReceiveByteCount -= 2; + + DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); + } + } + } + } + } + + return kStatus_Success; +} + +static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer) +{ + assert(handle); + assert(transfer); + + dspi_command_data_config_t commandStruct; + + DSPI_StopTransfer(base); + DSPI_FlushFifo(base, true, true); + DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag); + + commandStruct.whichPcs = + (dspi_which_pcs_t)(1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT)); + commandStruct.isEndOfQueue = false; + commandStruct.clearTransferCount = false; + commandStruct.whichCtar = + (dspi_ctar_selection_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT); + commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous); + handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct)); + + commandStruct.isEndOfQueue = true; + commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer); + handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct)); + + handle->bitsPerFrame = ((base->CTAR[commandStruct.whichCtar] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1; + + if ((base->MCR & SPI_MCR_DIS_RXF_MASK) || (base->MCR & SPI_MCR_DIS_TXF_MASK)) + { + handle->fifoSize = 1; + } + else + { + handle->fifoSize = FSL_FEATURE_DSPI_FIFO_SIZEn(base); + } + handle->txData = transfer->txData; + handle->rxData = transfer->rxData; + handle->remainingSendByteCount = transfer->dataSize; + handle->remainingReceiveByteCount = transfer->dataSize; + handle->totalByteCount = transfer->dataSize; +} + +status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer) +{ + assert(handle); + assert(transfer); + + /* If the transfer count is zero, then return immediately.*/ + if (transfer->dataSize == 0) + { + return kStatus_InvalidArgument; + } + + /* Check that we're not busy.*/ + if (handle->state == kDSPI_Busy) + { + return kStatus_DSPI_Busy; + } + + handle->state = kDSPI_Busy; + + DSPI_MasterTransferPrepare(base, handle, transfer); + DSPI_StartTransfer(base); + + /* Enable the NVIC for DSPI peripheral. */ + EnableIRQ(s_dspiIRQ[DSPI_GetInstance(base)]); + + DSPI_MasterTransferFillUpTxFifo(base, handle); + + /* RX FIFO Drain request: RFDF_RE to enable RFDF interrupt + * Since SPI is a synchronous interface, we only need to enable the RX interrupt. + * The IRQ handler will get the status of RX and TX interrupt flags. + */ + s_dspiMasterIsr = DSPI_MasterTransferHandleIRQ; + + DSPI_EnableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable); + + return kStatus_Success; +} + +status_t DSPI_MasterTransferGetCount(SPI_Type *base, dspi_master_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (handle->state != kDSPI_Busy) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + *count = handle->totalByteCount - handle->remainingReceiveByteCount; + return kStatus_Success; +} + +static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *handle) +{ + assert(handle); + + /* Disable interrupt requests*/ + DSPI_DisableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable); + + status_t status = 0; + if (handle->state == kDSPI_Error) + { + status = kStatus_DSPI_Error; + } + else + { + status = kStatus_Success; + } + + if (handle->callback) + { + handle->callback(base, handle, status, handle->userData); + } + + /* The transfer is complete.*/ + handle->state = kDSPI_Idle; +} + +static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t *handle) +{ + assert(handle); + + uint16_t wordToSend = 0; + uint8_t dummyData = DSPI_DUMMY_DATA; + + /* If bits/frame is greater than one byte */ + if (handle->bitsPerFrame > 8) + { + /* Fill the fifo until it is full or until the send word count is 0 or until the difference + * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth. + * The reason for checking the difference is to ensure we only send as much as the + * RX FIFO can receive. + * For this case where bitsPerFrame > 8, each entry in the FIFO contains 2 bytes of the + * send data, hence the difference between the remainingReceiveByteCount and + * remainingSendByteCount must be divided by 2 to convert this difference into a + * 16-bit (2 byte) value. + */ + while ((DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag) && + ((handle->remainingReceiveByteCount - handle->remainingSendByteCount) / 2 < handle->fifoSize)) + { + if (handle->remainingSendByteCount <= 2) + { + if (handle->txData) + { + if (handle->remainingSendByteCount == 1) + { + wordToSend = *(handle->txData); + } + else + { + wordToSend = *(handle->txData); + ++handle->txData; /* increment to next data byte */ + wordToSend |= (unsigned)(*(handle->txData)) << 8U; + } + } + else + { + wordToSend = dummyData; + } + handle->remainingSendByteCount = 0; + base->PUSHR = handle->lastCommand | wordToSend; + } + /* For all words except the last word */ + else + { + if (handle->txData) + { + wordToSend = *(handle->txData); + ++handle->txData; /* increment to next data byte */ + wordToSend |= (unsigned)(*(handle->txData)) << 8U; + ++handle->txData; /* increment to next data byte */ + } + else + { + wordToSend = dummyData; + } + handle->remainingSendByteCount -= 2; /* decrement remainingSendByteCount by 2 */ + base->PUSHR = handle->command | wordToSend; + } + + /* Try to clear the TFFF; if the TX FIFO is full this will clear */ + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + + /* exit loop if send count is zero, else update local variables for next loop */ + if (handle->remainingSendByteCount == 0) + { + break; + } + } /* End of TX FIFO fill while loop */ + } + /* Optimized for bits/frame less than or equal to one byte. */ + else + { + /* Fill the fifo until it is full or until the send word count is 0 or until the difference + * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth. + * The reason for checking the difference is to ensure we only send as much as the + * RX FIFO can receive. + */ + while ((DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag) && + ((handle->remainingReceiveByteCount - handle->remainingSendByteCount) < handle->fifoSize)) + { + if (handle->txData) + { + wordToSend = *(handle->txData); + ++handle->txData; + } + else + { + wordToSend = dummyData; + } + + if (handle->remainingSendByteCount == 1) + { + base->PUSHR = handle->lastCommand | wordToSend; + } + else + { + base->PUSHR = handle->command | wordToSend; + } + + /* Try to clear the TFFF; if the TX FIFO is full this will clear */ + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + + --handle->remainingSendByteCount; + + /* exit loop if send count is zero, else update local variables for next loop */ + if (handle->remainingSendByteCount == 0) + { + break; + } + } + } +} + +void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle) +{ + assert(handle); + + DSPI_StopTransfer(base); + + /* Disable interrupt requests*/ + DSPI_DisableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable); + + handle->state = kDSPI_Idle; +} + +void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle) +{ + assert(handle); + + /* RECEIVE IRQ handler: Check read buffer only if there are remaining bytes to read. */ + if (handle->remainingReceiveByteCount) + { + /* Check read buffer.*/ + uint16_t wordReceived; /* Maximum supported data bit length in master mode is 16-bits */ + + /* If bits/frame is greater than one byte */ + if (handle->bitsPerFrame > 8) + { + while (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) + { + wordReceived = DSPI_ReadData(base); + /* clear the rx fifo drain request, needed for non-DMA applications as this flag + * will remain set even if the rx fifo is empty. By manually clearing this flag, it + * either remain clear if no more data is in the fifo, or it will set if there is + * more data in the fifo. + */ + DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); + + /* Store read bytes into rx buffer only if a buffer pointer was provided */ + if (handle->rxData) + { + /* For the last word received, if there is an extra byte due to the odd transfer + * byte count, only save the the last byte and discard the upper byte + */ + if (handle->remainingReceiveByteCount == 1) + { + *handle->rxData = wordReceived; /* Write first data byte */ + --handle->remainingReceiveByteCount; + } + else + { + *handle->rxData = wordReceived; /* Write first data byte */ + ++handle->rxData; /* increment to next data byte */ + *handle->rxData = wordReceived >> 8; /* Write second data byte */ + ++handle->rxData; /* increment to next data byte */ + handle->remainingReceiveByteCount -= 2; + } + } + else + { + if (handle->remainingReceiveByteCount == 1) + { + --handle->remainingReceiveByteCount; + } + else + { + handle->remainingReceiveByteCount -= 2; + } + } + if (handle->remainingReceiveByteCount == 0) + { + break; + } + } /* End of RX FIFO drain while loop */ + } + /* Optimized for bits/frame less than or equal to one byte. */ + else + { + while (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) + { + wordReceived = DSPI_ReadData(base); + /* clear the rx fifo drain request, needed for non-DMA applications as this flag + * will remain set even if the rx fifo is empty. By manually clearing this flag, it + * either remain clear if no more data is in the fifo, or it will set if there is + * more data in the fifo. + */ + DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); + + /* Store read bytes into rx buffer only if a buffer pointer was provided */ + if (handle->rxData) + { + *handle->rxData = wordReceived; + ++handle->rxData; + } + + --handle->remainingReceiveByteCount; + + if (handle->remainingReceiveByteCount == 0) + { + break; + } + } /* End of RX FIFO drain while loop */ + } + } + + /* Check write buffer. We always have to send a word in order to keep the transfer + * moving. So if the caller didn't provide a send buffer, we just send a zero. + */ + if (handle->remainingSendByteCount) + { + DSPI_MasterTransferFillUpTxFifo(base, handle); + } + + /* Check if we're done with this transfer.*/ + if ((handle->remainingSendByteCount == 0) && (handle->remainingReceiveByteCount == 0)) + { + /* Complete the transfer and disable the interrupts */ + DSPI_MasterTransferComplete(base, handle); + } +} + +/*Transactional APIs -- Slave*/ +void DSPI_SlaveTransferCreateHandle(SPI_Type *base, + dspi_slave_handle_t *handle, + dspi_slave_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + g_dspiHandle[DSPI_GetInstance(base)] = handle; + + handle->callback = callback; + handle->userData = userData; +} + +status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer) +{ + assert(handle); + assert(transfer); + + /* If receive length is zero */ + if (transfer->dataSize == 0) + { + return kStatus_InvalidArgument; + } + + /* If both send buffer and receive buffer is null */ + if ((!(transfer->txData)) && (!(transfer->rxData))) + { + return kStatus_InvalidArgument; + } + + /* Check that we're not busy.*/ + if (handle->state == kDSPI_Busy) + { + return kStatus_DSPI_Busy; + } + handle->state = kDSPI_Busy; + + /* Enable the NVIC for DSPI peripheral. */ + EnableIRQ(s_dspiIRQ[DSPI_GetInstance(base)]); + + /* Store transfer information */ + handle->txData = transfer->txData; + handle->rxData = transfer->rxData; + handle->remainingSendByteCount = transfer->dataSize; + handle->remainingReceiveByteCount = transfer->dataSize; + handle->totalByteCount = transfer->dataSize; + + handle->errorCount = 0; + + uint8_t whichCtar = (transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT; + handle->bitsPerFrame = + (((base->CTAR_SLAVE[whichCtar]) & SPI_CTAR_SLAVE_FMSZ_MASK) >> SPI_CTAR_SLAVE_FMSZ_SHIFT) + 1; + + DSPI_StopTransfer(base); + + DSPI_FlushFifo(base, true, true); + DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag); + + DSPI_StartTransfer(base); + + /* Prepare data to transmit */ + DSPI_SlaveTransferFillUpTxFifo(base, handle); + + s_dspiSlaveIsr = DSPI_SlaveTransferHandleIRQ; + + /* Enable RX FIFO drain request, the slave only use this interrupt */ + DSPI_EnableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable); + + if (handle->rxData) + { + /* RX FIFO overflow request enable */ + DSPI_EnableInterrupts(base, kDSPI_RxFifoOverflowInterruptEnable); + } + if (handle->txData) + { + /* TX FIFO underflow request enable */ + DSPI_EnableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable); + } + + return kStatus_Success; +} + +status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (handle->state != kDSPI_Busy) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + *count = handle->totalByteCount - handle->remainingReceiveByteCount; + return kStatus_Success; +} + +static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *handle) +{ + assert(handle); + + uint16_t transmitData = 0; + uint8_t dummyPattern = DSPI_DUMMY_DATA; + + /* Service the transmitter, if transmit buffer provided, transmit the data, + * else transmit dummy pattern + */ + while (DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag) + { + /* Transmit data */ + if (handle->remainingSendByteCount > 0) + { + /* Have data to transmit, update the transmit data and push to FIFO */ + if (handle->bitsPerFrame <= 8) + { + /* bits/frame is 1 byte */ + if (handle->txData) + { + /* Update transmit data and transmit pointer */ + transmitData = *handle->txData; + handle->txData++; + } + else + { + transmitData = dummyPattern; + } + + /* Decrease remaining dataSize */ + --handle->remainingSendByteCount; + } + /* bits/frame is 2 bytes */ + else + { + /* With multibytes per frame transmission, the transmit frame contains data from + * transmit buffer until sent dataSize matches user request. Other bytes will set to + * dummy pattern value. + */ + if (handle->txData) + { + /* Update first byte of transmit data and transmit pointer */ + transmitData = *handle->txData; + handle->txData++; + + if (handle->remainingSendByteCount == 1) + { + /* Decrease remaining dataSize */ + --handle->remainingSendByteCount; + /* Update second byte of transmit data to second byte of dummy pattern */ + transmitData = transmitData | (uint16_t)(((uint16_t)dummyPattern) << 8); + } + else + { + /* Update second byte of transmit data and transmit pointer */ + transmitData = transmitData | (uint16_t)((uint16_t)(*handle->txData) << 8); + handle->txData++; + handle->remainingSendByteCount -= 2; + } + } + else + { + if (handle->remainingSendByteCount == 1) + { + --handle->remainingSendByteCount; + } + else + { + handle->remainingSendByteCount -= 2; + } + transmitData = (uint16_t)((uint16_t)(dummyPattern) << 8) | dummyPattern; + } + } + } + else + { + break; + } + + /* Write the data to the DSPI data register */ + base->PUSHR_SLAVE = transmitData; + + /* Try to clear TFFF by writing a one to it; it will not clear if TX FIFO not full */ + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + } +} + +static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *handle) +{ + assert(handle); + + /* Disable interrupt requests */ + DSPI_DisableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable | + kDSPI_RxFifoOverflowInterruptEnable | kDSPI_RxFifoDrainRequestInterruptEnable); + + /* The transfer is complete. */ + handle->txData = NULL; + handle->rxData = NULL; + handle->remainingReceiveByteCount = 0; + handle->remainingSendByteCount = 0; + + status_t status = 0; + if (handle->state == kDSPI_Error) + { + status = kStatus_DSPI_Error; + } + else + { + status = kStatus_Success; + } + + if (handle->callback) + { + handle->callback(base, handle, status, handle->userData); + } + + handle->state = kDSPI_Idle; +} + +void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle) +{ + assert(handle); + + DSPI_StopTransfer(base); + + /* Disable interrupt requests */ + DSPI_DisableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable | + kDSPI_RxFifoOverflowInterruptEnable | kDSPI_RxFifoDrainRequestInterruptEnable); + + handle->state = kDSPI_Idle; + handle->remainingSendByteCount = 0; + handle->remainingReceiveByteCount = 0; +} + +void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle) +{ + assert(handle); + + uint8_t dummyPattern = DSPI_DUMMY_DATA; + uint32_t dataReceived; + uint32_t dataSend = 0; + + /* Because SPI protocol is synchronous, the number of bytes that that slave received from the + * master is the actual number of bytes that the slave transmitted to the master. So we only + * monitor the received dataSize to know when the transfer is complete. + */ + if (handle->remainingReceiveByteCount > 0) + { + while (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) + { + /* Have received data in the buffer. */ + dataReceived = base->POPR; + /*Clear the rx fifo drain request, needed for non-DMA applications as this flag + * will remain set even if the rx fifo is empty. By manually clearing this flag, it + * either remain clear if no more data is in the fifo, or it will set if there is + * more data in the fifo. + */ + DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); + + /* If bits/frame is one byte */ + if (handle->bitsPerFrame <= 8) + { + if (handle->rxData) + { + /* Receive buffer is not null, store data into it */ + *handle->rxData = dataReceived; + ++handle->rxData; + } + /* Descrease remaining receive byte count */ + --handle->remainingReceiveByteCount; + + if (handle->remainingSendByteCount > 0) + { + if (handle->txData) + { + dataSend = *handle->txData; + ++handle->txData; + } + else + { + dataSend = dummyPattern; + } + + --handle->remainingSendByteCount; + /* Write the data to the DSPI data register */ + base->PUSHR_SLAVE = dataSend; + } + } + else /* If bits/frame is 2 bytes */ + { + /* With multibytes frame receiving, we only receive till the received dataSize + * matches user request. Other bytes will be ignored. + */ + if (handle->rxData) + { + /* Receive buffer is not null, store first byte into it */ + *handle->rxData = dataReceived; + ++handle->rxData; + + if (handle->remainingReceiveByteCount == 1) + { + /* Decrease remaining receive byte count */ + --handle->remainingReceiveByteCount; + } + else + { + /* Receive buffer is not null, store second byte into it */ + *handle->rxData = dataReceived >> 8; + ++handle->rxData; + handle->remainingReceiveByteCount -= 2; + } + } + /* If no handle->rxData*/ + else + { + if (handle->remainingReceiveByteCount == 1) + { + /* Decrease remaining receive byte count */ + --handle->remainingReceiveByteCount; + } + else + { + handle->remainingReceiveByteCount -= 2; + } + } + + if (handle->remainingSendByteCount > 0) + { + if (handle->txData) + { + dataSend = *handle->txData; + ++handle->txData; + + if (handle->remainingSendByteCount == 1) + { + --handle->remainingSendByteCount; + dataSend |= (uint16_t)((uint16_t)(dummyPattern) << 8); + } + else + { + dataSend |= (uint32_t)(*handle->txData) << 8; + ++handle->txData; + handle->remainingSendByteCount -= 2; + } + } + /* If no handle->txData*/ + else + { + if (handle->remainingSendByteCount == 1) + { + --handle->remainingSendByteCount; + } + else + { + handle->remainingSendByteCount -= 2; + } + dataSend = (uint16_t)((uint16_t)(dummyPattern) << 8) | dummyPattern; + } + /* Write the data to the DSPI data register */ + base->PUSHR_SLAVE = dataSend; + } + } + /* Try to clear TFFF by writing a one to it; it will not clear if TX FIFO not full */ + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + + if (handle->remainingReceiveByteCount == 0) + { + break; + } + } + } + /* Check if remaining receive byte count matches user request */ + if ((handle->remainingReceiveByteCount == 0) || (handle->state == kDSPI_Error)) + { + /* Other cases, stop the transfer. */ + DSPI_SlaveTransferComplete(base, handle); + return; + } + + /* Catch tx fifo underflow conditions, service only if tx under flow interrupt enabled */ + if ((DSPI_GetStatusFlags(base) & kDSPI_TxFifoUnderflowFlag) && (base->RSER & SPI_RSER_TFUF_RE_MASK)) + { + DSPI_ClearStatusFlags(base, kDSPI_TxFifoUnderflowFlag); + /* Change state to error and clear flag */ + if (handle->txData) + { + handle->state = kDSPI_Error; + } + handle->errorCount++; + } + /* Catch rx fifo overflow conditions, service only if rx over flow interrupt enabled */ + if ((DSPI_GetStatusFlags(base) & kDSPI_RxFifoOverflowFlag) && (base->RSER & SPI_RSER_RFOF_RE_MASK)) + { + DSPI_ClearStatusFlags(base, kDSPI_RxFifoOverflowFlag); + /* Change state to error and clear flag */ + if (handle->txData) + { + handle->state = kDSPI_Error; + } + handle->errorCount++; + } +} + +static void DSPI_CommonIRQHandler(SPI_Type *base, void *param) +{ + if (DSPI_IsMaster(base)) + { + s_dspiMasterIsr(base, (dspi_master_handle_t *)param); + } + else + { + s_dspiSlaveIsr(base, (dspi_slave_handle_t *)param); + } +} + +#if (FSL_FEATURE_SOC_DSPI_COUNT > 0) +void SPI0_DriverIRQHandler(void) +{ + assert(g_dspiHandle[0]); + DSPI_CommonIRQHandler(SPI0, g_dspiHandle[0]); +} +#endif + +#if (FSL_FEATURE_SOC_DSPI_COUNT > 1) +void SPI1_DriverIRQHandler(void) +{ + assert(g_dspiHandle[1]); + DSPI_CommonIRQHandler(SPI1, g_dspiHandle[1]); +} +#endif + +#if (FSL_FEATURE_SOC_DSPI_COUNT > 2) +void SPI2_DriverIRQHandler(void) +{ + assert(g_dspiHandle[2]); + DSPI_CommonIRQHandler(SPI2, g_dspiHandle[2]); +} +#endif + +#if (FSL_FEATURE_SOC_DSPI_COUNT > 3) +void SPI3_DriverIRQHandler(void) +{ + assert(g_dspiHandle[3]); + DSPI_CommonIRQHandler(SPI3, g_dspiHandle[3]); +} +#endif + +#if (FSL_FEATURE_SOC_DSPI_COUNT > 4) +void SPI4_DriverIRQHandler(void) +{ + assert(g_dspiHandle[4]); + DSPI_CommonIRQHandler(SPI4, g_dspiHandle[4]); +} +#endif + +#if (FSL_FEATURE_SOC_DSPI_COUNT > 5) +void SPI5_DriverIRQHandler(void) +{ + assert(g_dspiHandle[5]); + DSPI_CommonIRQHandler(SPI5, g_dspiHandle[5]); +} +#endif + +#if (FSL_FEATURE_SOC_DSPI_COUNT > 6) +#error "Should write the SPIx_DriverIRQHandler function that instance greater than 5 !" +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi.h new file mode 100644 index 00000000000..eb730bd13a0 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi.h @@ -0,0 +1,1180 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_DSPI_H_ +#define _FSL_DSPI_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup dspi_driver + * @{ + */ + + +/********************************************************************************************************************** + * Definitions + *********************************************************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief DSPI driver version 2.1.3. */ +#define FSL_DSPI_DRIVER_VERSION (MAKE_VERSION(2, 1, 3)) +/*@}*/ + +#ifndef DSPI_DUMMY_DATA +/*! @brief DSPI dummy data if there is no Tx data.*/ +#define DSPI_DUMMY_DATA (0x00U) /*!< Dummy data used for Tx if there is no txData. */ +#endif + +/*! @brief Status for the DSPI driver.*/ +enum _dspi_status +{ + kStatus_DSPI_Busy = MAKE_STATUS(kStatusGroup_DSPI, 0), /*!< DSPI transfer is busy.*/ + kStatus_DSPI_Error = MAKE_STATUS(kStatusGroup_DSPI, 1), /*!< DSPI driver error. */ + kStatus_DSPI_Idle = MAKE_STATUS(kStatusGroup_DSPI, 2), /*!< DSPI is idle.*/ + kStatus_DSPI_OutOfRange = MAKE_STATUS(kStatusGroup_DSPI, 3) /*!< DSPI transfer out of range. */ +}; + +/*! @brief DSPI status flags in SPIx_SR register.*/ +enum _dspi_flags +{ + kDSPI_TxCompleteFlag = SPI_SR_TCF_MASK, /*!< Transfer Complete Flag. */ + kDSPI_EndOfQueueFlag = SPI_SR_EOQF_MASK, /*!< End of Queue Flag.*/ + kDSPI_TxFifoUnderflowFlag = SPI_SR_TFUF_MASK, /*!< Transmit FIFO Underflow Flag.*/ + kDSPI_TxFifoFillRequestFlag = SPI_SR_TFFF_MASK, /*!< Transmit FIFO Fill Flag.*/ + kDSPI_RxFifoOverflowFlag = SPI_SR_RFOF_MASK, /*!< Receive FIFO Overflow Flag.*/ + kDSPI_RxFifoDrainRequestFlag = SPI_SR_RFDF_MASK, /*!< Receive FIFO Drain Flag.*/ + kDSPI_TxAndRxStatusFlag = SPI_SR_TXRXS_MASK, /*!< The module is in Stopped/Running state.*/ + kDSPI_AllStatusFlag = SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | + SPI_SR_RFDF_MASK | SPI_SR_TXRXS_MASK /*!< All statuses above.*/ +}; + +/*! @brief DSPI interrupt source.*/ +enum _dspi_interrupt_enable +{ + kDSPI_TxCompleteInterruptEnable = SPI_RSER_TCF_RE_MASK, /*!< TCF interrupt enable.*/ + kDSPI_EndOfQueueInterruptEnable = SPI_RSER_EOQF_RE_MASK, /*!< EOQF interrupt enable.*/ + kDSPI_TxFifoUnderflowInterruptEnable = SPI_RSER_TFUF_RE_MASK, /*!< TFUF interrupt enable.*/ + kDSPI_TxFifoFillRequestInterruptEnable = SPI_RSER_TFFF_RE_MASK, /*!< TFFF interrupt enable, DMA disable.*/ + kDSPI_RxFifoOverflowInterruptEnable = SPI_RSER_RFOF_RE_MASK, /*!< RFOF interrupt enable.*/ + kDSPI_RxFifoDrainRequestInterruptEnable = SPI_RSER_RFDF_RE_MASK, /*!< RFDF interrupt enable, DMA disable.*/ + kDSPI_AllInterruptEnable = SPI_RSER_TCF_RE_MASK | SPI_RSER_EOQF_RE_MASK | SPI_RSER_TFUF_RE_MASK | + SPI_RSER_TFFF_RE_MASK | SPI_RSER_RFOF_RE_MASK | SPI_RSER_RFDF_RE_MASK + /*!< All above interrupts enable.*/ +}; + +/*! @brief DSPI DMA source.*/ +enum _dspi_dma_enable +{ + kDSPI_TxDmaEnable = (SPI_RSER_TFFF_RE_MASK | SPI_RSER_TFFF_DIRS_MASK), /*!< TFFF flag generates DMA requests. + No Tx interrupt request. */ + kDSPI_RxDmaEnable = (SPI_RSER_RFDF_RE_MASK | SPI_RSER_RFDF_DIRS_MASK) /*!< RFDF flag generates DMA requests. + No Rx interrupt request. */ +}; + +/*! @brief DSPI master or slave mode configuration.*/ +typedef enum _dspi_master_slave_mode +{ + kDSPI_Master = 1U, /*!< DSPI peripheral operates in master mode.*/ + kDSPI_Slave = 0U /*!< DSPI peripheral operates in slave mode.*/ +} dspi_master_slave_mode_t; + +/*! + * @brief DSPI Sample Point: Controls when the DSPI master samples SIN in the Modified Transfer Format. This field is valid + * only when the CPHA bit in the CTAR register is 0. + */ +typedef enum _dspi_master_sample_point +{ + kDSPI_SckToSin0Clock = 0U, /*!< 0 system clocks between SCK edge and SIN sample.*/ + kDSPI_SckToSin1Clock = 1U, /*!< 1 system clock between SCK edge and SIN sample.*/ + kDSPI_SckToSin2Clock = 2U /*!< 2 system clocks between SCK edge and SIN sample.*/ +} dspi_master_sample_point_t; + +/*! @brief DSPI Peripheral Chip Select (Pcs) configuration (which Pcs to configure).*/ +typedef enum _dspi_which_pcs_config +{ + kDSPI_Pcs0 = 1U << 0, /*!< Pcs[0] */ + kDSPI_Pcs1 = 1U << 1, /*!< Pcs[1] */ + kDSPI_Pcs2 = 1U << 2, /*!< Pcs[2] */ + kDSPI_Pcs3 = 1U << 3, /*!< Pcs[3] */ + kDSPI_Pcs4 = 1U << 4, /*!< Pcs[4] */ + kDSPI_Pcs5 = 1U << 5 /*!< Pcs[5] */ +} dspi_which_pcs_t; + +/*! @brief DSPI Peripheral Chip Select (Pcs) Polarity configuration.*/ +typedef enum _dspi_pcs_polarity_config +{ + kDSPI_PcsActiveHigh = 0U, /*!< Pcs Active High (idles low). */ + kDSPI_PcsActiveLow = 1U /*!< Pcs Active Low (idles high). */ +} dspi_pcs_polarity_config_t; + +/*! @brief DSPI Peripheral Chip Select (Pcs) Polarity.*/ +enum _dspi_pcs_polarity +{ + kDSPI_Pcs0ActiveLow = 1U << 0, /*!< Pcs0 Active Low (idles high). */ + kDSPI_Pcs1ActiveLow = 1U << 1, /*!< Pcs1 Active Low (idles high). */ + kDSPI_Pcs2ActiveLow = 1U << 2, /*!< Pcs2 Active Low (idles high). */ + kDSPI_Pcs3ActiveLow = 1U << 3, /*!< Pcs3 Active Low (idles high). */ + kDSPI_Pcs4ActiveLow = 1U << 4, /*!< Pcs4 Active Low (idles high). */ + kDSPI_Pcs5ActiveLow = 1U << 5, /*!< Pcs5 Active Low (idles high). */ + kDSPI_PcsAllActiveLow = 0xFFU /*!< Pcs0 to Pcs5 Active Low (idles high). */ +}; + +/*! @brief DSPI clock polarity configuration for a given CTAR.*/ +typedef enum _dspi_clock_polarity +{ + kDSPI_ClockPolarityActiveHigh = 0U, /*!< CPOL=0. Active-high DSPI clock (idles low).*/ + kDSPI_ClockPolarityActiveLow = 1U /*!< CPOL=1. Active-low DSPI clock (idles high).*/ +} dspi_clock_polarity_t; + +/*! @brief DSPI clock phase configuration for a given CTAR.*/ +typedef enum _dspi_clock_phase +{ + kDSPI_ClockPhaseFirstEdge = 0U, /*!< CPHA=0. Data is captured on the leading edge of the SCK and changed on the + following edge.*/ + kDSPI_ClockPhaseSecondEdge = 1U /*!< CPHA=1. Data is changed on the leading edge of the SCK and captured on the + following edge.*/ +} dspi_clock_phase_t; + +/*! @brief DSPI data shifter direction options for a given CTAR.*/ +typedef enum _dspi_shift_direction +{ + kDSPI_MsbFirst = 0U, /*!< Data transfers start with most significant bit.*/ + kDSPI_LsbFirst = 1U /*!< Data transfers start with least significant bit. + Shifting out of LSB is not supported for slave */ +} dspi_shift_direction_t; + +/*! @brief DSPI delay type selection.*/ +typedef enum _dspi_delay_type +{ + kDSPI_PcsToSck = 1U, /*!< Pcs-to-SCK delay. */ + kDSPI_LastSckToPcs, /*!< The last SCK edge to Pcs delay. */ + kDSPI_BetweenTransfer /*!< Delay between transfers. */ +} dspi_delay_type_t; + +/*! @brief DSPI Clock and Transfer Attributes Register (CTAR) selection.*/ +typedef enum _dspi_ctar_selection +{ + kDSPI_Ctar0 = 0U, /*!< CTAR0 selection option for master or slave mode; note that CTAR0 and CTAR0_SLAVE are the + same register address. */ + kDSPI_Ctar1 = 1U, /*!< CTAR1 selection option for master mode only. */ + kDSPI_Ctar2 = 2U, /*!< CTAR2 selection option for master mode only; note that some devices do not support CTAR2. */ + kDSPI_Ctar3 = 3U, /*!< CTAR3 selection option for master mode only; note that some devices do not support CTAR3. */ + kDSPI_Ctar4 = 4U, /*!< CTAR4 selection option for master mode only; note that some devices do not support CTAR4. */ + kDSPI_Ctar5 = 5U, /*!< CTAR5 selection option for master mode only; note that some devices do not support CTAR5. */ + kDSPI_Ctar6 = 6U, /*!< CTAR6 selection option for master mode only; note that some devices do not support CTAR6. */ + kDSPI_Ctar7 = 7U /*!< CTAR7 selection option for master mode only; note that some devices do not support CTAR7. */ +} dspi_ctar_selection_t; + +#define DSPI_MASTER_CTAR_SHIFT (0U) /*!< DSPI master CTAR shift macro; used internally. */ +#define DSPI_MASTER_CTAR_MASK (0x0FU) /*!< DSPI master CTAR mask macro; used internally. */ +#define DSPI_MASTER_PCS_SHIFT (4U) /*!< DSPI master PCS shift macro; used internally. */ +#define DSPI_MASTER_PCS_MASK (0xF0U) /*!< DSPI master PCS mask macro; used internally. */ +/*! @brief Use this enumeration for the DSPI master transfer configFlags. */ +enum _dspi_transfer_config_flag_for_master +{ + kDSPI_MasterCtar0 = 0U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR0 setting. */ + kDSPI_MasterCtar1 = 1U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR1 setting. */ + kDSPI_MasterCtar2 = 2U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR2 setting. */ + kDSPI_MasterCtar3 = 3U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR3 setting. */ + kDSPI_MasterCtar4 = 4U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR4 setting. */ + kDSPI_MasterCtar5 = 5U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR5 setting. */ + kDSPI_MasterCtar6 = 6U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR6 setting. */ + kDSPI_MasterCtar7 = 7U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR7 setting. */ + + kDSPI_MasterPcs0 = 0U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS0 signal. */ + kDSPI_MasterPcs1 = 1U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS1 signal. */ + kDSPI_MasterPcs2 = 2U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS2 signal.*/ + kDSPI_MasterPcs3 = 3U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS3 signal. */ + kDSPI_MasterPcs4 = 4U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS4 signal. */ + kDSPI_MasterPcs5 = 5U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS5 signal. */ + + kDSPI_MasterPcsContinuous = 1U << 20, /*!< Indicates whether the PCS signal is continuous. */ + kDSPI_MasterActiveAfterTransfer = 1U << 21, /*!< Indicates whether the PCS signal is active after the last frame transfer.*/ +}; + +#define DSPI_SLAVE_CTAR_SHIFT (0U) /*!< DSPI slave CTAR shift macro; used internally. */ +#define DSPI_SLAVE_CTAR_MASK (0x07U) /*!< DSPI slave CTAR mask macro; used internally. */ +/*! @brief Use this enumeration for the DSPI slave transfer configFlags. */ +enum _dspi_transfer_config_flag_for_slave +{ + kDSPI_SlaveCtar0 = 0U << DSPI_SLAVE_CTAR_SHIFT, /*!< DSPI slave transfer use CTAR0 setting. */ + /*!< DSPI slave can only use PCS0. */ +}; + +/*! @brief DSPI transfer state, which is used for DSPI transactional API state machine. */ +enum _dspi_transfer_state +{ + kDSPI_Idle = 0x0U, /*!< Nothing in the transmitter/receiver. */ + kDSPI_Busy, /*!< Transfer queue is not finished. */ + kDSPI_Error /*!< Transfer error. */ +}; + +/*! @brief DSPI master command date configuration used for the SPIx_PUSHR.*/ +typedef struct _dspi_command_data_config +{ + bool isPcsContinuous; /*!< Option to enable the continuous assertion of the chip select between transfers.*/ + dspi_ctar_selection_t whichCtar; /*!< The desired Clock and Transfer Attributes + Register (CTAR) to use for CTAS.*/ + dspi_which_pcs_t whichPcs; /*!< The desired PCS signal to use for the data transfer.*/ + bool isEndOfQueue; /*!< Signals that the current transfer is the last in the queue.*/ + bool clearTransferCount; /*!< Clears the SPI Transfer Counter (SPI_TCNT) before transmission starts.*/ +} dspi_command_data_config_t; + +/*! @brief DSPI master ctar configuration structure.*/ +typedef struct _dspi_master_ctar_config +{ + uint32_t baudRate; /*!< Baud Rate for DSPI. */ + uint32_t bitsPerFrame; /*!< Bits per frame, minimum 4, maximum 16.*/ + dspi_clock_polarity_t cpol; /*!< Clock polarity. */ + dspi_clock_phase_t cpha; /*!< Clock phase. */ + dspi_shift_direction_t direction; /*!< MSB or LSB data shift direction. */ + + uint32_t pcsToSckDelayInNanoSec; /*!< PCS to SCK delay time in nanoseconds; setting to 0 sets the minimum + delay. It also sets the boundary value if out of range.*/ + uint32_t lastSckToPcsDelayInNanoSec; /*!< The last SCK to PCS delay time in nanoseconds; setting to 0 sets the + minimum delay. It also sets the boundary value if out of range.*/ + + uint32_t betweenTransferDelayInNanoSec; /*!< After the SCK delay time in nanoseconds; setting to 0 sets the minimum + delay. It also sets the boundary value if out of range.*/ +} dspi_master_ctar_config_t; + +/*! @brief DSPI master configuration structure.*/ +typedef struct _dspi_master_config +{ + dspi_ctar_selection_t whichCtar; /*!< The desired CTAR to use. */ + dspi_master_ctar_config_t ctarConfig; /*!< Set the ctarConfig to the desired CTAR. */ + + dspi_which_pcs_t whichPcs; /*!< The desired Peripheral Chip Select (pcs). */ + dspi_pcs_polarity_config_t pcsActiveHighOrLow; /*!< The desired PCS active high or low. */ + + bool enableContinuousSCK; /*!< CONT_SCKE, continuous SCK enable. Note that the continuous SCK is only + supported for CPHA = 1.*/ + bool enableRxFifoOverWrite; /*!< ROOE, receive FIFO overflow overwrite enable. If ROOE = 0, the incoming + data is ignored and the data from the transfer that generated the overflow + is also ignored. If ROOE = 1, the incoming data is shifted to the + shift register. */ + + bool enableModifiedTimingFormat; /*!< Enables a modified transfer format to be used if true.*/ + dspi_master_sample_point_t samplePoint; /*!< Controls when the module master samples SIN in the Modified Transfer + Format. It's valid only when CPHA=0. */ +} dspi_master_config_t; + +/*! @brief DSPI slave ctar configuration structure.*/ +typedef struct _dspi_slave_ctar_config +{ + uint32_t bitsPerFrame; /*!< Bits per frame, minimum 4, maximum 16.*/ + dspi_clock_polarity_t cpol; /*!< Clock polarity. */ + dspi_clock_phase_t cpha; /*!< Clock phase. */ + /*!< Slave only supports MSB and does not support LSB.*/ +} dspi_slave_ctar_config_t; + +/*! @brief DSPI slave configuration structure.*/ +typedef struct _dspi_slave_config +{ + dspi_ctar_selection_t whichCtar; /*!< The desired CTAR to use. */ + dspi_slave_ctar_config_t ctarConfig; /*!< Set the ctarConfig to the desired CTAR. */ + + bool enableContinuousSCK; /*!< CONT_SCKE, continuous SCK enable. Note that the continuous SCK is only + supported for CPHA = 1.*/ + bool enableRxFifoOverWrite; /*!< ROOE, receive FIFO overflow overwrite enable. If ROOE = 0, the incoming + data is ignored and the data from the transfer that generated the overflow + is also ignored. If ROOE = 1, the incoming data is shifted to the + shift register. */ + bool enableModifiedTimingFormat; /*!< Enables a modified transfer format to be used if true.*/ + dspi_master_sample_point_t samplePoint; /*!< Controls when the module master samples SIN in the Modified Transfer + Format. It's valid only when CPHA=0. */ +} dspi_slave_config_t; + +/*! +* @brief Forward declaration of the _dspi_master_handle typedefs. +*/ +typedef struct _dspi_master_handle dspi_master_handle_t; + +/*! +* @brief Forward declaration of the _dspi_slave_handle typedefs. +*/ +typedef struct _dspi_slave_handle dspi_slave_handle_t; + +/*! + * @brief Completion callback function pointer type. + * + * @param base DSPI peripheral address. + * @param handle Pointer to the handle for the DSPI master. + * @param status Success or error code describing whether the transfer completed. + * @param userData Arbitrary pointer-dataSized value passed from the application. + */ +typedef void (*dspi_master_transfer_callback_t)(SPI_Type *base, + dspi_master_handle_t *handle, + status_t status, + void *userData); +/*! + * @brief Completion callback function pointer type. + * + * @param base DSPI peripheral address. + * @param handle Pointer to the handle for the DSPI slave. + * @param status Success or error code describing whether the transfer completed. + * @param userData Arbitrary pointer-dataSized value passed from the application. + */ +typedef void (*dspi_slave_transfer_callback_t)(SPI_Type *base, + dspi_slave_handle_t *handle, + status_t status, + void *userData); + +/*! @brief DSPI master/slave transfer structure.*/ +typedef struct _dspi_transfer +{ + uint8_t *txData; /*!< Send buffer. */ + uint8_t *rxData; /*!< Receive buffer. */ + volatile size_t dataSize; /*!< Transfer bytes. */ + + uint32_t + configFlags; /*!< Transfer transfer configuration flags; set from _dspi_transfer_config_flag_for_master if the + transfer is used for master or _dspi_transfer_config_flag_for_slave enumeration if the transfer + is used for slave.*/ +} dspi_transfer_t; + +/*! @brief DSPI master transfer handle structure used for transactional API. */ +struct _dspi_master_handle +{ + uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */ + volatile uint32_t command; /*!< The desired data command. */ + volatile uint32_t lastCommand; /*!< The desired last data command. */ + + uint8_t fifoSize; /*!< FIFO dataSize. */ + + volatile bool isPcsActiveAfterTransfer; /*!< Indicates whether the PCS signal is active after the last frame transfer.*/ + volatile bool isThereExtraByte; /*!< Indicates whether there are extra bytes.*/ + + uint8_t *volatile txData; /*!< Send buffer. */ + uint8_t *volatile rxData; /*!< Receive buffer. */ + volatile size_t remainingSendByteCount; /*!< A number of bytes remaining to send.*/ + volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/ + size_t totalByteCount; /*!< A number of transfer bytes*/ + + volatile uint8_t state; /*!< DSPI transfer state, see _dspi_transfer_state.*/ + + dspi_master_transfer_callback_t callback; /*!< Completion callback. */ + void *userData; /*!< Callback user data. */ +}; + +/*! @brief DSPI slave transfer handle structure used for the transactional API. */ +struct _dspi_slave_handle +{ + uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */ + volatile bool isThereExtraByte; /*!< Indicates whether there are extra bytes.*/ + + uint8_t *volatile txData; /*!< Send buffer. */ + uint8_t *volatile rxData; /*!< Receive buffer. */ + volatile size_t remainingSendByteCount; /*!< A number of bytes remaining to send.*/ + volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/ + size_t totalByteCount; /*!< A number of transfer bytes*/ + + volatile uint8_t state; /*!< DSPI transfer state.*/ + + volatile uint32_t errorCount; /*!< Error count for slave transfer.*/ + + dspi_slave_transfer_callback_t callback; /*!< Completion callback. */ + void *userData; /*!< Callback user data. */ +}; + +/********************************************************************************************************************** + * API + *********************************************************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes the DSPI master. + * + * This function initializes the DSPI master configuration. This is an example use case. + * @code + * dspi_master_config_t masterConfig; + * masterConfig.whichCtar = kDSPI_Ctar0; + * masterConfig.ctarConfig.baudRate = 500000000U; + * masterConfig.ctarConfig.bitsPerFrame = 8; + * masterConfig.ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh; + * masterConfig.ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge; + * masterConfig.ctarConfig.direction = kDSPI_MsbFirst; + * masterConfig.ctarConfig.pcsToSckDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ; + * masterConfig.ctarConfig.lastSckToPcsDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ; + * masterConfig.ctarConfig.betweenTransferDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ; + * masterConfig.whichPcs = kDSPI_Pcs0; + * masterConfig.pcsActiveHighOrLow = kDSPI_PcsActiveLow; + * masterConfig.enableContinuousSCK = false; + * masterConfig.enableRxFifoOverWrite = false; + * masterConfig.enableModifiedTimingFormat = false; + * masterConfig.samplePoint = kDSPI_SckToSin0Clock; + * DSPI_MasterInit(base, &masterConfig, srcClock_Hz); + * @endcode + * + * @param base DSPI peripheral address. + * @param masterConfig Pointer to the structure dspi_master_config_t. + * @param srcClock_Hz Module source input clock in Hertz. + */ +void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz); + +/*! + * @brief Sets the dspi_master_config_t structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for the DSPI_MasterInit(). + * Users may use the initialized structure unchanged in the DSPI_MasterInit() or modify the structure + * before calling the DSPI_MasterInit(). + * Example: + * @code + * dspi_master_config_t masterConfig; + * DSPI_MasterGetDefaultConfig(&masterConfig); + * @endcode + * @param masterConfig pointer to dspi_master_config_t structure + */ +void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig); + +/*! + * @brief DSPI slave configuration. + * + * This function initializes the DSPI slave configuration. This is an example use case. + * @code + * dspi_slave_config_t slaveConfig; + * slaveConfig->whichCtar = kDSPI_Ctar0; + * slaveConfig->ctarConfig.bitsPerFrame = 8; + * slaveConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh; + * slaveConfig->ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge; + * slaveConfig->enableContinuousSCK = false; + * slaveConfig->enableRxFifoOverWrite = false; + * slaveConfig->enableModifiedTimingFormat = false; + * slaveConfig->samplePoint = kDSPI_SckToSin0Clock; + * DSPI_SlaveInit(base, &slaveConfig); + * @endcode + * + * @param base DSPI peripheral address. + * @param slaveConfig Pointer to the structure dspi_master_config_t. + */ +void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig); + +/*! + * @brief Sets the dspi_slave_config_t structure to a default value. + * + * The purpose of this API is to get the configuration structure initialized for the DSPI_SlaveInit(). + * Users may use the initialized structure unchanged in the DSPI_SlaveInit() or modify the structure + * before calling the DSPI_SlaveInit(). + * This is an example. + * @code + * dspi_slave_config_t slaveConfig; + * DSPI_SlaveGetDefaultConfig(&slaveConfig); + * @endcode + * @param slaveConfig Pointer to the dspi_slave_config_t structure. + */ +void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig); + +/*! + * @brief De-initializes the DSPI peripheral. Call this API to disable the DSPI clock. + * @param base DSPI peripheral address. + */ +void DSPI_Deinit(SPI_Type *base); + +/*! + * @brief Enables the DSPI peripheral and sets the MCR MDIS to 0. + * + * @param base DSPI peripheral address. + * @param enable Pass true to enable module, false to disable module. + */ +static inline void DSPI_Enable(SPI_Type *base, bool enable) +{ + if (enable) + { + base->MCR &= ~SPI_MCR_MDIS_MASK; + } + else + { + base->MCR |= SPI_MCR_MDIS_MASK; + } +} + +/*! + *@} +*/ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the DSPI status flag state. + * @param base DSPI peripheral address. + * @return DSPI status (in SR register). + */ +static inline uint32_t DSPI_GetStatusFlags(SPI_Type *base) +{ + return (base->SR); +} + +/*! + * @brief Clears the DSPI status flag. + * + * This function clears the desired status bit by using a write-1-to-clear. The user passes in the base and the + * desired status bit to clear. The list of status bits is defined in the dspi_status_and_interrupt_request_t. The + * function uses these bit positions in its algorithm to clear the desired flag state. + * This is an example. + * @code + * DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag|kDSPI_EndOfQueueFlag); + * @endcode + * + * @param base DSPI peripheral address. + * @param statusFlags The status flag used from the type dspi_flags. + */ +static inline void DSPI_ClearStatusFlags(SPI_Type *base, uint32_t statusFlags) +{ + base->SR = statusFlags; /*!< The status flags are cleared by writing 1 (w1c).*/ +} + +/*! + *@} +*/ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the DSPI interrupts. + * + * This function configures the various interrupt masks of the DSPI. The parameters are a base and an interrupt mask. + * Note, for Tx Fill and Rx FIFO drain requests, enable the interrupt request and disable the DMA request. + * + * @code + * DSPI_EnableInterrupts(base, kDSPI_TxCompleteInterruptEnable | kDSPI_EndOfQueueInterruptEnable ); + * @endcode + * + * @param base DSPI peripheral address. + * @param mask The interrupt mask; use the enum _dspi_interrupt_enable. + */ +void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask); + +/*! + * @brief Disables the DSPI interrupts. + * + * @code + * DSPI_DisableInterrupts(base, kDSPI_TxCompleteInterruptEnable | kDSPI_EndOfQueueInterruptEnable ); + * @endcode + * + * @param base DSPI peripheral address. + * @param mask The interrupt mask; use the enum _dspi_interrupt_enable. + */ +static inline void DSPI_DisableInterrupts(SPI_Type *base, uint32_t mask) +{ + base->RSER &= ~mask; +} + +/*! + *@} +*/ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Enables the DSPI DMA request. + * + * This function configures the Rx and Tx DMA mask of the DSPI. The parameters are a base and a DMA mask. + * @code + * DSPI_EnableDMA(base, kDSPI_TxDmaEnable | kDSPI_RxDmaEnable); + * @endcode + * + * @param base DSPI peripheral address. + * @param mask The interrupt mask; use the enum dspi_dma_enable. + */ +static inline void DSPI_EnableDMA(SPI_Type *base, uint32_t mask) +{ + base->RSER |= mask; +} + +/*! + * @brief Disables the DSPI DMA request. + * + * This function configures the Rx and Tx DMA mask of the DSPI. The parameters are a base and a DMA mask. + * @code + * SPI_DisableDMA(base, kDSPI_TxDmaEnable | kDSPI_RxDmaEnable); + * @endcode + * + * @param base DSPI peripheral address. + * @param mask The interrupt mask; use the enum dspi_dma_enable. + */ +static inline void DSPI_DisableDMA(SPI_Type *base, uint32_t mask) +{ + base->RSER &= ~mask; +} + +/*! + * @brief Gets the DSPI master PUSHR data register address for the DMA operation. + * + * This function gets the DSPI master PUSHR data register address because this value is needed for the DMA operation. + * + * @param base DSPI peripheral address. + * @return The DSPI master PUSHR data register address. + */ +static inline uint32_t DSPI_MasterGetTxRegisterAddress(SPI_Type *base) +{ + return (uint32_t) & (base->PUSHR); +} + +/*! + * @brief Gets the DSPI slave PUSHR data register address for the DMA operation. + * + * This function gets the DSPI slave PUSHR data register address as this value is needed for the DMA operation. + * + * @param base DSPI peripheral address. + * @return The DSPI slave PUSHR data register address. + */ +static inline uint32_t DSPI_SlaveGetTxRegisterAddress(SPI_Type *base) +{ + return (uint32_t) & (base->PUSHR_SLAVE); +} + +/*! + * @brief Gets the DSPI POPR data register address for the DMA operation. + * + * This function gets the DSPI POPR data register address as this value is needed for the DMA operation. + * + * @param base DSPI peripheral address. + * @return The DSPI POPR data register address. + */ +static inline uint32_t DSPI_GetRxRegisterAddress(SPI_Type *base) +{ + return (uint32_t) & (base->POPR); +} + +/*! + *@} +*/ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Configures the DSPI for master or slave. + * + * @param base DSPI peripheral address. + * @param mode Mode setting (master or slave) of type dspi_master_slave_mode_t. + */ +static inline void DSPI_SetMasterSlaveMode(SPI_Type *base, dspi_master_slave_mode_t mode) +{ + base->MCR = (base->MCR & (~SPI_MCR_MSTR_MASK)) | SPI_MCR_MSTR(mode); +} + +/*! + * @brief Returns whether the DSPI module is in master mode. + * + * @param base DSPI peripheral address. + * @return Returns true if the module is in master mode or false if the module is in slave mode. + */ +static inline bool DSPI_IsMaster(SPI_Type *base) +{ + return (bool)((base->MCR) & SPI_MCR_MSTR_MASK); +} +/*! + * @brief Starts the DSPI transfers and clears HALT bit in MCR. + * + * This function sets the module to start data transfer in either master or slave mode. + * + * @param base DSPI peripheral address. + */ +static inline void DSPI_StartTransfer(SPI_Type *base) +{ + base->MCR &= ~SPI_MCR_HALT_MASK; +} +/*! + * @brief Stops DSPI transfers and sets the HALT bit in MCR. + * + * This function stops data transfers in either master or slave modes. + * + * @param base DSPI peripheral address. + */ +static inline void DSPI_StopTransfer(SPI_Type *base) +{ + base->MCR |= SPI_MCR_HALT_MASK; +} + +/*! + * @brief Enables or disables the DSPI FIFOs. + * + * This function allows the caller to disable/enable the Tx and Rx FIFOs independently. + * Note that to disable, pass in a logic 0 (false) for the particular FIFO configuration. To enable, + * pass in a logic 1 (true). + * + * @param base DSPI peripheral address. + * @param enableTxFifo Disables (false) the TX FIFO; Otherwise, enables (true) the TX FIFO + * @param enableRxFifo Disables (false) the RX FIFO; Otherwise, enables (true) the RX FIFO + */ +static inline void DSPI_SetFifoEnable(SPI_Type *base, bool enableTxFifo, bool enableRxFifo) +{ + base->MCR = (base->MCR & (~(SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK))) | SPI_MCR_DIS_TXF(!enableTxFifo) | + SPI_MCR_DIS_RXF(!enableRxFifo); +} + +/*! + * @brief Flushes the DSPI FIFOs. + * + * @param base DSPI peripheral address. + * @param flushTxFifo Flushes (true) the Tx FIFO; Otherwise, does not flush (false) the Tx FIFO + * @param flushRxFifo Flushes (true) the Rx FIFO; Otherwise, does not flush (false) the Rx FIFO + */ +static inline void DSPI_FlushFifo(SPI_Type *base, bool flushTxFifo, bool flushRxFifo) +{ + base->MCR = (base->MCR & (~(SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK))) | SPI_MCR_CLR_TXF(flushTxFifo) | + SPI_MCR_CLR_RXF(flushRxFifo); +} + +/*! + * @brief Configures the DSPI peripheral chip select polarity simultaneously. + * For example, PCS0 and PCS1 are set to active low and other PCS is set to active high. Note that the number of + * PCSs is specific to the device. + * @code + * DSPI_SetAllPcsPolarity(base, kDSPI_Pcs0ActiveLow | kDSPI_Pcs1ActiveLow); + @endcode + * @param base DSPI peripheral address. + * @param mask The PCS polarity mask; use the enum _dspi_pcs_polarity. + */ +static inline void DSPI_SetAllPcsPolarity(SPI_Type *base, uint32_t mask) +{ + base->MCR = (base->MCR & ~SPI_MCR_PCSIS_MASK) | SPI_MCR_PCSIS(mask); +} + +/*! + * @brief Sets the DSPI baud rate in bits per second. + * + * This function takes in the desired baudRate_Bps (baud rate) and calculates the nearest possible baud rate without + * exceeding the desired baud rate, and returns the calculated baud rate in bits-per-second. It requires that the + * caller also provide the frequency of the module source clock (in Hertz). + * + * @param base DSPI peripheral address. + * @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of the type dspi_ctar_selection_t + * @param baudRate_Bps The desired baud rate in bits per second + * @param srcClock_Hz Module source input clock in Hertz + * @return The actual calculated baud rate + */ +uint32_t DSPI_MasterSetBaudRate(SPI_Type *base, + dspi_ctar_selection_t whichCtar, + uint32_t baudRate_Bps, + uint32_t srcClock_Hz); + +/*! + * @brief Manually configures the delay prescaler and scaler for a particular CTAR. + * + * This function configures the PCS to SCK delay pre-scalar (PcsSCK) and scalar (CSSCK), after SCK delay pre-scalar + * (PASC) and scalar (ASC), and the delay after transfer pre-scalar (PDT) and scalar (DT). + * + * These delay names are available in the type dspi_delay_type_t. + * + * The user passes the delay to the configuration along with the prescaler and scaler value. + * This allows the user to directly set the prescaler/scaler values if pre-calculated or + * to manually increment either value. + * + * @param base DSPI peripheral address. + * @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type dspi_ctar_selection_t. + * @param prescaler The prescaler delay value (can be an integer 0, 1, 2, or 3). + * @param scaler The scaler delay value (can be any integer between 0 to 15). + * @param whichDelay The desired delay to configure; must be of type dspi_delay_type_t + */ +void DSPI_MasterSetDelayScaler( + SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay); + +/*! + * @brief Calculates the delay prescaler and scaler based on the desired delay input in nanoseconds. + * + * This function calculates the values for the following. + * PCS to SCK delay pre-scalar (PCSSCK) and scalar (CSSCK), or + * After SCK delay pre-scalar (PASC) and scalar (ASC), or + * Delay after transfer pre-scalar (PDT) and scalar (DT). + * + * These delay names are available in the type dspi_delay_type_t. + * + * The user passes which delay to configure along with the desired delay value in nanoseconds. The function + * calculates the values needed for the prescaler and scaler. Note that returning the calculated delay as an exact + * delay match may not be possible. In this case, the closest match is calculated without going below the desired + * delay value input. + * It is possible to input a very large delay value that exceeds the capability of the part, in which case the maximum + * supported delay is returned. The higher-level peripheral driver alerts the user of an out of range delay + * input. + * + * @param base DSPI peripheral address. + * @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type dspi_ctar_selection_t. + * @param whichDelay The desired delay to configure, must be of type dspi_delay_type_t + * @param srcClock_Hz Module source input clock in Hertz + * @param delayTimeInNanoSec The desired delay value in nanoseconds. + * @return The actual calculated delay value. + */ +uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base, + dspi_ctar_selection_t whichCtar, + dspi_delay_type_t whichDelay, + uint32_t srcClock_Hz, + uint32_t delayTimeInNanoSec); + +/*! + * @brief Writes data into the data buffer for master mode. + * + * In master mode, the 16-bit data is appended to the 16-bit command info. The command portion + * provides characteristics of the data, such as the optional continuous chip select + * operation between transfers, the desired Clock and Transfer Attributes register to use for the + * associated SPI frame, the desired PCS signal to use for the data transfer, whether the current + * transfer is the last in the queue, and whether to clear the transfer count (normally needed when + * sending the first frame of a data packet). This is an example. + * @code + * dspi_command_data_config_t commandConfig; + * commandConfig.isPcsContinuous = true; + * commandConfig.whichCtar = kDSPICtar0; + * commandConfig.whichPcs = kDSPIPcs0; + * commandConfig.clearTransferCount = false; + * commandConfig.isEndOfQueue = false; + * DSPI_MasterWriteData(base, &commandConfig, dataWord); + @endcode + * + * @param base DSPI peripheral address. + * @param command Pointer to the command structure. + * @param data The data word to be sent. + */ +static inline void DSPI_MasterWriteData(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data) +{ + base->PUSHR = SPI_PUSHR_CONT(command->isPcsContinuous) | SPI_PUSHR_CTAS(command->whichCtar) | + SPI_PUSHR_PCS(command->whichPcs) | SPI_PUSHR_EOQ(command->isEndOfQueue) | + SPI_PUSHR_CTCNT(command->clearTransferCount) | SPI_PUSHR_TXDATA(data); +} + +/*! + * @brief Sets the dspi_command_data_config_t structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in the DSPI_MasterWrite_xx(). + * Users may use the initialized structure unchanged in the DSPI_MasterWrite_xx() or modify the structure + * before calling the DSPI_MasterWrite_xx(). + * This is an example. + * @code + * dspi_command_data_config_t command; + * DSPI_GetDefaultDataCommandConfig(&command); + * @endcode + * @param command Pointer to the dspi_command_data_config_t structure. + */ +void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command); + +/*! + * @brief Writes data into the data buffer master mode and waits till complete to return. + * + * In master mode, the 16-bit data is appended to the 16-bit command info. The command portion + * provides characteristics of the data, such as the optional continuous chip select + * operation between transfers, the desired Clock and Transfer Attributes register to use for the + * associated SPI frame, the desired PCS signal to use for the data transfer, whether the current + * transfer is the last in the queue, and whether to clear the transfer count (normally needed when + * sending the first frame of a data packet). This is an example. + * @code + * dspi_command_config_t commandConfig; + * commandConfig.isPcsContinuous = true; + * commandConfig.whichCtar = kDSPICtar0; + * commandConfig.whichPcs = kDSPIPcs1; + * commandConfig.clearTransferCount = false; + * commandConfig.isEndOfQueue = false; + * DSPI_MasterWriteDataBlocking(base, &commandConfig, dataWord); + * @endcode + * + * Note that this function does not return until after the transmit is complete. Also note that the DSPI must be + * enabled and running to transmit data (MCR[MDIS] & [HALT] = 0). Because the SPI is a synchronous protocol, + * the received data is available when the transmit completes. + * + * @param base DSPI peripheral address. + * @param command Pointer to the command structure. + * @param data The data word to be sent. + */ +void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data); + +/*! + * @brief Returns the DSPI command word formatted to the PUSHR data register bit field. + * + * This function allows the caller to pass in the data command structure and returns the command word formatted + * according to the DSPI PUSHR register bit field placement. The user can then "OR" the returned command word with the + * desired data to send and use the function DSPI_HAL_WriteCommandDataMastermode or + * DSPI_HAL_WriteCommandDataMastermodeBlocking to write the entire 32-bit command data word to the PUSHR. This helps + * improve performance in cases where the command structure is constant. For example, the user calls this function + * before starting a transfer to generate the command word. When they are ready to transmit the data, they OR + * this formatted command word with the desired data to transmit. This process increases transmit performance when + * compared to calling send functions, such as DSPI_HAL_WriteDataMastermode, which format the command word each time a + * data word is to be sent. + * + * @param command Pointer to the command structure. + * @return The command word formatted to the PUSHR data register bit field. + */ +static inline uint32_t DSPI_MasterGetFormattedCommand(dspi_command_data_config_t *command) +{ + /* Format the 16-bit command word according to the PUSHR data register bit field*/ + return (uint32_t)(SPI_PUSHR_CONT(command->isPcsContinuous) | SPI_PUSHR_CTAS(command->whichCtar) | + SPI_PUSHR_PCS(command->whichPcs) | SPI_PUSHR_EOQ(command->isEndOfQueue) | + SPI_PUSHR_CTCNT(command->clearTransferCount)); +} + +/*! + * @brief Writes a 32-bit data word (16-bit command appended with 16-bit data) into the data + * buffer master mode and waits till complete to return. + * + * In this function, the user must append the 16-bit data to the 16-bit command information and then provide the total 32-bit word + * as the data to send. + * The command portion provides characteristics of the data, such as the optional continuous chip select operation + * between transfers, the desired Clock and Transfer Attributes register to use for the associated SPI frame, the desired PCS + * signal to use for the data transfer, whether the current transfer is the last in the queue, and whether to clear the + * transfer count (normally needed when sending the first frame of a data packet). The user is responsible for + * appending this command with the data to send. This is an example: + * @code + * dataWord = <16-bit command> | <16-bit data>; + * DSPI_MasterWriteCommandDataBlocking(base, dataWord); + * @endcode + * + * Note that this function does not return until after the transmit is complete. Also note that the DSPI must be + * enabled and running to transmit data (MCR[MDIS] & [HALT] = 0). + * Because the SPI is a synchronous protocol, the received data is available when the transmit completes. + * + * For a blocking polling transfer, see methods below. + * Option 1: +* uint32_t command_to_send = DSPI_MasterGetFormattedCommand(&command); +* uint32_t data0 = command_to_send | data_need_to_send_0; +* uint32_t data1 = command_to_send | data_need_to_send_1; +* uint32_t data2 = command_to_send | data_need_to_send_2; +* +* DSPI_MasterWriteCommandDataBlocking(base,data0); +* DSPI_MasterWriteCommandDataBlocking(base,data1); +* DSPI_MasterWriteCommandDataBlocking(base,data2); +* +* Option 2: +* DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_0); +* DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_1); +* DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_2); +* + * @param base DSPI peripheral address. + * @param data The data word (command and data combined) to be sent. + */ +void DSPI_MasterWriteCommandDataBlocking(SPI_Type *base, uint32_t data); + +/*! + * @brief Writes data into the data buffer in slave mode. + * + * In slave mode, up to 16-bit words may be written. + * + * @param base DSPI peripheral address. + * @param data The data to send. + */ +static inline void DSPI_SlaveWriteData(SPI_Type *base, uint32_t data) +{ + base->PUSHR_SLAVE = data; +} + +/*! + * @brief Writes data into the data buffer in slave mode, waits till data was transmitted, and returns. + * + * In slave mode, up to 16-bit words may be written. The function first clears the transmit complete flag, writes data + * into data register, and finally waits until the data is transmitted. + * + * @param base DSPI peripheral address. + * @param data The data to send. + */ +void DSPI_SlaveWriteDataBlocking(SPI_Type *base, uint32_t data); + +/*! + * @brief Reads data from the data buffer. + * + * @param base DSPI peripheral address. + * @return The data from the read data buffer. + */ +static inline uint32_t DSPI_ReadData(SPI_Type *base) +{ + return (base->POPR); +} + +/*! + *@} +*/ + +/*! + * @name Transactional + * @{ + */ +/*Transactional APIs*/ + +/*! + * @brief Initializes the DSPI master handle. + * + * This function initializes the DSPI handle, which can be used for other DSPI transactional APIs. Usually, for a + * specified DSPI instance, call this API once to get the initialized handle. + * + * @param base DSPI peripheral base address. + * @param handle DSPI handle pointer to dspi_master_handle_t. + * @param callback DSPI callback. + * @param userData Callback function parameter. + */ +void DSPI_MasterTransferCreateHandle(SPI_Type *base, + dspi_master_handle_t *handle, + dspi_master_transfer_callback_t callback, + void *userData); + +/*! + * @brief DSPI master transfer data using polling. + * + * This function transfers data using polling. This is a blocking function, which does not return until all transfers + * have been completed. + * + * @param base DSPI peripheral base address. + * @param transfer Pointer to the dspi_transfer_t structure. + * @return status of status_t. + */ +status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer); + +/*! + * @brief DSPI master transfer data using interrupts. + * + * This function transfers data using interrupts. This is a non-blocking function, which returns right away. When all + * data is transferred, the callback function is called. + + * @param base DSPI peripheral base address. + * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state. + * @param transfer Pointer to the dspi_transfer_t structure. + * @return status of status_t. + */ +status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer); + +/*! + * @brief Gets the master transfer count. + * + * This function gets the master transfer count. + * + * @param base DSPI peripheral base address. + * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state. + * @param count The number of bytes transferred by using the non-blocking transaction. + * @return status of status_t. + */ +status_t DSPI_MasterTransferGetCount(SPI_Type *base, dspi_master_handle_t *handle, size_t *count); + +/*! + * @brief DSPI master aborts a transfer using an interrupt. + * + * This function aborts a transfer using an interrupt. + * + * @param base DSPI peripheral base address. + * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state. + */ +void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle); + +/*! + * @brief DSPI Master IRQ handler function. + * + * This function processes the DSPI transmit and receive IRQ. + + * @param base DSPI peripheral base address. + * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state. + */ +void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle); + +/*! + * @brief Initializes the DSPI slave handle. + * + * This function initializes the DSPI handle, which can be used for other DSPI transactional APIs. Usually, for a + * specified DSPI instance, call this API once to get the initialized handle. + * + * @param handle DSPI handle pointer to the dspi_slave_handle_t. + * @param base DSPI peripheral base address. + * @param callback DSPI callback. + * @param userData Callback function parameter. + */ +void DSPI_SlaveTransferCreateHandle(SPI_Type *base, + dspi_slave_handle_t *handle, + dspi_slave_transfer_callback_t callback, + void *userData); + +/*! + * @brief DSPI slave transfers data using an interrupt. + * + * This function transfers data using an interrupt. This is a non-blocking function, which returns right away. When all + * data is transferred, the callback function is called. + * + * @param base DSPI peripheral base address. + * @param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state. + * @param transfer Pointer to the dspi_transfer_t structure. + * @return status of status_t. + */ +status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer); + +/*! + * @brief Gets the slave transfer count. + * + * This function gets the slave transfer count. + * + * @param base DSPI peripheral base address. + * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state. + * @param count The number of bytes transferred by using the non-blocking transaction. + * @return status of status_t. + */ +status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle, size_t *count); + +/*! + * @brief DSPI slave aborts a transfer using an interrupt. + * + * This function aborts a transfer using an interrupt. + * + * @param base DSPI peripheral base address. + * @param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state. + */ +void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle); + +/*! + * @brief DSPI Master IRQ handler function. + * + * This function processes the DSPI transmit and receive IRQ. + * + * @param base DSPI peripheral base address. + * @param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state. + */ +void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle); + +/*! + *@} +*/ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ + /*! + *@} + */ + +#endif /*_FSL_DSPI_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi_edma.c new file mode 100644 index 00000000000..e37c78eac71 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi_edma.c @@ -0,0 +1,1156 @@ +/* +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "fsl_dspi_edma.h" + +/*********************************************************************************************************************** +* Definitons +***********************************************************************************************************************/ + +/*! +* @brief Structure definition for dspi_master_edma_private_handle_t. The structure is private. +*/ +typedef struct _dspi_master_edma_private_handle +{ + SPI_Type *base; /*!< DSPI peripheral base address. */ + dspi_master_edma_handle_t *handle; /*!< dspi_master_edma_handle_t handle */ +} dspi_master_edma_private_handle_t; + +/*! +* @brief Structure definition for dspi_slave_edma_private_handle_t. The structure is private. +*/ +typedef struct _dspi_slave_edma_private_handle +{ + SPI_Type *base; /*!< DSPI peripheral base address. */ + dspi_slave_edma_handle_t *handle; /*!< dspi_master_edma_handle_t handle */ +} dspi_slave_edma_private_handle_t; + +/*********************************************************************************************************************** +* Prototypes +***********************************************************************************************************************/ +/*! +* @brief EDMA_DspiMasterCallback after the DSPI master transfer completed by using EDMA. +* This is not a public API as it is called from other driver functions. +*/ +static void EDMA_DspiMasterCallback(edma_handle_t *edmaHandle, + void *g_dspiEdmaPrivateHandle, + bool transferDone, + uint32_t tcds); + +/*! +* @brief EDMA_DspiSlaveCallback after the DSPI slave transfer completed by using EDMA. +* This is not a public API as it is called from other driver functions. +*/ +static void EDMA_DspiSlaveCallback(edma_handle_t *edmaHandle, + void *g_dspiEdmaPrivateHandle, + bool transferDone, + uint32_t tcds); +/*! +* @brief Get instance number for DSPI module. +* +* This is not a public API and it's extern from fsl_dspi.c. +* +* @param base DSPI peripheral base address +*/ +extern uint32_t DSPI_GetInstance(SPI_Type *base); + +/*********************************************************************************************************************** +* Variables +***********************************************************************************************************************/ + +/*! @brief Pointers to dspi edma handles for each instance. */ +static dspi_master_edma_private_handle_t s_dspiMasterEdmaPrivateHandle[FSL_FEATURE_SOC_DSPI_COUNT]; +static dspi_slave_edma_private_handle_t s_dspiSlaveEdmaPrivateHandle[FSL_FEATURE_SOC_DSPI_COUNT]; + +/*********************************************************************************************************************** +* Code +***********************************************************************************************************************/ + +void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base, + dspi_master_edma_handle_t *handle, + dspi_master_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *edmaRxRegToRxDataHandle, + edma_handle_t *edmaTxDataToIntermediaryHandle, + edma_handle_t *edmaIntermediaryToTxRegHandle) +{ + assert(handle); + assert(edmaRxRegToRxDataHandle); + assert(edmaTxDataToIntermediaryHandle); + assert(edmaIntermediaryToTxRegHandle); + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + uint32_t instance = DSPI_GetInstance(base); + + s_dspiMasterEdmaPrivateHandle[instance].base = base; + s_dspiMasterEdmaPrivateHandle[instance].handle = handle; + + handle->callback = callback; + handle->userData = userData; + + handle->edmaRxRegToRxDataHandle = edmaRxRegToRxDataHandle; + handle->edmaTxDataToIntermediaryHandle = edmaTxDataToIntermediaryHandle; + handle->edmaIntermediaryToTxRegHandle = edmaIntermediaryToTxRegHandle; +} + +status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, dspi_transfer_t *transfer) +{ + assert(handle); + assert(transfer); + + /* If the transfer count is zero, then return immediately.*/ + if (transfer->dataSize == 0) + { + return kStatus_InvalidArgument; + } + + /* If both send buffer and receive buffer is null */ + if ((!(transfer->txData)) && (!(transfer->rxData))) + { + return kStatus_InvalidArgument; + } + + /* Check that we're not busy.*/ + if (handle->state == kDSPI_Busy) + { + return kStatus_DSPI_Busy; + } + + uint32_t instance = DSPI_GetInstance(base); + uint16_t wordToSend = 0; + uint8_t dummyData = DSPI_DUMMY_DATA; + uint8_t dataAlreadyFed = 0; + uint8_t dataFedMax = 2; + + uint32_t rxAddr = DSPI_GetRxRegisterAddress(base); + uint32_t txAddr = DSPI_MasterGetTxRegisterAddress(base); + + edma_tcd_t *softwareTCD = (edma_tcd_t *)((uint32_t)(&handle->dspiSoftwareTCD[1]) & (~0x1FU)); + + edma_transfer_config_t transferConfigA; + edma_transfer_config_t transferConfigB; + edma_transfer_config_t transferConfigC; + + handle->txBuffIfNull = ((uint32_t)DSPI_DUMMY_DATA << 8) | DSPI_DUMMY_DATA; + + handle->state = kDSPI_Busy; + + dspi_command_data_config_t commandStruct; + DSPI_StopTransfer(base); + DSPI_FlushFifo(base, true, true); + DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag); + + commandStruct.whichPcs = + (dspi_which_pcs_t)(1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT)); + commandStruct.isEndOfQueue = false; + commandStruct.clearTransferCount = false; + commandStruct.whichCtar = + (dspi_ctar_selection_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT); + commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous); + handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct)); + + commandStruct.isEndOfQueue = true; + commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer); + handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct)); + + handle->bitsPerFrame = ((base->CTAR[commandStruct.whichCtar] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1; + + if ((base->MCR & SPI_MCR_DIS_RXF_MASK) || (base->MCR & SPI_MCR_DIS_TXF_MASK)) + { + handle->fifoSize = 1; + } + else + { + handle->fifoSize = FSL_FEATURE_DSPI_FIFO_SIZEn(base); + } + handle->txData = transfer->txData; + handle->rxData = transfer->rxData; + handle->remainingSendByteCount = transfer->dataSize; + handle->remainingReceiveByteCount = transfer->dataSize; + handle->totalByteCount = transfer->dataSize; + + /* This limits the amount of data we can transfer due to the linked channel. + * The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame + */ + if (handle->bitsPerFrame > 8) + { + if (transfer->dataSize > 1022) + { + return kStatus_DSPI_OutOfRange; + } + } + else + { + if (transfer->dataSize > 511) + { + return kStatus_DSPI_OutOfRange; + } + } + + /*The data size should be even if the bitsPerFrame is greater than 8 (that is 2 bytes per frame in dspi) */ + if ((handle->bitsPerFrame > 8) && (transfer->dataSize & 0x1)) + { + return kStatus_InvalidArgument; + } + + DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); + + EDMA_SetCallback(handle->edmaRxRegToRxDataHandle, EDMA_DspiMasterCallback, + &s_dspiMasterEdmaPrivateHandle[instance]); + + /*If dspi has separate dma request , prepare the first data in "intermediary" . + else (dspi has shared dma request) , send first 2 data if there is fifo or send first 1 data if there is no fifo*/ + if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + /* For DSPI instances with separate RX/TX DMA requests, we'll use the TX DMA request to + * trigger the TX DMA channel and RX DMA request to trigger the RX DMA channel + */ + + /*Prepare the firt data*/ + if (handle->bitsPerFrame > 8) + { + /* If it's the last word */ + if (handle->remainingSendByteCount <= 2) + { + if (handle->txData) + { + wordToSend = *(handle->txData); + ++handle->txData; /* increment to next data byte */ + wordToSend |= (unsigned)(*(handle->txData)) << 8U; + } + else + { + wordToSend = ((uint32_t)dummyData << 8) | dummyData; + } + handle->lastCommand = (handle->lastCommand & 0xffff0000U) | wordToSend; + } + else /* For all words except the last word , frame > 8bits */ + { + if (handle->txData) + { + wordToSend = *(handle->txData); + ++handle->txData; /* increment to next data byte */ + wordToSend |= (unsigned)(*(handle->txData)) << 8U; + ++handle->txData; /* increment to next data byte */ + } + else + { + wordToSend = ((uint32_t)dummyData << 8) | dummyData; + } + handle->command = (handle->command & 0xffff0000U) | wordToSend; + } + } + else /* Optimized for bits/frame less than or equal to one byte. */ + { + if (handle->txData) + { + wordToSend = *(handle->txData); + ++handle->txData; /* increment to next data word*/ + } + else + { + wordToSend = dummyData; + } + + if (handle->remainingSendByteCount == 1) + { + handle->lastCommand = (handle->lastCommand & 0xffff0000U) | wordToSend; + } + else + { + handle->command = (handle->command & 0xffff0000U) | wordToSend; + } + } + } + + else /*dspi has shared dma request*/ + + { + /* For DSPI instances with shared RX/TX DMA requests, we'll use the RX DMA request to + * trigger ongoing transfers and will link to the TX DMA channel from the RX DMA channel. + */ + + /* If bits/frame is greater than one byte */ + if (handle->bitsPerFrame > 8) + { + while (DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag) + { + if (handle->remainingSendByteCount <= 2) + { + if (handle->txData) + { + wordToSend = *(handle->txData); + ++handle->txData; + wordToSend |= (unsigned)(*(handle->txData)) << 8U; + } + else + { + wordToSend = ((uint32_t)dummyData << 8) | dummyData; + } + handle->remainingSendByteCount = 0; + base->PUSHR = (handle->lastCommand & 0xffff0000U) | wordToSend; + } + /* For all words except the last word */ + else + { + if (handle->txData) + { + wordToSend = *(handle->txData); + ++handle->txData; + wordToSend |= (unsigned)(*(handle->txData)) << 8U; + ++handle->txData; + } + else + { + wordToSend = ((uint32_t)dummyData << 8) | dummyData; + } + handle->remainingSendByteCount -= 2; + base->PUSHR = (handle->command & 0xffff0000U) | wordToSend; + } + + /* Try to clear the TFFF; if the TX FIFO is full this will clear */ + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + + dataAlreadyFed += 2; + + /* exit loop if send count is zero, else update local variables for next loop */ + if ((handle->remainingSendByteCount == 0) || (dataAlreadyFed == (dataFedMax * 2))) + { + break; + } + } /* End of TX FIFO fill while loop */ + } + else /* Optimized for bits/frame less than or equal to one byte. */ + { + while (DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag) + { + if (handle->txData) + { + wordToSend = *(handle->txData); + ++handle->txData; + } + else + { + wordToSend = dummyData; + } + + if (handle->remainingSendByteCount == 1) + { + base->PUSHR = (handle->lastCommand & 0xffff0000U) | wordToSend; + } + else + { + base->PUSHR = (handle->command & 0xffff0000U) | wordToSend; + } + + /* Try to clear the TFFF; if the TX FIFO is full this will clear */ + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + + --handle->remainingSendByteCount; + + dataAlreadyFed++; + + /* exit loop if send count is zero, else update local variables for next loop */ + if ((handle->remainingSendByteCount == 0) || (dataAlreadyFed == dataFedMax)) + { + break; + } + } /* End of TX FIFO fill while loop */ + } + } + + /***channel_A *** used for carry the data from Rx_Data_Register(POPR) to User_Receive_Buffer*/ + EDMA_ResetChannel(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel); + + transferConfigA.srcAddr = (uint32_t)rxAddr; + transferConfigA.srcOffset = 0; + + if (handle->rxData) + { + transferConfigA.destAddr = (uint32_t) & (handle->rxData[0]); + transferConfigA.destOffset = 1; + } + else + { + transferConfigA.destAddr = (uint32_t) & (handle->rxBuffIfNull); + transferConfigA.destOffset = 0; + } + + transferConfigA.destTransferSize = kEDMA_TransferSize1Bytes; + + if (handle->bitsPerFrame <= 8) + { + transferConfigA.srcTransferSize = kEDMA_TransferSize1Bytes; + transferConfigA.minorLoopBytes = 1; + transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount; + } + else + { + transferConfigA.srcTransferSize = kEDMA_TransferSize2Bytes; + transferConfigA.minorLoopBytes = 2; + transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount / 2; + } + + /* Store the initially configured eDMA minor byte transfer count into the DSPI handle */ + handle->nbytes = transferConfigA.minorLoopBytes; + + EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, + &transferConfigA, NULL); + EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, + kEDMA_MajorInterruptEnable); + + /***channel_B *** used for carry the data from User_Send_Buffer to "intermediary" because the SPIx_PUSHR should + write the 32bits at once time . Then use channel_C to carry the "intermediary" to SPIx_PUSHR. Note that the + SPIx_PUSHR upper 16 bits are the "command" and the low 16bits are data */ + EDMA_ResetChannel(handle->edmaTxDataToIntermediaryHandle->base, handle->edmaTxDataToIntermediaryHandle->channel); + + if (handle->remainingSendByteCount > 0) + { + if (handle->txData) + { + transferConfigB.srcAddr = (uint32_t)(handle->txData); + transferConfigB.srcOffset = 1; + } + else + { + transferConfigB.srcAddr = (uint32_t)(&handle->txBuffIfNull); + transferConfigB.srcOffset = 0; + } + + transferConfigB.destAddr = (uint32_t)(&handle->command); + transferConfigB.destOffset = 0; + + transferConfigB.srcTransferSize = kEDMA_TransferSize1Bytes; + + if (handle->bitsPerFrame <= 8) + { + transferConfigB.destTransferSize = kEDMA_TransferSize1Bytes; + transferConfigB.minorLoopBytes = 1; + + if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + /*already prepared the first data in "intermediary" , so minus 1 */ + transferConfigB.majorLoopCounts = handle->remainingSendByteCount - 1; + } + else + { + /*Only enable channel_B minorlink to channel_C , so need to add one count due to the last time is + majorlink , the majorlink would not trigger the channel_C*/ + transferConfigB.majorLoopCounts = handle->remainingSendByteCount + 1; + } + } + else + { + transferConfigB.destTransferSize = kEDMA_TransferSize2Bytes; + transferConfigB.minorLoopBytes = 2; + if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + /*already prepared the first data in "intermediary" , so minus 1 */ + transferConfigB.majorLoopCounts = handle->remainingSendByteCount / 2 - 1; + } + else + { + /*Only enable channel_B minorlink to channel_C , so need to add one count due to the last time is + * majorlink*/ + transferConfigB.majorLoopCounts = handle->remainingSendByteCount / 2 + 1; + } + } + + EDMA_SetTransferConfig(handle->edmaTxDataToIntermediaryHandle->base, + handle->edmaTxDataToIntermediaryHandle->channel, &transferConfigB, NULL); + } + + /***channel_C ***carry the "intermediary" to SPIx_PUSHR. used the edma Scatter Gather function on channel_C to + handle the last data */ + EDMA_ResetChannel(handle->edmaIntermediaryToTxRegHandle->base, handle->edmaIntermediaryToTxRegHandle->channel); + + if (((handle->remainingSendByteCount > 0) && (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))) || + ((((handle->remainingSendByteCount > 1) && (handle->bitsPerFrame <= 8)) || + ((handle->remainingSendByteCount > 2) && (handle->bitsPerFrame > 8))) && + (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)))) + { + if (handle->txData) + { + uint32_t bufferIndex = 0; + + if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + if (handle->bitsPerFrame <= 8) + { + bufferIndex = handle->remainingSendByteCount - 1; + } + else + { + bufferIndex = handle->remainingSendByteCount - 2; + } + } + else + { + bufferIndex = handle->remainingSendByteCount; + } + + if (handle->bitsPerFrame <= 8) + { + handle->lastCommand = (handle->lastCommand & 0xffff0000U) | handle->txData[bufferIndex - 1]; + } + else + { + handle->lastCommand = (handle->lastCommand & 0xffff0000U) | + ((uint32_t)handle->txData[bufferIndex - 1] << 8) | + handle->txData[bufferIndex - 2]; + } + } + else + { + if (handle->bitsPerFrame <= 8) + { + wordToSend = dummyData; + } + else + { + wordToSend = ((uint32_t)dummyData << 8) | dummyData; + } + handle->lastCommand = (handle->lastCommand & 0xffff0000U) | wordToSend; + } + } + + if ((1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) || + ((1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) && (handle->remainingSendByteCount > 0))) + { + transferConfigC.srcAddr = (uint32_t) & (handle->lastCommand); + transferConfigC.destAddr = (uint32_t)txAddr; + transferConfigC.srcTransferSize = kEDMA_TransferSize4Bytes; + transferConfigC.destTransferSize = kEDMA_TransferSize4Bytes; + transferConfigC.srcOffset = 0; + transferConfigC.destOffset = 0; + transferConfigC.minorLoopBytes = 4; + transferConfigC.majorLoopCounts = 1; + + EDMA_TcdReset(softwareTCD); + EDMA_TcdSetTransferConfig(softwareTCD, &transferConfigC, NULL); + } + + if (((handle->remainingSendByteCount > 1) && (handle->bitsPerFrame <= 8)) || + ((handle->remainingSendByteCount > 2) && (handle->bitsPerFrame > 8))) + { + transferConfigC.srcAddr = (uint32_t)(&(handle->command)); + transferConfigC.destAddr = (uint32_t)txAddr; + + transferConfigC.srcTransferSize = kEDMA_TransferSize4Bytes; + transferConfigC.destTransferSize = kEDMA_TransferSize4Bytes; + transferConfigC.srcOffset = 0; + transferConfigC.destOffset = 0; + transferConfigC.minorLoopBytes = 4; + + if (handle->bitsPerFrame <= 8) + { + transferConfigC.majorLoopCounts = handle->remainingSendByteCount - 1; + } + else + { + transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2 - 1; + } + + EDMA_SetTransferConfig(handle->edmaIntermediaryToTxRegHandle->base, + handle->edmaIntermediaryToTxRegHandle->channel, &transferConfigC, softwareTCD); + EDMA_EnableAutoStopRequest(handle->edmaIntermediaryToTxRegHandle->base, + handle->edmaIntermediaryToTxRegHandle->channel, false); + } + else + { + EDMA_SetTransferConfig(handle->edmaIntermediaryToTxRegHandle->base, + handle->edmaIntermediaryToTxRegHandle->channel, &transferConfigC, NULL); + } + + /*Start the EDMA channel_A , channel_B , channel_C transfer*/ + EDMA_StartTransfer(handle->edmaRxRegToRxDataHandle); + EDMA_StartTransfer(handle->edmaTxDataToIntermediaryHandle); + EDMA_StartTransfer(handle->edmaIntermediaryToTxRegHandle); + + /*Set channel priority*/ + uint8_t channelPriorityLow = handle->edmaRxRegToRxDataHandle->channel; + uint8_t channelPriorityMid = handle->edmaTxDataToIntermediaryHandle->channel; + uint8_t channelPriorityHigh = handle->edmaIntermediaryToTxRegHandle->channel; + uint8_t t = 0; + if (channelPriorityLow > channelPriorityMid) + { + t = channelPriorityLow; + channelPriorityLow = channelPriorityMid; + channelPriorityMid = t; + } + + if (channelPriorityLow > channelPriorityHigh) + { + t = channelPriorityLow; + channelPriorityLow = channelPriorityHigh; + channelPriorityHigh = t; + } + + if (channelPriorityMid > channelPriorityHigh) + { + t = channelPriorityMid; + channelPriorityMid = channelPriorityHigh; + channelPriorityHigh = t; + } + edma_channel_Preemption_config_t preemption_config_t; + preemption_config_t.enableChannelPreemption = true; + preemption_config_t.enablePreemptAbility = true; + preemption_config_t.channelPriority = channelPriorityLow; + + if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + EDMA_SetChannelPreemptionConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, + &preemption_config_t); + + preemption_config_t.channelPriority = channelPriorityMid; + EDMA_SetChannelPreemptionConfig(handle->edmaTxDataToIntermediaryHandle->base, + handle->edmaTxDataToIntermediaryHandle->channel, &preemption_config_t); + + preemption_config_t.channelPriority = channelPriorityHigh; + EDMA_SetChannelPreemptionConfig(handle->edmaIntermediaryToTxRegHandle->base, + handle->edmaIntermediaryToTxRegHandle->channel, &preemption_config_t); + } + else + { + EDMA_SetChannelPreemptionConfig(handle->edmaIntermediaryToTxRegHandle->base, + handle->edmaIntermediaryToTxRegHandle->channel, &preemption_config_t); + + preemption_config_t.channelPriority = channelPriorityMid; + EDMA_SetChannelPreemptionConfig(handle->edmaTxDataToIntermediaryHandle->base, + handle->edmaTxDataToIntermediaryHandle->channel, &preemption_config_t); + + preemption_config_t.channelPriority = channelPriorityHigh; + EDMA_SetChannelPreemptionConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, + &preemption_config_t); + } + + /*Set the channel link. + For DSPI instances with shared RX/TX DMA requests: Rx DMA request -> channel_A -> channel_B-> channel_C. + For DSPI instances with separate RX and TX DMA requests: + Rx DMA request -> channel_A + Tx DMA request -> channel_C -> channel_B . (so need prepare the first data in "intermediary" before the DMA + transfer and then channel_B is used to prepare the next data to "intermediary" ) */ + if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + /*if there is Tx DMA request , carry the 32bits data (handle->command) to PUSHR first , then link to channelB + to prepare the next 32bits data (User_send_buffer to handle->command) */ + if (handle->remainingSendByteCount > 1) + { + EDMA_SetChannelLink(handle->edmaIntermediaryToTxRegHandle->base, + handle->edmaIntermediaryToTxRegHandle->channel, kEDMA_MinorLink, + handle->edmaTxDataToIntermediaryHandle->channel); + } + + DSPI_EnableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); + } + else + { + if (handle->remainingSendByteCount > 0) + { + EDMA_SetChannelLink(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, + kEDMA_MinorLink, handle->edmaTxDataToIntermediaryHandle->channel); + + EDMA_SetChannelLink(handle->edmaTxDataToIntermediaryHandle->base, + handle->edmaTxDataToIntermediaryHandle->channel, kEDMA_MinorLink, + handle->edmaIntermediaryToTxRegHandle->channel); + } + + DSPI_EnableDMA(base, kDSPI_RxDmaEnable); + } + + DSPI_StartTransfer(base); + + return kStatus_Success; +} + +static void EDMA_DspiMasterCallback(edma_handle_t *edmaHandle, + void *g_dspiEdmaPrivateHandle, + bool transferDone, + uint32_t tcds) +{ + assert(edmaHandle); + assert(g_dspiEdmaPrivateHandle); + + dspi_master_edma_private_handle_t *dspiEdmaPrivateHandle; + + dspiEdmaPrivateHandle = (dspi_master_edma_private_handle_t *)g_dspiEdmaPrivateHandle; + + DSPI_DisableDMA((dspiEdmaPrivateHandle->base), kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); + + if (dspiEdmaPrivateHandle->handle->callback) + { + dspiEdmaPrivateHandle->handle->callback(dspiEdmaPrivateHandle->base, dspiEdmaPrivateHandle->handle, + kStatus_Success, dspiEdmaPrivateHandle->handle->userData); + } + + dspiEdmaPrivateHandle->handle->state = kDSPI_Idle; +} + +void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle) +{ + assert(handle); + + DSPI_StopTransfer(base); + + DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); + + EDMA_AbortTransfer(handle->edmaRxRegToRxDataHandle); + EDMA_AbortTransfer(handle->edmaTxDataToIntermediaryHandle); + EDMA_AbortTransfer(handle->edmaIntermediaryToTxRegHandle); + + handle->state = kDSPI_Idle; +} + +status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (handle->state != kDSPI_Busy) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + size_t bytes; + + bytes = (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->edmaRxRegToRxDataHandle->base, + handle->edmaRxRegToRxDataHandle->channel); + + *count = handle->totalByteCount - bytes; + + return kStatus_Success; +} + +void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base, + dspi_slave_edma_handle_t *handle, + dspi_slave_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *edmaRxRegToRxDataHandle, + edma_handle_t *edmaTxDataToTxRegHandle) +{ + assert(handle); + assert(edmaRxRegToRxDataHandle); + assert(edmaTxDataToTxRegHandle); + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + uint32_t instance = DSPI_GetInstance(base); + + s_dspiSlaveEdmaPrivateHandle[instance].base = base; + s_dspiSlaveEdmaPrivateHandle[instance].handle = handle; + + handle->callback = callback; + handle->userData = userData; + + handle->edmaRxRegToRxDataHandle = edmaRxRegToRxDataHandle; + handle->edmaTxDataToTxRegHandle = edmaTxDataToTxRegHandle; +} + +status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, dspi_transfer_t *transfer) +{ + assert(handle); + assert(transfer); + + /* If send/receive length is zero */ + if (transfer->dataSize == 0) + { + return kStatus_InvalidArgument; + } + + /* If both send buffer and receive buffer is null */ + if ((!(transfer->txData)) && (!(transfer->rxData))) + { + return kStatus_InvalidArgument; + } + + /* Check that we're not busy.*/ + if (handle->state == kDSPI_Busy) + { + return kStatus_DSPI_Busy; + } + + uint32_t instance = DSPI_GetInstance(base); + uint8_t whichCtar = (transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT; + handle->bitsPerFrame = + (((base->CTAR_SLAVE[whichCtar]) & SPI_CTAR_SLAVE_FMSZ_MASK) >> SPI_CTAR_SLAVE_FMSZ_SHIFT) + 1; + + /* If using a shared RX/TX DMA request, then this limits the amount of data we can transfer + * due to the linked channel. The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame + */ + if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + if (handle->bitsPerFrame > 8) + { + if (transfer->dataSize > 1022) + { + return kStatus_DSPI_OutOfRange; + } + } + else + { + if (transfer->dataSize > 511) + { + return kStatus_DSPI_OutOfRange; + } + } + } + + /*The data size should be even if the bitsPerFrame is greater than 8 (that is 2 bytes per frame in dspi) */ + if ((handle->bitsPerFrame > 8) && (transfer->dataSize & 0x1)) + { + return kStatus_InvalidArgument; + } + + EDMA_SetCallback(handle->edmaRxRegToRxDataHandle, EDMA_DspiSlaveCallback, &s_dspiSlaveEdmaPrivateHandle[instance]); + + handle->state = kDSPI_Busy; + + /* Store transfer information */ + handle->txData = transfer->txData; + handle->rxData = transfer->rxData; + handle->remainingSendByteCount = transfer->dataSize; + handle->remainingReceiveByteCount = transfer->dataSize; + handle->totalByteCount = transfer->dataSize; + + uint16_t wordToSend = 0; + uint8_t dummyData = DSPI_DUMMY_DATA; + uint8_t dataAlreadyFed = 0; + uint8_t dataFedMax = 2; + + uint32_t rxAddr = DSPI_GetRxRegisterAddress(base); + uint32_t txAddr = DSPI_SlaveGetTxRegisterAddress(base); + + edma_transfer_config_t transferConfigA; + edma_transfer_config_t transferConfigC; + + DSPI_StopTransfer(base); + + DSPI_FlushFifo(base, true, true); + DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag); + + DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); + + DSPI_StartTransfer(base); + + /*if dspi has separate dma request , need not prepare data first . + else (dspi has shared dma request) , send first 2 data into fifo if there is fifo or send first 1 data to + slaveGetTxRegister if there is no fifo*/ + if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + /* For DSPI instances with shared RX/TX DMA requests, we'll use the RX DMA request to + * trigger ongoing transfers and will link to the TX DMA channel from the RX DMA channel. + */ + /* If bits/frame is greater than one byte */ + if (handle->bitsPerFrame > 8) + { + while (DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag) + { + if (handle->txData) + { + wordToSend = *(handle->txData); + ++handle->txData; /* Increment to next data byte */ + + wordToSend |= (unsigned)(*(handle->txData)) << 8U; + ++handle->txData; /* Increment to next data byte */ + } + else + { + wordToSend = ((uint32_t)dummyData << 8) | dummyData; + } + handle->remainingSendByteCount -= 2; /* decrement remainingSendByteCount by 2 */ + base->PUSHR_SLAVE = wordToSend; + + /* Try to clear the TFFF; if the TX FIFO is full this will clear */ + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + + dataAlreadyFed += 2; + + /* Exit loop if send count is zero, else update local variables for next loop */ + if ((handle->remainingSendByteCount == 0) || (dataAlreadyFed == (dataFedMax * 2))) + { + break; + } + } /* End of TX FIFO fill while loop */ + } + else /* Optimized for bits/frame less than or equal to one byte. */ + { + while (DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag) + { + if (handle->txData) + { + wordToSend = *(handle->txData); + /* Increment to next data word*/ + ++handle->txData; + } + else + { + wordToSend = dummyData; + } + + base->PUSHR_SLAVE = wordToSend; + + /* Try to clear the TFFF; if the TX FIFO is full this will clear */ + DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); + /* Decrement remainingSendByteCount*/ + --handle->remainingSendByteCount; + + dataAlreadyFed++; + + /* Exit loop if send count is zero, else update local variables for next loop */ + if ((handle->remainingSendByteCount == 0) || (dataAlreadyFed == dataFedMax)) + { + break; + } + } /* End of TX FIFO fill while loop */ + } + } + + /***channel_A *** used for carry the data from Rx_Data_Register(POPR) to User_Receive_Buffer*/ + if (handle->remainingReceiveByteCount > 0) + { + EDMA_ResetChannel(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel); + + transferConfigA.srcAddr = (uint32_t)rxAddr; + transferConfigA.srcOffset = 0; + + if (handle->rxData) + { + transferConfigA.destAddr = (uint32_t) & (handle->rxData[0]); + transferConfigA.destOffset = 1; + } + else + { + transferConfigA.destAddr = (uint32_t) & (handle->rxBuffIfNull); + transferConfigA.destOffset = 0; + } + + transferConfigA.destTransferSize = kEDMA_TransferSize1Bytes; + + if (handle->bitsPerFrame <= 8) + { + transferConfigA.srcTransferSize = kEDMA_TransferSize1Bytes; + transferConfigA.minorLoopBytes = 1; + transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount; + } + else + { + transferConfigA.srcTransferSize = kEDMA_TransferSize2Bytes; + transferConfigA.minorLoopBytes = 2; + transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount / 2; + } + + /* Store the initially configured eDMA minor byte transfer count into the DSPI handle */ + handle->nbytes = transferConfigA.minorLoopBytes; + + EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, + &transferConfigA, NULL); + EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, + kEDMA_MajorInterruptEnable); + } + + if (handle->remainingSendByteCount > 0) + { + /***channel_C *** used for carry the data from User_Send_Buffer to Tx_Data_Register(PUSHR_SLAVE)*/ + EDMA_ResetChannel(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel); + + transferConfigC.destAddr = (uint32_t)txAddr; + transferConfigC.destOffset = 0; + + if (handle->txData) + { + transferConfigC.srcAddr = (uint32_t)(&(handle->txData[0])); + transferConfigC.srcOffset = 1; + } + else + { + transferConfigC.srcAddr = (uint32_t)(&handle->txBuffIfNull); + transferConfigC.srcOffset = 0; + if (handle->bitsPerFrame <= 8) + { + handle->txBuffIfNull = DSPI_DUMMY_DATA; + } + else + { + handle->txBuffIfNull = (DSPI_DUMMY_DATA << 8) | DSPI_DUMMY_DATA; + } + } + + transferConfigC.srcTransferSize = kEDMA_TransferSize1Bytes; + + if (handle->bitsPerFrame <= 8) + { + transferConfigC.destTransferSize = kEDMA_TransferSize1Bytes; + transferConfigC.minorLoopBytes = 1; + transferConfigC.majorLoopCounts = handle->remainingSendByteCount; + } + else + { + transferConfigC.destTransferSize = kEDMA_TransferSize2Bytes; + transferConfigC.minorLoopBytes = 2; + transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2; + } + + EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, + &transferConfigC, NULL); + + EDMA_StartTransfer(handle->edmaTxDataToTxRegHandle); + } + + EDMA_StartTransfer(handle->edmaRxRegToRxDataHandle); + + /*Set channel priority*/ + uint8_t channelPriorityLow = handle->edmaRxRegToRxDataHandle->channel; + uint8_t channelPriorityHigh = handle->edmaTxDataToTxRegHandle->channel; + uint8_t t = 0; + + if (channelPriorityLow > channelPriorityHigh) + { + t = channelPriorityLow; + channelPriorityLow = channelPriorityHigh; + channelPriorityHigh = t; + } + + edma_channel_Preemption_config_t preemption_config_t; + preemption_config_t.enableChannelPreemption = true; + preemption_config_t.enablePreemptAbility = true; + preemption_config_t.channelPriority = channelPriorityLow; + + if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + EDMA_SetChannelPreemptionConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, + &preemption_config_t); + + preemption_config_t.channelPriority = channelPriorityHigh; + EDMA_SetChannelPreemptionConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, + &preemption_config_t); + } + else + { + EDMA_SetChannelPreemptionConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, + &preemption_config_t); + + preemption_config_t.channelPriority = channelPriorityHigh; + EDMA_SetChannelPreemptionConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, + &preemption_config_t); + } + + /*Set the channel link. + For DSPI instances with shared RX/TX DMA requests: Rx DMA request -> channel_A -> channel_C. + For DSPI instances with separate RX and TX DMA requests: + Rx DMA request -> channel_A + Tx DMA request -> channel_C */ + if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + if (handle->remainingSendByteCount > 0) + { + EDMA_SetChannelLink(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, + kEDMA_MinorLink, handle->edmaTxDataToTxRegHandle->channel); + } + DSPI_EnableDMA(base, kDSPI_RxDmaEnable); + } + else + { + DSPI_EnableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); + } + + return kStatus_Success; +} + +static void EDMA_DspiSlaveCallback(edma_handle_t *edmaHandle, + void *g_dspiEdmaPrivateHandle, + bool transferDone, + uint32_t tcds) +{ + assert(edmaHandle); + assert(g_dspiEdmaPrivateHandle); + + dspi_slave_edma_private_handle_t *dspiEdmaPrivateHandle; + + dspiEdmaPrivateHandle = (dspi_slave_edma_private_handle_t *)g_dspiEdmaPrivateHandle; + + DSPI_DisableDMA((dspiEdmaPrivateHandle->base), kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); + + if (dspiEdmaPrivateHandle->handle->callback) + { + dspiEdmaPrivateHandle->handle->callback(dspiEdmaPrivateHandle->base, dspiEdmaPrivateHandle->handle, + kStatus_Success, dspiEdmaPrivateHandle->handle->userData); + } + + dspiEdmaPrivateHandle->handle->state = kDSPI_Idle; +} + +void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle) +{ + assert(handle); + + DSPI_StopTransfer(base); + + DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); + + EDMA_AbortTransfer(handle->edmaRxRegToRxDataHandle); + EDMA_AbortTransfer(handle->edmaTxDataToTxRegHandle); + + handle->state = kDSPI_Idle; +} + +status_t DSPI_SlaveTransferGetCountEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (handle->state != kDSPI_Busy) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + size_t bytes; + + bytes = (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->edmaRxRegToRxDataHandle->base, + handle->edmaRxRegToRxDataHandle->channel); + + *count = handle->totalByteCount - bytes; + + return kStatus_Success; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi_edma.h new file mode 100644 index 00000000000..4b4dbd930ea --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_dspi_edma.h @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_DSPI_EDMA_H_ +#define _FSL_DSPI_EDMA_H_ + +#include "fsl_dspi.h" +#include "fsl_edma.h" +/*! + * @addtogroup dspi_edma_driver + * @{ + */ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! +* @brief Forward declaration of the DSPI eDMA master handle typedefs. +*/ +typedef struct _dspi_master_edma_handle dspi_master_edma_handle_t; + +/*! +* @brief Forward declaration of the DSPI eDMA slave handle typedefs. +*/ +typedef struct _dspi_slave_edma_handle dspi_slave_edma_handle_t; + +/*! + * @brief Completion callback function pointer type. + * + * @param base DSPI peripheral base address. + * @param handle A pointer to the handle for the DSPI master. + * @param status Success or error code describing whether the transfer completed. + * @param userData An arbitrary pointer-dataSized value passed from the application. + */ +typedef void (*dspi_master_edma_transfer_callback_t)(SPI_Type *base, + dspi_master_edma_handle_t *handle, + status_t status, + void *userData); +/*! + * @brief Completion callback function pointer type. + * + * @param base DSPI peripheral base address. + * @param handle A pointer to the handle for the DSPI slave. + * @param status Success or error code describing whether the transfer completed. + * @param userData An arbitrary pointer-dataSized value passed from the application. + */ +typedef void (*dspi_slave_edma_transfer_callback_t)(SPI_Type *base, + dspi_slave_edma_handle_t *handle, + status_t status, + void *userData); + +/*! @brief DSPI master eDMA transfer handle structure used for the transactional API. */ +struct _dspi_master_edma_handle +{ + uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */ + volatile uint32_t command; /*!< The desired data command. */ + volatile uint32_t lastCommand; /*!< The desired last data command. */ + + uint8_t fifoSize; /*!< FIFO dataSize. */ + + volatile bool + isPcsActiveAfterTransfer; /*!< Indicates whether the PCS signal keeps active after the last frame transfer.*/ + + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + volatile uint8_t state; /*!< DSPI transfer state , _dspi_transfer_state.*/ + + uint8_t *volatile txData; /*!< Send buffer. */ + uint8_t *volatile rxData; /*!< Receive buffer. */ + volatile size_t remainingSendByteCount; /*!< A number of bytes remaining to send.*/ + volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/ + size_t totalByteCount; /*!< A number of transfer bytes*/ + + uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/ + uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/ + + dspi_master_edma_transfer_callback_t callback; /*!< Completion callback. */ + void *userData; /*!< Callback user data. */ + + edma_handle_t *edmaRxRegToRxDataHandle; /*! 1U) +/*! @brief Array to map EDMA instance number to IRQ number. */ +static const IRQn_Type s_edmaIRQNumber[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = DMA_CHN_IRQS; +#endif + +/*! @brief Pointers to transfer handle for each EDMA channel. */ +static edma_handle_t *s_EDMAHandle[FSL_FEATURE_EDMA_MODULE_CHANNEL * FSL_FEATURE_SOC_EDMA_COUNT]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t EDMA_GetInstance(DMA_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_EDMA_COUNT; instance++) + { + if (s_edmaBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_EDMA_COUNT); + + return instance; +} + +static void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + + /* Push tcd into hardware TCD register */ + base->TCD[channel].SADDR = tcd->SADDR; + base->TCD[channel].SOFF = tcd->SOFF; + base->TCD[channel].ATTR = tcd->ATTR; + base->TCD[channel].NBYTES_MLNO = tcd->NBYTES; + base->TCD[channel].SLAST = tcd->SLAST; + base->TCD[channel].DADDR = tcd->DADDR; + base->TCD[channel].DOFF = tcd->DOFF; + base->TCD[channel].CITER_ELINKNO = tcd->CITER; + base->TCD[channel].DLAST_SGA = tcd->DLAST_SGA; + /* Clear DONE bit first, otherwise ESG cannot be set */ + base->TCD[channel].CSR = 0; + base->TCD[channel].CSR = tcd->CSR; + base->TCD[channel].BITER_ELINKNO = tcd->BITER; +} + +void EDMA_Init(DMA_Type *base, const edma_config_t *config) +{ + assert(config != NULL); + + uint32_t tmpreg; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate EDMA periphral clock */ + CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + /* Configure EDMA peripheral according to the configuration structure. */ + tmpreg = base->CR; + tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); + tmpreg |= (DMA_CR_ERCA(config->enableRoundRobinArbitration) | DMA_CR_HOE(config->enableHaltOnError) | + DMA_CR_CLM(config->enableContinuousLinkMode) | DMA_CR_EDBG(config->enableDebugMode) | DMA_CR_EMLM(true)); + base->CR = tmpreg; +} + +void EDMA_Deinit(DMA_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate EDMA periphral clock */ + CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void EDMA_GetDefaultConfig(edma_config_t *config) +{ + assert(config != NULL); + + config->enableRoundRobinArbitration = false; + config->enableHaltOnError = true; + config->enableContinuousLinkMode = false; + config->enableDebugMode = false; +} + +void EDMA_ResetChannel(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + EDMA_TcdReset((edma_tcd_t *)&base->TCD[channel]); +} + +void EDMA_SetTransferConfig(DMA_Type *base, uint32_t channel, const edma_transfer_config_t *config, edma_tcd_t *nextTcd) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + assert(config != NULL); + assert(((uint32_t)nextTcd & 0x1FU) == 0); + + EDMA_TcdSetTransferConfig((edma_tcd_t *)&base->TCD[channel], config, nextTcd); +} + +void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + assert(config != NULL); + + uint32_t tmpreg; + + tmpreg = base->TCD[channel].NBYTES_MLOFFYES; + tmpreg &= ~(DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK | DMA_NBYTES_MLOFFYES_MLOFF_MASK); + tmpreg |= + (DMA_NBYTES_MLOFFYES_SMLOE(config->enableSrcMinorOffset) | + DMA_NBYTES_MLOFFYES_DMLOE(config->enableDestMinorOffset) | DMA_NBYTES_MLOFFYES_MLOFF(config->minorOffset)); + base->TCD[channel].NBYTES_MLOFFYES = tmpreg; +} + +void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + assert(linkedChannel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + EDMA_TcdSetChannelLink((edma_tcd_t *)&base->TCD[channel], type, linkedChannel); +} + +void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + base->TCD[channel].CSR = (base->TCD[channel].CSR & (~DMA_CSR_BWC_MASK)) | DMA_CSR_BWC(bandWidth); +} + +void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + uint32_t tmpreg; + + tmpreg = base->TCD[channel].ATTR & (~(DMA_ATTR_SMOD_MASK | DMA_ATTR_DMOD_MASK)); + base->TCD[channel].ATTR = tmpreg | DMA_ATTR_DMOD(destModulo) | DMA_ATTR_SMOD(srcModulo); +} + +void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + /* Enable error interrupt */ + if (mask & kEDMA_ErrorInterruptEnable) + { + base->EEI |= (0x1U << channel); + } + + /* Enable Major interrupt */ + if (mask & kEDMA_MajorInterruptEnable) + { + base->TCD[channel].CSR |= DMA_CSR_INTMAJOR_MASK; + } + + /* Enable Half major interrupt */ + if (mask & kEDMA_HalfInterruptEnable) + { + base->TCD[channel].CSR |= DMA_CSR_INTHALF_MASK; + } +} + +void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + /* Disable error interrupt */ + if (mask & kEDMA_ErrorInterruptEnable) + { + base->EEI &= ~(0x1U << channel); + } + + /* Disable Major interrupt */ + if (mask & kEDMA_MajorInterruptEnable) + { + base->TCD[channel].CSR &= ~DMA_CSR_INTMAJOR_MASK; + } + + /* Disable Half major interrupt */ + if (mask & kEDMA_HalfInterruptEnable) + { + base->TCD[channel].CSR &= ~DMA_CSR_INTHALF_MASK; + } +} + +void EDMA_TcdReset(edma_tcd_t *tcd) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + + /* Reset channel TCD */ + tcd->SADDR = 0U; + tcd->SOFF = 0U; + tcd->ATTR = 0U; + tcd->NBYTES = 0U; + tcd->SLAST = 0U; + tcd->DADDR = 0U; + tcd->DOFF = 0U; + tcd->CITER = 0U; + tcd->DLAST_SGA = 0U; + /* Enable auto disable request feature */ + tcd->CSR = DMA_CSR_DREQ(true); + tcd->BITER = 0U; +} + +void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + assert(config != NULL); + assert(((uint32_t)nextTcd & 0x1FU) == 0); + + /* source address */ + tcd->SADDR = config->srcAddr; + /* destination address */ + tcd->DADDR = config->destAddr; + /* Source data and destination data transfer size */ + tcd->ATTR = DMA_ATTR_SSIZE(config->srcTransferSize) | DMA_ATTR_DSIZE(config->destTransferSize); + /* Source address signed offset */ + tcd->SOFF = config->srcOffset; + /* Destination address signed offset */ + tcd->DOFF = config->destOffset; + /* Minor byte transfer count */ + tcd->NBYTES = config->minorLoopBytes; + /* Current major iteration count */ + tcd->CITER = config->majorLoopCounts; + /* Starting major iteration count */ + tcd->BITER = config->majorLoopCounts; + /* Enable scatter/gather processing */ + if (nextTcd != NULL) + { + tcd->DLAST_SGA = (uint32_t)nextTcd; + /* + Before call EDMA_TcdSetTransferConfig or EDMA_SetTransferConfig, + user must call EDMA_TcdReset or EDMA_ResetChannel which will set + DREQ, so must use "|" or "&" rather than "=". + + Clear the DREQ bit because scatter gather has been enabled, so the + previous transfer is not the last transfer, and channel request should + be enabled at the next transfer(the next TCD). + */ + tcd->CSR = (tcd->CSR | DMA_CSR_ESG_MASK) & ~DMA_CSR_DREQ_MASK; + } +} + +void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + + uint32_t tmpreg; + + tmpreg = tcd->NBYTES & + ~(DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK | DMA_NBYTES_MLOFFYES_MLOFF_MASK); + tmpreg |= + (DMA_NBYTES_MLOFFYES_SMLOE(config->enableSrcMinorOffset) | + DMA_NBYTES_MLOFFYES_DMLOE(config->enableDestMinorOffset) | DMA_NBYTES_MLOFFYES_MLOFF(config->minorOffset)); + tcd->NBYTES = tmpreg; +} + +void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint32_t linkedChannel) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + assert(linkedChannel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + if (type == kEDMA_MinorLink) /* Minor link config */ + { + uint32_t tmpreg; + + /* Enable minor link */ + tcd->CITER |= DMA_CITER_ELINKYES_ELINK_MASK; + tcd->BITER |= DMA_BITER_ELINKYES_ELINK_MASK; + /* Set likned channel */ + tmpreg = tcd->CITER & (~DMA_CITER_ELINKYES_LINKCH_MASK); + tmpreg |= DMA_CITER_ELINKYES_LINKCH(linkedChannel); + tcd->CITER = tmpreg; + tmpreg = tcd->BITER & (~DMA_BITER_ELINKYES_LINKCH_MASK); + tmpreg |= DMA_BITER_ELINKYES_LINKCH(linkedChannel); + tcd->BITER = tmpreg; + } + else if (type == kEDMA_MajorLink) /* Major link config */ + { + uint32_t tmpreg; + + /* Enable major link */ + tcd->CSR |= DMA_CSR_MAJORELINK_MASK; + /* Set major linked channel */ + tmpreg = tcd->CSR & (~DMA_CSR_MAJORLINKCH_MASK); + tcd->CSR = tmpreg | DMA_CSR_MAJORLINKCH(linkedChannel); + } + else /* Link none */ + { + tcd->CITER &= ~DMA_CITER_ELINKYES_ELINK_MASK; + tcd->BITER &= ~DMA_BITER_ELINKYES_ELINK_MASK; + tcd->CSR &= ~DMA_CSR_MAJORELINK_MASK; + } +} + +void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + + uint32_t tmpreg; + + tmpreg = tcd->ATTR & (~(DMA_ATTR_SMOD_MASK | DMA_ATTR_DMOD_MASK)); + tcd->ATTR = tmpreg | DMA_ATTR_DMOD(destModulo) | DMA_ATTR_SMOD(srcModulo); +} + +void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask) +{ + assert(tcd != NULL); + + /* Enable Major interrupt */ + if (mask & kEDMA_MajorInterruptEnable) + { + tcd->CSR |= DMA_CSR_INTMAJOR_MASK; + } + + /* Enable Half major interrupt */ + if (mask & kEDMA_HalfInterruptEnable) + { + tcd->CSR |= DMA_CSR_INTHALF_MASK; + } +} + +void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask) +{ + assert(tcd != NULL); + + /* Disable Major interrupt */ + if (mask & kEDMA_MajorInterruptEnable) + { + tcd->CSR &= ~DMA_CSR_INTMAJOR_MASK; + } + + /* Disable Half major interrupt */ + if (mask & kEDMA_HalfInterruptEnable) + { + tcd->CSR &= ~DMA_CSR_INTHALF_MASK; + } +} + +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + uint32_t remainingCount = 0; + + if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR) + { + remainingCount = 0; + } + else + { + /* Calculate the unfinished bytes */ + if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK) + { + remainingCount = + (base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> DMA_CITER_ELINKYES_CITER_SHIFT; + } + else + { + remainingCount = + (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT; + } + } + + return remainingCount; +} + +uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + uint32_t retval = 0; + + /* Get DONE bit flag */ + retval |= ((base->TCD[channel].CSR & DMA_CSR_DONE_MASK) >> DMA_CSR_DONE_SHIFT); + /* Get ERROR bit flag */ + retval |= (((base->ERR >> channel) & 0x1U) << 1U); + /* Get INT bit flag */ + retval |= (((base->INT >> channel) & 0x1U) << 2U); + + return retval; +} + +void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + /* Clear DONE bit flag */ + if (mask & kEDMA_DoneFlag) + { + base->CDNE = channel; + } + /* Clear ERROR bit flag */ + if (mask & kEDMA_ErrorFlag) + { + base->CERR = channel; + } + /* Clear INT bit flag */ + if (mask & kEDMA_InterruptFlag) + { + base->CINT = channel; + } +} + +void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel) +{ + assert(handle != NULL); + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + uint32_t edmaInstance; + uint32_t channelIndex; + edma_tcd_t *tcdRegs; + + handle->base = base; + handle->channel = channel; + /* Get the DMA instance number */ + edmaInstance = EDMA_GetInstance(base); + channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; + s_EDMAHandle[channelIndex] = handle; +#if defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT == 1U) + /* Enable NVIC interrupt */ + EnableIRQ(s_edmaIRQNumber[channel]); +#elif defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 1U) + /* Enable NVIC interrupt */ + EnableIRQ(s_edmaIRQNumber[edmaInstance][channel]); +#endif + /* + Reset TCD registers to zero. Unlike the EDMA_TcdReset(DREQ will be set), + CSR will be 0. Because in order to suit EDMA busy check mechanism in + EDMA_SubmitTransfer, CSR must be set 0. + */ + tcdRegs = (edma_tcd_t *)&handle->base->TCD[handle->channel]; + tcdRegs->SADDR = 0; + tcdRegs->SOFF = 0; + tcdRegs->ATTR = 0; + tcdRegs->NBYTES = 0; + tcdRegs->SLAST = 0; + tcdRegs->DADDR = 0; + tcdRegs->DOFF = 0; + tcdRegs->CITER = 0; + tcdRegs->DLAST_SGA = 0; + tcdRegs->CSR = 0; + tcdRegs->BITER = 0; +} + +void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize) +{ + assert(handle != NULL); + assert(((uint32_t)tcdPool & 0x1FU) == 0); + + /* Initialize tcd queue attibute. */ + handle->header = 0; + handle->tail = 0; + handle->tcdUsed = 0; + handle->tcdSize = tcdSize; + handle->flags = 0; + handle->tcdPool = tcdPool; +} + +void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData) +{ + assert(handle != NULL); + + handle->callback = callback; + handle->userData = userData; +} + +void EDMA_PrepareTransfer(edma_transfer_config_t *config, + void *srcAddr, + uint32_t srcWidth, + void *destAddr, + uint32_t destWidth, + uint32_t bytesEachRequest, + uint32_t transferBytes, + edma_transfer_type_t type) +{ + assert(config != NULL); + assert(srcAddr != NULL); + assert(destAddr != NULL); + assert((srcWidth == 1U) || (srcWidth == 2U) || (srcWidth == 4U) || (srcWidth == 16U) || (srcWidth == 32U)); + assert((destWidth == 1U) || (destWidth == 2U) || (destWidth == 4U) || (destWidth == 16U) || (destWidth == 32U)); + assert(transferBytes % bytesEachRequest == 0); + + config->destAddr = (uint32_t)destAddr; + config->srcAddr = (uint32_t)srcAddr; + config->minorLoopBytes = bytesEachRequest; + config->majorLoopCounts = transferBytes / bytesEachRequest; + switch (srcWidth) + { + case 1U: + config->srcTransferSize = kEDMA_TransferSize1Bytes; + break; + case 2U: + config->srcTransferSize = kEDMA_TransferSize2Bytes; + break; + case 4U: + config->srcTransferSize = kEDMA_TransferSize4Bytes; + break; + case 16U: + config->srcTransferSize = kEDMA_TransferSize16Bytes; + break; + case 32U: + config->srcTransferSize = kEDMA_TransferSize32Bytes; + break; + default: + break; + } + switch (destWidth) + { + case 1U: + config->destTransferSize = kEDMA_TransferSize1Bytes; + break; + case 2U: + config->destTransferSize = kEDMA_TransferSize2Bytes; + break; + case 4U: + config->destTransferSize = kEDMA_TransferSize4Bytes; + break; + case 16U: + config->destTransferSize = kEDMA_TransferSize16Bytes; + break; + case 32U: + config->destTransferSize = kEDMA_TransferSize32Bytes; + break; + default: + break; + } + switch (type) + { + case kEDMA_MemoryToMemory: + config->destOffset = destWidth; + config->srcOffset = srcWidth; + break; + case kEDMA_MemoryToPeripheral: + config->destOffset = 0U; + config->srcOffset = srcWidth; + break; + case kEDMA_PeripheralToMemory: + config->destOffset = destWidth; + config->srcOffset = 0U; + break; + default: + break; + } +} + +status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config) +{ + assert(handle != NULL); + assert(config != NULL); + + edma_tcd_t *tcdRegs = (edma_tcd_t *)&handle->base->TCD[handle->channel]; + + if (handle->tcdPool == NULL) + { + /* + Check if EDMA is busy: if the given channel started transfer, CSR will be not zero. Because + if it is the last transfer, DREQ will be set. If not, ESG will be set. So in order to suit + this check mechanism, EDMA_CreatHandle will clear CSR register. + */ + if ((tcdRegs->CSR != 0) && ((tcdRegs->CSR & DMA_CSR_DONE_MASK) == 0)) + { + return kStatus_EDMA_Busy; + } + else + { + EDMA_SetTransferConfig(handle->base, handle->channel, config, NULL); + /* Enable auto disable request feature */ + handle->base->TCD[handle->channel].CSR |= DMA_CSR_DREQ_MASK; + /* Enable major interrupt */ + handle->base->TCD[handle->channel].CSR |= DMA_CSR_INTMAJOR_MASK; + + return kStatus_Success; + } + } + else /* Use the TCD queue. */ + { + uint32_t primask; + uint32_t csr; + int8_t currentTcd; + int8_t previousTcd; + int8_t nextTcd; + + /* Check if tcd pool is full. */ + primask = DisableGlobalIRQ(); + if (handle->tcdUsed >= handle->tcdSize) + { + EnableGlobalIRQ(primask); + + return kStatus_EDMA_QueueFull; + } + currentTcd = handle->tail; + handle->tcdUsed++; + /* Calculate index of next TCD */ + nextTcd = currentTcd + 1U; + if (nextTcd == handle->tcdSize) + { + nextTcd = 0U; + } + /* Advance queue tail index */ + handle->tail = nextTcd; + EnableGlobalIRQ(primask); + /* Calculate index of previous TCD */ + previousTcd = currentTcd ? currentTcd - 1U : handle->tcdSize - 1U; + /* Configure current TCD block. */ + EDMA_TcdReset(&handle->tcdPool[currentTcd]); + EDMA_TcdSetTransferConfig(&handle->tcdPool[currentTcd], config, NULL); + /* Enable major interrupt */ + handle->tcdPool[currentTcd].CSR |= DMA_CSR_INTMAJOR_MASK; + /* Link current TCD with next TCD for identification of current TCD */ + handle->tcdPool[currentTcd].DLAST_SGA = (uint32_t)&handle->tcdPool[nextTcd]; + /* Chain from previous descriptor unless tcd pool size is 1(this descriptor is its own predecessor). */ + if (currentTcd != previousTcd) + { + /* Enable scatter/gather feature in the previous TCD block. */ + csr = (handle->tcdPool[previousTcd].CSR | DMA_CSR_ESG_MASK) & ~DMA_CSR_DREQ_MASK; + handle->tcdPool[previousTcd].CSR = csr; + /* + Check if the TCD blcok in the registers is the previous one (points to current TCD block). It + is used to check if the previous TCD linked has been loaded in TCD register. If so, it need to + link the TCD register in case link the current TCD with the dead chain when TCD loading occurs + before link the previous TCD block. + */ + if (tcdRegs->DLAST_SGA == (uint32_t)&handle->tcdPool[currentTcd]) + { + /* Enable scatter/gather also in the TCD registers. */ + csr = (tcdRegs->CSR | DMA_CSR_ESG_MASK) & ~DMA_CSR_DREQ_MASK; + /* Must write the CSR register one-time, because the transfer maybe finished anytime. */ + tcdRegs->CSR = csr; + /* + It is very important to check the ESG bit! + Because this hardware design: if DONE bit is set, the ESG bit can not be set. So it can + be used to check if the dynamic TCD link operation is successful. If ESG bit is not set + and the DLAST_SGA is not the next TCD address(it means the dynamic TCD link succeed and + the current TCD block has been loaded into TCD registers), it means transfer finished + and TCD link operation fail, so must install TCD content into TCD registers and enable + transfer again. And if ESG is set, it means transfer has notfinished, so TCD dynamic + link succeed. + */ + if (tcdRegs->CSR & DMA_CSR_ESG_MASK) + { + return kStatus_Success; + } + /* + Check whether the current TCD block is already loaded in the TCD registers. It is another + condition when ESG bit is not set: it means the dynamic TCD link succeed and the current + TCD block has been loaded into TCD registers. + */ + if (tcdRegs->DLAST_SGA == (uint32_t)&handle->tcdPool[nextTcd]) + { + return kStatus_Success; + } + /* + If go to this, means the previous transfer finished, and the DONE bit is set. + So shall configure TCD registers. + */ + } + else if (tcdRegs->DLAST_SGA != 0) + { + /* The current TCD block has been linked successfully. */ + return kStatus_Success; + } + else + { + /* + DLAST_SGA is 0 and it means the first submit transfer, so shall configure + TCD registers. + */ + } + } + /* There is no live chain, TCD block need to be installed in TCD registers. */ + EDMA_InstallTCD(handle->base, handle->channel, &handle->tcdPool[currentTcd]); + /* Enable channel request again. */ + if (handle->flags & EDMA_TRANSFER_ENABLED_MASK) + { + handle->base->SERQ = DMA_SERQ_SERQ(handle->channel); + } + + return kStatus_Success; + } +} + +void EDMA_StartTransfer(edma_handle_t *handle) +{ + assert(handle != NULL); + + if (handle->tcdPool == NULL) + { + handle->base->SERQ = DMA_SERQ_SERQ(handle->channel); + } + else /* Use the TCD queue. */ + { + uint32_t primask; + edma_tcd_t *tcdRegs = (edma_tcd_t *)&handle->base->TCD[handle->channel]; + + handle->flags |= EDMA_TRANSFER_ENABLED_MASK; + + /* Check if there was at least one descriptor submitted since reset (TCD in registers is valid) */ + if (tcdRegs->DLAST_SGA != 0U) + { + primask = DisableGlobalIRQ(); + /* Check if channel request is actually disable. */ + if ((handle->base->ERQ & (1U << handle->channel)) == 0U) + { + /* Check if transfer is paused. */ + if ((!(tcdRegs->CSR & DMA_CSR_DONE_MASK)) || (tcdRegs->CSR & DMA_CSR_ESG_MASK)) + { + /* + Re-enable channel request must be as soon as possible, so must put it into + critical section to avoid task switching or interrupt service routine. + */ + handle->base->SERQ = DMA_SERQ_SERQ(handle->channel); + } + } + EnableGlobalIRQ(primask); + } + } +} + +void EDMA_StopTransfer(edma_handle_t *handle) +{ + assert(handle != NULL); + + handle->flags &= (~EDMA_TRANSFER_ENABLED_MASK); + handle->base->CERQ = DMA_CERQ_CERQ(handle->channel); +} + +void EDMA_AbortTransfer(edma_handle_t *handle) +{ + handle->base->CERQ = DMA_CERQ_CERQ(handle->channel); + /* + Clear CSR to release channel. Because if the given channel started transfer, + CSR will be not zero. Because if it is the last transfer, DREQ will be set. + If not, ESG will be set. + */ + handle->base->TCD[handle->channel].CSR = 0; + /* Cancel all next TCD transfer. */ + handle->base->TCD[handle->channel].DLAST_SGA = 0; +} + +void EDMA_HandleIRQ(edma_handle_t *handle) +{ + assert(handle != NULL); + + /* Clear EDMA interrupt flag */ + handle->base->CINT = handle->channel; + if ((handle->tcdPool == NULL) && (handle->callback != NULL)) + { + (handle->callback)(handle, handle->userData, true, 0); + } + else /* Use the TCD queue. Please refer to the API descriptions in the eDMA header file for detailed information. */ + { + uint32_t sga = handle->base->TCD[handle->channel].DLAST_SGA; + uint32_t sga_index; + int32_t tcds_done; + uint8_t new_header; + bool transfer_done; + + /* Check if transfer is already finished. */ + transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0); + /* Get the offset of the next transfer TCD blcoks to be loaded into the eDMA engine. */ + sga -= (uint32_t)handle->tcdPool; + /* Get the index of the next transfer TCD blcoks to be loaded into the eDMA engine. */ + sga_index = sga / sizeof(edma_tcd_t); + /* Adjust header positions. */ + if (transfer_done) + { + /* New header shall point to the next TCD to be loaded (current one is already finished) */ + new_header = sga_index; + } + else + { + /* New header shall point to this descriptor currently loaded (not finished yet) */ + new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U; + } + /* Calculate the number of finished TCDs */ + if (new_header == handle->header) + { + if (handle->tcdUsed == handle->tcdSize) + { + tcds_done = handle->tcdUsed; + } + else + { + /* No TCD in the memory are going to be loaded or internal error occurs. */ + tcds_done = 0; + } + } + else + { + tcds_done = new_header - handle->header; + if (tcds_done < 0) + { + tcds_done += handle->tcdSize; + } + } + /* Advance header which points to the TCD to be loaded into the eDMA engine from memory. */ + handle->header = new_header; + /* Release TCD blocks. tcdUsed is the TCD number which can be used/loaded in the memory pool. */ + handle->tcdUsed -= tcds_done; + /* Invoke callback function. */ + if (handle->callback) + { + (handle->callback)(handle, handle->userData, transfer_done, tcds_done); + } + } +} + +/* 8 channels (Shared): kl28 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 8U + +void DMA0_04_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } +} + +void DMA0_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } +} + +void DMA0_26_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } +} + +void DMA0_37_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } +} + +#if defined(DMA1) +void DMA1_04_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA1_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA1_26_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA1_37_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} +#endif +#endif /* 8 channels (Shared) */ + +/* 16 channels (Shared): K32H844P */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 16U + +void DMA0_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } +} + +void DMA0_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } +} + +void DMA0_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } +} + +void DMA0_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } +} + +void DMA0_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA0_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA0_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA0_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} + +#if defined(DMA1) +void DMA1_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } +} + +void DMA1_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } +} + +void DMA1_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } +} + +void DMA1_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } +} + +void DMA1_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA1_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA1_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA1_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif +#endif /* 16 channels (Shared) */ + +/* 32 channels (Shared): k80 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U + +void DMA0_DMA16_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } +} + +void DMA1_DMA17_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } +} + +void DMA2_DMA18_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } +} + +void DMA3_DMA19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } +} + +void DMA4_DMA20_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } +} + +void DMA5_DMA21_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } +} + +void DMA6_DMA22_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } +} + +void DMA7_DMA23_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } +} + +void DMA8_DMA24_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } +} + +void DMA9_DMA25_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } +} + +void DMA10_DMA26_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } +} + +void DMA11_DMA27_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } +} + +void DMA12_DMA28_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA13_DMA29_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA14_DMA30_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA15_DMA31_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif /* 32 channels (Shared) */ + +/* 32 channels (Shared): MCIMX7U5_M4 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U + +void DMA0_0_4_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } +} + +void DMA0_1_5_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } +} + +void DMA0_2_6_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } +} + +void DMA0_3_7_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } +} + +void DMA0_8_12_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA0_9_13_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA0_10_14_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA0_11_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} + +void DMA0_16_20_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } +} + +void DMA0_17_21_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } +} + +void DMA0_18_22_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } +} + +void DMA0_19_23_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } +} + +void DMA0_24_28_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA0_25_29_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA0_26_30_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA0_27_31_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif /* 32 channels (Shared): MCIMX7U5 */ + +/* 4 channels (No Shared): kv10 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0 + +void DMA0_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[0]); +} + +void DMA1_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[1]); +} + +void DMA2_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[2]); +} + +void DMA3_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[3]); +} + +/* 8 channels (No Shared) */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 4U + +void DMA4_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[4]); +} + +void DMA5_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[5]); +} + +void DMA6_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[6]); +} + +void DMA7_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[7]); +} +#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL == 8 */ + +/* 16 channels (No Shared) */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 8U + +void DMA8_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[8]); +} + +void DMA9_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[9]); +} + +void DMA10_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[10]); +} + +void DMA11_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[11]); +} + +void DMA12_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[12]); +} + +void DMA13_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[13]); +} + +void DMA14_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[14]); +} + +void DMA15_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[15]); +} +#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL == 16 */ + +/* 32 channels (No Shared) */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 16U + +void DMA16_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[16]); +} + +void DMA17_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[17]); +} + +void DMA18_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[18]); +} + +void DMA19_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[19]); +} + +void DMA20_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[20]); +} + +void DMA21_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[21]); +} + +void DMA22_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[22]); +} + +void DMA23_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[23]); +} + +void DMA24_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[24]); +} + +void DMA25_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[25]); +} + +void DMA26_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[26]); +} + +void DMA27_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[27]); +} + +void DMA28_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[28]); +} + +void DMA29_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[29]); +} + +void DMA30_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[30]); +} + +void DMA31_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[31]); +} +#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL == 32 */ + +#endif /* 4/8/16/32 channels (No Shared) */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_edma.h new file mode 100644 index 00000000000..52760a9cd18 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_edma.h @@ -0,0 +1,910 @@ +/* +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _FSL_EDMA_H_ +#define _FSL_EDMA_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup edma + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief eDMA driver version */ +#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1. */ +/*@}*/ + +/*! @brief Compute the offset unit from DCHPRI3 */ +#define DMA_DCHPRI_INDEX(channel) (((channel) & ~0x03U) | (3 - ((channel)&0x03U))) + +/*! @brief Get the pointer of DCHPRIn */ +#define DMA_DCHPRIn(base, channel) ((volatile uint8_t *)&(base->DCHPRI3))[DMA_DCHPRI_INDEX(channel)] + +/*! @brief eDMA transfer configuration */ +typedef enum _edma_transfer_size +{ + kEDMA_TransferSize1Bytes = 0x0U, /*!< Source/Destination data transfer size is 1 byte every time */ + kEDMA_TransferSize2Bytes = 0x1U, /*!< Source/Destination data transfer size is 2 bytes every time */ + kEDMA_TransferSize4Bytes = 0x2U, /*!< Source/Destination data transfer size is 4 bytes every time */ + kEDMA_TransferSize16Bytes = 0x4U, /*!< Source/Destination data transfer size is 16 bytes every time */ + kEDMA_TransferSize32Bytes = 0x5U, /*!< Source/Destination data transfer size is 32 bytes every time */ +} edma_transfer_size_t; + +/*! @brief eDMA modulo configuration */ +typedef enum _edma_modulo +{ + kEDMA_ModuloDisable = 0x0U, /*!< Disable modulo */ + kEDMA_Modulo2bytes, /*!< Circular buffer size is 2 bytes. */ + kEDMA_Modulo4bytes, /*!< Circular buffer size is 4 bytes. */ + kEDMA_Modulo8bytes, /*!< Circular buffer size is 8 bytes. */ + kEDMA_Modulo16bytes, /*!< Circular buffer size is 16 bytes. */ + kEDMA_Modulo32bytes, /*!< Circular buffer size is 32 bytes. */ + kEDMA_Modulo64bytes, /*!< Circular buffer size is 64 bytes. */ + kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */ + kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */ + kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */ + kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1 K bytes. */ + kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2 K bytes. */ + kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4 K bytes. */ + kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8 K bytes. */ + kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16 K bytes. */ + kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32 K bytes. */ + kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64 K bytes. */ + kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128 K bytes. */ + kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256 K bytes. */ + kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512 K bytes. */ + kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1 M bytes. */ + kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2 M bytes. */ + kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4 M bytes. */ + kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8 M bytes. */ + kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16 M bytes. */ + kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32 M bytes. */ + kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64 M bytes. */ + kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128 M bytes. */ + kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256 M bytes. */ + kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512 M bytes. */ + kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1 G bytes. */ + kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2 G bytes. */ +} edma_modulo_t; + +/*! @brief Bandwidth control */ +typedef enum _edma_bandwidth +{ + kEDMA_BandwidthStallNone = 0x0U, /*!< No eDMA engine stalls. */ + kEDMA_BandwidthStall4Cycle = 0x2U, /*!< eDMA engine stalls for 4 cycles after each read/write. */ + kEDMA_BandwidthStall8Cycle = 0x3U, /*!< eDMA engine stalls for 8 cycles after each read/write. */ +} edma_bandwidth_t; + +/*! @brief Channel link type */ +typedef enum _edma_channel_link_type +{ + kEDMA_LinkNone = 0x0U, /*!< No channel link */ + kEDMA_MinorLink, /*!< Channel link after each minor loop */ + kEDMA_MajorLink, /*!< Channel link while major loop count exhausted */ +} edma_channel_link_type_t; + +/*!@brief eDMA channel status flags. */ +enum _edma_channel_status_flags +{ + kEDMA_DoneFlag = 0x1U, /*!< DONE flag, set while transfer finished, CITER value exhausted*/ + kEDMA_ErrorFlag = 0x2U, /*!< eDMA error flag, an error occurred in a transfer */ + kEDMA_InterruptFlag = 0x4U, /*!< eDMA interrupt flag, set while an interrupt occurred of this channel */ +}; + +/*! @brief eDMA channel error status flags. */ +enum _edma_error_status_flags +{ + kEDMA_DestinationBusErrorFlag = DMA_ES_DBE_MASK, /*!< Bus error on destination address */ + kEDMA_SourceBusErrorFlag = DMA_ES_SBE_MASK, /*!< Bus error on the source address */ + kEDMA_ScatterGatherErrorFlag = DMA_ES_SGE_MASK, /*!< Error on the Scatter/Gather address, not 32byte aligned. */ + kEDMA_NbytesErrorFlag = DMA_ES_NCE_MASK, /*!< NBYTES/CITER configuration error */ + kEDMA_DestinationOffsetErrorFlag = DMA_ES_DOE_MASK, /*!< Destination offset not aligned with destination size */ + kEDMA_DestinationAddressErrorFlag = DMA_ES_DAE_MASK, /*!< Destination address not aligned with destination size */ + kEDMA_SourceOffsetErrorFlag = DMA_ES_SOE_MASK, /*!< Source offset not aligned with source size */ + kEDMA_SourceAddressErrorFlag = DMA_ES_SAE_MASK, /*!< Source address not aligned with source size*/ + kEDMA_ErrorChannelFlag = DMA_ES_ERRCHN_MASK, /*!< Error channel number of the cancelled channel number */ + kEDMA_ChannelPriorityErrorFlag = DMA_ES_CPE_MASK, /*!< Channel priority is not unique. */ + kEDMA_TransferCanceledFlag = DMA_ES_ECX_MASK, /*!< Transfer cancelled */ +#if defined(FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT) && FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 1 + kEDMA_GroupPriorityErrorFlag = DMA_ES_GPE_MASK, /*!< Group priority is not unique. */ +#endif + kEDMA_ValidFlag = DMA_ES_VLD_MASK, /*!< No error occurred, this bit is 0. Otherwise, it is 1. */ +}; + +/*! @brief eDMA interrupt source */ +typedef enum _edma_interrupt_enable +{ + kEDMA_ErrorInterruptEnable = 0x1U, /*!< Enable interrupt while channel error occurs. */ + kEDMA_MajorInterruptEnable = DMA_CSR_INTMAJOR_MASK, /*!< Enable interrupt while major count exhausted. */ + kEDMA_HalfInterruptEnable = DMA_CSR_INTHALF_MASK, /*!< Enable interrupt while major count to half value. */ +} edma_interrupt_enable_t; + +/*! @brief eDMA transfer type */ +typedef enum _edma_transfer_type +{ + kEDMA_MemoryToMemory = 0x0U, /*!< Transfer from memory to memory */ + kEDMA_PeripheralToMemory, /*!< Transfer from peripheral to memory */ + kEDMA_MemoryToPeripheral, /*!< Transfer from memory to peripheral */ +} edma_transfer_type_t; + +/*! @brief eDMA transfer status */ +enum _edma_transfer_status +{ + kStatus_EDMA_QueueFull = MAKE_STATUS(kStatusGroup_EDMA, 0), /*!< TCD queue is full. */ + kStatus_EDMA_Busy = MAKE_STATUS(kStatusGroup_EDMA, 1), /*!< Channel is busy and can't handle the + transfer request. */ +}; + +/*! @brief eDMA global configuration structure.*/ +typedef struct _edma_config +{ + bool enableContinuousLinkMode; /*!< Enable (true) continuous link mode. Upon minor loop completion, the channel + activates again if that channel has a minor loop channel link enabled and + the link channel is itself. */ + bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. + Subsequently, all service requests are ignored until the HALT bit is cleared.*/ + bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method or fixed priority + arbitration is used for channel selection */ + bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of + a new channel. Executing channels are allowed to complete. */ +} edma_config_t; + +/*! + * @brief eDMA transfer configuration + * + * This structure configures the source/destination transfer attribute. + * This figure shows the eDMA's transfer model: + * _________________________________________________ + * | Transfer Size | | + * Minor Loop |_______________| Major loop Count 1 | + * Bytes | Transfer Size | | + * ____________|_______________|____________________|--> Minor loop complete + * ____________________________________ + * | | | + * |_______________| Major Loop Count 2 | + * | | | + * |_______________|____________________|--> Minor loop Complete + * + * ---------------------------------------------------------> Transfer complete + */ +typedef struct _edma_transfer_config +{ + uint32_t srcAddr; /*!< Source data address. */ + uint32_t destAddr; /*!< Destination data address. */ + edma_transfer_size_t srcTransferSize; /*!< Source data transfer size. */ + edma_transfer_size_t destTransferSize; /*!< Destination data transfer size. */ + int16_t srcOffset; /*!< Sign-extended offset applied to the current source address to + form the next-state value as each source read is completed. */ + int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to + form the next-state value as each destination write is completed. */ + uint32_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ + uint32_t majorLoopCounts; /*!< Major loop iteration count. */ +} edma_transfer_config_t; + +/*! @brief eDMA channel priority configuration */ +typedef struct _edma_channel_Preemption_config +{ + bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */ + bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */ + uint8_t channelPriority; /*!< Channel priority */ +} edma_channel_Preemption_config_t; + +/*! @brief eDMA minor offset configuration */ +typedef struct _edma_minor_offset_config +{ + bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */ + bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */ + uint32_t minorOffset; /*!< Offset for a minor loop mapping. */ +} edma_minor_offset_config_t; + +/*! + * @brief eDMA TCD. + * + * This structure is same as TCD register which is described in reference manual, + * and is used to configure the scatter/gather feature as a next hardware TCD. + */ +typedef struct _edma_tcd +{ + __IO uint32_t SADDR; /*!< SADDR register, used to save source address */ + __IO uint16_t SOFF; /*!< SOFF register, save offset bytes every transfer */ + __IO uint16_t ATTR; /*!< ATTR register, source/destination transfer size and modulo */ + __IO uint32_t NBYTES; /*!< Nbytes register, minor loop length in bytes */ + __IO uint32_t SLAST; /*!< SLAST register */ + __IO uint32_t DADDR; /*!< DADDR register, used for destination address */ + __IO uint16_t DOFF; /*!< DOFF register, used for destination offset */ + __IO uint16_t CITER; /*!< CITER register, current minor loop numbers, for unfinished minor loop.*/ + __IO uint32_t DLAST_SGA; /*!< DLASTSGA register, next stcd address used in scatter-gather mode */ + __IO uint16_t CSR; /*!< CSR register, for TCD control status */ + __IO uint16_t BITER; /*!< BITER register, begin minor loop count. */ +} edma_tcd_t; + +/*! @brief Callback for eDMA */ +struct _edma_handle; + +/*! @brief Define callback function for eDMA. */ +typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds); + +/*! @brief eDMA transfer handle structure */ +typedef struct _edma_handle +{ + edma_callback callback; /*!< Callback function for major count exhausted. */ + void *userData; /*!< Callback function parameter. */ + DMA_Type *base; /*!< eDMA peripheral base address. */ + edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ + uint8_t channel; /*!< eDMA channel number. */ + volatile int8_t header; /*!< The first TCD index. Should point to the next TCD to be loaded into the eDMA engine. */ + volatile int8_t tail; /*!< The last TCD index. Should point to the next TCD to be stored into the memory pool. */ + volatile int8_t tcdUsed; /*!< The number of used TCD slots. Should reflect the number of TCDs can be used/loaded in + the memory. */ + volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */ + uint8_t flags; /*!< The status of the current channel. */ +} edma_handle_t; + +/******************************************************************************* + * APIs + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name eDMA initialization and de-initialization + * @{ + */ + +/*! + * @brief Initializes the eDMA peripheral. + * + * This function ungates the eDMA clock and configures the eDMA peripheral according + * to the configuration structure. + * + * @param base eDMA peripheral base address. + * @param config A pointer to the configuration structure, see "edma_config_t". + * @note This function enables the minor loop map feature. + */ +void EDMA_Init(DMA_Type *base, const edma_config_t *config); + +/*! + * @brief Deinitializes the eDMA peripheral. + * + * This function gates the eDMA clock. + * + * @param base eDMA peripheral base address. + */ +void EDMA_Deinit(DMA_Type *base); + +/*! + * @brief Gets the eDMA default configuration structure. + * + * This function sets the configuration structure to default values. + * The default configuration is set to the following values. + * @code + * config.enableContinuousLinkMode = false; + * config.enableHaltOnError = true; + * config.enableRoundRobinArbitration = false; + * config.enableDebugMode = false; + * @endcode + * + * @param config A pointer to the eDMA configuration structure. + */ +void EDMA_GetDefaultConfig(edma_config_t *config); + +/* @} */ +/*! + * @name eDMA Channel Operation + * @{ + */ + +/*! + * @brief Sets all TCD registers to default values. + * + * This function sets TCD registers for this channel to default values. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @note This function must not be called while the channel transfer is ongoing + * or it causes unpredictable results. + * @note This function enables the auto stop request feature. + */ +void EDMA_ResetChannel(DMA_Type *base, uint32_t channel); + +/*! + * @brief Configures the eDMA transfer attribute. + * + * This function configures the transfer attribute, including source address, destination address, + * transfer size, address offset, and so on. It also configures the scatter gather feature if the + * user supplies the TCD address. + * Example: + * @code + * edma_transfer_t config; + * edma_tcd_t tcd; + * config.srcAddr = ..; + * config.destAddr = ..; + * ... + * EDMA_SetTransferConfig(DMA0, channel, &config, &stcd); + * @endcode + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param config Pointer to eDMA transfer configuration structure. + * @param nextTcd Point to TCD structure. It can be NULL if users + * do not want to enable scatter/gather feature. + * @note If nextTcd is not NULL, it means scatter gather feature is enabled + * and DREQ bit is cleared in the previous transfer configuration, which + * is set in the eDMA_ResetChannel. + */ +void EDMA_SetTransferConfig(DMA_Type *base, + uint32_t channel, + const edma_transfer_config_t *config, + edma_tcd_t *nextTcd); + +/*! + * @brief Configures the eDMA minor offset feature. + * + * The minor offset means that the signed-extended value is added to the source address or destination + * address after each minor loop. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param config A pointer to the minor offset configuration structure. + */ +void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config); + +/*! + * @brief Configures the eDMA channel preemption feature. + * + * This function configures the channel preemption attribute and the priority of the channel. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number + * @param config A pointer to the channel preemption configuration structure. + */ +static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, + uint32_t channel, + const edma_channel_Preemption_config_t *config) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + assert(config != NULL); + + DMA_DCHPRIn(base, channel) = + (DMA_DCHPRI0_DPA(!config->enablePreemptAbility) | DMA_DCHPRI0_ECP(config->enableChannelPreemption) | + DMA_DCHPRI0_CHPRI(config->channelPriority)); +} + +/*! + * @brief Sets the channel link for the eDMA transfer. + * + * This function configures either the minor link or the major link mode. The minor link means that the channel link is + * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is + * exhausted. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param type A channel link type, which can be one of the following: + * @arg kEDMA_LinkNone + * @arg kEDMA_MinorLink + * @arg kEDMA_MajorLink + * @param linkedChannel The linked channel number. + * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. + */ +void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel); + +/*! + * @brief Sets the bandwidth for the eDMA transfer. + * + * Because the eDMA processes the minor loop, it continuously generates read/write sequences + * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of + * each read/write access to control the bus request bandwidth seen by the crossbar switch. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param bandWidth A bandwidth setting, which can be one of the following: + * @arg kEDMABandwidthStallNone + * @arg kEDMABandwidthStall4Cycle + * @arg kEDMABandwidthStall8Cycle + */ +void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth); + +/*! + * @brief Sets the source modulo and the destination modulo for the eDMA transfer. + * + * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) + * calculation is performed or the original register value. It provides the ability to implement a circular data + * queue easily. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. + */ +void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo); + +#if defined(FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT) && FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT +/*! + * @brief Enables an async request for the eDMA transfer. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param enable The command to enable (true) or disable (false). + */ +static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->EARS = (base->EARS & (~(1U << channel))) | ((uint32_t)enable << channel); +} +#endif /* FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT */ + +/*! + * @brief Enables an auto stop request for the eDMA transfer. + * + * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param enable The command to enable (true) or disable (false). + */ +static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->TCD[channel].CSR = (base->TCD[channel].CSR & (~DMA_CSR_DREQ_MASK)) | DMA_CSR_DREQ(enable); +} + +/*! + * @brief Enables the interrupt source for the eDMA transfer. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param mask The mask of interrupt source to be set. Users need to use + * the defined edma_interrupt_enable_t type. + */ +void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); + +/*! + * @brief Disables the interrupt source for the eDMA transfer. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param mask The mask of the interrupt source to be set. Use + * the defined edma_interrupt_enable_t type. + */ +void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); + +/* @} */ +/*! + * @name eDMA TCD Operation + * @{ + */ + +/*! + * @brief Sets all fields to default values for the TCD structure. + * + * This function sets all fields for this TCD structure to default value. + * + * @param tcd Pointer to the TCD structure. + * @note This function enables the auto stop request feature. + */ +void EDMA_TcdReset(edma_tcd_t *tcd); + +/*! + * @brief Configures the eDMA TCD transfer attribute. + * + * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers. + * The STCD is used in the scatter-gather mode. + * This function configures the TCD transfer attribute, including source address, destination address, + * transfer size, address offset, and so on. It also configures the scatter gather feature if the + * user supplies the next TCD address. + * Example: + * @code + * edma_transfer_t config = { + * ... + * } + * edma_tcd_t tcd __aligned(32); + * edma_tcd_t nextTcd __aligned(32); + * EDMA_TcdSetTransferConfig(&tcd, &config, &nextTcd); + * @endcode + * + * @param tcd Pointer to the TCD structure. + * @param config Pointer to eDMA transfer configuration structure. + * @param nextTcd Pointer to the next TCD structure. It can be NULL if users + * do not want to enable scatter/gather feature. + * @note TCD address should be 32 bytes aligned or it causes an eDMA error. + * @note If the nextTcd is not NULL, the scatter gather feature is enabled + * and DREQ bit is cleared in the previous transfer configuration, which + * is set in the EDMA_TcdReset. + */ +void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd); + +/*! + * @brief Configures the eDMA TCD minor offset feature. + * + * A minor offset is a signed-extended value added to the source address or a destination + * address after each minor loop. + * + * @param tcd A point to the TCD structure. + * @param config A pointer to the minor offset configuration structure. + */ +void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config); + +/*! + * @brief Sets the channel link for the eDMA TCD. + * + * This function configures either a minor link or a major link. The minor link means the channel link is + * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is + * exhausted. + * + * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. + * @param tcd Point to the TCD structure. + * @param type Channel link type, it can be one of: + * @arg kEDMA_LinkNone + * @arg kEDMA_MinorLink + * @arg kEDMA_MajorLink + * @param linkedChannel The linked channel number. + */ +void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint32_t linkedChannel); + +/*! + * @brief Sets the bandwidth for the eDMA TCD. + * + * Because the eDMA processes the minor loop, it continuously generates read/write sequences + * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of + * each read/write access to control the bus request bandwidth seen by the crossbar switch. + * @param tcd A pointer to the TCD structure. + * @param bandWidth A bandwidth setting, which can be one of the following: + * @arg kEDMABandwidthStallNone + * @arg kEDMABandwidthStall4Cycle + * @arg kEDMABandwidthStall8Cycle + */ +static inline void EDMA_TcdSetBandWidth(edma_tcd_t *tcd, edma_bandwidth_t bandWidth) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + + tcd->CSR = (tcd->CSR & (~DMA_CSR_BWC_MASK)) | DMA_CSR_BWC(bandWidth); +} + +/*! + * @brief Sets the source modulo and the destination modulo for the eDMA TCD. + * + * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) + * calculation is performed or the original register value. It provides the ability to implement a circular data + * queue easily. + * + * @param tcd A pointer to the TCD structure. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. + */ +void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); + +/*! + * @brief Sets the auto stop request for the eDMA TCD. + * + * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request. + * + * @param tcd A pointer to the TCD structure. + * @param enable The command to enable (true) or disable (false). + */ +static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + + tcd->CSR = (tcd->CSR & (~DMA_CSR_DREQ_MASK)) | DMA_CSR_DREQ(enable); +} + +/*! + * @brief Enables the interrupt source for the eDMA TCD. + * + * @param tcd Point to the TCD structure. + * @param mask The mask of interrupt source to be set. Users need to use + * the defined edma_interrupt_enable_t type. + */ +void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask); + +/*! + * @brief Disables the interrupt source for the eDMA TCD. + * + * @param tcd Point to the TCD structure. + * @param mask The mask of interrupt source to be set. Users need to use + * the defined edma_interrupt_enable_t type. + */ +void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask); + +/*! @} */ +/*! + * @name eDMA Channel Transfer Operation + * @{ + */ + +/*! + * @brief Enables the eDMA hardware channel request. + * + * This function enables the hardware channel request. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + */ +static inline void EDMA_EnableChannelRequest(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->SERQ = DMA_SERQ_SERQ(channel); +} + +/*! + * @brief Disables the eDMA hardware channel request. + * + * This function disables the hardware channel request. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + */ +static inline void EDMA_DisableChannelRequest(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CERQ = DMA_CERQ_CERQ(channel); +} + +/*! + * @brief Starts the eDMA transfer by using the software trigger. + * + * This function starts a minor loop transfer. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + */ +static inline void EDMA_TriggerChannelStart(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->SSRT = DMA_SSRT_SSRT(channel); +} + +/*! @} */ +/*! + * @name eDMA Channel Status Operation + * @{ + */ + +/*! + * @brief Gets the remaining major loop count from the eDMA current channel TCD. + * + * This function checks the TCD (Task Control Descriptor) status for a specified + * eDMA channel and returns the the number of major loop count that has not finished. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @return Major loop count which has not been transferred yet for the current TCD. + * @note 1. This function can only be used to get unfinished major loop count of transfer without + * the next TCD, or it might be inaccuracy. + * 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while + * the channel is running. + * Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO + * register is needed while the eDMA IP does not support getting it while a channel is active. + * In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine + * is working with while a channel is running. + * Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example + * copied before enabling the channel) is needed. The formula to calculate it is shown below: + * RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured) + */ +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel); + +/*! + * @brief Gets the eDMA channel error status flags. + * + * @param base eDMA peripheral base address. + * @return The mask of error status flags. Users need to use the +* _edma_error_status_flags type to decode the return variables. + */ +static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base) +{ + return base->ES; +} + +/*! + * @brief Gets the eDMA channel status flags. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @return The mask of channel status flags. Users need to use the + * _edma_channel_status_flags type to decode the return variables. + */ +uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel); + +/*! + * @brief Clears the eDMA channel status flags. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param mask The mask of channel status to be cleared. Users need to use + * the defined _edma_channel_status_flags type. + */ +void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask); + +/*! @} */ +/*! + * @name eDMA Transactional Operation + */ + +/*! + * @brief Creates the eDMA handle. + * + * This function is called if using the transactional API for eDMA. This function + * initializes the internal state of the eDMA handle. + * + * @param handle eDMA handle pointer. The eDMA handle stores callback function and + * parameters. + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + */ +void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel); + +/*! + * @brief Installs the TCDs memory pool into the eDMA handle. + * + * This function is called after the EDMA_CreateHandle to use scatter/gather feature. + * + * @param handle eDMA handle pointer. + * @param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned. + * @param tcdSize The number of TCD slots. + */ +void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); + +/*! + * @brief Installs a callback function for the eDMA transfer. + * + * This callback is called in the eDMA IRQ handler. Use the callback to do something after + * the current major loop transfer completes. + * + * @param handle eDMA handle pointer. + * @param callback eDMA callback function pointer. + * @param userData A parameter for the callback function. + */ +void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData); + +/*! + * @brief Prepares the eDMA transfer structure. + * + * This function prepares the transfer configuration structure according to the user input. + * + * @param config The user configuration structure of type edma_transfer_t. + * @param srcAddr eDMA transfer source address. + * @param srcWidth eDMA transfer source address width(bytes). + * @param destAddr eDMA transfer destination address. + * @param destWidth eDMA transfer destination address width(bytes). + * @param bytesEachRequest eDMA transfer bytes per channel request. + * @param transferBytes eDMA transfer bytes to be transferred. + * @param type eDMA transfer type. + * @note The data address and the data width must be consistent. For example, if the SRC + * is 4 bytes, the source address must be 4 bytes aligned, or it results in + * source address error (SAE). + */ +void EDMA_PrepareTransfer(edma_transfer_config_t *config, + void *srcAddr, + uint32_t srcWidth, + void *destAddr, + uint32_t destWidth, + uint32_t bytesEachRequest, + uint32_t transferBytes, + edma_transfer_type_t type); + +/*! + * @brief Submits the eDMA transfer request. + * + * This function submits the eDMA transfer request according to the transfer configuration structure. + * If submitting the transfer request repeatedly, this function packs an unprocessed request as + * a TCD and enables scatter/gather feature to process it in the next time. + * + * @param handle eDMA handle pointer. + * @param config Pointer to eDMA transfer configuration structure. + * @retval kStatus_EDMA_Success It means submit transfer request succeed. + * @retval kStatus_EDMA_QueueFull It means TCD queue is full. Submit transfer request is not allowed. + * @retval kStatus_EDMA_Busy It means the given channel is busy, need to submit request later. + */ +status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config); + +/*! + * @brief eDMA starts transfer. + * + * This function enables the channel request. Users can call this function after submitting the transfer request + * or before submitting the transfer request. + * + * @param handle eDMA handle pointer. + */ +void EDMA_StartTransfer(edma_handle_t *handle); + +/*! + * @brief eDMA stops transfer. + * + * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer() + * again to resume the transfer. + * + * @param handle eDMA handle pointer. + */ +void EDMA_StopTransfer(edma_handle_t *handle); + +/*! + * @brief eDMA aborts transfer. + * + * This function disables the channel request and clear transfer status bits. + * Users can submit another transfer after calling this API. + * + * @param handle DMA handle pointer. + */ +void EDMA_AbortTransfer(edma_handle_t *handle); + +/*! + * @brief eDMA IRQ handler for the current major loop transfer completion. + * + * This function clears the channel major interrupt flag and calls + * the callback function if it is not NULL. + * + * Note: + * For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed. + * These include the final address adjustments and reloading of the BITER field into the CITER. + * Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from + * memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled). + * + * For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine. + * As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index + * in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be + * (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have + * been loaded into the eDMA engine at this point already.). + * + * For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not + * load a new TCD) from the memory pool to the eDMA engine when major loop completes. + * Therefore, ensure that the header and tcdUsed updated are identical for them. + * tcdUsed are both 0 in this case as no TCD to be loaded. + * + * See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for + * further details. + * + * @param handle eDMA handle pointer. + */ +void EDMA_HandleIRQ(edma_handle_t *handle); + +/* @} */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/* @} */ + +#endif /*_FSL_EDMA_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ewm.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ewm.c new file mode 100644 index 00000000000..34efd5d5bd8 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ewm.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_ewm.h" + +/******************************************************************************* + * Code + ******************************************************************************/ + +void EWM_Init(EWM_Type *base, const ewm_config_t *config) +{ + assert(config); + + uint32_t value = 0U; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(kCLOCK_Ewm0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + value = EWM_CTRL_EWMEN(config->enableEwm) | EWM_CTRL_ASSIN(config->setInputAssertLogic) | + EWM_CTRL_INEN(config->enableEwmInput) | EWM_CTRL_INTEN(config->enableInterrupt); +#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER + base->CLKPRESCALER = config->prescaler; +#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */ + +#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT + base->CLKCTRL = config->clockSource; +#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/ + + base->CMPL = config->compareLowValue; + base->CMPH = config->compareHighValue; + base->CTRL = value; +} + +void EWM_Deinit(EWM_Type *base) +{ + EWM_DisableInterrupts(base, kEWM_InterruptEnable); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(kCLOCK_Ewm0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void EWM_GetDefaultConfig(ewm_config_t *config) +{ + assert(config); + + config->enableEwm = true; + config->enableEwmInput = false; + config->setInputAssertLogic = false; + config->enableInterrupt = false; +#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT + config->clockSource = kEWM_LpoClockSource0; +#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/ +#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER + config->prescaler = 0U; +#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */ + config->compareLowValue = 0U; + config->compareHighValue = 0xFEU; +} + +void EWM_Refresh(EWM_Type *base) +{ + uint32_t primaskValue = 0U; + + /* Disable the global interrupt to protect refresh sequence */ + primaskValue = DisableGlobalIRQ(); + base->SERV = (uint8_t)0xB4U; + base->SERV = (uint8_t)0x2CU; + EnableGlobalIRQ(primaskValue); +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ewm.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ewm.h new file mode 100644 index 00000000000..abe1231c081 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ewm.h @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_EWM_H_ +#define _FSL_EWM_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup ewm + * @{ + */ + + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief EWM driver version 2.0.1. */ +#define FSL_EWM_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! @brief Describes EWM clock source. */ +#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT +typedef enum _ewm_lpo_clock_source +{ + kEWM_LpoClockSource0 = 0U, /*!< EWM clock sourced from lpo_clk[0]*/ + kEWM_LpoClockSource1 = 1U, /*!< EWM clock sourced from lpo_clk[1]*/ + kEWM_LpoClockSource2 = 2U, /*!< EWM clock sourced from lpo_clk[2]*/ + kEWM_LpoClockSource3 = 3U, /*!< EWM clock sourced from lpo_clk[3]*/ +} ewm_lpo_clock_source_t; +#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */ + +/*! +* @brief Data structure for EWM configuration. +* +* This structure is used to configure the EWM. +*/ +typedef struct _ewm_config +{ + bool enableEwm; /*!< Enable EWM module */ + bool enableEwmInput; /*!< Enable EWM_in input */ + bool setInputAssertLogic; /*!< EWM_in signal assertion state */ + bool enableInterrupt; /*!< Enable EWM interrupt */ +#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT + ewm_lpo_clock_source_t clockSource; /*!< Clock source select */ +#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */ +#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER + uint8_t prescaler; /*!< Clock prescaler value */ +#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */ + uint8_t compareLowValue; /*!< Compare low-register value */ + uint8_t compareHighValue; /*!< Compare high-register value */ +} ewm_config_t; + +/*! + * @brief EWM interrupt configuration structure with default settings all disabled. + * + * This structure contains the settings for all of EWM interrupt configurations. + */ +enum _ewm_interrupt_enable_t +{ + kEWM_InterruptEnable = EWM_CTRL_INTEN_MASK, /*!< Enable the EWM to generate an interrupt*/ +}; + +/*! + * @brief EWM status flags. + * + * This structure contains the constants for the EWM status flags for use in the EWM functions. + */ +enum _ewm_status_flags_t +{ + kEWM_RunningFlag = EWM_CTRL_EWMEN_MASK, /*!< Running flag, set when EWM is enabled*/ +}; + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name EWM initialization and de-initialization + * @{ + */ + +/*! + * @brief Initializes the EWM peripheral. + * + * This function is used to initialize the EWM. After calling, the EWM + * runs immediately according to the configuration. + * Note that, except for the interrupt enable control bit, other control bits and registers are write once after a + * CPU reset. Modifying them more than once generates a bus transfer error. + * + * This is an example. + * @code + * ewm_config_t config; + * EWM_GetDefaultConfig(&config); + * config.compareHighValue = 0xAAU; + * EWM_Init(ewm_base,&config); + * @endcode + * + * @param base EWM peripheral base address + * @param config The configuration of the EWM +*/ +void EWM_Init(EWM_Type *base, const ewm_config_t *config); + +/*! + * @brief Deinitializes the EWM peripheral. + * + * This function is used to shut down the EWM. + * + * @param base EWM peripheral base address +*/ +void EWM_Deinit(EWM_Type *base); + +/*! + * @brief Initializes the EWM configuration structure. + * + * This function initializes the EWM configuration structure to default values. The default + * values are as follows. + * @code + * ewmConfig->enableEwm = true; + * ewmConfig->enableEwmInput = false; + * ewmConfig->setInputAssertLogic = false; + * ewmConfig->enableInterrupt = false; + * ewmConfig->ewm_lpo_clock_source_t = kEWM_LpoClockSource0; + * ewmConfig->prescaler = 0; + * ewmConfig->compareLowValue = 0; + * ewmConfig->compareHighValue = 0xFEU; + * @endcode + * + * @param config Pointer to the EWM configuration structure. + * @see ewm_config_t + */ +void EWM_GetDefaultConfig(ewm_config_t *config); + +/* @} */ + +/*! + * @name EWM functional Operation + * @{ + */ + +/*! + * @brief Enables the EWM interrupt. + * + * This function enables the EWM interrupt. + * + * @param base EWM peripheral base address + * @param mask The interrupts to enable + * The parameter can be combination of the following source if defined + * @arg kEWM_InterruptEnable + */ +static inline void EWM_EnableInterrupts(EWM_Type *base, uint32_t mask) +{ + base->CTRL |= mask; +} + +/*! + * @brief Disables the EWM interrupt. + * + * This function enables the EWM interrupt. + * + * @param base EWM peripheral base address + * @param mask The interrupts to disable + * The parameter can be combination of the following source if defined + * @arg kEWM_InterruptEnable + */ +static inline void EWM_DisableInterrupts(EWM_Type *base, uint32_t mask) +{ + base->CTRL &= ~mask; +} + +/*! + * @brief Gets all status flags. + * + * This function gets all status flags. + * + * This is an example for getting the running flag. + * @code + * uint32_t status; + * status = EWM_GetStatusFlags(ewm_base) & kEWM_RunningFlag; + * @endcode + * @param base EWM peripheral base address + * @return State of the status flag: asserted (true) or not-asserted (false).@see _ewm_status_flags_t + * - True: a related status flag has been set. + * - False: a related status flag is not set. + */ +static inline uint32_t EWM_GetStatusFlags(EWM_Type *base) +{ + return (base->CTRL & EWM_CTRL_EWMEN_MASK); +} + +/*! + * @brief Services the EWM. + * + * This function resets the EWM counter to zero. + * + * @param base EWM peripheral base address +*/ +void EWM_Refresh(EWM_Type *base); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_EWM_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flash.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flash.c new file mode 100644 index 00000000000..b844547e60a --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flash.c @@ -0,0 +1,3264 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flash.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @name Misc utility defines + * @{ + */ +#ifndef ALIGN_DOWN +#define ALIGN_DOWN(x, a) ((x) & (uint32_t)(-((int32_t)(a)))) +#endif +#ifndef ALIGN_UP +#define ALIGN_UP(x, a) (-((int32_t)((uint32_t)(-((int32_t)(x))) & (uint32_t)(-((int32_t)(a)))))) +#endif + +#define BYTES_JOIN_TO_WORD_1_3(x, y) ((((uint32_t)(x)&0xFFU) << 24) | ((uint32_t)(y)&0xFFFFFFU)) +#define BYTES_JOIN_TO_WORD_2_2(x, y) ((((uint32_t)(x)&0xFFFFU) << 16) | ((uint32_t)(y)&0xFFFFU)) +#define BYTES_JOIN_TO_WORD_3_1(x, y) ((((uint32_t)(x)&0xFFFFFFU) << 8) | ((uint32_t)(y)&0xFFU)) +#define BYTES_JOIN_TO_WORD_1_1_2(x, y, z) \ + ((((uint32_t)(x)&0xFFU) << 24) | (((uint32_t)(y)&0xFFU) << 16) | ((uint32_t)(z)&0xFFFFU)) +#define BYTES_JOIN_TO_WORD_1_2_1(x, y, z) \ + ((((uint32_t)(x)&0xFFU) << 24) | (((uint32_t)(y)&0xFFFFU) << 8) | ((uint32_t)(z)&0xFFU)) +#define BYTES_JOIN_TO_WORD_2_1_1(x, y, z) \ + ((((uint32_t)(x)&0xFFFFU) << 16) | (((uint32_t)(y)&0xFFU) << 8) | ((uint32_t)(z)&0xFFU)) +#define BYTES_JOIN_TO_WORD_1_1_1_1(x, y, z, w) \ + ((((uint32_t)(x)&0xFFU) << 24) | (((uint32_t)(y)&0xFFU) << 16) | (((uint32_t)(z)&0xFFU) << 8) | \ + ((uint32_t)(w)&0xFFU)) +/*@}*/ + +/*! @brief Data flash IFR map Field*/ +#if defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE +#define DFLASH_IFR_READRESOURCE_START_ADDRESS 0x8003F8U +#else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA = =1 */ +#define DFLASH_IFR_READRESOURCE_START_ADDRESS 0x8000F8U +#endif + +/*! + * @name Reserved FlexNVM size (For a variety of purposes) defines + * @{ + */ +#define FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED 0xFFFFFFFFU +#define FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED 0xFFFFU +/*@}*/ + +/*! + * @name Flash Program Once Field defines + * @{ + */ +#if defined(FSL_FEATURE_FLASH_IS_FTFA) && FSL_FEATURE_FLASH_IS_FTFA +/* FTFA parts(eg. K80, KL80, L5K) support both 4-bytes and 8-bytes unit size */ +#define FLASH_PROGRAM_ONCE_MIN_ID_8BYTES \ + 0x10U /* Minimum Index indcating one of Progam Once Fields which is accessed in 8-byte records */ +#define FLASH_PROGRAM_ONCE_MAX_ID_8BYTES \ + 0x13U /* Maximum Index indcating one of Progam Once Fields which is accessed in 8-byte records */ +#define FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 1 +#define FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 1 +#elif defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE +/* FTFE parts(eg. K65, KE18) only support 8-bytes unit size */ +#define FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 0 +#define FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 1 +#elif defined(FSL_FEATURE_FLASH_IS_FTFL) && FSL_FEATURE_FLASH_IS_FTFL +/* FTFL parts(eg. K20) only support 4-bytes unit size */ +#define FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 1 +#define FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 0 +#endif +/*@}*/ + +/*! + * @name Flash security status defines + * @{ + */ +#define FLASH_SECURITY_STATE_KEYEN 0x80U +#define FLASH_SECURITY_STATE_UNSECURED 0x02U +#define FLASH_NOT_SECURE 0x01U +#define FLASH_SECURE_BACKDOOR_ENABLED 0x02U +#define FLASH_SECURE_BACKDOOR_DISABLED 0x04U +/*@}*/ + +/*! + * @name Flash controller command numbers + * @{ + */ +#define FTFx_VERIFY_BLOCK 0x00U /*!< RD1BLK*/ +#define FTFx_VERIFY_SECTION 0x01U /*!< RD1SEC*/ +#define FTFx_PROGRAM_CHECK 0x02U /*!< PGMCHK*/ +#define FTFx_READ_RESOURCE 0x03U /*!< RDRSRC*/ +#define FTFx_PROGRAM_LONGWORD 0x06U /*!< PGM4*/ +#define FTFx_PROGRAM_PHRASE 0x07U /*!< PGM8*/ +#define FTFx_ERASE_BLOCK 0x08U /*!< ERSBLK*/ +#define FTFx_ERASE_SECTOR 0x09U /*!< ERSSCR*/ +#define FTFx_PROGRAM_SECTION 0x0BU /*!< PGMSEC*/ +#define FTFx_GENERATE_CRC 0x0CU /*!< CRCGEN*/ +#define FTFx_VERIFY_ALL_BLOCK 0x40U /*!< RD1ALL*/ +#define FTFx_READ_ONCE 0x41U /*!< RDONCE or RDINDEX*/ +#define FTFx_PROGRAM_ONCE 0x43U /*!< PGMONCE or PGMINDEX*/ +#define FTFx_ERASE_ALL_BLOCK 0x44U /*!< ERSALL*/ +#define FTFx_SECURITY_BY_PASS 0x45U /*!< VFYKEY*/ +#define FTFx_SWAP_CONTROL 0x46U /*!< SWAP*/ +#define FTFx_ERASE_ALL_BLOCK_UNSECURE 0x49U /*!< ERSALLU*/ +#define FTFx_VERIFY_ALL_EXECUTE_ONLY_SEGMENT 0x4AU /*!< RD1XA*/ +#define FTFx_ERASE_ALL_EXECUTE_ONLY_SEGMENT 0x4BU /*!< ERSXA*/ +#define FTFx_PROGRAM_PARTITION 0x80U /*!< PGMPART)*/ +#define FTFx_SET_FLEXRAM_FUNCTION 0x81U /*!< SETRAM*/ + /*@}*/ + +/*! + * @name Common flash register info defines + * @{ + */ +#if defined(FTFA) +#define FTFx FTFA +#define FTFx_BASE FTFA_BASE +#define FTFx_FSTAT_CCIF_MASK FTFA_FSTAT_CCIF_MASK +#define FTFx_FSTAT_RDCOLERR_MASK FTFA_FSTAT_RDCOLERR_MASK +#define FTFx_FSTAT_ACCERR_MASK FTFA_FSTAT_ACCERR_MASK +#define FTFx_FSTAT_FPVIOL_MASK FTFA_FSTAT_FPVIOL_MASK +#define FTFx_FSTAT_MGSTAT0_MASK FTFA_FSTAT_MGSTAT0_MASK +#define FTFx_FSEC_SEC_MASK FTFA_FSEC_SEC_MASK +#define FTFx_FSEC_KEYEN_MASK FTFA_FSEC_KEYEN_MASK +#if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM +#define FTFx_FCNFG_RAMRDY_MASK FTFA_FCNFG_RAMRDY_MASK +#endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */ +#if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM +#define FTFx_FCNFG_EEERDY_MASK FTFA_FCNFG_EEERDY_MASK +#endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ +#elif defined(FTFE) +#define FTFx FTFE +#define FTFx_BASE FTFE_BASE +#define FTFx_FSTAT_CCIF_MASK FTFE_FSTAT_CCIF_MASK +#define FTFx_FSTAT_RDCOLERR_MASK FTFE_FSTAT_RDCOLERR_MASK +#define FTFx_FSTAT_ACCERR_MASK FTFE_FSTAT_ACCERR_MASK +#define FTFx_FSTAT_FPVIOL_MASK FTFE_FSTAT_FPVIOL_MASK +#define FTFx_FSTAT_MGSTAT0_MASK FTFE_FSTAT_MGSTAT0_MASK +#define FTFx_FSEC_SEC_MASK FTFE_FSEC_SEC_MASK +#define FTFx_FSEC_KEYEN_MASK FTFE_FSEC_KEYEN_MASK +#if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM +#define FTFx_FCNFG_RAMRDY_MASK FTFE_FCNFG_RAMRDY_MASK +#endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */ +#if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM +#define FTFx_FCNFG_EEERDY_MASK FTFE_FCNFG_EEERDY_MASK +#endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ +#elif defined(FTFL) +#define FTFx FTFL +#define FTFx_BASE FTFL_BASE +#define FTFx_FSTAT_CCIF_MASK FTFL_FSTAT_CCIF_MASK +#define FTFx_FSTAT_RDCOLERR_MASK FTFL_FSTAT_RDCOLERR_MASK +#define FTFx_FSTAT_ACCERR_MASK FTFL_FSTAT_ACCERR_MASK +#define FTFx_FSTAT_FPVIOL_MASK FTFL_FSTAT_FPVIOL_MASK +#define FTFx_FSTAT_MGSTAT0_MASK FTFL_FSTAT_MGSTAT0_MASK +#define FTFx_FSEC_SEC_MASK FTFL_FSEC_SEC_MASK +#define FTFx_FSEC_KEYEN_MASK FTFL_FSEC_KEYEN_MASK +#if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM +#define FTFx_FCNFG_RAMRDY_MASK FTFL_FCNFG_RAMRDY_MASK +#endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */ +#if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM +#define FTFx_FCNFG_EEERDY_MASK FTFL_FCNFG_EEERDY_MASK +#endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ +#else +#error "Unknown flash controller" +#endif +/*@}*/ + +/*! + * @name Common flash register access info defines + * @{ + */ +#if defined(FTFA_FCCOB_CCOBn_MASK) || defined(FTFE_FCCOB_CCOBn_MASK) || defined(FTFL_FCCOB_CCOBn_MASK) +#define FTFx_FCCOB3_REG (FTFx->FCCOB[0]) +#define FTFx_FCCOB5_REG (FTFx->FCCOB[6]) +#define FTFx_FCCOB6_REG (FTFx->FCCOB[5]) +#define FTFx_FCCOB7_REG (FTFx->FCCOB[4]) +#else +#define FTFx_FCCOB3_REG (FTFx->FCCOB3) +#define FTFx_FCCOB5_REG (FTFx->FCCOB5) +#define FTFx_FCCOB6_REG (FTFx->FCCOB6) +#define FTFx_FCCOB7_REG (FTFx->FCCOB7) +#endif + +#if defined(FTFA_FPROT_PROT_MASK) || defined(FTFE_FPROT_PROT_MASK) || defined(FTFL_FPROT_PROT_MASK) +#define FTFx_FPROT_LOW_REG (FTFx->FPROT[4]) +#define FTFx_FPROTL3_REG (FTFx->FPROT[4]) +#define FTFx_FPROTL2_REG (FTFx->FPROT[5]) +#define FTFx_FPROTL1_REG (FTFx->FPROT[6]) +#define FTFx_FPROTL0_REG (FTFx->FPROT[7]) +#define FTFx_FPROT_HIGH_REG (FTFx->FPROT[0]) +#define FTFx_FPROTH3_REG (FTFx->FPROT[0]) +#define FTFx_FPROTH2_REG (FTFx->FPROT[1]) +#define FTFx_FPROTH1_REG (FTFx->FPROT[2]) +#define FTFx_FPROTH0_REG (FTFx->FPROT[3]) +#else +#define FTFx_FPROT_LOW_REG (FTFx->FPROT3) +#define FTFx_FPROTL3_REG (FTFx->FPROT3) +#define FTFx_FPROTL2_REG (FTFx->FPROT2) +#define FTFx_FPROTL1_REG (FTFx->FPROT1) +#define FTFx_FPROTL0_REG (FTFx->FPROT0) +#endif + +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER +#if defined(FTFA_FPROTS_PROTS_MASK) || defined(FTFE_FPROTS_PROTS_MASK) || defined(FTFL_FPROTS_PROTS_MASK) +#define FTFx_FPROTSH_REG (FTFx->FPROTS[1]) +#define FTFx_FPROTSL_REG (FTFx->FPROTS[0]) +#else +#define FTFx_FPROTSH_REG (FTFx->FPROTSH) +#define FTFx_FPROTSL_REG (FTFx->FPROTSL) +#endif +#endif + +#if defined(FTFA_XACC_XA_MASK) || defined(FTFE_XACC_XA_MASK) || defined(FTFL_XACC_XA_MASK) +#define FTFx_XACCH3_REG (FTFx->XACC[0]) +#define FTFx_XACCL3_REG (FTFx->XACC[4]) +#else +#define FTFx_XACCH3_REG (FTFx->XACCH3) +#define FTFx_XACCL3_REG (FTFx->XACCL3) +#endif + +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER +#if defined(FTFA_XACCS_XA_S_MASK) || defined(FTFE_XACCS_XA_S_MASK) || defined(FTFL_XACCS_XA_S_MASK) +#define FTFx_XACCSH_REG (FTFx->XACCS[1]) +#define FTFx_XACCSL_REG (FTFx->XACCS[0]) +#else +#define FTFx_XACCSH_REG (FTFx->XACCSH) +#define FTFx_XACCSL_REG (FTFx->XACCSL) +#endif +#endif +/*@}*/ + +/*! + * @brief Enumeration for access segment property. + */ +enum _flash_access_segment_property +{ + kFLASH_AccessSegmentBase = 256UL, +}; + +/*! + * @brief Enumeration for flash config area. + */ +enum _flash_config_area_range +{ + kFLASH_ConfigAreaStart = 0x400U, + kFLASH_ConfigAreaEnd = 0x40FU +}; + +/*! + * @name Flash register access type defines + * @{ + */ +#define FTFx_REG8_ACCESS_TYPE volatile uint8_t * +#define FTFx_REG32_ACCESS_TYPE volatile uint32_t * +/*@}*/ + +/*! + * @brief MSCM prefetch speculation defines. + */ +#define MSCM_OCMDR_OCMC1_DFDS_MASK (0x10U) +#define MSCM_OCMDR_OCMC1_DFCS_MASK (0x20U) + +#define MSCM_OCMDR_OCMC1_DFDS_SHIFT (4U) +#define MSCM_OCMDR_OCMC1_DFCS_SHIFT (5U) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +/*! @brief Copy flash_run_command() to RAM*/ +static void copy_flash_run_command(uint32_t *flashRunCommand); +/*! @brief Copy flash_cache_clear_command() to RAM*/ +static void copy_flash_common_bit_operation(uint32_t *flashCommonBitOperation); +/*! @brief Check whether flash execute-in-ram functions are ready*/ +static status_t flash_check_execute_in_ram_function_info(flash_config_t *config); +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +/*! @brief Internal function Flash command sequence. Called by driver APIs only*/ +static status_t flash_command_sequence(flash_config_t *config); + +/*! @brief Perform the cache clear to the flash*/ +void flash_cache_clear(flash_config_t *config); + +/*! @brief Validates the range and alignment of the given address range.*/ +static status_t flash_check_range(flash_config_t *config, + uint32_t startAddress, + uint32_t lengthInBytes, + uint32_t alignmentBaseline); +/*! @brief Gets the right address, sector and block size of current flash type which is indicated by address.*/ +static status_t flash_get_matched_operation_info(flash_config_t *config, + uint32_t address, + flash_operation_config_t *info); +/*! @brief Validates the given user key for flash erase APIs.*/ +static status_t flash_check_user_key(uint32_t key); + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +/*! @brief Updates FlexNVM memory partition status according to data flash 0 IFR.*/ +static status_t flash_update_flexnvm_memory_partition_status(flash_config_t *config); +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD +/*! @brief Validates the range of the given resource address.*/ +static status_t flash_check_resource_range(uint32_t start, + uint32_t lengthInBytes, + uint32_t alignmentBaseline, + flash_read_resource_option_t option); +#endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ + +#if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD +/*! @brief Validates the gived swap control option.*/ +static status_t flash_check_swap_control_option(flash_swap_control_option_t option); +#endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */ + +#if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP +/*! @brief Validates the gived address to see if it is equal to swap indicator address in pflash swap IFR.*/ +static status_t flash_validate_swap_indicator_address(flash_config_t *config, uint32_t address); +#endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ + +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD +/*! @brief Validates the gived flexram function option.*/ +static inline status_t flasn_check_flexram_function_option_range(flash_flexram_function_option_t option); +#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + +/*! @brief Gets the flash protection information (region size, region count).*/ +static status_t flash_get_protection_info(flash_config_t *config, flash_protection_config_t *info); + +#if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL +/*! @brief Gets the flash Execute-Only access information (Segment size, Segment count).*/ +static status_t flash_get_access_info(flash_config_t *config, flash_access_config_t *info); +#endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Access to FTFx->FCCOB */ +volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFx_FCCOB3_REG; +/*! @brief Access to FTFx->FPROT */ +volatile uint32_t *const kFPROTL = (volatile uint32_t *)&FTFx_FPROT_LOW_REG; +#if defined(FTFx_FPROT_HIGH_REG) +volatile uint32_t *const kFPROTH = (volatile uint32_t *)&FTFx_FPROT_HIGH_REG; +#endif + +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER +volatile uint8_t *const kFPROTSL = (volatile uint8_t *)&FTFx_FPROTSL_REG; +volatile uint8_t *const kFPROTSH = (volatile uint8_t *)&FTFx_FPROTSH_REG; +#endif + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +/*! @brief A function pointer used to point to relocated flash_run_command() */ +static void (*callFlashRunCommand)(FTFx_REG8_ACCESS_TYPE ftfx_fstat); +/*! @brief A function pointer used to point to relocated flash_common_bit_operation() */ +static void (*callFlashCommonBitOperation)(FTFx_REG32_ACCESS_TYPE base, + uint32_t bitMask, + uint32_t bitShift, + uint32_t bitValue); + +/*! + * @brief Position independent code of flash_run_command() + * + * Note1: The prototype of C function is shown as below: + * @code + * void flash_run_command(FTFx_REG8_ACCESS_TYPE ftfx_fstat) + * { + * // clear CCIF bit + * *ftfx_fstat = FTFx_FSTAT_CCIF_MASK; + * + * // Check CCIF bit of the flash status register, wait till it is set. + * // IP team indicates that this loop will always complete. + * while (!((*ftfx_fstat) & FTFx_FSTAT_CCIF_MASK)) + * { + * } + * } + * @endcode + * Note2: The binary code is generated by IAR 7.70.1 + */ +const static uint16_t s_flashRunCommandFunctionCode[] = { + 0x2180, /* MOVS R1, #128 ; 0x80 */ + 0x7001, /* STRB R1, [R0] */ + /* @4: */ + 0x7802, /* LDRB R2, [R0] */ + 0x420a, /* TST R2, R1 */ + 0xd0fc, /* BEQ.N @4 */ + 0x4770 /* BX LR */ +}; + +/*! + * @brief Position independent code of flash_common_bit_operation() + * + * Note1: The prototype of C function is shown as below: + * @code + * void flash_common_bit_operation(FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, uint32_t + * bitValue) + * { + * if (bitMask) + * { + * uint32_t value = (((uint32_t)(((uint32_t)(bitValue)) << bitShift)) & bitMask); + * *base = (*base & (~bitMask)) | value; + * } + * + * __ISB(); + * __DSB(); + * } + * @endcode + * Note2: The binary code is generated by IAR 7.70.1 + */ +const static uint16_t s_flashCommonBitOperationFunctionCode[] = { + 0xb510, /* PUSH {R4, LR} */ + 0x2900, /* CMP R1, #0 */ + 0xd005, /* BEQ.N @12 */ + 0x6804, /* LDR R4, [R0] */ + 0x438c, /* BICS R4, R4, R1 */ + 0x4093, /* LSLS R3, R3, R2 */ + 0x4019, /* ANDS R1, R1, R3 */ + 0x4321, /* ORRS R1, R1, R4 */ + 0x6001, /* STR R1, [R0] */ + /* @12: */ + 0xf3bf, 0x8f6f, /* ISB */ + 0xf3bf, 0x8f4f, /* DSB */ + 0xbd10 /* POP {R4, PC} */ +}; +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +#if (FLASH_DRIVER_IS_FLASH_RESIDENT && !FLASH_DRIVER_IS_EXPORTED) +/*! @brief A static buffer used to hold flash_run_command() */ +static uint32_t s_flashRunCommand[kFLASH_ExecuteInRamFunctionMaxSizeInWords]; +/*! @brief A static buffer used to hold flash_common_bit_operation() */ +static uint32_t s_flashCommonBitOperation[kFLASH_ExecuteInRamFunctionMaxSizeInWords]; +/*! @brief Flash execute-in-ram function information */ +static flash_execute_in_ram_function_config_t s_flashExecuteInRamFunctionInfo; +#endif + +/*! + * @brief Table of pflash sizes. + * + * The index into this table is the value of the SIM_FCFG1.PFSIZE bitfield. + * + * The values in this table have been right shifted 10 bits so that they will all fit within + * an 16-bit integer. To get the actual flash density, you must left shift the looked up value + * by 10 bits. + * + * Elements of this table have a value of 0 in cases where the PFSIZE bitfield value is + * reserved. + * + * Code to use the table: + * @code + * uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_PFSIZE_MASK) >> SIM_FCFG1_PFSIZE_SHIFT; + * flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10; + * @endcode + */ +const uint16_t kPFlashDensities[] = { + 8, /* 0x0 - 8192, 8KB */ + 16, /* 0x1 - 16384, 16KB */ + 24, /* 0x2 - 24576, 24KB */ + 32, /* 0x3 - 32768, 32KB */ + 48, /* 0x4 - 49152, 48KB */ + 64, /* 0x5 - 65536, 64KB */ + 96, /* 0x6 - 98304, 96KB */ + 128, /* 0x7 - 131072, 128KB */ + 192, /* 0x8 - 196608, 192KB */ + 256, /* 0x9 - 262144, 256KB */ + 384, /* 0xa - 393216, 384KB */ + 512, /* 0xb - 524288, 512KB */ + 768, /* 0xc - 786432, 768KB */ + 1024, /* 0xd - 1048576, 1MB */ + 1536, /* 0xe - 1572864, 1.5MB */ + /* 2048, 0xf - 2097152, 2MB */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +status_t FLASH_Init(flash_config_t *config) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED + if (config->FlashMemoryIndex == (uint32_t)kFLASH_MemoryIndexSecondaryFlash) + { +/* calculate the flash density from SIM_FCFG1.PFSIZE */ +#if defined(SIM_FCFG1_CORE1_PFSIZE_MASK) + uint32_t flashDensity; + uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_CORE1_PFSIZE_MASK) >> SIM_FCFG1_CORE1_PFSIZE_SHIFT; + if (pfsize == 0xf) + { + flashDensity = FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SIZE; + } + else + { + flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10; + } + config->PFlashTotalSize = flashDensity; +#else + /* Unused code to solve MISRA-C issue*/ + config->PFlashBlockBase = kPFlashDensities[0]; + config->PFlashTotalSize = FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SIZE; +#endif + config->PFlashBlockBase = FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS; + config->PFlashBlockCount = FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT; + config->PFlashSectorSize = FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SECTOR_SIZE; + } + else +#endif /* FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED */ + { + uint32_t flashDensity; + +/* calculate the flash density from SIM_FCFG1.PFSIZE */ +#if defined(SIM_FCFG1_CORE0_PFSIZE_MASK) + uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_CORE0_PFSIZE_MASK) >> SIM_FCFG1_CORE0_PFSIZE_SHIFT; +#elif defined(SIM_FCFG1_PFSIZE_MASK) + uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_PFSIZE_MASK) >> SIM_FCFG1_PFSIZE_SHIFT; +#else +#error "Unknown flash size" +#endif + /* PFSIZE=0xf means that on customer parts the IFR was not correctly programmed. + * We just use the pre-defined flash size in feature file here to support pre-production parts */ + if (pfsize == 0xf) + { + flashDensity = FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE; + } + else + { + flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10; + } + + /* fill out a few of the structure members */ + config->PFlashBlockBase = FSL_FEATURE_FLASH_PFLASH_START_ADDRESS; + config->PFlashTotalSize = flashDensity; + config->PFlashBlockCount = FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT; + config->PFlashSectorSize = FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE; + } + + { +#if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER + if (config->FlashMemoryIndex == (uint32_t)kFLASH_MemoryIndexSecondaryFlash) + { + config->PFlashAccessSegmentSize = kFLASH_AccessSegmentBase << FTFx->FACSSS; + config->PFlashAccessSegmentCount = FTFx->FACSNS; + } + else +#endif + { + config->PFlashAccessSegmentSize = kFLASH_AccessSegmentBase << FTFx->FACSS; + config->PFlashAccessSegmentCount = FTFx->FACSN; + } +#else + config->PFlashAccessSegmentSize = 0; + config->PFlashAccessSegmentCount = 0; +#endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ + } + + config->PFlashCallback = NULL; + +/* copy required flash commands to RAM */ +#if (FLASH_DRIVER_IS_FLASH_RESIDENT && !FLASH_DRIVER_IS_EXPORTED) + if (kStatus_FLASH_Success != flash_check_execute_in_ram_function_info(config)) + { + s_flashExecuteInRamFunctionInfo.activeFunctionCount = 0; + s_flashExecuteInRamFunctionInfo.flashRunCommand = s_flashRunCommand; + s_flashExecuteInRamFunctionInfo.flashCommonBitOperation = s_flashCommonBitOperation; + config->flashExecuteInRamFunctionInfo = &s_flashExecuteInRamFunctionInfo.activeFunctionCount; + FLASH_PrepareExecuteInRamFunctions(config); + } +#endif + + config->FlexRAMBlockBase = FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS; + config->FlexRAMTotalSize = FSL_FEATURE_FLASH_FLEX_RAM_SIZE; + +#if FLASH_SSD_IS_FLEXNVM_ENABLED + { + status_t returnCode; + config->DFlashBlockBase = FSL_FEATURE_FLASH_FLEX_NVM_START_ADDRESS; + returnCode = flash_update_flexnvm_memory_partition_status(config); + if (returnCode != kStatus_FLASH_Success) + { + return returnCode; + } + } +#endif + + return kStatus_FLASH_Success; +} + +status_t FLASH_SetCallback(flash_config_t *config, flash_callback_t callback) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + config->PFlashCallback = callback; + + return kStatus_FLASH_Success; +} + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +status_t FLASH_PrepareExecuteInRamFunctions(flash_config_t *config) +{ + flash_execute_in_ram_function_config_t *flashExecuteInRamFunctionInfo; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + flashExecuteInRamFunctionInfo = (flash_execute_in_ram_function_config_t *)config->flashExecuteInRamFunctionInfo; + + copy_flash_run_command(flashExecuteInRamFunctionInfo->flashRunCommand); + copy_flash_common_bit_operation(flashExecuteInRamFunctionInfo->flashCommonBitOperation); + flashExecuteInRamFunctionInfo->activeFunctionCount = kFLASH_ExecuteInRamFunctionTotalNum; + + return kStatus_FLASH_Success; +} +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +status_t FLASH_EraseAll(flash_config_t *config, uint32_t key) +{ + status_t returnCode; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* preparing passing parameter to erase all flash blocks */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_ALL_BLOCK, 0xFFFFFFU); + + /* Validate the user key */ + returnCode = flash_check_user_key(key); + if (returnCode) + { + return returnCode; + } + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + flash_cache_clear(config); + +#if FLASH_SSD_IS_FLEXNVM_ENABLED + /* Data flash IFR will be erased by erase all command, so we need to + * update FlexNVM memory partition status synchronously */ + if (returnCode == kStatus_FLASH_Success) + { + returnCode = flash_update_flexnvm_memory_partition_status(config); + } +#endif + + return returnCode; +} + +status_t FLASH_Erase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key) +{ + uint32_t sectorSize; + flash_operation_config_t flashOperationInfo; + uint32_t endAddress; /* storing end address */ + uint32_t numberOfSectors; /* number of sectors calculated by endAddress */ + status_t returnCode; + + flash_get_matched_operation_info(config, start, &flashOperationInfo); + + /* Check the supplied address range. */ + returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.sectorCmdAddressAligment); + if (returnCode) + { + return returnCode; + } + + start = flashOperationInfo.convertedAddress; + sectorSize = flashOperationInfo.activeSectorSize; + + /* calculating Flash end address */ + endAddress = start + lengthInBytes - 1; + + /* re-calculate the endAddress and align it to the start of the next sector + * which will be used in the comparison below */ + if (endAddress % sectorSize) + { + numberOfSectors = endAddress / sectorSize + 1; + endAddress = numberOfSectors * sectorSize - 1; + } + + /* the start address will increment to the next sector address + * until it reaches the endAdddress */ + while (start <= endAddress) + { + /* preparing passing parameter to erase a flash block */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_SECTOR, start); + + /* Validate the user key */ + returnCode = flash_check_user_key(key); + if (returnCode) + { + return returnCode; + } + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + /* calling flash callback function if it is available */ + if (config->PFlashCallback) + { + config->PFlashCallback(); + } + + /* checking the success of command execution */ + if (kStatus_FLASH_Success != returnCode) + { + break; + } + else + { + /* Increment to the next sector */ + start += sectorSize; + } + } + + flash_cache_clear(config); + + return (returnCode); +} + +#if defined(FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD) && FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD +status_t FLASH_EraseAllUnsecure(flash_config_t *config, uint32_t key) +{ + status_t returnCode; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Prepare passing parameter to erase all flash blocks (unsecure). */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_ALL_BLOCK_UNSECURE, 0xFFFFFFU); + + /* Validate the user key */ + returnCode = flash_check_user_key(key); + if (returnCode) + { + return returnCode; + } + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + flash_cache_clear(config); + +#if FLASH_SSD_IS_FLEXNVM_ENABLED + /* Data flash IFR will be erased by erase all unsecure command, so we need to + * update FlexNVM memory partition status synchronously */ + if (returnCode == kStatus_FLASH_Success) + { + returnCode = flash_update_flexnvm_memory_partition_status(config); + } +#endif + + return returnCode; +} +#endif /* FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD */ + +status_t FLASH_EraseAllExecuteOnlySegments(flash_config_t *config, uint32_t key) +{ + status_t returnCode; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* preparing passing parameter to erase all execute-only segments + * 1st element for the FCCOB register */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_ALL_EXECUTE_ONLY_SEGMENT, 0xFFFFFFU); + + /* Validate the user key */ + returnCode = flash_check_user_key(key); + if (returnCode) + { + return returnCode; + } + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + flash_cache_clear(config); + + return returnCode; +} + +status_t FLASH_Program(flash_config_t *config, uint32_t start, uint32_t *src, uint32_t lengthInBytes) +{ + status_t returnCode; + flash_operation_config_t flashOperationInfo; + + if (src == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + flash_get_matched_operation_info(config, start, &flashOperationInfo); + + /* Check the supplied address range. */ + returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.blockWriteUnitSize); + if (returnCode) + { + return returnCode; + } + + start = flashOperationInfo.convertedAddress; + + while (lengthInBytes > 0) + { + /* preparing passing parameter to program the flash block */ + kFCCOBx[1] = *src++; + if (4 == flashOperationInfo.blockWriteUnitSize) + { + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_LONGWORD, start); + } + else if (8 == flashOperationInfo.blockWriteUnitSize) + { + kFCCOBx[2] = *src++; + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_PHRASE, start); + } + else + { + } + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + /* calling flash callback function if it is available */ + if (config->PFlashCallback) + { + config->PFlashCallback(); + } + + /* checking for the success of command execution */ + if (kStatus_FLASH_Success != returnCode) + { + break; + } + else + { + /* update start address for next iteration */ + start += flashOperationInfo.blockWriteUnitSize; + + /* update lengthInBytes for next iteration */ + lengthInBytes -= flashOperationInfo.blockWriteUnitSize; + } + } + + flash_cache_clear(config); + + return (returnCode); +} + +status_t FLASH_ProgramOnce(flash_config_t *config, uint32_t index, uint32_t *src, uint32_t lengthInBytes) +{ + status_t returnCode; + + if ((config == NULL) || (src == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + /* pass paramters to FTFx */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_PROGRAM_ONCE, index, 0xFFFFU); + + kFCCOBx[1] = *src; + +/* Note: Have to seperate the first index from the rest if it equals 0 + * to avoid a pointless comparison of unsigned int to 0 compiler warning */ +#if FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT +#if FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT + if (((index == FLASH_PROGRAM_ONCE_MIN_ID_8BYTES) || + /* Range check */ + ((index >= FLASH_PROGRAM_ONCE_MIN_ID_8BYTES + 1) && (index <= FLASH_PROGRAM_ONCE_MAX_ID_8BYTES))) && + (lengthInBytes == 8)) +#endif /* FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT */ + { + kFCCOBx[2] = *(src + 1); + } +#endif /* FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT */ + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + flash_cache_clear(config); + + return returnCode; +} + +#if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD +status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint32_t *src, uint32_t lengthInBytes) +{ + status_t returnCode; + uint32_t sectorSize; + flash_operation_config_t flashOperationInfo; +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD + bool needSwitchFlexRamMode = false; +#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + + if (src == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + flash_get_matched_operation_info(config, start, &flashOperationInfo); + + /* Check the supplied address range. */ + returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.sectionCmdAddressAligment); + if (returnCode) + { + return returnCode; + } + + start = flashOperationInfo.convertedAddress; + sectorSize = flashOperationInfo.activeSectorSize; + +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD + /* Switch function of FlexRAM if needed */ + if (!(FTFx->FCNFG & FTFx_FCNFG_RAMRDY_MASK)) + { + needSwitchFlexRamMode = true; + + returnCode = FLASH_SetFlexramFunction(config, kFLASH_FlexramFunctionOptionAvailableAsRam); + if (returnCode != kStatus_FLASH_Success) + { + return kStatus_FLASH_SetFlexramAsRamError; + } + } +#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + + while (lengthInBytes > 0) + { + /* Make sure the write operation doesn't span two sectors */ + uint32_t endAddressOfCurrentSector = ALIGN_UP(start, sectorSize); + uint32_t lengthTobeProgrammedOfCurrentSector; + uint32_t currentOffset = 0; + + if (endAddressOfCurrentSector == start) + { + endAddressOfCurrentSector += sectorSize; + } + + if (lengthInBytes + start > endAddressOfCurrentSector) + { + lengthTobeProgrammedOfCurrentSector = endAddressOfCurrentSector - start; + } + else + { + lengthTobeProgrammedOfCurrentSector = lengthInBytes; + } + + /* Program Current Sector */ + while (lengthTobeProgrammedOfCurrentSector > 0) + { + /* Make sure the program size doesn't exceeds Acceleration RAM size */ + uint32_t programSizeOfCurrentPass; + uint32_t numberOfPhases; + + if (lengthTobeProgrammedOfCurrentSector > kFLASH_AccelerationRamSize) + { + programSizeOfCurrentPass = kFLASH_AccelerationRamSize; + } + else + { + programSizeOfCurrentPass = lengthTobeProgrammedOfCurrentSector; + } + + /* Copy data to FlexRAM */ + memcpy((void *)FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS, src + currentOffset / 4, programSizeOfCurrentPass); + /* Set start address of the data to be programmed */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_SECTION, start + currentOffset); + /* Set program size in terms of FEATURE_FLASH_SECTION_CMD_ADDRESS_ALIGMENT */ + numberOfPhases = programSizeOfCurrentPass / flashOperationInfo.sectionCmdAddressAligment; + + kFCCOBx[1] = BYTES_JOIN_TO_WORD_2_2(numberOfPhases, 0xFFFFU); + + /* Peform command sequence */ + returnCode = flash_command_sequence(config); + + /* calling flash callback function if it is available */ + if (config->PFlashCallback) + { + config->PFlashCallback(); + } + + if (returnCode != kStatus_FLASH_Success) + { + flash_cache_clear(config); + return returnCode; + } + + lengthTobeProgrammedOfCurrentSector -= programSizeOfCurrentPass; + currentOffset += programSizeOfCurrentPass; + } + + src += currentOffset / 4; + start += currentOffset; + lengthInBytes -= currentOffset; + } + + flash_cache_clear(config); + +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD + /* Restore function of FlexRAM if needed. */ + if (needSwitchFlexRamMode) + { + returnCode = FLASH_SetFlexramFunction(config, kFLASH_FlexramFunctionOptionAvailableForEeprom); + if (returnCode != kStatus_FLASH_Success) + { + return kStatus_FLASH_RecoverFlexramAsEepromError; + } + } +#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + + return returnCode; +} +#endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD */ + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_EepromWrite(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes) +{ + status_t returnCode; + bool needSwitchFlexRamMode = false; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Validates the range of the given address */ + if ((start < config->FlexRAMBlockBase) || + ((start + lengthInBytes) > (config->FlexRAMBlockBase + config->EEpromTotalSize))) + { + return kStatus_FLASH_AddressError; + } + + returnCode = kStatus_FLASH_Success; + + /* Switch function of FlexRAM if needed */ + if (!(FTFx->FCNFG & FTFx_FCNFG_EEERDY_MASK)) + { + needSwitchFlexRamMode = true; + + returnCode = FLASH_SetFlexramFunction(config, kFLASH_FlexramFunctionOptionAvailableForEeprom); + if (returnCode != kStatus_FLASH_Success) + { + return kStatus_FLASH_SetFlexramAsEepromError; + } + } + + /* Write data to FlexRAM when it is used as EEPROM emulator */ + while (lengthInBytes > 0) + { + if ((!(start & 0x3U)) && (lengthInBytes >= 4)) + { + *(uint32_t *)start = *(uint32_t *)src; + start += 4; + src += 4; + lengthInBytes -= 4; + } + else if ((!(start & 0x1U)) && (lengthInBytes >= 2)) + { + *(uint16_t *)start = *(uint16_t *)src; + start += 2; + src += 2; + lengthInBytes -= 2; + } + else + { + *(uint8_t *)start = *src; + start += 1; + src += 1; + lengthInBytes -= 1; + } + /* Wait till EEERDY bit is set */ + while (!(FTFx->FCNFG & FTFx_FCNFG_EEERDY_MASK)) + { + } + + /* Check for protection violation error */ + if (FTFx->FSTAT & FTFx_FSTAT_FPVIOL_MASK) + { + return kStatus_FLASH_ProtectionViolation; + } + } + + /* Switch function of FlexRAM if needed */ + if (needSwitchFlexRamMode) + { + returnCode = FLASH_SetFlexramFunction(config, kFLASH_FlexramFunctionOptionAvailableAsRam); + if (returnCode != kStatus_FLASH_Success) + { + return kStatus_FLASH_RecoverFlexramAsRamError; + } + } + + return returnCode; +} +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD +status_t FLASH_ReadResource( + flash_config_t *config, uint32_t start, uint32_t *dst, uint32_t lengthInBytes, flash_read_resource_option_t option) +{ + status_t returnCode; + flash_operation_config_t flashOperationInfo; + + if ((config == NULL) || (dst == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + flash_get_matched_operation_info(config, start, &flashOperationInfo); + + /* Check the supplied address range. */ + returnCode = + flash_check_resource_range(start, lengthInBytes, flashOperationInfo.resourceCmdAddressAligment, option); + if (returnCode != kStatus_FLASH_Success) + { + return returnCode; + } + + while (lengthInBytes > 0) + { + /* preparing passing parameter */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_READ_RESOURCE, start); + if (flashOperationInfo.resourceCmdAddressAligment == 4) + { + kFCCOBx[2] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU); + } + else if (flashOperationInfo.resourceCmdAddressAligment == 8) + { + kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU); + } + else + { + } + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + if (kStatus_FLASH_Success != returnCode) + { + break; + } + + /* fetch data */ + *dst++ = kFCCOBx[1]; + if (flashOperationInfo.resourceCmdAddressAligment == 8) + { + *dst++ = kFCCOBx[2]; + } + /* update start address for next iteration */ + start += flashOperationInfo.resourceCmdAddressAligment; + /* update lengthInBytes for next iteration */ + lengthInBytes -= flashOperationInfo.resourceCmdAddressAligment; + } + + return (returnCode); +} +#endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ + +status_t FLASH_ReadOnce(flash_config_t *config, uint32_t index, uint32_t *dst, uint32_t lengthInBytes) +{ + status_t returnCode; + + if ((config == NULL) || (dst == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + /* pass paramters to FTFx */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_READ_ONCE, index, 0xFFFFU); + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + if (kStatus_FLASH_Success == returnCode) + { + *dst = kFCCOBx[1]; +/* Note: Have to seperate the first index from the rest if it equals 0 + * to avoid a pointless comparison of unsigned int to 0 compiler warning */ +#if FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT +#if FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT + if (((index == FLASH_PROGRAM_ONCE_MIN_ID_8BYTES) || + /* Range check */ + ((index >= FLASH_PROGRAM_ONCE_MIN_ID_8BYTES + 1) && (index <= FLASH_PROGRAM_ONCE_MAX_ID_8BYTES))) && + (lengthInBytes == 8)) +#endif /* FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT */ + { + *(dst + 1) = kFCCOBx[2]; + } +#endif /* FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT */ + } + + return returnCode; +} + +status_t FLASH_GetSecurityState(flash_config_t *config, flash_security_state_t *state) +{ + /* store data read from flash register */ + uint8_t registerValue; + + if ((config == NULL) || (state == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Get flash security register value */ + registerValue = FTFx->FSEC; + + /* check the status of the flash security bits in the security register */ + if (FLASH_SECURITY_STATE_UNSECURED == (registerValue & FTFx_FSEC_SEC_MASK)) + { + /* Flash in unsecured state */ + *state = kFLASH_SecurityStateNotSecure; + } + else + { + /* Flash in secured state + * check for backdoor key security enable bit */ + if (FLASH_SECURITY_STATE_KEYEN == (registerValue & FTFx_FSEC_KEYEN_MASK)) + { + /* Backdoor key security enabled */ + *state = kFLASH_SecurityStateBackdoorEnabled; + } + else + { + /* Backdoor key security disabled */ + *state = kFLASH_SecurityStateBackdoorDisabled; + } + } + + return (kStatus_FLASH_Success); +} + +status_t FLASH_SecurityBypass(flash_config_t *config, const uint8_t *backdoorKey) +{ + uint8_t registerValue; /* registerValue */ + status_t returnCode; /* return code variable */ + + if ((config == NULL) || (backdoorKey == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + /* set the default return code as kStatus_Success */ + returnCode = kStatus_FLASH_Success; + + /* Get flash security register value */ + registerValue = FTFx->FSEC; + + /* Check to see if flash is in secure state (any state other than 0x2) + * If not, then skip this since flash is not secure */ + if (0x02 != (registerValue & 0x03)) + { + /* preparing passing parameter to erase a flash block */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_SECURITY_BY_PASS, 0xFFFFFFU); + kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_1_1_1(backdoorKey[0], backdoorKey[1], backdoorKey[2], backdoorKey[3]); + kFCCOBx[2] = BYTES_JOIN_TO_WORD_1_1_1_1(backdoorKey[4], backdoorKey[5], backdoorKey[6], backdoorKey[7]); + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + } + + return (returnCode); +} + +status_t FLASH_VerifyEraseAll(flash_config_t *config, flash_margin_value_t margin) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* preparing passing parameter to verify all block command */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_VERIFY_ALL_BLOCK, margin, 0xFFFFU); + + /* calling flash command sequence function to execute the command */ + return flash_command_sequence(config); +} + +status_t FLASH_VerifyErase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, flash_margin_value_t margin) +{ + /* Check arguments. */ + uint32_t blockSize; + flash_operation_config_t flashOperationInfo; + uint32_t nextBlockStartAddress; + uint32_t remainingBytes; + status_t returnCode; + + flash_get_matched_operation_info(config, start, &flashOperationInfo); + + returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.sectionCmdAddressAligment); + if (returnCode) + { + return returnCode; + } + + flash_get_matched_operation_info(config, start, &flashOperationInfo); + start = flashOperationInfo.convertedAddress; + blockSize = flashOperationInfo.activeBlockSize; + + nextBlockStartAddress = ALIGN_UP(start, blockSize); + if (nextBlockStartAddress == start) + { + nextBlockStartAddress += blockSize; + } + + remainingBytes = lengthInBytes; + + while (remainingBytes) + { + uint32_t numberOfPhrases; + uint32_t verifyLength = nextBlockStartAddress - start; + if (verifyLength > remainingBytes) + { + verifyLength = remainingBytes; + } + + numberOfPhrases = verifyLength / flashOperationInfo.sectionCmdAddressAligment; + + /* Fill in verify section command parameters. */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_VERIFY_SECTION, start); + kFCCOBx[1] = BYTES_JOIN_TO_WORD_2_1_1(numberOfPhrases, margin, 0xFFU); + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + if (returnCode) + { + return returnCode; + } + + remainingBytes -= verifyLength; + start += verifyLength; + nextBlockStartAddress += blockSize; + } + + return kStatus_FLASH_Success; +} + +status_t FLASH_VerifyProgram(flash_config_t *config, + uint32_t start, + uint32_t lengthInBytes, + const uint32_t *expectedData, + flash_margin_value_t margin, + uint32_t *failedAddress, + uint32_t *failedData) +{ + status_t returnCode; + flash_operation_config_t flashOperationInfo; + + if (expectedData == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + flash_get_matched_operation_info(config, start, &flashOperationInfo); + + returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.checkCmdAddressAligment); + if (returnCode) + { + return returnCode; + } + + start = flashOperationInfo.convertedAddress; + + while (lengthInBytes) + { + /* preparing passing parameter to program check the flash block */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_CHECK, start); + kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(margin, 0xFFFFFFU); + kFCCOBx[2] = *expectedData; + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + /* checking for the success of command execution */ + if (kStatus_FLASH_Success != returnCode) + { + if (failedAddress) + { + *failedAddress = start; + } + if (failedData) + { + *failedData = 0; + } + break; + } + + lengthInBytes -= flashOperationInfo.checkCmdAddressAligment; + expectedData += flashOperationInfo.checkCmdAddressAligment / sizeof(*expectedData); + start += flashOperationInfo.checkCmdAddressAligment; + } + + return (returnCode); +} + +status_t FLASH_VerifyEraseAllExecuteOnlySegments(flash_config_t *config, flash_margin_value_t margin) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* preparing passing parameter to verify erase all execute-only segments command */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_VERIFY_ALL_EXECUTE_ONLY_SEGMENT, margin, 0xFFFFU); + + /* calling flash command sequence function to execute the command */ + return flash_command_sequence(config); +} + +status_t FLASH_IsProtected(flash_config_t *config, + uint32_t start, + uint32_t lengthInBytes, + flash_protection_state_t *protection_state) +{ + uint32_t endAddress; /* end address for protection check */ + uint32_t regionCheckedCounter; /* increments each time the flash address was checked for + * protection status */ + uint32_t regionCounter; /* incrementing variable used to increment through the flash + * protection regions */ + uint32_t protectStatusCounter; /* increments each time a flash region was detected as protected */ + + uint8_t flashRegionProtectStatus[FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT]; /* array of the protection + * status for each + * protection region */ + uint32_t flashRegionAddress[FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT + + 1]; /* array of the start addresses for each flash + * protection region. Note this is REGION_COUNT+1 + * due to requiring the next start address after + * the end of flash for loop-check purposes below */ + flash_protection_config_t flashProtectionInfo; /* flash protection information */ + status_t returnCode; + + if (protection_state == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Check the supplied address range. */ + returnCode = flash_check_range(config, start, lengthInBytes, FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE); + if (returnCode) + { + return returnCode; + } + + /* Get necessary flash protection information. */ + returnCode = flash_get_protection_info(config, &flashProtectionInfo); + if (returnCode) + { + return returnCode; + } + + /* calculating Flash end address */ + endAddress = start + lengthInBytes; + + /* populate the flashRegionAddress array with the start address of each flash region */ + regionCounter = 0; /* make sure regionCounter is initialized to 0 first */ + + /* populate up to 33rd element of array, this is the next address after end of flash array */ + while (regionCounter <= flashProtectionInfo.regionCount) + { + flashRegionAddress[regionCounter] = + flashProtectionInfo.regionBase + flashProtectionInfo.regionSize * regionCounter; + regionCounter++; + } + + /* populate flashRegionProtectStatus array with status information + * Protection status for each region is stored in the FPROT[3:0] registers + * Each bit represents one region of flash + * 4 registers * 8-bits-per-register = 32-bits (32-regions) + * The convention is: + * FPROT3[bit 0] is the first protection region (start of flash memory) + * FPROT0[bit 7] is the last protection region (end of flash memory) + * regionCounter is used to determine which FPROT[3:0] register to check for protection status + * Note: FPROT=1 means NOT protected, FPROT=0 means protected */ + regionCounter = 0; /* make sure regionCounter is initialized to 0 first */ + while (regionCounter < flashProtectionInfo.regionCount) + { +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER + if (config->FlashMemoryIndex == (uint32_t)kFLASH_MemoryIndexSecondaryFlash) + { + if (regionCounter < 8) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTSL_REG >> regionCounter) & (0x01u); + } + else if ((regionCounter >= 8) && (regionCounter < 16)) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTSH_REG >> (regionCounter - 8)) & (0x01u); + } + else + { + break; + } + } + else +#endif + { + /* Note: So far protection region count may be 16/20/24/32/64 */ + if (regionCounter < 8) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL3_REG >> regionCounter) & (0x01u); + } + else if ((regionCounter >= 8) && (regionCounter < 16)) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL2_REG >> (regionCounter - 8)) & (0x01u); + } +#if defined(FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT) && (FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT > 16) +#if (FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT == 20) + else if ((regionCounter >= 16) && (regionCounter < 20)) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL1_REG >> (regionCounter - 16)) & (0x01u); + } +#else + else if ((regionCounter >= 16) && (regionCounter < 24)) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL1_REG >> (regionCounter - 16)) & (0x01u); + } +#endif /* (FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT == 20) */ +#endif +#if defined(FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT) && (FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT > 24) + else if ((regionCounter >= 24) && (regionCounter < 32)) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL0_REG >> (regionCounter - 24)) & (0x01u); + } +#endif +#if defined(FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT) && \ + (FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT == 64) + else if (regionCounter < 40) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTH3_REG >> (regionCounter - 32)) & (0x01u); + } + else if (regionCounter < 48) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTH2_REG >> (regionCounter - 40)) & (0x01u); + } + else if (regionCounter < 56) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTH1_REG >> (regionCounter - 48)) & (0x01u); + } + else if (regionCounter < 64) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTH0_REG >> (regionCounter - 56)) & (0x01u); + } +#endif + else + { + break; + } + } + + regionCounter++; + } + + /* loop through the flash regions and check + * desired flash address range for protection status + * loop stops when it is detected that start has exceeded the endAddress */ + regionCounter = 0; /* make sure regionCounter is initialized to 0 first */ + regionCheckedCounter = 0; + protectStatusCounter = 0; /* make sure protectStatusCounter is initialized to 0 first */ + while (start < endAddress) + { + /* check to see if the address falls within this protection region + * Note that if the entire flash is to be checked, the last protection + * region checked would consist of the last protection start address and + * the start address following the end of flash */ + if ((start >= flashRegionAddress[regionCounter]) && (start < flashRegionAddress[regionCounter + 1])) + { + /* increment regionCheckedCounter to indicate this region was checked */ + regionCheckedCounter++; + + /* check the protection status of this region + * Note: FPROT=1 means NOT protected, FPROT=0 means protected */ + if (!flashRegionProtectStatus[regionCounter]) + { + /* increment protectStatusCounter to indicate this region is protected */ + protectStatusCounter++; + } + start += flashProtectionInfo.regionSize; /* increment to an address within the next region */ + } + regionCounter++; /* increment regionCounter to check for the next flash protection region */ + } + + /* if protectStatusCounter == 0, then no region of the desired flash region is protected */ + if (protectStatusCounter == 0) + { + *protection_state = kFLASH_ProtectionStateUnprotected; + } + /* if protectStatusCounter == regionCheckedCounter, then each region checked was protected */ + else if (protectStatusCounter == regionCheckedCounter) + { + *protection_state = kFLASH_ProtectionStateProtected; + } + /* if protectStatusCounter != regionCheckedCounter, then protection status is mixed + * In other words, some regions are protected while others are unprotected */ + else + { + *protection_state = kFLASH_ProtectionStateMixed; + } + + return (returnCode); +} + +status_t FLASH_IsExecuteOnly(flash_config_t *config, + uint32_t start, + uint32_t lengthInBytes, + flash_execute_only_access_state_t *access_state) +{ +#if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL + flash_access_config_t flashAccessInfo; /* flash Execute-Only information */ +#endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ + status_t returnCode; + + if (access_state == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Check the supplied address range. */ + returnCode = flash_check_range(config, start, lengthInBytes, FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE); + if (returnCode) + { + return returnCode; + } + +#if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL + /* Get necessary flash Execute-Only information. */ + returnCode = flash_get_access_info(config, &flashAccessInfo); + if (returnCode) + { + return returnCode; + } + + { + uint32_t executeOnlySegmentCounter = 0; + + /* calculating end address */ + uint32_t endAddress = start + lengthInBytes; + + /* Aligning start address and end address */ + uint32_t alignedStartAddress = ALIGN_DOWN(start, flashAccessInfo.SegmentSize); + uint32_t alignedEndAddress = ALIGN_UP(endAddress, flashAccessInfo.SegmentSize); + + uint32_t segmentIndex = 0; + uint32_t maxSupportedExecuteOnlySegmentCount = + (alignedEndAddress - alignedStartAddress) / flashAccessInfo.SegmentSize; + + while (start < endAddress) + { + uint32_t xacc; + + segmentIndex = (start - flashAccessInfo.SegmentBase) / flashAccessInfo.SegmentSize; + +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER + if (config->FlashMemoryIndex == (uint32_t)kFLASH_MemoryIndexSecondaryFlash) + { + /* For secondary flash, The two XACCS registers allow up to 16 restricted segments of equal memory size. + */ + if (segmentIndex < 8) + { + xacc = *(const volatile uint8_t *)&FTFx_XACCSL_REG; + } + else if (segmentIndex < flashAccessInfo.SegmentCount) + { + xacc = *(const volatile uint8_t *)&FTFx_XACCSH_REG; + segmentIndex -= 8; + } + else + { + break; + } + } + else +#endif + { + /* For primary flash, The eight XACC registers allow up to 64 restricted segments of equal memory size. + */ + if (segmentIndex < 32) + { + xacc = *(const volatile uint32_t *)&FTFx_XACCL3_REG; + } + else if (segmentIndex < flashAccessInfo.SegmentCount) + { + xacc = *(const volatile uint32_t *)&FTFx_XACCH3_REG; + segmentIndex -= 32; + } + else + { + break; + } + } + + /* Determine if this address range is in a execute-only protection flash segment. */ + if ((~xacc) & (1u << segmentIndex)) + { + executeOnlySegmentCounter++; + } + + start += flashAccessInfo.SegmentSize; + } + + if (executeOnlySegmentCounter < 1u) + { + *access_state = kFLASH_AccessStateUnLimited; + } + else if (executeOnlySegmentCounter < maxSupportedExecuteOnlySegmentCount) + { + *access_state = kFLASH_AccessStateMixed; + } + else + { + *access_state = kFLASH_AccessStateExecuteOnly; + } + } +#else + *access_state = kFLASH_AccessStateUnLimited; +#endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ + + return (returnCode); +} + +status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value) +{ + if ((config == NULL) || (value == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + switch (whichProperty) + { + case kFLASH_PropertyPflashSectorSize: + *value = config->PFlashSectorSize; + break; + + case kFLASH_PropertyPflashTotalSize: + *value = config->PFlashTotalSize; + break; + + case kFLASH_PropertyPflashBlockSize: + *value = config->PFlashTotalSize / FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT; + break; + + case kFLASH_PropertyPflashBlockCount: + *value = config->PFlashBlockCount; + break; + + case kFLASH_PropertyPflashBlockBaseAddr: + *value = config->PFlashBlockBase; + break; + + case kFLASH_PropertyPflashFacSupport: +#if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) + *value = FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL; +#else + *value = 0; +#endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ + break; + + case kFLASH_PropertyPflashAccessSegmentSize: + *value = config->PFlashAccessSegmentSize; + break; + + case kFLASH_PropertyPflashAccessSegmentCount: + *value = config->PFlashAccessSegmentCount; + break; + + case kFLASH_PropertyFlexRamBlockBaseAddr: + *value = config->FlexRAMBlockBase; + break; + + case kFLASH_PropertyFlexRamTotalSize: + *value = config->FlexRAMTotalSize; + break; + +#if FLASH_SSD_IS_FLEXNVM_ENABLED + case kFLASH_PropertyDflashSectorSize: + *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE; + break; + case kFLASH_PropertyDflashTotalSize: + *value = config->DFlashTotalSize; + break; + case kFLASH_PropertyDflashBlockSize: + *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SIZE; + break; + case kFLASH_PropertyDflashBlockCount: + *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT; + break; + case kFLASH_PropertyDflashBlockBaseAddr: + *value = config->DFlashBlockBase; + break; + case kFLASH_PropertyEepromTotalSize: + *value = config->EEpromTotalSize; + break; +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + + default: /* catch inputs that are not recognized */ + return kStatus_FLASH_UnknownProperty; + } + + return kStatus_FLASH_Success; +} + +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED +status_t FLASH_SetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t value) +{ + status_t status = kStatus_FLASH_Success; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + switch (whichProperty) + { + case kFLASH_PropertyFlashMemoryIndex: + if ((value != (uint32_t)kFLASH_MemoryIndexPrimaryFlash) && + (value != (uint32_t)kFLASH_MemoryIndexSecondaryFlash)) + { + return kStatus_FLASH_InvalidPropertyValue; + } + config->FlashMemoryIndex = value; + break; + + case kFLASH_PropertyPflashSectorSize: + case kFLASH_PropertyPflashTotalSize: + case kFLASH_PropertyPflashBlockSize: + case kFLASH_PropertyPflashBlockCount: + case kFLASH_PropertyPflashBlockBaseAddr: + case kFLASH_PropertyPflashFacSupport: + case kFLASH_PropertyPflashAccessSegmentSize: + case kFLASH_PropertyPflashAccessSegmentCount: + case kFLASH_PropertyFlexRamBlockBaseAddr: + case kFLASH_PropertyFlexRamTotalSize: +#if FLASH_SSD_IS_FLEXNVM_ENABLED + case kFLASH_PropertyDflashSectorSize: + case kFLASH_PropertyDflashTotalSize: + case kFLASH_PropertyDflashBlockSize: + case kFLASH_PropertyDflashBlockCount: + case kFLASH_PropertyDflashBlockBaseAddr: + case kFLASH_PropertyEepromTotalSize: +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + status = kStatus_FLASH_ReadOnlyProperty; + break; + default: /* catch inputs that are not recognized */ + status = kStatus_FLASH_UnknownProperty; + break; + } + + return status; +} +#endif /* FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED */ + +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD +status_t FLASH_SetFlexramFunction(flash_config_t *config, flash_flexram_function_option_t option) +{ + status_t status; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + status = flasn_check_flexram_function_option_range(option); + if (status != kStatus_FLASH_Success) + { + return status; + } + + /* preparing passing parameter to verify all block command */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_SET_FLEXRAM_FUNCTION, option, 0xFFFFU); + + /* calling flash command sequence function to execute the command */ + return flash_command_sequence(config); +} +#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + +#if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD +status_t FLASH_SwapControl(flash_config_t *config, + uint32_t address, + flash_swap_control_option_t option, + flash_swap_state_config_t *returnInfo) +{ + status_t returnCode; + + if ((config == NULL) || (returnInfo == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + if (address & (FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT - 1)) + { + return kStatus_FLASH_AlignmentError; + } + + /* Make sure address provided is in the lower half of Program flash but not in the Flash Configuration Field */ + if ((address >= (config->PFlashTotalSize / 2)) || + ((address >= kFLASH_ConfigAreaStart) && (address <= kFLASH_ConfigAreaEnd))) + { + return kStatus_FLASH_SwapIndicatorAddressError; + } + + /* Check the option. */ + returnCode = flash_check_swap_control_option(option); + if (returnCode) + { + return returnCode; + } + + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_SWAP_CONTROL, address); + kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU); + + returnCode = flash_command_sequence(config); + + returnInfo->flashSwapState = (flash_swap_state_t)FTFx_FCCOB5_REG; + returnInfo->currentSwapBlockStatus = (flash_swap_block_status_t)FTFx_FCCOB6_REG; + returnInfo->nextSwapBlockStatus = (flash_swap_block_status_t)FTFx_FCCOB7_REG; + + return returnCode; +} +#endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */ + +#if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP +status_t FLASH_Swap(flash_config_t *config, uint32_t address, flash_swap_function_option_t option) +{ + flash_swap_state_config_t returnInfo; + status_t returnCode; + + memset(&returnInfo, 0xFFU, sizeof(returnInfo)); + + do + { + returnCode = FLASH_SwapControl(config, address, kFLASH_SwapControlOptionReportStatus, &returnInfo); + if (returnCode != kStatus_FLASH_Success) + { + return returnCode; + } + + if (kFLASH_SwapFunctionOptionDisable == option) + { + if (returnInfo.flashSwapState == kFLASH_SwapStateDisabled) + { + return kStatus_FLASH_Success; + } + else if (returnInfo.flashSwapState == kFLASH_SwapStateUninitialized) + { + /* The swap system changed to the DISABLED state with Program flash block 0 + * located at relative flash address 0x0_0000 */ + returnCode = FLASH_SwapControl(config, address, kFLASH_SwapControlOptionDisableSystem, &returnInfo); + } + else + { + /* Swap disable should be requested only when swap system is in the uninitialized state */ + return kStatus_FLASH_SwapSystemNotInUninitialized; + } + } + else + { + /* When first swap: the initial swap state is Uninitialized, flash swap inidicator address is unset, + * the swap procedure should be Uninitialized -> Update-Erased -> Complete. + * After the first swap has been completed, the flash swap inidicator address cannot be modified + * unless EraseAllBlocks command is issued, the swap procedure is changed to Update -> Update-Erased -> + * Complete. */ + switch (returnInfo.flashSwapState) + { + case kFLASH_SwapStateUninitialized: + /* If current swap mode is Uninitialized, Initialize Swap to Initialized/READY state. */ + returnCode = + FLASH_SwapControl(config, address, kFLASH_SwapControlOptionIntializeSystem, &returnInfo); + break; + case kFLASH_SwapStateReady: + /* Validate whether the address provided to the swap system is matched to + * swap indicator address in the IFR */ + returnCode = flash_validate_swap_indicator_address(config, address); + if (returnCode == kStatus_FLASH_Success) + { + /* If current swap mode is Initialized/Ready, Initialize Swap to UPDATE state. */ + returnCode = + FLASH_SwapControl(config, address, kFLASH_SwapControlOptionSetInUpdateState, &returnInfo); + } + break; + case kFLASH_SwapStateUpdate: + /* If current swap mode is Update, Erase indicator sector in non active block + * to proceed swap system to update-erased state */ + returnCode = FLASH_Erase(config, address + (config->PFlashTotalSize >> 1), + FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT, kFLASH_ApiEraseKey); + break; + case kFLASH_SwapStateUpdateErased: + /* If current swap mode is Update or Update-Erased, progress Swap to COMPLETE State */ + returnCode = + FLASH_SwapControl(config, address, kFLASH_SwapControlOptionSetInCompleteState, &returnInfo); + break; + case kFLASH_SwapStateComplete: + break; + case kFLASH_SwapStateDisabled: + /* When swap system is in disabled state, We need to clear swap system back to uninitialized + * by issuing EraseAllBlocks command */ + returnCode = kStatus_FLASH_SwapSystemNotInUninitialized; + break; + default: + returnCode = kStatus_FLASH_InvalidArgument; + break; + } + } + if (returnCode != kStatus_FLASH_Success) + { + break; + } + } while (!((kFLASH_SwapStateComplete == returnInfo.flashSwapState) && (kFLASH_SwapFunctionOptionEnable == option))); + + return returnCode; +} +#endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ + +#if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD +status_t FLASH_ProgramPartition(flash_config_t *config, + flash_partition_flexram_load_option_t option, + uint32_t eepromDataSizeCode, + uint32_t flexnvmPartitionCode) +{ + status_t returnCode; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* eepromDataSizeCode[7:6], flexnvmPartitionCode[7:4] should be all 1'b0 + * or it will cause access error. */ + /* eepromDataSizeCode &= 0x3FU; */ + /* flexnvmPartitionCode &= 0x0FU; */ + + /* preparing passing parameter to program the flash block */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_2_1(FTFx_PROGRAM_PARTITION, 0xFFFFU, option); + kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_1_2(eepromDataSizeCode, flexnvmPartitionCode, 0xFFFFU); + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + flash_cache_clear(config); + +#if FLASH_SSD_IS_FLEXNVM_ENABLED + /* Data flash IFR will be updated by program partition command during reset sequence, + * so we just set reserved values for partitioned FlexNVM size here */ + config->EEpromTotalSize = FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED; + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif + + return (returnCode); +} +#endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD */ + +status_t FLASH_PflashSetProtection(flash_config_t *config, pflash_protection_status_t *protectStatus) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER + if (config->FlashMemoryIndex == (uint32_t)kFLASH_MemoryIndexSecondaryFlash) + { + *kFPROTSL = protectStatus->valueLow32b.prots16b.protsl; + if (protectStatus->valueLow32b.prots16b.protsl != *kFPROTSL) + { + return kStatus_FLASH_CommandFailure; + } + + *kFPROTSH = protectStatus->valueLow32b.prots16b.protsh; + if (protectStatus->valueLow32b.prots16b.protsh != *kFPROTSH) + { + return kStatus_FLASH_CommandFailure; + } + } + else +#endif + { + *kFPROTL = protectStatus->valueLow32b.protl32b; + if (protectStatus->valueLow32b.protl32b != *kFPROTL) + { + return kStatus_FLASH_CommandFailure; + } + +#if defined(FTFx_FPROT_HIGH_REG) + *kFPROTH = protectStatus->valueHigh32b.proth32b; + if (protectStatus->valueHigh32b.proth32b != *kFPROTH) + { + return kStatus_FLASH_CommandFailure; + } +#endif + } + + return kStatus_FLASH_Success; +} + +status_t FLASH_PflashGetProtection(flash_config_t *config, pflash_protection_status_t *protectStatus) +{ + if ((config == NULL) || (protectStatus == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER + if (config->FlashMemoryIndex == (uint32_t)kFLASH_MemoryIndexSecondaryFlash) + { + protectStatus->valueLow32b.prots16b.protsl = *kFPROTSL; + protectStatus->valueLow32b.prots16b.protsh = *kFPROTSH; + } + else +#endif + { + protectStatus->valueLow32b.protl32b = *kFPROTL; +#if defined(FTFx_FPROT_HIGH_REG) + protectStatus->valueHigh32b.proth32b = *kFPROTH; +#endif + } + + return kStatus_FLASH_Success; +} + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_DflashSetProtection(flash_config_t *config, uint8_t protectStatus) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + if ((config->DFlashTotalSize == 0) || (config->DFlashTotalSize == FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED)) + { + return kStatus_FLASH_CommandNotSupported; + } + + FTFx->FDPROT = protectStatus; + + if (FTFx->FDPROT != protectStatus) + { + return kStatus_FLASH_CommandFailure; + } + + return kStatus_FLASH_Success; +} +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_DflashGetProtection(flash_config_t *config, uint8_t *protectStatus) +{ + if ((config == NULL) || (protectStatus == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + if ((config->DFlashTotalSize == 0) || (config->DFlashTotalSize == FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED)) + { + return kStatus_FLASH_CommandNotSupported; + } + + *protectStatus = FTFx->FDPROT; + + return kStatus_FLASH_Success; +} +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_EepromSetProtection(flash_config_t *config, uint8_t protectStatus) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + if ((config->EEpromTotalSize == 0) || (config->EEpromTotalSize == FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED)) + { + return kStatus_FLASH_CommandNotSupported; + } + + FTFx->FEPROT = protectStatus; + + if (FTFx->FEPROT != protectStatus) + { + return kStatus_FLASH_CommandFailure; + } + + return kStatus_FLASH_Success; +} +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_EepromGetProtection(flash_config_t *config, uint8_t *protectStatus) +{ + if ((config == NULL) || (protectStatus == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + if ((config->EEpromTotalSize == 0) || (config->EEpromTotalSize == FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED)) + { + return kStatus_FLASH_CommandNotSupported; + } + + *protectStatus = FTFx->FEPROT; + + return kStatus_FLASH_Success; +} +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +status_t FLASH_PflashSetPrefetchSpeculation(flash_prefetch_speculation_status_t *speculationStatus) +{ +#if FLASH_DRIVER_IS_FLASH_RESIDENT + void (*flashCommonBitOperationCallback)(FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, + uint32_t bitValue); + uint32_t flashCommonBitOperationBuffer[kFLASH_ExecuteInRamFunctionMaxSizeInWords]; + + assert(sizeof(s_flashCommonBitOperationFunctionCode) <= (kFLASH_ExecuteInRamFunctionMaxSizeInWords * 4)); + + memcpy((void *)flashCommonBitOperationBuffer, (void *)s_flashCommonBitOperationFunctionCode, + sizeof(s_flashCommonBitOperationFunctionCode)); + flashCommonBitOperationCallback = (void (*)(FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, + uint32_t bitValue))((uint32_t)flashCommonBitOperationBuffer + 1); +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +#if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS + { + FTFx_REG32_ACCESS_TYPE regBase; +#if defined(MCM) + regBase = (FTFx_REG32_ACCESS_TYPE)&MCM->PLACR; +#elif defined(MCM0) + regBase = (FTFx_REG32_ACCESS_TYPE)&MCM0->PLACR; +#endif + if (speculationStatus->instructionOption == kFLASH_prefetchSpeculationOptionDisable) + { + if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable) + { + return kStatus_FLASH_InvalidSpeculationOption; + } + else + { +#if FLASH_DRIVER_IS_FLASH_RESIDENT + flashCommonBitOperationCallback(regBase, MCM_PLACR_DFCS_MASK, MCM_PLACR_DFCS_SHIFT, 1U); +#else + *regBase |= MCM_PLACR_DFCS_MASK; +#endif + } + } + else + { +#if FLASH_DRIVER_IS_FLASH_RESIDENT + flashCommonBitOperationCallback(regBase, MCM_PLACR_DFCS_MASK, MCM_PLACR_DFCS_SHIFT, 0U); +#else + *regBase &= ~MCM_PLACR_DFCS_MASK; +#endif + if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable) + { +#if FLASH_DRIVER_IS_FLASH_RESIDENT + flashCommonBitOperationCallback(regBase, MCM_PLACR_EFDS_MASK, MCM_PLACR_EFDS_SHIFT, 1U); +#else + *regBase |= MCM_PLACR_EFDS_MASK; +#endif + } + else + { +#if FLASH_DRIVER_IS_FLASH_RESIDENT + flashCommonBitOperationCallback(regBase, MCM_PLACR_EFDS_MASK, MCM_PLACR_EFDS_SHIFT, 0U); +#else + *regBase &= ~MCM_PLACR_EFDS_MASK; +#endif + } + } + } +#elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS + { + FTFx_REG32_ACCESS_TYPE regBase; + uint32_t b0dpeMask, b0ipeMask; +#if FLASH_DRIVER_IS_FLASH_RESIDENT + uint32_t b0dpeShift, b0ipeShift; +#endif +#if defined(FMC_PFB01CR_B0DPE_MASK) + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR; + b0dpeMask = FMC_PFB01CR_B0DPE_MASK; + b0ipeMask = FMC_PFB01CR_B0IPE_MASK; +#if FLASH_DRIVER_IS_FLASH_RESIDENT + b0dpeShift = FMC_PFB01CR_B0DPE_SHIFT; + b0ipeShift = FMC_PFB01CR_B0IPE_SHIFT; +#endif +#elif defined(FMC_PFB0CR_B0DPE_MASK) + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR; + b0dpeMask = FMC_PFB0CR_B0DPE_MASK; + b0ipeMask = FMC_PFB0CR_B0IPE_MASK; +#if FLASH_DRIVER_IS_FLASH_RESIDENT + b0dpeShift = FMC_PFB0CR_B0DPE_SHIFT; + b0ipeShift = FMC_PFB0CR_B0IPE_SHIFT; +#endif +#endif + if (speculationStatus->instructionOption == kFLASH_prefetchSpeculationOptionEnable) + { +#if FLASH_DRIVER_IS_FLASH_RESIDENT + flashCommonBitOperationCallback(regBase, b0ipeMask, b0ipeShift, 1U); +#else + *regBase |= b0ipeMask; +#endif + } + else + { +#if FLASH_DRIVER_IS_FLASH_RESIDENT + flashCommonBitOperationCallback(regBase, b0ipeMask, b0ipeShift, 0U); +#else + *regBase &= ~b0ipeMask; +#endif + } + if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable) + { +#if FLASH_DRIVER_IS_FLASH_RESIDENT + flashCommonBitOperationCallback(regBase, b0dpeMask, b0dpeShift, 1U); +#else + *regBase |= b0dpeMask; +#endif + } + else + { +#if FLASH_DRIVER_IS_FLASH_RESIDENT + flashCommonBitOperationCallback(regBase, b0dpeMask, b0dpeShift, 0U); +#else + *regBase &= ~b0dpeMask; +#endif + } + +/* Invalidate Prefetch Speculation Buffer */ +#if defined(FMC_PFB01CR_S_INV_MASK) + FMC->PFB01CR |= FMC_PFB01CR_S_INV_MASK; +#elif defined(FMC_PFB0CR_S_INV_MASK) + FMC->PFB0CR |= FMC_PFB0CR_S_INV_MASK; +#endif + } +#elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS + { + FTFx_REG32_ACCESS_TYPE regBase; + uint32_t flashSpeculationMask, dataPrefetchMask; +#if FLASH_DRIVER_IS_FLASH_RESIDENT + uint32_t flashSpeculationShift, dataPrefetchShift; + flashSpeculationShift = MSCM_OCMDR_OCMC1_DFCS_SHIFT; + dataPrefetchShift = MSCM_OCMDR_OCMC1_DFDS_SHIFT; +#endif + + regBase = (FTFx_REG32_ACCESS_TYPE)&MSCM->OCMDR[0]; + flashSpeculationMask = MSCM_OCMDR_OCMC1_DFCS_MASK; + dataPrefetchMask = MSCM_OCMDR_OCMC1_DFDS_MASK; + + if (speculationStatus->instructionOption == kFLASH_prefetchSpeculationOptionDisable) + { + if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable) + { + return kStatus_FLASH_InvalidSpeculationOption; + } + else + { +#if FLASH_DRIVER_IS_FLASH_RESIDENT + flashCommonBitOperationCallback(regBase, flashSpeculationMask, flashSpeculationShift, 1U); +#else + *regBase |= flashSpeculationMask; +#endif + } + } + else + { + *regBase &= ~flashSpeculationMask; + if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable) + { +#if FLASH_DRIVER_IS_FLASH_RESIDENT + flashCommonBitOperationCallback(regBase, dataPrefetchMask, dataPrefetchShift, 0U); +#else + *regBase &= ~dataPrefetchMask; +#endif + } + else + { +#if FLASH_DRIVER_IS_FLASH_RESIDENT + flashCommonBitOperationCallback(regBase, dataPrefetchMask, dataPrefetchShift, 1U); +#else + *regBase |= dataPrefetchMask; +#endif + } + } + } +#else +#if FLASH_DRIVER_IS_FLASH_RESIDENT + flashCommonBitOperationCallback((FTFx_REG32_ACCESS_TYPE)0, 0, 0, 0); +#endif +#endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ + + return kStatus_FLASH_Success; +} + +status_t FLASH_PflashGetPrefetchSpeculation(flash_prefetch_speculation_status_t *speculationStatus) +{ + memset(speculationStatus, 0, sizeof(flash_prefetch_speculation_status_t)); + + /* Assuming that all speculation options are enabled. */ + speculationStatus->instructionOption = kFLASH_prefetchSpeculationOptionEnable; + speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionEnable; + +#if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS + { + uint32_t value; +#if defined(MCM) + value = MCM->PLACR; +#elif defined(MCM0) + value = MCM0->PLACR; +#endif + if (value & MCM_PLACR_DFCS_MASK) + { + /* Speculation buffer is off. */ + speculationStatus->instructionOption = kFLASH_prefetchSpeculationOptionDisable; + speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable; + } + else + { + /* Speculation buffer is on for instruction. */ + if (!(value & MCM_PLACR_EFDS_MASK)) + { + /* Speculation buffer is off for data. */ + speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable; + } + } + } +#elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS + { + uint32_t value; + uint32_t b0dpeMask, b0ipeMask; +#if defined(FMC_PFB01CR_B0DPE_MASK) + value = FMC->PFB01CR; + b0dpeMask = FMC_PFB01CR_B0DPE_MASK; + b0ipeMask = FMC_PFB01CR_B0IPE_MASK; +#elif defined(FMC_PFB0CR_B0DPE_MASK) + value = FMC->PFB0CR; + b0dpeMask = FMC_PFB0CR_B0DPE_MASK; + b0ipeMask = FMC_PFB0CR_B0IPE_MASK; +#endif + if (!(value & b0dpeMask)) + { + /* Do not prefetch in response to data references. */ + speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable; + } + if (!(value & b0ipeMask)) + { + /* Do not prefetch in response to instruction fetches. */ + speculationStatus->instructionOption = kFLASH_prefetchSpeculationOptionDisable; + } + } +#elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS + { + uint32_t value; + uint32_t flashSpeculationMask, dataPrefetchMask; + value = MSCM->OCMDR[0]; + flashSpeculationMask = MSCM_OCMDR_OCMC1_DFCS_MASK; + dataPrefetchMask = MSCM_OCMDR_OCMC1_DFDS_MASK; + + if (value & flashSpeculationMask) + { + /* Speculation buffer is off. */ + speculationStatus->instructionOption = kFLASH_prefetchSpeculationOptionDisable; + speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable; + } + else + { + /* Speculation buffer is on for instruction. */ + if (value & dataPrefetchMask) + { + /* Speculation buffer is off for data. */ + speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable; + } + } + } +#endif + + return kStatus_FLASH_Success; +} + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +/*! + * @brief Copy PIC of flash_run_command() to RAM + */ +static void copy_flash_run_command(uint32_t *flashRunCommand) +{ + assert(sizeof(s_flashRunCommandFunctionCode) <= (kFLASH_ExecuteInRamFunctionMaxSizeInWords * 4)); + + /* Since the value of ARM function pointer is always odd, but the real start address + * of function memory should be even, that's why +1 operation exist. */ + memcpy((void *)flashRunCommand, (void *)s_flashRunCommandFunctionCode, sizeof(s_flashRunCommandFunctionCode)); + callFlashRunCommand = (void (*)(FTFx_REG8_ACCESS_TYPE ftfx_fstat))((uint32_t)flashRunCommand + 1); +} +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +/*! + * @brief Flash Command Sequence + * + * This function is used to perform the command write sequence to the flash. + * + * @param driver Pointer to storage for the driver runtime state. + * @return An error code or kStatus_FLASH_Success + */ +static status_t flash_command_sequence(flash_config_t *config) +{ + uint8_t registerValue; + +#if FLASH_DRIVER_IS_FLASH_RESIDENT + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */ + FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK; + + status_t returnCode = flash_check_execute_in_ram_function_info(config); + if (kStatus_FLASH_Success != returnCode) + { + return returnCode; + } + + /* We pass the ftfx_fstat address as a parameter to flash_run_comamnd() instead of using + * pre-processed MICRO sentences or operating global variable in flash_run_comamnd() + * to make sure that flash_run_command() will be compiled into position-independent code (PIC). */ + callFlashRunCommand((FTFx_REG8_ACCESS_TYPE)(&FTFx->FSTAT)); +#else + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */ + FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK; + + /* clear CCIF bit */ + FTFx->FSTAT = FTFx_FSTAT_CCIF_MASK; + + /* Check CCIF bit of the flash status register, wait till it is set. + * IP team indicates that this loop will always complete. */ + while (!(FTFx->FSTAT & FTFx_FSTAT_CCIF_MASK)) + { + } +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + + /* Check error bits */ + /* Get flash status register value */ + registerValue = FTFx->FSTAT; + + /* checking access error */ + if (registerValue & FTFx_FSTAT_ACCERR_MASK) + { + return kStatus_FLASH_AccessError; + } + /* checking protection error */ + else if (registerValue & FTFx_FSTAT_FPVIOL_MASK) + { + return kStatus_FLASH_ProtectionViolation; + } + /* checking MGSTAT0 non-correctable error */ + else if (registerValue & FTFx_FSTAT_MGSTAT0_MASK) + { + return kStatus_FLASH_CommandFailure; + } + else + { + return kStatus_FLASH_Success; + } +} + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +/*! + * @brief Copy PIC of flash_common_bit_operation() to RAM + * + */ +static void copy_flash_common_bit_operation(uint32_t *flashCommonBitOperation) +{ + assert(sizeof(s_flashCommonBitOperationFunctionCode) <= (kFLASH_ExecuteInRamFunctionMaxSizeInWords * 4)); + + /* Since the value of ARM function pointer is always odd, but the real start address + * of function memory should be even, that's why +1 operation exist. */ + memcpy((void *)flashCommonBitOperation, (void *)s_flashCommonBitOperationFunctionCode, + sizeof(s_flashCommonBitOperationFunctionCode)); + callFlashCommonBitOperation = (void (*)(FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, + uint32_t bitValue))((uint32_t)flashCommonBitOperation + 1); +} +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +/*! + * @brief Flash Cache Clear + * + * This function is used to perform the cache clear to the flash. + */ +#if (defined(__GNUC__)) +/* #pragma GCC push_options */ +/* #pragma GCC optimize("O0") */ +void __attribute__((optimize("O0"))) flash_cache_clear(flash_config_t *config) +#else +#if (defined(__ICCARM__)) +#pragma optimize = none +#endif +#if (defined(__CC_ARM)) +#pragma push +#pragma O0 +#endif +void flash_cache_clear(flash_config_t *config) +#endif +{ +#if FLASH_DRIVER_IS_FLASH_RESIDENT + FTFx_REG32_ACCESS_TYPE regBase = (FTFx_REG32_ACCESS_TYPE)0; + status_t returnCode = flash_check_execute_in_ram_function_info(config); + if (kStatus_FLASH_Success != returnCode) + { + return; + } + +/* We pass the ftfx register address as a parameter to flash_common_bit_operation() instead of using + * pre-processed MACROs or a global variable in flash_common_bit_operation() + * to make sure that flash_common_bit_operation() will be compiled into position-independent code (PIC). */ +#if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS +#if defined(MCM) + regBase = (FTFx_REG32_ACCESS_TYPE)&MCM->PLACR; + callFlashCommonBitOperation(regBase, MCM_PLACR_CFCC_MASK, MCM_PLACR_CFCC_SHIFT, 1U); +#endif +#if defined(MCM0) + regBase = (FTFx_REG32_ACCESS_TYPE)&MCM0->PLACR; + callFlashCommonBitOperation(regBase, MCM_PLACR_CFCC_MASK, MCM_PLACR_CFCC_SHIFT, 1U); +#endif +#if defined(MCM1) + regBase = (FTFx_REG32_ACCESS_TYPE)&MCM1->PLACR; + callFlashCommonBitOperation(regBase, MCM_PLACR_CFCC_MASK, MCM_PLACR_CFCC_SHIFT, 1U); +#endif +#elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS +#if defined(FMC_PFB01CR_CINV_WAY_MASK) + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR; + callFlashCommonBitOperation(regBase, FMC_PFB01CR_CINV_WAY_MASK, FMC_PFB01CR_CINV_WAY_SHIFT, 0xFU); +#else + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR; + callFlashCommonBitOperation(regBase, FMC_PFB0CR_CINV_WAY_MASK, FMC_PFB0CR_CINV_WAY_SHIFT, 0xFU); +#endif +#elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS + regBase = (FTFx_REG32_ACCESS_TYPE)&MSCM->OCMDR[0]; +#if defined(MSCM_OCMDR_OCM1_MASK) + callFlashCommonBitOperation(regBase, MSCM_OCMDR_OCM1_MASK, MSCM_OCMDR_OCM1_SHIFT, 0x3U); +#else + callFlashCommonBitOperation(regBase, MSCM_OCMDR_OCMC1_MASK, MSCM_OCMDR_OCMC1_SHIFT, 0x3U); +#endif +#if FLASH_SSD_IS_FLEXNVM_ENABLED + regBase = (FTFx_REG32_ACCESS_TYPE)&MSCM->OCMDR[1]; +#if defined(MSCM_OCMDR_OCM1_MASK) + callFlashCommonBitOperation(regBase, MSCM_OCMDR_OCM1_MASK, MSCM_OCMDR_OCM1_SHIFT, 0x3U); +#else + callFlashCommonBitOperation(regBase, MSCM_OCMDR_OCMC1_MASK, MSCM_OCMDR_OCMC1_SHIFT, 0x3U); +#endif +#endif +#else +#if defined(FMC_PFB0CR_S_INV_MASK) + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR; + callFlashCommonBitOperation(regBase, FMC_PFB0CR_S_INV_MASK, FMC_PFB0CR_S_INV_SHIFT, 1U); +#elif defined(FMC_PFB01CR_S_INV_MASK) + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR; + callFlashCommonBitOperation(regBase, FMC_PFB01CR_S_INV_MASK, FMC_PFB01CR_S_INV_SHIFT, 1U); +#endif +/* #error "Unknown flash cache controller" */ +#endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ + + callFlashCommonBitOperation(regBase, 0, 0, 0); +#else + +#if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS +#if defined(MCM) + MCM->PLACR |= MCM_PLACR_CFCC_MASK; +#endif +#if defined(MCM0) + MCM0->PLACR |= MCM_PLACR_CFCC_MASK; +#endif +#if defined(MCM1) + MCM1->PLACR |= MCM_PLACR_CFCC_MASK; +#endif +#elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS +#if defined(FMC_PFB01CR_CINV_WAY_MASK) + FMC->PFB01CR = (FMC->PFB01CR & ~FMC_PFB01CR_CINV_WAY_MASK) | FMC_PFB01CR_CINV_WAY(~0); +#else + FMC->PFB0CR = (FMC->PFB0CR & ~FMC_PFB0CR_CINV_WAY_MASK) | FMC_PFB0CR_CINV_WAY(~0); +#endif +#elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS +#if defined(MSCM_OCMDR_OCM1_MASK) + MSCM->OCMDR[0] |= MSCM_OCMDR_OCM1(3); +#else + MSCM->OCMDR[0] |= MSCM_OCMDR_OCMC1(3); +#endif +#if FLASH_SSD_IS_FLEXNVM_ENABLED +#if defined(MSCM_OCMDR_OCM1_MASK) + MSCM->OCMDR[1] |= MSCM_OCMDR_OCM1(3); +#else + MSCM->OCMDR[1] |= MSCM_OCMDR_OCMC1(3); +#endif +#endif +#else +#if defined(FMC_PFB0CR_S_INV_MASK) + FMC->PFB0CR |= FMC_PFB0CR_S_INV_MASK; +#elif defined(FMC_PFB01CR_S_INV_MASK) + FMC->PFB01CR |= FMC_PFB01CR_S_INV_MASK; +#endif +/* #error "Unknown flash cache controller" */ +#endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ + + /* Memory barriers for good measure. + * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ + __ISB(); + __DSB(); +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ +} +#if (defined(__CC_ARM)) +#pragma pop +#endif +#if (defined(__GNUC__)) +/* #pragma GCC pop_options */ +#endif + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +/*! @brief Check whether flash execute-in-ram functions are ready */ +static status_t flash_check_execute_in_ram_function_info(flash_config_t *config) +{ + flash_execute_in_ram_function_config_t *flashExecuteInRamFunctionInfo; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + flashExecuteInRamFunctionInfo = (flash_execute_in_ram_function_config_t *)config->flashExecuteInRamFunctionInfo; + + if ((config->flashExecuteInRamFunctionInfo) && + (kFLASH_ExecuteInRamFunctionTotalNum == flashExecuteInRamFunctionInfo->activeFunctionCount)) + { + return kStatus_FLASH_Success; + } + + return kStatus_FLASH_ExecuteInRamFunctionNotReady; +} +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +/*! @brief Validates the range and alignment of the given address range.*/ +static status_t flash_check_range(flash_config_t *config, + uint32_t startAddress, + uint32_t lengthInBytes, + uint32_t alignmentBaseline) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Verify the start and length are alignmentBaseline aligned. */ + if ((startAddress & (alignmentBaseline - 1)) || (lengthInBytes & (alignmentBaseline - 1))) + { + return kStatus_FLASH_AlignmentError; + } + + /* check for valid range of the target addresses */ + if ( +#if FLASH_SSD_IS_FLEXNVM_ENABLED + ((startAddress >= config->DFlashBlockBase) && + ((startAddress + lengthInBytes) <= (config->DFlashBlockBase + config->DFlashTotalSize))) || +#endif + ((startAddress >= config->PFlashBlockBase) && + ((startAddress + lengthInBytes) <= (config->PFlashBlockBase + config->PFlashTotalSize)))) + { + return kStatus_FLASH_Success; + } + + return kStatus_FLASH_AddressError; +} + +/*! @brief Gets the right address, sector and block size of current flash type which is indicated by address.*/ +static status_t flash_get_matched_operation_info(flash_config_t *config, + uint32_t address, + flash_operation_config_t *info) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Clean up info Structure*/ + memset(info, 0, sizeof(flash_operation_config_t)); + +#if FLASH_SSD_IS_FLEXNVM_ENABLED + if ((address >= config->DFlashBlockBase) && (address <= (config->DFlashBlockBase + config->DFlashTotalSize))) + { + /* When required by the command, address bit 23 selects between program flash memory + * (=0) and data flash memory (=1).*/ + info->convertedAddress = address - config->DFlashBlockBase + 0x800000U; + info->activeSectorSize = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE; + info->activeBlockSize = config->DFlashTotalSize / FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT; + + info->blockWriteUnitSize = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_WRITE_UNIT_SIZE; + info->sectorCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_SECTOR_CMD_ADDRESS_ALIGMENT; + info->sectionCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_SECTION_CMD_ADDRESS_ALIGMENT; + info->resourceCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_RESOURCE_CMD_ADDRESS_ALIGMENT; + info->checkCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_CHECK_CMD_ADDRESS_ALIGMENT; + } + else +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + { + info->convertedAddress = address - config->PFlashBlockBase; + info->activeSectorSize = config->PFlashSectorSize; + info->activeBlockSize = config->PFlashTotalSize / config->PFlashBlockCount; +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED + if (config->FlashMemoryIndex == (uint32_t)kFLASH_MemoryIndexSecondaryFlash) + { +#if FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER || FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER + /* When required by the command, address bit 23 selects between main flash memory + * (=0) and secondary flash memory (=1).*/ + info->convertedAddress += 0x800000U; +#endif + info->blockWriteUnitSize = FSL_FEATURE_FLASH_PFLASH_1_BLOCK_WRITE_UNIT_SIZE; + } + else +#endif /* FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED */ + { + info->blockWriteUnitSize = FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE; + } + + info->sectorCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT; + info->sectionCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT; + info->resourceCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_RESOURCE_CMD_ADDRESS_ALIGMENT; + info->checkCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT; + } + + return kStatus_FLASH_Success; +} + +/*! @brief Validates the given user key for flash erase APIs.*/ +static status_t flash_check_user_key(uint32_t key) +{ + /* Validate the user key */ + if (key != kFLASH_ApiEraseKey) + { + return kStatus_FLASH_EraseKeyError; + } + + return kStatus_FLASH_Success; +} + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +/*! @brief Updates FlexNVM memory partition status according to data flash 0 IFR.*/ +static status_t flash_update_flexnvm_memory_partition_status(flash_config_t *config) +{ + struct + { + uint32_t reserved0; + uint8_t FlexNVMPartitionCode; + uint8_t EEPROMDataSetSize; + uint16_t reserved1; + } dataIFRReadOut; + status_t returnCode; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Get FlexNVM memory partition info from data flash IFR */ + returnCode = FLASH_ReadResource(config, DFLASH_IFR_READRESOURCE_START_ADDRESS, (uint32_t *)&dataIFRReadOut, + sizeof(dataIFRReadOut), kFLASH_ResourceOptionFlashIfr); + if (returnCode != kStatus_FLASH_Success) + { + return kStatus_FLASH_PartitionStatusUpdateFailure; + } + + /* Fill out partitioned EEPROM size */ + dataIFRReadOut.EEPROMDataSetSize &= 0x0FU; + switch (dataIFRReadOut.EEPROMDataSetSize) + { + case 0x00U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0000; + break; + case 0x01U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0001; + break; + case 0x02U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0010; + break; + case 0x03U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0011; + break; + case 0x04U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0100; + break; + case 0x05U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0101; + break; + case 0x06U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0110; + break; + case 0x07U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0111; + break; + case 0x08U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1000; + break; + case 0x09U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1001; + break; + case 0x0AU: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1010; + break; + case 0x0BU: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1011; + break; + case 0x0CU: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1100; + break; + case 0x0DU: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1101; + break; + case 0x0EU: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110; + break; + case 0x0FU: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111; + break; + default: + config->EEpromTotalSize = FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED; + break; + } + + /* Fill out partitioned DFlash size */ + dataIFRReadOut.FlexNVMPartitionCode &= 0x0FU; + switch (dataIFRReadOut.FlexNVMPartitionCode) + { + case 0x00U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 */ + break; + case 0x01U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 */ + break; + case 0x02U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 */ + break; + case 0x03U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 */ + break; + case 0x04U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 */ + break; + case 0x05U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 */ + break; + case 0x06U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 */ + break; + case 0x07U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 */ + break; + case 0x08U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 */ + break; + case 0x09U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 */ + break; + case 0x0AU: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 */ + break; + case 0x0BU: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 */ + break; + case 0x0CU: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 */ + break; + case 0x0DU: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 */ + break; + case 0x0EU: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 */ + break; + case 0x0FU: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 */ + break; + default: + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; + break; + } + + return kStatus_FLASH_Success; +} +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD +/*! @brief Validates the range of the given resource address.*/ +static status_t flash_check_resource_range(uint32_t start, + uint32_t lengthInBytes, + uint32_t alignmentBaseline, + flash_read_resource_option_t option) +{ + status_t status; + uint32_t maxReadbleAddress; + + if ((start & (alignmentBaseline - 1)) || (lengthInBytes & (alignmentBaseline - 1))) + { + return kStatus_FLASH_AlignmentError; + } + + status = kStatus_FLASH_Success; + + maxReadbleAddress = start + lengthInBytes - 1; + if (option == kFLASH_ResourceOptionVersionId) + { + if ((start != kFLASH_ResourceRangeVersionIdStart) || + ((start + lengthInBytes - 1) != kFLASH_ResourceRangeVersionIdEnd)) + { + status = kStatus_FLASH_InvalidArgument; + } + } + else if (option == kFLASH_ResourceOptionFlashIfr) + { + if (maxReadbleAddress < kFLASH_ResourceRangePflashIfrSizeInBytes) + { + } +#if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP + else if ((start >= kFLASH_ResourceRangePflashSwapIfrStart) && + (maxReadbleAddress <= kFLASH_ResourceRangePflashSwapIfrEnd)) + { + } +#endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ + else if ((start >= kFLASH_ResourceRangeDflashIfrStart) && + (maxReadbleAddress <= kFLASH_ResourceRangeDflashIfrEnd)) + { + } + else + { + status = kStatus_FLASH_InvalidArgument; + } + } + else + { + status = kStatus_FLASH_InvalidArgument; + } + + return status; +} +#endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ + +#if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD +/*! @brief Validates the gived swap control option.*/ +static status_t flash_check_swap_control_option(flash_swap_control_option_t option) +{ + if ((option == kFLASH_SwapControlOptionIntializeSystem) || (option == kFLASH_SwapControlOptionSetInUpdateState) || + (option == kFLASH_SwapControlOptionSetInCompleteState) || (option == kFLASH_SwapControlOptionReportStatus) || + (option == kFLASH_SwapControlOptionDisableSystem)) + { + return kStatus_FLASH_Success; + } + + return kStatus_FLASH_InvalidArgument; +} +#endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */ + +#if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP +/*! @brief Validates the gived address to see if it is equal to swap indicator address in pflash swap IFR.*/ +static status_t flash_validate_swap_indicator_address(flash_config_t *config, uint32_t address) +{ + flash_swap_ifr_field_data_t flashSwapIfrFieldData; + uint32_t swapIndicatorAddress; + + status_t returnCode; + returnCode = + FLASH_ReadResource(config, kFLASH_ResourceRangePflashSwapIfrStart, flashSwapIfrFieldData.flashSwapIfrData, + sizeof(flashSwapIfrFieldData.flashSwapIfrData), kFLASH_ResourceOptionFlashIfr); + + if (returnCode != kStatus_FLASH_Success) + { + return returnCode; + } + + /* The high bits value of Swap Indicator Address is stored in Program Flash Swap IFR Field, + * the low severval bit value of Swap Indicator Address is always 1'b0 */ + swapIndicatorAddress = (uint32_t)flashSwapIfrFieldData.flashSwapIfrField.swapIndicatorAddress * + FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT; + if (address != swapIndicatorAddress) + { + return kStatus_FLASH_SwapIndicatorAddressError; + } + + return returnCode; +} +#endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ + +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD +/*! @brief Validates the gived flexram function option.*/ +static inline status_t flasn_check_flexram_function_option_range(flash_flexram_function_option_t option) +{ + if ((option != kFLASH_FlexramFunctionOptionAvailableAsRam) && + (option != kFLASH_FlexramFunctionOptionAvailableForEeprom)) + { + return kStatus_FLASH_InvalidArgument; + } + + return kStatus_FLASH_Success; +} +#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + +/*! @brief Gets the flash protection information (region size, region count).*/ +static status_t flash_get_protection_info(flash_config_t *config, flash_protection_config_t *info) +{ + uint32_t pflashTotalSize; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Clean up info Structure*/ + memset(info, 0, sizeof(flash_protection_config_t)); + +/* Note: KW40 has a secondary flash, but it doesn't have independent protection register*/ +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED && (!FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER) + pflashTotalSize = FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE + + FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SIZE; + info->regionBase = FSL_FEATURE_FLASH_PFLASH_START_ADDRESS; +#else + pflashTotalSize = config->PFlashTotalSize; + info->regionBase = config->PFlashBlockBase; +#endif + +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER + if (config->FlashMemoryIndex == (uint32_t)kFLASH_MemoryIndexSecondaryFlash) + { + info->regionCount = FSL_FEATURE_FLASH_PFLASH_1_PROTECTION_REGION_COUNT; + } + else +#endif + { + info->regionCount = FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT; + } + + /* Calculate the size of the flash protection region + * If the flash density is > 32KB, then protection region is 1/32 of total flash density + * Else if flash density is < 32KB, then flash protection region is set to 1KB */ + if (pflashTotalSize > info->regionCount * 1024) + { + info->regionSize = (pflashTotalSize) / info->regionCount; + } + else + { + info->regionSize = 1024; + } + + return kStatus_FLASH_Success; +} + +#if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL +/*! @brief Gets the flash Execute-Only access information (Segment size, Segment count).*/ +static status_t flash_get_access_info(flash_config_t *config, flash_access_config_t *info) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Clean up info Structure*/ + memset(info, 0, sizeof(flash_access_config_t)); + +/* Note: KW40 has a secondary flash, but it doesn't have independent access register*/ +#if FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED && (!FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER) + info->SegmentBase = FSL_FEATURE_FLASH_PFLASH_START_ADDRESS; +#else + info->SegmentBase = config->PFlashBlockBase; +#endif + info->SegmentSize = config->PFlashAccessSegmentSize; + info->SegmentCount = config->PFlashAccessSegmentCount; + + return kStatus_FLASH_Success; +} +#endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flash.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flash.h new file mode 100644 index 00000000000..457309c6ef4 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flash.h @@ -0,0 +1,1368 @@ +/* + * Copyright (c) 2013-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_FLASH_H_ +#define _FSL_FLASH_H_ + +#if (defined(BL_TARGET_FLASH) || defined(BL_TARGET_ROM) || defined(BL_TARGET_RAM)) +#include +#include +#include "fsl_device_registers.h" +#include "bootloader_common.h" +#else +#include "fsl_common.h" +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @addtogroup flash_driver + * @{ + */ + +/*! + * @name Flash version + * @{ + */ +/*! @brief Constructs the version number for drivers. */ +#if !defined(MAKE_VERSION) +#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) +#endif + +/*! @brief Flash driver version for SDK*/ +#define FSL_FLASH_DRIVER_VERSION (MAKE_VERSION(2, 2, 0)) /*!< Version 2.2.0. */ + +/*! @brief Flash driver version for ROM*/ +enum _flash_driver_version_constants +{ + kFLASH_DriverVersionName = 'F', /*!< Flash driver version name.*/ + kFLASH_DriverVersionMajor = 2, /*!< Major flash driver version.*/ + kFLASH_DriverVersionMinor = 2, /*!< Minor flash driver version.*/ + kFLASH_DriverVersionBugfix = 0 /*!< Bugfix for flash driver version.*/ +}; +/*@}*/ + +/*! + * @name Flash configuration + * @{ + */ +/*! @brief Indicates whether to support FlexNVM in the Flash driver */ +#if !defined(FLASH_SSD_CONFIG_ENABLE_FLEXNVM_SUPPORT) +#define FLASH_SSD_CONFIG_ENABLE_FLEXNVM_SUPPORT 1 /*!< Enables the FlexNVM support by default. */ +#endif + +/*! @brief Indicates whether the FlexNVM is enabled in the Flash driver */ +#define FLASH_SSD_IS_FLEXNVM_ENABLED (FLASH_SSD_CONFIG_ENABLE_FLEXNVM_SUPPORT && FSL_FEATURE_FLASH_HAS_FLEX_NVM) + +/*! @brief Indicates whether the secondary flash is supported in the Flash driver */ +#if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) || defined(FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS) +#define FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED (1) +#else +#define FLASH_SSD_IS_SECONDARY_FLASH_SUPPORTED (0) +#endif + +/*! @brief Indicates whether the secondary flash has its own protection register in flash module */ +#if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) && defined(FTFE_FPROTS_PROTS_MASK) +#define FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER (1) +#else +#define FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER (0) +#endif + +/*! @brief Indicates whether the secondary flash has its own Execute-Only access register in flash module */ +#if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) && defined(FTFE_FACSSS_SGSIZE_S_MASK) +#define FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER (1) +#else +#define FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER (0) +#endif + +/*! @brief Flash driver location. */ +#if !defined(FLASH_DRIVER_IS_FLASH_RESIDENT) +#if (!defined(BL_TARGET_ROM) && !defined(BL_TARGET_RAM)) +#define FLASH_DRIVER_IS_FLASH_RESIDENT 1 /*!< Used for the flash resident application. */ +#else +#define FLASH_DRIVER_IS_FLASH_RESIDENT 0 /*!< Used for the non-flash resident application. */ +#endif +#endif + +/*! @brief Flash Driver Export option */ +#if !defined(FLASH_DRIVER_IS_EXPORTED) +#if (defined(BL_TARGET_ROM) || defined(BL_TARGET_FLASH)) +#define FLASH_DRIVER_IS_EXPORTED 1 /*!< Used for the ROM bootloader. */ +#else +#define FLASH_DRIVER_IS_EXPORTED 0 /*!< Used for the KSDK application. */ +#endif +#endif +/*@}*/ + +/*! + * @name Flash status + * @{ + */ +/*! @brief Flash driver status group. */ +#if defined(kStatusGroup_FlashDriver) +#define kStatusGroupGeneric kStatusGroup_Generic +#define kStatusGroupFlashDriver kStatusGroup_FlashDriver +#elif defined(kStatusGroup_FLASH) +#define kStatusGroupGeneric kStatusGroup_Generic +#define kStatusGroupFlashDriver kStatusGroup_FLASH +#else +#define kStatusGroupGeneric 0 +#define kStatusGroupFlashDriver 1 +#endif + +/*! @brief Constructs a status code value from a group and a code number. */ +#if !defined(MAKE_STATUS) +#define MAKE_STATUS(group, code) ((((group)*100) + (code))) +#endif + +/*! + * @brief Flash driver status codes. + */ +enum _flash_status +{ + kStatus_FLASH_Success = MAKE_STATUS(kStatusGroupGeneric, 0), /*!< API is executed successfully*/ + kStatus_FLASH_InvalidArgument = MAKE_STATUS(kStatusGroupGeneric, 4), /*!< Invalid argument*/ + kStatus_FLASH_SizeError = MAKE_STATUS(kStatusGroupFlashDriver, 0), /*!< Error size*/ + kStatus_FLASH_AlignmentError = + MAKE_STATUS(kStatusGroupFlashDriver, 1), /*!< Parameter is not aligned with the specified baseline*/ + kStatus_FLASH_AddressError = MAKE_STATUS(kStatusGroupFlashDriver, 2), /*!< Address is out of range */ + kStatus_FLASH_AccessError = + MAKE_STATUS(kStatusGroupFlashDriver, 3), /*!< Invalid instruction codes and out-of bound addresses */ + kStatus_FLASH_ProtectionViolation = MAKE_STATUS( + kStatusGroupFlashDriver, 4), /*!< The program/erase operation is requested to execute on protected areas */ + kStatus_FLASH_CommandFailure = + MAKE_STATUS(kStatusGroupFlashDriver, 5), /*!< Run-time error during command execution. */ + kStatus_FLASH_UnknownProperty = MAKE_STATUS(kStatusGroupFlashDriver, 6), /*!< Unknown property.*/ + kStatus_FLASH_EraseKeyError = MAKE_STATUS(kStatusGroupFlashDriver, 7), /*!< API erase key is invalid.*/ + kStatus_FLASH_RegionExecuteOnly = + MAKE_STATUS(kStatusGroupFlashDriver, 8), /*!< The current region is execute-only.*/ + kStatus_FLASH_ExecuteInRamFunctionNotReady = + MAKE_STATUS(kStatusGroupFlashDriver, 9), /*!< Execute-in-RAM function is not available.*/ + kStatus_FLASH_PartitionStatusUpdateFailure = + MAKE_STATUS(kStatusGroupFlashDriver, 10), /*!< Failed to update partition status.*/ + kStatus_FLASH_SetFlexramAsEepromError = + MAKE_STATUS(kStatusGroupFlashDriver, 11), /*!< Failed to set FlexRAM as EEPROM.*/ + kStatus_FLASH_RecoverFlexramAsRamError = + MAKE_STATUS(kStatusGroupFlashDriver, 12), /*!< Failed to recover FlexRAM as RAM.*/ + kStatus_FLASH_SetFlexramAsRamError = MAKE_STATUS(kStatusGroupFlashDriver, 13), /*!< Failed to set FlexRAM as RAM.*/ + kStatus_FLASH_RecoverFlexramAsEepromError = + MAKE_STATUS(kStatusGroupFlashDriver, 14), /*!< Failed to recover FlexRAM as EEPROM.*/ + kStatus_FLASH_CommandNotSupported = MAKE_STATUS(kStatusGroupFlashDriver, 15), /*!< Flash API is not supported.*/ + kStatus_FLASH_SwapSystemNotInUninitialized = + MAKE_STATUS(kStatusGroupFlashDriver, 16), /*!< Swap system is not in an uninitialzed state.*/ + kStatus_FLASH_SwapIndicatorAddressError = + MAKE_STATUS(kStatusGroupFlashDriver, 17), /*!< The swap indicator address is invalid.*/ + kStatus_FLASH_ReadOnlyProperty = MAKE_STATUS(kStatusGroupFlashDriver, 18), /*!< The flash property is read-only.*/ + kStatus_FLASH_InvalidPropertyValue = + MAKE_STATUS(kStatusGroupFlashDriver, 19), /*!< The flash property value is out of range.*/ + kStatus_FLASH_InvalidSpeculationOption = + MAKE_STATUS(kStatusGroupFlashDriver, 20), /*!< The option of flash prefetch speculation is invalid.*/ +}; +/*@}*/ + +/*! + * @name Flash API key + * @{ + */ +/*! @brief Constructs the four character code for the Flash driver API key. */ +#if !defined(FOUR_CHAR_CODE) +#define FOUR_CHAR_CODE(a, b, c, d) (((d) << 24) | ((c) << 16) | ((b) << 8) | ((a))) +#endif + +/*! + * @brief Enumeration for Flash driver API keys. + * + * @note The resulting value is built with a byte order such that the string + * being readable in expected order when viewed in a hex editor, if the value + * is treated as a 32-bit little endian value. + */ +enum _flash_driver_api_keys +{ + kFLASH_ApiEraseKey = FOUR_CHAR_CODE('k', 'f', 'e', 'k') /*!< Key value used to validate all flash erase APIs.*/ +}; +/*@}*/ + +/*! + * @brief Enumeration for supported flash margin levels. + */ +typedef enum _flash_margin_value +{ + kFLASH_MarginValueNormal, /*!< Use the 'normal' read level for 1s.*/ + kFLASH_MarginValueUser, /*!< Apply the 'User' margin to the normal read-1 level.*/ + kFLASH_MarginValueFactory, /*!< Apply the 'Factory' margin to the normal read-1 level.*/ + kFLASH_MarginValueInvalid /*!< Not real margin level, Used to determine the range of valid margin level. */ +} flash_margin_value_t; + +/*! + * @brief Enumeration for the three possible flash security states. + */ +typedef enum _flash_security_state +{ + kFLASH_SecurityStateNotSecure, /*!< Flash is not secure.*/ + kFLASH_SecurityStateBackdoorEnabled, /*!< Flash backdoor is enabled.*/ + kFLASH_SecurityStateBackdoorDisabled /*!< Flash backdoor is disabled.*/ +} flash_security_state_t; + +/*! + * @brief Enumeration for the three possible flash protection levels. + */ +typedef enum _flash_protection_state +{ + kFLASH_ProtectionStateUnprotected, /*!< Flash region is not protected.*/ + kFLASH_ProtectionStateProtected, /*!< Flash region is protected.*/ + kFLASH_ProtectionStateMixed /*!< Flash is mixed with protected and unprotected region.*/ +} flash_protection_state_t; + +/*! + * @brief Enumeration for the three possible flash execute access levels. + */ +typedef enum _flash_execute_only_access_state +{ + kFLASH_AccessStateUnLimited, /*!< Flash region is unlimited.*/ + kFLASH_AccessStateExecuteOnly, /*!< Flash region is execute only.*/ + kFLASH_AccessStateMixed /*!< Flash is mixed with unlimited and execute only region.*/ +} flash_execute_only_access_state_t; + +/*! + * @brief Enumeration for various flash properties. + */ +typedef enum _flash_property_tag +{ + kFLASH_PropertyPflashSectorSize = 0x00U, /*!< Pflash sector size property.*/ + kFLASH_PropertyPflashTotalSize = 0x01U, /*!< Pflash total size property.*/ + kFLASH_PropertyPflashBlockSize = 0x02U, /*!< Pflash block size property.*/ + kFLASH_PropertyPflashBlockCount = 0x03U, /*!< Pflash block count property.*/ + kFLASH_PropertyPflashBlockBaseAddr = 0x04U, /*!< Pflash block base address property.*/ + kFLASH_PropertyPflashFacSupport = 0x05U, /*!< Pflash fac support property.*/ + kFLASH_PropertyPflashAccessSegmentSize = 0x06U, /*!< Pflash access segment size property.*/ + kFLASH_PropertyPflashAccessSegmentCount = 0x07U, /*!< Pflash access segment count property.*/ + kFLASH_PropertyFlexRamBlockBaseAddr = 0x08U, /*!< FlexRam block base address property.*/ + kFLASH_PropertyFlexRamTotalSize = 0x09U, /*!< FlexRam total size property.*/ + kFLASH_PropertyDflashSectorSize = 0x10U, /*!< Dflash sector size property.*/ + kFLASH_PropertyDflashTotalSize = 0x11U, /*!< Dflash total size property.*/ + kFLASH_PropertyDflashBlockSize = 0x12U, /*!< Dflash block size property.*/ + kFLASH_PropertyDflashBlockCount = 0x13U, /*!< Dflash block count property.*/ + kFLASH_PropertyDflashBlockBaseAddr = 0x14U, /*!< Dflash block base address property.*/ + kFLASH_PropertyEepromTotalSize = 0x15U, /*!< EEPROM total size property.*/ + kFLASH_PropertyFlashMemoryIndex = 0x20U /*!< Flash memory index property.*/ +} flash_property_tag_t; + +/*! + * @brief Constants for execute-in-RAM flash function. + */ +enum _flash_execute_in_ram_function_constants +{ + kFLASH_ExecuteInRamFunctionMaxSizeInWords = 16U, /*!< The maximum size of execute-in-RAM function.*/ + kFLASH_ExecuteInRamFunctionTotalNum = 2U /*!< Total number of execute-in-RAM functions.*/ +}; + +/*! + * @brief Flash execute-in-RAM function information. + */ +typedef struct _flash_execute_in_ram_function_config +{ + uint32_t activeFunctionCount; /*!< Number of available execute-in-RAM functions.*/ + uint32_t *flashRunCommand; /*!< Execute-in-RAM function: flash_run_command.*/ + uint32_t *flashCommonBitOperation; /*!< Execute-in-RAM function: flash_common_bit_operation.*/ +} flash_execute_in_ram_function_config_t; + +/*! + * @brief Enumeration for the two possible options of flash read resource command. + */ +typedef enum _flash_read_resource_option +{ + kFLASH_ResourceOptionFlashIfr = + 0x00U, /*!< Select code for Program flash 0 IFR, Program flash swap 0 IFR, Data flash 0 IFR */ + kFLASH_ResourceOptionVersionId = 0x01U /*!< Select code for the version ID*/ +} flash_read_resource_option_t; + +/*! + * @brief Enumeration for the range of special-purpose flash resource + */ +enum _flash_read_resource_range +{ +#if (FSL_FEATURE_FLASH_IS_FTFE == 1) + kFLASH_ResourceRangePflashIfrSizeInBytes = 1024U, /*!< Pflash IFR size in byte.*/ + kFLASH_ResourceRangeVersionIdSizeInBytes = 8U, /*!< Version ID IFR size in byte.*/ + kFLASH_ResourceRangeVersionIdStart = 0x08U, /*!< Version ID IFR start address.*/ + kFLASH_ResourceRangeVersionIdEnd = 0x0FU, /*!< Version ID IFR end address.*/ + kFLASH_ResourceRangePflashSwapIfrStart = 0x40000U, /*!< Pflash swap IFR start address.*/ + kFLASH_ResourceRangePflashSwapIfrEnd = + (kFLASH_ResourceRangePflashSwapIfrStart + 0x3FFU), /*!< Pflash swap IFR end address.*/ +#else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA = =1 */ + kFLASH_ResourceRangePflashIfrSizeInBytes = 256U, /*!< Pflash IFR size in byte.*/ + kFLASH_ResourceRangeVersionIdSizeInBytes = 8U, /*!< Version ID IFR size in byte.*/ + kFLASH_ResourceRangeVersionIdStart = 0x00U, /*!< Version ID IFR start address.*/ + kFLASH_ResourceRangeVersionIdEnd = 0x07U, /*!< Version ID IFR end address.*/ +#if 0x20000U == (FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE) + kFLASH_ResourceRangePflashSwapIfrStart = 0x8000U, /*!< Pflash swap IFR start address.*/ +#elif 0x40000U == (FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE) + kFLASH_ResourceRangePflashSwapIfrStart = 0x10000U, /*!< Pflash swap IFR start address.*/ +#elif 0x80000U == (FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE) + kFLASH_ResourceRangePflashSwapIfrStart = 0x20000U, /*!< Pflash swap IFR start address.*/ +#else + kFLASH_ResourceRangePflashSwapIfrStart = 0, +#endif + kFLASH_ResourceRangePflashSwapIfrEnd = + (kFLASH_ResourceRangePflashSwapIfrStart + 0xFFU), /*!< Pflash swap IFR end address.*/ +#endif + kFLASH_ResourceRangeDflashIfrStart = 0x800000U, /*!< Dflash IFR start address.*/ + kFLASH_ResourceRangeDflashIfrEnd = 0x8003FFU, /*!< Dflash IFR end address.*/ +}; + +/*! + * @brief Enumeration for the two possilbe options of set FlexRAM function command. + */ +typedef enum _flash_flexram_function_option +{ + kFLASH_FlexramFunctionOptionAvailableAsRam = 0xFFU, /*!< An option used to make FlexRAM available as RAM */ + kFLASH_FlexramFunctionOptionAvailableForEeprom = 0x00U /*!< An option used to make FlexRAM available for EEPROM */ +} flash_flexram_function_option_t; + +/*! + * @brief Enumeration for acceleration RAM property. + */ +enum _flash_acceleration_ram_property +{ + kFLASH_AccelerationRamSize = 0x400U +}; + +/*! + * @brief Enumeration for the possible options of Swap function + */ +typedef enum _flash_swap_function_option +{ + kFLASH_SwapFunctionOptionEnable = 0x00U, /*!< An option used to enable the Swap function */ + kFLASH_SwapFunctionOptionDisable = 0x01U /*!< An option used to disable the Swap function */ +} flash_swap_function_option_t; + +/*! + * @brief Enumeration for the possible options of Swap control commands + */ +typedef enum _flash_swap_control_option +{ + kFLASH_SwapControlOptionIntializeSystem = 0x01U, /*!< An option used to initialize the Swap system */ + kFLASH_SwapControlOptionSetInUpdateState = 0x02U, /*!< An option used to set the Swap in an update state */ + kFLASH_SwapControlOptionSetInCompleteState = 0x04U, /*!< An option used to set the Swap in a complete state */ + kFLASH_SwapControlOptionReportStatus = 0x08U, /*!< An option used to report the Swap status */ + kFLASH_SwapControlOptionDisableSystem = 0x10U /*!< An option used to disable the Swap status */ +} flash_swap_control_option_t; + +/*! + * @brief Enumeration for the possible flash Swap status. + */ +typedef enum _flash_swap_state +{ + kFLASH_SwapStateUninitialized = 0x00U, /*!< Flash Swap system is in an uninitialized state.*/ + kFLASH_SwapStateReady = 0x01U, /*!< Flash Swap system is in a ready state.*/ + kFLASH_SwapStateUpdate = 0x02U, /*!< Flash Swap system is in an update state.*/ + kFLASH_SwapStateUpdateErased = 0x03U, /*!< Flash Swap system is in an updateErased state.*/ + kFLASH_SwapStateComplete = 0x04U, /*!< Flash Swap system is in a complete state.*/ + kFLASH_SwapStateDisabled = 0x05U /*!< Flash Swap system is in a disabled state.*/ +} flash_swap_state_t; + +/*! + * @breif Enumeration for the possible flash Swap block status + */ +typedef enum _flash_swap_block_status +{ + kFLASH_SwapBlockStatusLowerHalfProgramBlocksAtZero = + 0x00U, /*!< Swap block status is that lower half program block at zero.*/ + kFLASH_SwapBlockStatusUpperHalfProgramBlocksAtZero = + 0x01U, /*!< Swap block status is that upper half program block at zero.*/ +} flash_swap_block_status_t; + +/*! + * @brief Flash Swap information + */ +typedef struct _flash_swap_state_config +{ + flash_swap_state_t flashSwapState; /*!chip < FB_CSAR_COUNT); + assert(config->waitStates <= 0x3FU); + + uint32_t chip = 0; + uint32_t reg_value = 0; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate clock for FLEXBUS */ + CLOCK_EnableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset all the register to default state */ + for (chip = 0; chip < FB_CSAR_COUNT; chip++) + { + /* Reset CSMR register, all chips not valid (disabled) */ + base->CS[chip].CSMR = 0x0000U; + /* Set default base address */ + base->CS[chip].CSAR &= (~FB_CSAR_BA_MASK); + /* Reset FB_CSCRx register */ + base->CS[chip].CSCR = 0x0000U; + } + /* Set FB_CSPMCR register */ + /* FlexBus signal group 1 multiplex control */ + reg_value |= kFLEXBUS_MultiplexGroup1_FB_ALE << FB_CSPMCR_GROUP1_SHIFT; + /* FlexBus signal group 2 multiplex control */ + reg_value |= kFLEXBUS_MultiplexGroup2_FB_CS4 << FB_CSPMCR_GROUP2_SHIFT; + /* FlexBus signal group 3 multiplex control */ + reg_value |= kFLEXBUS_MultiplexGroup3_FB_CS5 << FB_CSPMCR_GROUP3_SHIFT; + /* FlexBus signal group 4 multiplex control */ + reg_value |= kFLEXBUS_MultiplexGroup4_FB_TBST << FB_CSPMCR_GROUP4_SHIFT; + /* FlexBus signal group 5 multiplex control */ + reg_value |= kFLEXBUS_MultiplexGroup5_FB_TA << FB_CSPMCR_GROUP5_SHIFT; + /* Write to CSPMCR register */ + base->CSPMCR = reg_value; + + /* Update chip value */ + chip = config->chip; + + /* Base address */ + reg_value = config->chipBaseAddress; + /* Write to CSAR register */ + base->CS[chip].CSAR = reg_value; + /* Chip-select validation */ + reg_value = 0x1U << FB_CSMR_V_SHIFT; + /* Write protect */ + reg_value |= (uint32_t)(config->writeProtect) << FB_CSMR_WP_SHIFT; + /* Base address mask */ + reg_value |= config->chipBaseAddressMask << FB_CSMR_BAM_SHIFT; + /* Write to CSMR register */ + base->CS[chip].CSMR = reg_value; + /* Burst write */ + reg_value = (uint32_t)(config->burstWrite) << FB_CSCR_BSTW_SHIFT; + /* Burst read */ + reg_value |= (uint32_t)(config->burstRead) << FB_CSCR_BSTR_SHIFT; + /* Byte-enable mode */ + reg_value |= (uint32_t)(config->byteEnableMode) << FB_CSCR_BEM_SHIFT; + /* Port size */ + reg_value |= (uint32_t)config->portSize << FB_CSCR_PS_SHIFT; + /* The internal transfer acknowledge for accesses */ + reg_value |= (uint32_t)(config->autoAcknowledge) << FB_CSCR_AA_SHIFT; + /* Byte-Lane shift */ + reg_value |= (uint32_t)config->byteLaneShift << FB_CSCR_BLS_SHIFT; + /* The number of wait states */ + reg_value |= (uint32_t)config->waitStates << FB_CSCR_WS_SHIFT; + /* Write address hold or deselect */ + reg_value |= (uint32_t)config->writeAddressHold << FB_CSCR_WRAH_SHIFT; + /* Read address hold or deselect */ + reg_value |= (uint32_t)config->readAddressHold << FB_CSCR_RDAH_SHIFT; + /* Address setup */ + reg_value |= (uint32_t)config->addressSetup << FB_CSCR_ASET_SHIFT; + /* Extended transfer start/extended address latch */ + reg_value |= (uint32_t)(config->extendTransferAddress) << FB_CSCR_EXTS_SHIFT; + /* Secondary wait state */ + reg_value |= (uint32_t)(config->secondaryWaitStates) << FB_CSCR_SWSEN_SHIFT; + /* Write to CSCR register */ + base->CS[chip].CSCR = reg_value; + /* FlexBus signal group 1 multiplex control */ + reg_value = (uint32_t)config->group1MultiplexControl << FB_CSPMCR_GROUP1_SHIFT; + /* FlexBus signal group 2 multiplex control */ + reg_value |= (uint32_t)config->group2MultiplexControl << FB_CSPMCR_GROUP2_SHIFT; + /* FlexBus signal group 3 multiplex control */ + reg_value |= (uint32_t)config->group3MultiplexControl << FB_CSPMCR_GROUP3_SHIFT; + /* FlexBus signal group 4 multiplex control */ + reg_value |= (uint32_t)config->group4MultiplexControl << FB_CSPMCR_GROUP4_SHIFT; + /* FlexBus signal group 5 multiplex control */ + reg_value |= (uint32_t)config->group5MultiplexControl << FB_CSPMCR_GROUP5_SHIFT; + /* Write to CSPMCR register */ + base->CSPMCR = reg_value; +} + +void FLEXBUS_Deinit(FB_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate clock for FLEXBUS */ + CLOCK_DisableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void FLEXBUS_GetDefaultConfig(flexbus_config_t *config) +{ + config->chip = 0; /* Chip 0 FlexBus for validation */ + config->writeProtect = 0; /* Write accesses are allowed */ + config->burstWrite = 0; /* Burst-Write disable */ + config->burstRead = 0; /* Burst-Read disable */ + config->byteEnableMode = 0; /* Byte-Enable mode is asserted for data write only */ + config->autoAcknowledge = true; /* Auto-Acknowledge enable */ + config->extendTransferAddress = 0; /* Extend transfer start/extend address latch disable */ + config->secondaryWaitStates = 0; /* Secondary wait state disable */ + config->byteLaneShift = kFLEXBUS_NotShifted; /* Byte-Lane shift disable */ + config->writeAddressHold = kFLEXBUS_Hold1Cycle; /* Write address hold 1 cycles */ + config->readAddressHold = kFLEXBUS_Hold1Or0Cycles; /* Read address hold 0 cycles */ + config->addressSetup = + kFLEXBUS_FirstRisingEdge; /* Assert ~FB_CSn on the first rising clock edge after the address is asserted */ + config->portSize = kFLEXBUS_1Byte; /* 1 byte port size of transfer */ + config->group1MultiplexControl = kFLEXBUS_MultiplexGroup1_FB_ALE; /* FB_ALE */ + config->group2MultiplexControl = kFLEXBUS_MultiplexGroup2_FB_CS4; /* FB_CS4 */ + config->group3MultiplexControl = kFLEXBUS_MultiplexGroup3_FB_CS5; /* FB_CS5 */ + config->group4MultiplexControl = kFLEXBUS_MultiplexGroup4_FB_TBST; /* FB_TBST */ + config->group5MultiplexControl = kFLEXBUS_MultiplexGroup5_FB_TA; /* FB_TA */ +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexbus.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexbus.h new file mode 100644 index 00000000000..09943c27b68 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexbus.h @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_FLEXBUS_H_ +#define _FSL_FLEXBUS_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup flexbus + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_FLEXBUS_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1. */ +/*@}*/ + +/*! + * @brief Defines port size for FlexBus peripheral. + */ +typedef enum _flexbus_port_size +{ + kFLEXBUS_4Bytes = 0x00U, /*!< 32-bit port size */ + kFLEXBUS_1Byte = 0x01U, /*!< 8-bit port size */ + kFLEXBUS_2Bytes = 0x02U /*!< 16-bit port size */ +} flexbus_port_size_t; + +/*! + * @brief Defines number of cycles to hold address and attributes for FlexBus peripheral. + */ +typedef enum _flexbus_write_address_hold +{ + kFLEXBUS_Hold1Cycle = 0x00U, /*!< Hold address and attributes one cycles after FB_CSn negates on writes */ + kFLEXBUS_Hold2Cycles = 0x01U, /*!< Hold address and attributes two cycles after FB_CSn negates on writes */ + kFLEXBUS_Hold3Cycles = 0x02U, /*!< Hold address and attributes three cycles after FB_CSn negates on writes */ + kFLEXBUS_Hold4Cycles = 0x03U /*!< Hold address and attributes four cycles after FB_CSn negates on writes */ +} flexbus_write_address_hold_t; + +/*! + * @brief Defines number of cycles to hold address and attributes for FlexBus peripheral. + */ +typedef enum _flexbus_read_address_hold +{ + kFLEXBUS_Hold1Or0Cycles = 0x00U, /*!< Hold address and attributes 1 or 0 cycles on reads */ + kFLEXBUS_Hold2Or1Cycles = 0x01U, /*!< Hold address and attributes 2 or 1 cycles on reads */ + kFLEXBUS_Hold3Or2Cycle = 0x02U, /*!< Hold address and attributes 3 or 2 cycles on reads */ + kFLEXBUS_Hold4Or3Cycle = 0x03U /*!< Hold address and attributes 4 or 3 cycles on reads */ +} flexbus_read_address_hold_t; + +/*! + * @brief Address setup for FlexBus peripheral. + */ +typedef enum _flexbus_address_setup +{ + kFLEXBUS_FirstRisingEdge = 0x00U, /*!< Assert FB_CSn on first rising clock edge after address is asserted */ + kFLEXBUS_SecondRisingEdge = 0x01U, /*!< Assert FB_CSn on second rising clock edge after address is asserted */ + kFLEXBUS_ThirdRisingEdge = 0x02U, /*!< Assert FB_CSn on third rising clock edge after address is asserted */ + kFLEXBUS_FourthRisingEdge = 0x03U, /*!< Assert FB_CSn on fourth rising clock edge after address is asserted */ +} flexbus_address_setup_t; + +/*! + * @brief Defines byte-lane shift for FlexBus peripheral. + */ +typedef enum _flexbus_bytelane_shift +{ + kFLEXBUS_NotShifted = 0x00U, /*!< Not shifted. Data is left-justified on FB_AD */ + kFLEXBUS_Shifted = 0x01U, /*!< Shifted. Data is right justified on FB_AD */ +} flexbus_bytelane_shift_t; + +/*! + * @brief Defines multiplex group1 valid signals. + */ +typedef enum _flexbus_multiplex_group1_signal +{ + kFLEXBUS_MultiplexGroup1_FB_ALE = 0x00U, /*!< FB_ALE */ + kFLEXBUS_MultiplexGroup1_FB_CS1 = 0x01U, /*!< FB_CS1 */ + kFLEXBUS_MultiplexGroup1_FB_TS = 0x02U, /*!< FB_TS */ +} flexbus_multiplex_group1_t; + +/*! + * @brief Defines multiplex group2 valid signals. + */ +typedef enum _flexbus_multiplex_group2_signal +{ + kFLEXBUS_MultiplexGroup2_FB_CS4 = 0x00U, /*!< FB_CS4 */ + kFLEXBUS_MultiplexGroup2_FB_TSIZ0 = 0x01U, /*!< FB_TSIZ0 */ + kFLEXBUS_MultiplexGroup2_FB_BE_31_24 = 0x02U, /*!< FB_BE_31_24 */ +} flexbus_multiplex_group2_t; + +/*! + * @brief Defines multiplex group3 valid signals. + */ +typedef enum _flexbus_multiplex_group3_signal +{ + kFLEXBUS_MultiplexGroup3_FB_CS5 = 0x00U, /*!< FB_CS5 */ + kFLEXBUS_MultiplexGroup3_FB_TSIZ1 = 0x01U, /*!< FB_TSIZ1 */ + kFLEXBUS_MultiplexGroup3_FB_BE_23_16 = 0x02U, /*!< FB_BE_23_16 */ +} flexbus_multiplex_group3_t; + +/*! + * @brief Defines multiplex group4 valid signals. + */ +typedef enum _flexbus_multiplex_group4_signal +{ + kFLEXBUS_MultiplexGroup4_FB_TBST = 0x00U, /*!< FB_TBST */ + kFLEXBUS_MultiplexGroup4_FB_CS2 = 0x01U, /*!< FB_CS2 */ + kFLEXBUS_MultiplexGroup4_FB_BE_15_8 = 0x02U, /*!< FB_BE_15_8 */ +} flexbus_multiplex_group4_t; + +/*! + * @brief Defines multiplex group5 valid signals. + */ +typedef enum _flexbus_multiplex_group5_signal +{ + kFLEXBUS_MultiplexGroup5_FB_TA = 0x00U, /*!< FB_TA */ + kFLEXBUS_MultiplexGroup5_FB_CS3 = 0x01U, /*!< FB_CS3 */ + kFLEXBUS_MultiplexGroup5_FB_BE_7_0 = 0x02U, /*!< FB_BE_7_0 */ +} flexbus_multiplex_group5_t; + +/*! + * @brief Configuration structure that the user needs to set. + */ +typedef struct _flexbus_config +{ + uint8_t chip; /*!< Chip FlexBus for validation */ + uint8_t waitStates; /*!< Value of wait states */ + uint32_t chipBaseAddress; /*!< Chip base address for using FlexBus */ + uint32_t chipBaseAddressMask; /*!< Chip base address mask */ + bool writeProtect; /*!< Write protected */ + bool burstWrite; /*!< Burst-Write enable */ + bool burstRead; /*!< Burst-Read enable */ + bool byteEnableMode; /*!< Byte-enable mode support */ + bool autoAcknowledge; /*!< Auto acknowledge setting */ + bool extendTransferAddress; /*!< Extend transfer start/extend address latch enable */ + bool secondaryWaitStates; /*!< Secondary wait states number */ + flexbus_port_size_t portSize; /*!< Port size of transfer */ + flexbus_bytelane_shift_t byteLaneShift; /*!< Byte-lane shift enable */ + flexbus_write_address_hold_t writeAddressHold; /*!< Write address hold or deselect option */ + flexbus_read_address_hold_t readAddressHold; /*!< Read address hold or deselect option */ + flexbus_address_setup_t addressSetup; /*!< Address setup setting */ + flexbus_multiplex_group1_t group1MultiplexControl; /*!< FlexBus Signal Group 1 Multiplex control */ + flexbus_multiplex_group2_t group2MultiplexControl; /*!< FlexBus Signal Group 2 Multiplex control */ + flexbus_multiplex_group3_t group3MultiplexControl; /*!< FlexBus Signal Group 3 Multiplex control */ + flexbus_multiplex_group4_t group4MultiplexControl; /*!< FlexBus Signal Group 4 Multiplex control */ + flexbus_multiplex_group5_t group5MultiplexControl; /*!< FlexBus Signal Group 5 Multiplex control */ +} flexbus_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name FlexBus functional operation + * @{ + */ + +/*! + * @brief Initializes and configures the FlexBus module. + * + * This function enables the clock gate for FlexBus module. + * Only chip 0 is validated and set to known values. Other chips are disabled. + * Note that in this function, certain parameters, depending on external memories, must + * be set before using the FLEXBUS_Init() function. + * This example shows how to set up the uart_state_t and the + * flexbus_config_t parameters and how to call the FLEXBUS_Init function by passing + * in these parameters. + @code + flexbus_config_t flexbusConfig; + FLEXBUS_GetDefaultConfig(&flexbusConfig); + flexbusConfig.waitStates = 2U; + flexbusConfig.chipBaseAddress = 0x60000000U; + flexbusConfig.chipBaseAddressMask = 7U; + FLEXBUS_Init(FB, &flexbusConfig); + @endcode + * + * @param base FlexBus peripheral address. + * @param config Pointer to the configuration structure +*/ +void FLEXBUS_Init(FB_Type *base, const flexbus_config_t *config); + +/*! + * @brief De-initializes a FlexBus instance. + * + * This function disables the clock gate of the FlexBus module clock. + * + * @param base FlexBus peripheral address. + */ +void FLEXBUS_Deinit(FB_Type *base); + +/*! + * @brief Initializes the FlexBus configuration structure. + * + * This function initializes the FlexBus configuration structure to default value. The default + * values are. + @code + fbConfig->chip = 0; + fbConfig->writeProtect = 0; + fbConfig->burstWrite = 0; + fbConfig->burstRead = 0; + fbConfig->byteEnableMode = 0; + fbConfig->autoAcknowledge = true; + fbConfig->extendTransferAddress = 0; + fbConfig->secondaryWaitStates = 0; + fbConfig->byteLaneShift = kFLEXBUS_NotShifted; + fbConfig->writeAddressHold = kFLEXBUS_Hold1Cycle; + fbConfig->readAddressHold = kFLEXBUS_Hold1Or0Cycles; + fbConfig->addressSetup = kFLEXBUS_FirstRisingEdge; + fbConfig->portSize = kFLEXBUS_1Byte; + fbConfig->group1MultiplexControl = kFLEXBUS_MultiplexGroup1_FB_ALE; + fbConfig->group2MultiplexControl = kFLEXBUS_MultiplexGroup2_FB_CS4 ; + fbConfig->group3MultiplexControl = kFLEXBUS_MultiplexGroup3_FB_CS5; + fbConfig->group4MultiplexControl = kFLEXBUS_MultiplexGroup4_FB_TBST; + fbConfig->group5MultiplexControl = kFLEXBUS_MultiplexGroup5_FB_TA; + @endcode + * @param config Pointer to the initialization structure. + * @see FLEXBUS_Init + */ +void FLEXBUS_GetDefaultConfig(flexbus_config_t *config); + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_FLEXBUS_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio.c new file mode 100644 index 00000000000..24d9e98e619 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*< @brief user configurable flexio handle count. */ +#define FLEXIO_HANDLE_COUNT 2 + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*< @brief pointer to array of FLEXIO handle. */ +static void *s_flexioHandle[FLEXIO_HANDLE_COUNT]; + +/*< @brief pointer to array of FLEXIO IP types. */ +static void *s_flexioType[FLEXIO_HANDLE_COUNT]; + +/*< @brief pointer to array of FLEXIO Isr. */ +static flexio_isr_t s_flexioIsr[FLEXIO_HANDLE_COUNT]; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to flexio clocks for each instance. */ +const clock_ip_name_t s_flexioClocks[] = FLEXIO_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Pointers to flexio bases for each instance. */ +FLEXIO_Type *const s_flexioBases[] = FLEXIO_BASE_PTRS; + +/******************************************************************************* + * Codes + ******************************************************************************/ + +uint32_t FLEXIO_GetInstance(FLEXIO_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_FLEXIO_COUNT; instance++) + { + if (s_flexioBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_FLEXIO_COUNT); + + return instance; +} + +void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig) +{ + uint32_t ctrlReg = 0; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(s_flexioClocks[FLEXIO_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + FLEXIO_Reset(base); + + ctrlReg = base->CTRL; + ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); + ctrlReg |= (FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) | + FLEXIO_CTRL_FLEXEN(userConfig->enableFlexio)); + if (!userConfig->enableInDoze) + { + ctrlReg |= FLEXIO_CTRL_DOZEN_MASK; + } + + base->CTRL = ctrlReg; +} + +void FLEXIO_Deinit(FLEXIO_Type *base) +{ + FLEXIO_Enable(base, false); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(s_flexioClocks[FLEXIO_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig) +{ + assert(userConfig); + + userConfig->enableFlexio = true; + userConfig->enableInDoze = false; + userConfig->enableInDebug = true; + userConfig->enableFastAccess = false; +} + +void FLEXIO_Reset(FLEXIO_Type *base) +{ + /*do software reset, software reset operation affect all other FLEXIO registers except CTRL*/ + base->CTRL |= FLEXIO_CTRL_SWRST_MASK; + base->CTRL = 0; +} + +uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index) +{ + assert(index < FLEXIO_SHIFTBUF_COUNT); + + uint32_t address = 0; + + switch (type) + { + case kFLEXIO_ShifterBuffer: + address = (uint32_t) & (base->SHIFTBUF[index]); + break; + + case kFLEXIO_ShifterBufferBitSwapped: + address = (uint32_t) & (base->SHIFTBUFBIS[index]); + break; + + case kFLEXIO_ShifterBufferByteSwapped: + address = (uint32_t) & (base->SHIFTBUFBYS[index]); + break; + + case kFLEXIO_ShifterBufferBitByteSwapped: + address = (uint32_t) & (base->SHIFTBUFBBS[index]); + break; + +#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP + case kFLEXIO_ShifterBufferNibbleByteSwapped: + address = (uint32_t) & (base->SHIFTBUFNBS[index]); + break; + +#endif +#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP + case kFLEXIO_ShifterBufferHalfWordSwapped: + address = (uint32_t) & (base->SHIFTBUFHWS[index]); + break; + +#endif +#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP + case kFLEXIO_ShifterBufferNibbleSwapped: + address = (uint32_t) & (base->SHIFTBUFNIS[index]); + break; + +#endif + default: + break; + } + return address; +} + +void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig) +{ + base->SHIFTCFG[index] = FLEXIO_SHIFTCFG_INSRC(shifterConfig->inputSource) +#if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH + | FLEXIO_SHIFTCFG_PWIDTH(shifterConfig->parallelWidth) +#endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */ + | FLEXIO_SHIFTCFG_SSTOP(shifterConfig->shifterStop) | + FLEXIO_SHIFTCFG_SSTART(shifterConfig->shifterStart); + + base->SHIFTCTL[index] = + FLEXIO_SHIFTCTL_TIMSEL(shifterConfig->timerSelect) | FLEXIO_SHIFTCTL_TIMPOL(shifterConfig->timerPolarity) | + FLEXIO_SHIFTCTL_PINCFG(shifterConfig->pinConfig) | FLEXIO_SHIFTCTL_PINSEL(shifterConfig->pinSelect) | + FLEXIO_SHIFTCTL_PINPOL(shifterConfig->pinPolarity) | FLEXIO_SHIFTCTL_SMOD(shifterConfig->shifterMode); +} + +void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig) +{ + base->TIMCFG[index] = + FLEXIO_TIMCFG_TIMOUT(timerConfig->timerOutput) | FLEXIO_TIMCFG_TIMDEC(timerConfig->timerDecrement) | + FLEXIO_TIMCFG_TIMRST(timerConfig->timerReset) | FLEXIO_TIMCFG_TIMDIS(timerConfig->timerDisable) | + FLEXIO_TIMCFG_TIMENA(timerConfig->timerEnable) | FLEXIO_TIMCFG_TSTOP(timerConfig->timerStop) | + FLEXIO_TIMCFG_TSTART(timerConfig->timerStart); + + base->TIMCMP[index] = FLEXIO_TIMCMP_CMP(timerConfig->timerCompare); + + base->TIMCTL[index] = FLEXIO_TIMCTL_TRGSEL(timerConfig->triggerSelect) | + FLEXIO_TIMCTL_TRGPOL(timerConfig->triggerPolarity) | + FLEXIO_TIMCTL_TRGSRC(timerConfig->triggerSource) | + FLEXIO_TIMCTL_PINCFG(timerConfig->pinConfig) | FLEXIO_TIMCTL_PINSEL(timerConfig->pinSelect) | + FLEXIO_TIMCTL_PINPOL(timerConfig->pinPolarity) | FLEXIO_TIMCTL_TIMOD(timerConfig->timerMode); +} + +status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr) +{ + assert(base); + assert(handle); + assert(isr); + + uint8_t index = 0; + + /* Find the an empty handle pointer to store the handle. */ + for (index = 0; index < FLEXIO_HANDLE_COUNT; index++) + { + if (s_flexioHandle[index] == NULL) + { + /* Register FLEXIO simulated driver base, handle and isr. */ + s_flexioType[index] = base; + s_flexioHandle[index] = handle; + s_flexioIsr[index] = isr; + break; + } + } + + if (index == FLEXIO_HANDLE_COUNT) + { + return kStatus_OutOfRange; + } + else + { + return kStatus_Success; + } +} + +status_t FLEXIO_UnregisterHandleIRQ(void *base) +{ + assert(base); + + uint8_t index = 0; + + /* Find the index from base address mappings. */ + for (index = 0; index < FLEXIO_HANDLE_COUNT; index++) + { + if (s_flexioType[index] == base) + { + /* Unregister FLEXIO simulated driver handle and isr. */ + s_flexioType[index] = NULL; + s_flexioHandle[index] = NULL; + s_flexioIsr[index] = NULL; + break; + } + } + + if (index == FLEXIO_HANDLE_COUNT) + { + return kStatus_OutOfRange; + } + else + { + return kStatus_Success; + } +} + +void FLEXIO_CommonIRQHandler(void) +{ + uint8_t index; + + for (index = 0; index < FLEXIO_HANDLE_COUNT; index++) + { + if (s_flexioHandle[index]) + { + s_flexioIsr[index](s_flexioType[index], s_flexioHandle[index]); + } + } +} + +void FLEXIO_DriverIRQHandler(void) +{ + FLEXIO_CommonIRQHandler(); +} + +void FLEXIO0_DriverIRQHandler(void) +{ + FLEXIO_CommonIRQHandler(); +} + +void UART2_FLEXIO_DriverIRQHandler(void) +{ + FLEXIO_CommonIRQHandler(); +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio.h new file mode 100644 index 00000000000..836a788125d --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio.h @@ -0,0 +1,705 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_H_ +#define _FSL_FLEXIO_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup flexio_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief FlexIO driver version 2.0.1. */ +#define FSL_FLEXIO_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! @brief Calculate FlexIO timer trigger.*/ +#define FLEXIO_TIMER_TRIGGER_SEL_PININPUT(x) ((uint32_t)(x) << 1U) +#define FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(x) (((uint32_t)(x) << 2U) | 0x1U) +#define FLEXIO_TIMER_TRIGGER_SEL_TIMn(x) (((uint32_t)(x) << 2U) | 0x3U) + +/*! @brief Define time of timer trigger polarity.*/ +typedef enum _flexio_timer_trigger_polarity +{ + kFLEXIO_TimerTriggerPolarityActiveHigh = 0x0U, /*!< Active high. */ + kFLEXIO_TimerTriggerPolarityActiveLow = 0x1U, /*!< Active low. */ +} flexio_timer_trigger_polarity_t; + +/*! @brief Define type of timer trigger source.*/ +typedef enum _flexio_timer_trigger_source +{ + kFLEXIO_TimerTriggerSourceExternal = 0x0U, /*!< External trigger selected. */ + kFLEXIO_TimerTriggerSourceInternal = 0x1U, /*!< Internal trigger selected. */ +} flexio_timer_trigger_source_t; + +/*! @brief Define type of timer/shifter pin configuration.*/ +typedef enum _flexio_pin_config +{ + kFLEXIO_PinConfigOutputDisabled = 0x0U, /*!< Pin output disabled. */ + kFLEXIO_PinConfigOpenDrainOrBidirection = 0x1U, /*!< Pin open drain or bidirectional output enable. */ + kFLEXIO_PinConfigBidirectionOutputData = 0x2U, /*!< Pin bidirectional output data. */ + kFLEXIO_PinConfigOutput = 0x3U, /*!< Pin output. */ +} flexio_pin_config_t; + +/*! @brief Definition of pin polarity.*/ +typedef enum _flexio_pin_polarity +{ + kFLEXIO_PinActiveHigh = 0x0U, /*!< Active high. */ + kFLEXIO_PinActiveLow = 0x1U, /*!< Active low. */ +} flexio_pin_polarity_t; + +/*! @brief Define type of timer work mode.*/ +typedef enum _flexio_timer_mode +{ + kFLEXIO_TimerModeDisabled = 0x0U, /*!< Timer Disabled. */ + kFLEXIO_TimerModeDual8BitBaudBit = 0x1U, /*!< Dual 8-bit counters baud/bit mode. */ + kFLEXIO_TimerModeDual8BitPWM = 0x2U, /*!< Dual 8-bit counters PWM mode. */ + kFLEXIO_TimerModeSingle16Bit = 0x3U, /*!< Single 16-bit counter mode. */ +} flexio_timer_mode_t; + +/*! @brief Define type of timer initial output or timer reset condition.*/ +typedef enum _flexio_timer_output +{ + kFLEXIO_TimerOutputOneNotAffectedByReset = 0x0U, /*!< Logic one when enabled and is not affected by timer + reset. */ + kFLEXIO_TimerOutputZeroNotAffectedByReset = 0x1U, /*!< Logic zero when enabled and is not affected by timer + reset. */ + kFLEXIO_TimerOutputOneAffectedByReset = 0x2U, /*!< Logic one when enabled and on timer reset. */ + kFLEXIO_TimerOutputZeroAffectedByReset = 0x3U, /*!< Logic zero when enabled and on timer reset. */ +} flexio_timer_output_t; + +/*! @brief Define type of timer decrement.*/ +typedef enum _flexio_timer_decrement_source +{ + kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput = 0x0U, /*!< Decrement counter on FlexIO clock, Shift clock + equals Timer output. */ + kFLEXIO_TimerDecSrcOnTriggerInputShiftTimerOutput = 0x1U, /*!< Decrement counter on Trigger input (both edges), + Shift clock equals Timer output. */ + kFLEXIO_TimerDecSrcOnPinInputShiftPinInput = 0x2U, /*!< Decrement counter on Pin input (both edges), + Shift clock equals Pin input. */ + kFLEXIO_TimerDecSrcOnTriggerInputShiftTriggerInput = 0x3U, /*!< Decrement counter on Trigger input (both edges), + Shift clock equals Trigger input. */ +} flexio_timer_decrement_source_t; + +/*! @brief Define type of timer reset condition.*/ +typedef enum _flexio_timer_reset_condition +{ + kFLEXIO_TimerResetNever = 0x0U, /*!< Timer never reset. */ + kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput = 0x2U, /*!< Timer reset on Timer Pin equal to Timer Output. */ + kFLEXIO_TimerResetOnTimerTriggerEqualToTimerOutput = 0x3U, /*!< Timer reset on Timer Trigger equal to + Timer Output. */ + kFLEXIO_TimerResetOnTimerPinRisingEdge = 0x4U, /*!< Timer reset on Timer Pin rising edge. */ + kFLEXIO_TimerResetOnTimerTriggerRisingEdge = 0x6U, /*!< Timer reset on Trigger rising edge. */ + kFLEXIO_TimerResetOnTimerTriggerBothEdge = 0x7U, /*!< Timer reset on Trigger rising or falling edge. */ +} flexio_timer_reset_condition_t; + +/*! @brief Define type of timer disable condition.*/ +typedef enum _flexio_timer_disable_condition +{ + kFLEXIO_TimerDisableNever = 0x0U, /*!< Timer never disabled. */ + kFLEXIO_TimerDisableOnPreTimerDisable = 0x1U, /*!< Timer disabled on Timer N-1 disable. */ + kFLEXIO_TimerDisableOnTimerCompare = 0x2U, /*!< Timer disabled on Timer compare. */ + kFLEXIO_TimerDisableOnTimerCompareTriggerLow = 0x3U, /*!< Timer disabled on Timer compare and Trigger Low. */ + kFLEXIO_TimerDisableOnPinBothEdge = 0x4U, /*!< Timer disabled on Pin rising or falling edge. */ + kFLEXIO_TimerDisableOnPinBothEdgeTriggerHigh = 0x5U, /*!< Timer disabled on Pin rising or falling edge provided + Trigger is high. */ + kFLEXIO_TimerDisableOnTriggerFallingEdge = 0x6U, /*!< Timer disabled on Trigger falling edge. */ +} flexio_timer_disable_condition_t; + +/*! @brief Define type of timer enable condition.*/ +typedef enum _flexio_timer_enable_condition +{ + kFLEXIO_TimerEnabledAlways = 0x0U, /*!< Timer always enabled. */ + kFLEXIO_TimerEnableOnPrevTimerEnable = 0x1U, /*!< Timer enabled on Timer N-1 enable. */ + kFLEXIO_TimerEnableOnTriggerHigh = 0x2U, /*!< Timer enabled on Trigger high. */ + kFLEXIO_TimerEnableOnTriggerHighPinHigh = 0x3U, /*!< Timer enabled on Trigger high and Pin high. */ + kFLEXIO_TimerEnableOnPinRisingEdge = 0x4U, /*!< Timer enabled on Pin rising edge. */ + kFLEXIO_TimerEnableOnPinRisingEdgeTriggerHigh = 0x5U, /*!< Timer enabled on Pin rising edge and Trigger high. */ + kFLEXIO_TimerEnableOnTriggerRisingEdge = 0x6U, /*!< Timer enabled on Trigger rising edge. */ + kFLEXIO_TimerEnableOnTriggerBothEdge = 0x7U, /*!< Timer enabled on Trigger rising or falling edge. */ +} flexio_timer_enable_condition_t; + +/*! @brief Define type of timer stop bit generate condition.*/ +typedef enum _flexio_timer_stop_bit_condition +{ + kFLEXIO_TimerStopBitDisabled = 0x0U, /*!< Stop bit disabled. */ + kFLEXIO_TimerStopBitEnableOnTimerCompare = 0x1U, /*!< Stop bit is enabled on timer compare. */ + kFLEXIO_TimerStopBitEnableOnTimerDisable = 0x2U, /*!< Stop bit is enabled on timer disable. */ + kFLEXIO_TimerStopBitEnableOnTimerCompareDisable = 0x3U, /*!< Stop bit is enabled on timer compare and timer + disable. */ +} flexio_timer_stop_bit_condition_t; + +/*! @brief Define type of timer start bit generate condition.*/ +typedef enum _flexio_timer_start_bit_condition +{ + kFLEXIO_TimerStartBitDisabled = 0x0U, /*!< Start bit disabled. */ + kFLEXIO_TimerStartBitEnabled = 0x1U, /*!< Start bit enabled. */ +} flexio_timer_start_bit_condition_t; + +/*! @brief Define type of timer polarity for shifter control. */ +typedef enum _flexio_shifter_timer_polarity +{ + kFLEXIO_ShifterTimerPolarityOnPositive = 0x0U, /* Shift on positive edge of shift clock. */ + kFLEXIO_ShifterTimerPolarityOnNegitive = 0x1U, /* Shift on negative edge of shift clock. */ +} flexio_shifter_timer_polarity_t; + +/*! @brief Define type of shifter working mode.*/ +typedef enum _flexio_shifter_mode +{ + kFLEXIO_ShifterDisabled = 0x0U, /*!< Shifter is disabled. */ + kFLEXIO_ShifterModeReceive = 0x1U, /*!< Receive mode. */ + kFLEXIO_ShifterModeTransmit = 0x2U, /*!< Transmit mode. */ + kFLEXIO_ShifterModeMatchStore = 0x4U, /*!< Match store mode. */ + kFLEXIO_ShifterModeMatchContinuous = 0x5U, /*!< Match continuous mode. */ +#if FSL_FEATURE_FLEXIO_HAS_STATE_MODE + kFLEXIO_ShifterModeState = 0x6U, /*!< SHIFTBUF contents are used for storing + programmable state attributes. */ +#endif /* FSL_FEATURE_FLEXIO_HAS_STATE_MODE */ +#if FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE + kFLEXIO_ShifterModeLogic = 0x7U, /*!< SHIFTBUF contents are used for implementing + programmable logic look up table. */ +#endif /* FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE */ +} flexio_shifter_mode_t; + +/*! @brief Define type of shifter input source.*/ +typedef enum _flexio_shifter_input_source +{ + kFLEXIO_ShifterInputFromPin = 0x0U, /*!< Shifter input from pin. */ + kFLEXIO_ShifterInputFromNextShifterOutput = 0x1U, /*!< Shifter input from Shifter N+1. */ +} flexio_shifter_input_source_t; + +/*! @brief Define of STOP bit configuration.*/ +typedef enum _flexio_shifter_stop_bit +{ + kFLEXIO_ShifterStopBitDisable = 0x0U, /*!< Disable shifter stop bit. */ + kFLEXIO_ShifterStopBitLow = 0x2U, /*!< Set shifter stop bit to logic low level. */ + kFLEXIO_ShifterStopBitHigh = 0x3U, /*!< Set shifter stop bit to logic high level. */ +} flexio_shifter_stop_bit_t; + +/*! @brief Define type of START bit configuration.*/ +typedef enum _flexio_shifter_start_bit +{ + kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable = 0x0U, /*!< Disable shifter start bit, transmitter loads + data on enable. */ + kFLEXIO_ShifterStartBitDisabledLoadDataOnShift = 0x1U, /*!< Disable shifter start bit, transmitter loads + data on first shift. */ + kFLEXIO_ShifterStartBitLow = 0x2U, /*!< Set shifter start bit to logic low level. */ + kFLEXIO_ShifterStartBitHigh = 0x3U, /*!< Set shifter start bit to logic high level. */ +} flexio_shifter_start_bit_t; + +/*! @brief Define FlexIO shifter buffer type*/ +typedef enum _flexio_shifter_buffer_type +{ + kFLEXIO_ShifterBuffer = 0x0U, /*!< Shifter Buffer N Register. */ + kFLEXIO_ShifterBufferBitSwapped = 0x1U, /*!< Shifter Buffer N Bit Byte Swapped Register. */ + kFLEXIO_ShifterBufferByteSwapped = 0x2U, /*!< Shifter Buffer N Byte Swapped Register. */ + kFLEXIO_ShifterBufferBitByteSwapped = 0x3U, /*!< Shifter Buffer N Bit Swapped Register. */ +#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP + kFLEXIO_ShifterBufferNibbleByteSwapped = 0x4U, /*!< Shifter Buffer N Nibble Byte Swapped Register. */ +#endif /*FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP*/ +#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP + kFLEXIO_ShifterBufferHalfWordSwapped = 0x5U, /*!< Shifter Buffer N Half Word Swapped Register. */ +#endif +#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP + kFLEXIO_ShifterBufferNibbleSwapped = 0x6U, /*!< Shifter Buffer N Nibble Swapped Register. */ +#endif +} flexio_shifter_buffer_type_t; + +/*! @brief Define FlexIO user configuration structure. */ +typedef struct _flexio_config_ +{ + bool enableFlexio; /*!< Enable/disable FlexIO module */ + bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode */ + bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode */ + bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, fast access requires + the FlexIO clock to be at least twice the frequency of the bus clock. */ +} flexio_config_t; + +/*! @brief Define FlexIO timer configuration structure. */ +typedef struct _flexio_timer_config +{ + /* Trigger. */ + uint32_t triggerSelect; /*!< The internal trigger selection number using MACROs. */ + flexio_timer_trigger_polarity_t triggerPolarity; /*!< Trigger Polarity. */ + flexio_timer_trigger_source_t triggerSource; /*!< Trigger Source, internal (see 'trgsel') or external. */ + /* Pin. */ + flexio_pin_config_t pinConfig; /*!< Timer Pin Configuration. */ + uint32_t pinSelect; /*!< Timer Pin number Select. */ + flexio_pin_polarity_t pinPolarity; /*!< Timer Pin Polarity. */ + /* Timer. */ + flexio_timer_mode_t timerMode; /*!< Timer work Mode. */ + flexio_timer_output_t timerOutput; /*!< Configures the initial state of the Timer Output and + whether it is affected by the Timer reset. */ + flexio_timer_decrement_source_t timerDecrement; /*!< Configures the source of the Timer decrement and the + source of the Shift clock. */ + flexio_timer_reset_condition_t timerReset; /*!< Configures the condition that causes the timer counter + (and optionally the timer output) to be reset. */ + flexio_timer_disable_condition_t timerDisable; /*!< Configures the condition that causes the Timer to be + disabled and stop decrementing. */ + flexio_timer_enable_condition_t timerEnable; /*!< Configures the condition that causes the Timer to be + enabled and start decrementing. */ + flexio_timer_stop_bit_condition_t timerStop; /*!< Timer STOP Bit generation. */ + flexio_timer_start_bit_condition_t timerStart; /*!< Timer STRAT Bit generation. */ + uint32_t timerCompare; /*!< Value for Timer Compare N Register. */ +} flexio_timer_config_t; + +/*! @brief Define FlexIO shifter configuration structure. */ +typedef struct _flexio_shifter_config +{ + /* Timer. */ + uint32_t timerSelect; /*!< Selects which Timer is used for controlling the + logic/shift register and generating the Shift clock. */ + flexio_shifter_timer_polarity_t timerPolarity; /*!< Timer Polarity. */ + /* Pin. */ + flexio_pin_config_t pinConfig; /*!< Shifter Pin Configuration. */ + uint32_t pinSelect; /*!< Shifter Pin number Select. */ + flexio_pin_polarity_t pinPolarity; /*!< Shifter Pin Polarity. */ + /* Shifter. */ + flexio_shifter_mode_t shifterMode; /*!< Configures the mode of the Shifter. */ +#if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH + uint32_t parallelWidth; /*!< Configures the parallel width when using parallel mode.*/ +#endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */ + flexio_shifter_input_source_t inputSource; /*!< Selects the input source for the shifter. */ + flexio_shifter_stop_bit_t shifterStop; /*!< Shifter STOP bit. */ + flexio_shifter_start_bit_t shifterStart; /*!< Shifter START bit. */ +} flexio_shifter_config_t; + +/*! @brief typedef for FlexIO simulated driver interrupt handler.*/ +typedef void (*flexio_isr_t)(void *base, void *handle); + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name FlexIO Initialization and De-initialization + * @{ + */ + +/*! + * @brief Gets the default configuration to configure the FlexIO module. The configuration + * can used directly to call the FLEXIO_Configure(). + * + * Example: + @code + flexio_config_t config; + FLEXIO_GetDefaultConfig(&config); + @endcode + * + * @param userConfig pointer to flexio_config_t structure +*/ +void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig); + +/*! + * @brief Configures the FlexIO with a FlexIO configuration. The configuration structure + * can be filled by the user or be set with default values by FLEXIO_GetDefaultConfig(). + * + * Example + @code + flexio_config_t config = { + .enableFlexio = true, + .enableInDoze = false, + .enableInDebug = true, + .enableFastAccess = false + }; + FLEXIO_Configure(base, &config); + @endcode + * + * @param base FlexIO peripheral base address + * @param userConfig pointer to flexio_config_t structure +*/ +void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig); + +/*! + * @brief Gates the FlexIO clock. Call this API to stop the FlexIO clock. + * + * @note After calling this API, call the FLEXO_Init to use the FlexIO module. + * + * @param base FlexIO peripheral base address +*/ +void FLEXIO_Deinit(FLEXIO_Type *base); + +/* @} */ + +/*! + * @name FlexIO Basic Operation + * @{ + */ + +/*! + * @brief Resets the FlexIO module. + * + * @param base FlexIO peripheral base address +*/ +void FLEXIO_Reset(FLEXIO_Type *base); + +/*! + * @brief Enables the FlexIO module operation. + * + * @param base FlexIO peripheral base address + * @param enable true to enable, false to disable. +*/ +static inline void FLEXIO_Enable(FLEXIO_Type *base, bool enable) +{ + if (enable) + { + base->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +#if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS +/*! + * @brief Reads the input data on each of the FlexIO pins. + * + * @param base FlexIO peripheral base address + * @return FlexIO pin input data +*/ +static inline uint32_t FLEXIO_ReadPinInput(FLEXIO_Type *base) +{ + return base->PIN; +} +#endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/ + +#if defined(FSL_FEATURE_FLEXIO_HAS_STATE_MODE) && FSL_FEATURE_FLEXIO_HAS_STATE_MODE +/*! + * @brief Gets the current state pointer for state mode use. + * + * @param base FlexIO peripheral base address + * @return current State pointer +*/ +static inline uint8_t FLEXIO_GetShifterState(FLEXIO_Type *base) +{ + return ((base->SHIFTSTATE) & FLEXIO_SHIFTSTATE_STATE_MASK); +} +#endif /*FSL_FEATURE_FLEXIO_HAS_STATE_MODE*/ + +/*! + * @brief Configures the shifter with the shifter configuration. The configuration structure + * covers both the SHIFTCTL and SHIFTCFG registers. To configure the shifter to the proper + * mode, select which timer controls the shifter to shift, whether to generate start bit/stop + * bit, and the polarity of start bit and stop bit. + * + * Example + @code + flexio_shifter_config_t config = { + .timerSelect = 0, + .timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive, + .pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection, + .pinPolarity = kFLEXIO_PinActiveLow, + .shifterMode = kFLEXIO_ShifterModeTransmit, + .inputSource = kFLEXIO_ShifterInputFromPin, + .shifterStop = kFLEXIO_ShifterStopBitHigh, + .shifterStart = kFLEXIO_ShifterStartBitLow + }; + FLEXIO_SetShifterConfig(base, &config); + @endcode + * + * @param base FlexIO peripheral base address + * @param index Shifter index + * @param shifterConfig Pointer to flexio_shifter_config_t structure +*/ +void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig); +/*! + * @brief Configures the timer with the timer configuration. The configuration structure + * covers both the TIMCTL and TIMCFG registers. To configure the timer to the proper + * mode, select trigger source for timer and the timer pin output and the timing for timer. + * + * Example + @code + flexio_timer_config_t config = { + .triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0), + .triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow, + .triggerSource = kFLEXIO_TimerTriggerSourceInternal, + .pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection, + .pinSelect = 0, + .pinPolarity = kFLEXIO_PinActiveHigh, + .timerMode = kFLEXIO_TimerModeDual8BitBaudBit, + .timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset, + .timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput, + .timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput, + .timerDisable = kFLEXIO_TimerDisableOnTimerCompare, + .timerEnable = kFLEXIO_TimerEnableOnTriggerHigh, + .timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable, + .timerStart = kFLEXIO_TimerStartBitEnabled + }; + FLEXIO_SetTimerConfig(base, &config); + @endcode + * + * @param base FlexIO peripheral base address + * @param index Timer index + * @param timerConfig Pointer to the flexio_timer_config_t structure +*/ +void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig); + +/* @} */ + +/*! + * @name FlexIO Interrupt Operation + * @{ + */ + +/*! + * @brief Enables the shifter status interrupt. The interrupt generates when the corresponding SSF is set. + * + * @param base FlexIO peripheral base address + * @param mask The shifter status mask which can be calculated by (1 << shifter index) + * @note For multiple shifter status interrupt enable, for example, two shifter status enable, can calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) +*/ +static inline void FLEXIO_EnableShifterStatusInterrupts(FLEXIO_Type *base, uint32_t mask) +{ + base->SHIFTSIEN |= mask; +} + +/*! + * @brief Disables the shifter status interrupt. The interrupt won't generate when the corresponding SSF is set. + * + * @param base FlexIO peripheral base address + * @param mask The shifter status mask which can be calculated by (1 << shifter index) + * @note For multiple shifter status interrupt enable, for example, two shifter status enable, can calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) +*/ +static inline void FLEXIO_DisableShifterStatusInterrupts(FLEXIO_Type *base, uint32_t mask) +{ + base->SHIFTSIEN &= ~mask; +} + +/*! + * @brief Enables the shifter error interrupt. The interrupt generates when the corresponding SEF is set. + * + * @param base FlexIO peripheral base address + * @param mask The shifter error mask which can be calculated by (1 << shifter index) + * @note For multiple shifter error interrupt enable, for example, two shifter error enable, can calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) +*/ +static inline void FLEXIO_EnableShifterErrorInterrupts(FLEXIO_Type *base, uint32_t mask) +{ + base->SHIFTEIEN |= mask; +} + +/*! + * @brief Disables the shifter error interrupt. The interrupt won't generate when the corresponding SEF is set. + * + * @param base FlexIO peripheral base address + * @param mask The shifter error mask which can be calculated by (1 << shifter index) + * @note For multiple shifter error interrupt enable, for example, two shifter error enable, can calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) +*/ +static inline void FLEXIO_DisableShifterErrorInterrupts(FLEXIO_Type *base, uint32_t mask) +{ + base->SHIFTEIEN &= ~mask; +} + +/*! + * @brief Enables the timer status interrupt. The interrupt generates when the corresponding SSF is set. + * + * @param base FlexIO peripheral base address + * @param mask The timer status mask which can be calculated by (1 << timer index) + * @note For multiple timer status interrupt enable, for example, two timer status enable, can calculate + * the mask by using ((1 << timer index0) | (1 << timer index1)) +*/ +static inline void FLEXIO_EnableTimerStatusInterrupts(FLEXIO_Type *base, uint32_t mask) +{ + base->TIMIEN |= mask; +} + +/*! + * @brief Disables the timer status interrupt. The interrupt won't generate when the corresponding SSF is set. + * + * @param base FlexIO peripheral base address + * @param mask The timer status mask which can be calculated by (1 << timer index) + * @note For multiple timer status interrupt enable, for example, two timer status enable, can calculate + * the mask by using ((1 << timer index0) | (1 << timer index1)) +*/ +static inline void FLEXIO_DisableTimerStatusInterrupts(FLEXIO_Type *base, uint32_t mask) +{ + base->TIMIEN &= ~mask; +} + +/* @} */ + +/*! + * @name FlexIO Status Operation + * @{ + */ + +/*! + * @brief Gets the shifter status flags. + * + * @param base FlexIO peripheral base address + * @return Shifter status flags +*/ +static inline uint32_t FLEXIO_GetShifterStatusFlags(FLEXIO_Type *base) +{ + return ((base->SHIFTSTAT) & FLEXIO_SHIFTSTAT_SSF_MASK); +} + +/*! + * @brief Clears the shifter status flags. + * + * @param base FlexIO peripheral base address + * @param mask The shifter status mask which can be calculated by (1 << shifter index) + * @note For clearing multiple shifter status flags, for example, two shifter status flags, can calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) +*/ +static inline void FLEXIO_ClearShifterStatusFlags(FLEXIO_Type *base, uint32_t mask) +{ + base->SHIFTSTAT = mask; +} + +/*! + * @brief Gets the shifter error flags. + * + * @param base FlexIO peripheral base address + * @return Shifter error flags +*/ +static inline uint32_t FLEXIO_GetShifterErrorFlags(FLEXIO_Type *base) +{ + return ((base->SHIFTERR) & FLEXIO_SHIFTERR_SEF_MASK); +} + +/*! + * @brief Clears the shifter error flags. + * + * @param base FlexIO peripheral base address + * @param mask The shifter error mask which can be calculated by (1 << shifter index) + * @note For clearing multiple shifter error flags, for example, two shifter error flags, can calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) +*/ +static inline void FLEXIO_ClearShifterErrorFlags(FLEXIO_Type *base, uint32_t mask) +{ + base->SHIFTERR = mask; +} + +/*! + * @brief Gets the timer status flags. + * + * @param base FlexIO peripheral base address + * @return Timer status flags +*/ +static inline uint32_t FLEXIO_GetTimerStatusFlags(FLEXIO_Type *base) +{ + return ((base->TIMSTAT) & FLEXIO_TIMSTAT_TSF_MASK); +} + +/*! + * @brief Clears the timer status flags. + * + * @param base FlexIO peripheral base address + * @param mask The timer status mask which can be calculated by (1 << timer index) + * @note For clearing multiple timer status flags, for example, two timer status flags, can calculate + * the mask by using ((1 << timer index0) | (1 << timer index1)) +*/ +static inline void FLEXIO_ClearTimerStatusFlags(FLEXIO_Type *base, uint32_t mask) +{ + base->TIMSTAT = mask; +} + +/* @} */ + +/*! + * @name FlexIO DMA Operation + * @{ + */ + +/*! + * @brief Enables/disables the shifter status DMA. The DMA request generates when the corresponding SSF is set. + * + * @note For multiple shifter status DMA enables, for example, calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) + * + * @param base FlexIO peripheral base address + * @param mask The shifter status mask which can be calculated by (1 << shifter index) + * @param enable True to enable, false to disable. +*/ +static inline void FLEXIO_EnableShifterStatusDMA(FLEXIO_Type *base, uint32_t mask, bool enable) +{ + if (enable) + { + base->SHIFTSDEN |= mask; + } + else + { + base->SHIFTSDEN &= ~mask; + } +} + +/*! + * @brief Gets the shifter buffer address for the DMA transfer usage. + * + * @param base FlexIO peripheral base address + * @param type Shifter type of flexio_shifter_buffer_type_t + * @param index Shifter index + * @return Corresponding shifter buffer index +*/ +uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index); + +/*! + * @brief Registers the handle and the interrupt handler for the FlexIO-simulated peripheral. + * + * @param base Pointer to the FlexIO simulated peripheral type. + * @param handle Pointer to the handler for FlexIO simulated peripheral. + * @param isr FlexIO simulated peripheral interrupt handler. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. +*/ +status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr); + +/*! + * @brief Unregisters the handle and the interrupt handler for the FlexIO-simulated peripheral. + * + * @param base Pointer to the FlexIO simulated peripheral type. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. +*/ +status_t FLEXIO_UnregisterHandleIRQ(void *base); +/* @} */ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ +/*@}*/ + +#endif /*_FSL_FLEXIO_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera.c new file mode 100644 index 00000000000..0609db3f026 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_camera.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +extern const clock_ip_name_t s_flexioClocks[]; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +extern FLEXIO_Type *const s_flexioBases[]; + +/******************************************************************************* + * Codes + ******************************************************************************/ + +uint32_t FLEXIO_CAMERA_GetInstance(FLEXIO_CAMERA_Type *base) +{ + uint32_t instance; + FLEXIO_Type *flexioBase = base->flexioBase; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_FLEXIO_COUNT; instance++) + { + if (s_flexioBases[instance] == flexioBase) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_FLEXIO_COUNT); + + return instance; +} + +void FLEXIO_CAMERA_GetDefaultConfig(flexio_camera_config_t *config) +{ + assert(config); + + config->enablecamera = false; + config->enableInDoze = false; + config->enableInDebug = false; + config->enableFastAccess = false; +} + +void FLEXIO_CAMERA_Init(FLEXIO_CAMERA_Type *base, const flexio_camera_config_t *config) +{ + assert(base && config); + + volatile uint32_t i = 0; + volatile uint32_t controlVal = 0; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate flexio clock. */ + CLOCK_EnableClock(s_flexioClocks[FLEXIO_CAMERA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + flexio_shifter_config_t shifterConfig; + flexio_timer_config_t timerConfig; + + /* Clear the shifterConfig & timerConfig struct. */ + memset(&shifterConfig, 0, sizeof(shifterConfig)); + memset(&timerConfig, 0, sizeof(timerConfig)); + + /* Reset flexio before configuration. */ + FLEXIO_Reset(base->flexioBase); + + /* Configure flexio camera */ + controlVal = base->flexioBase->CTRL; + controlVal &= + ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); + controlVal |= (FLEXIO_CTRL_DBGE(config->enableInDebug) | FLEXIO_CTRL_FASTACC(config->enableFastAccess) | + FLEXIO_CTRL_FLEXEN(config->enablecamera)); + if (!config->enableInDoze) + { + controlVal |= FLEXIO_CTRL_DOZEN_MASK; + } + base->flexioBase->CTRL = controlVal; + + /* FLEXIO_CAMERA shifter config */ + shifterConfig.timerSelect = base->timerIdx; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + shifterConfig.pinSelect = base->datPinStartIdx; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; + shifterConfig.parallelWidth = FLEXIO_CAMERA_PARALLEL_DATA_WIDTH - 1U; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromNextShifterOutput; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + /* Configure the shifters as FIFO buffer. */ + for (i = base->shifterStartIdx; i < (base->shifterStartIdx + base->shifterCount - 1U); i++) + { + FLEXIO_SetShifterConfig(base->flexioBase, i, &shifterConfig); + } + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + FLEXIO_SetShifterConfig(base->flexioBase, i, &shifterConfig); + + /* FLEXIO_CAMERA timer config, the PCLK's clk is source of timer to drive the shifter, the HREF is the selecting + * signal for available data. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->hrefPinIdx); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinSelect = base->pclkPinIdx; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput; + timerConfig.timerReset = kFLEXIO_TimerResetOnTimerTriggerRisingEdge; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTriggerFallingEdge; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerRisingEdge; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + timerConfig.timerCompare = 8U * base->shifterCount - 1U; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIdx, &timerConfig); + /* Clear flags. */ + FLEXIO_ClearShifterErrorFlags(base->flexioBase, ((1U << (base->shifterCount)) - 1U) << (base->shifterStartIdx)); + FLEXIO_ClearTimerStatusFlags(base->flexioBase, 1U << (base->timerIdx)); +} + +void FLEXIO_CAMERA_Deinit(FLEXIO_CAMERA_Type *base) +{ + /* Disable FLEXIO CAMERA module. */ + FLEXIO_CAMERA_Enable(base, false); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate flexio clock. */ + CLOCK_DisableClock(kCLOCK_Flexio0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +uint32_t FLEXIO_CAMERA_GetStatusFlags(FLEXIO_CAMERA_Type *base) +{ + uint32_t status = 0; + status = ((FLEXIO_GetShifterStatusFlags(base->flexioBase) >> (base->shifterStartIdx)) & + ((1U << (base->shifterCount)) - 1U)); + return status; +} + +void FLEXIO_CAMERA_ClearStatusFlags(FLEXIO_CAMERA_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_CAMERA_RxDataRegFullFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, ((1U << (base->shifterCount)) - 1U) + << (base->shifterStartIdx)); + } + if (mask & kFLEXIO_CAMERA_RxErrorFlag) + { /* Clear error flags if they are asserted to make sure the buffer would be available. */ + FLEXIO_ClearShifterErrorFlags(base->flexioBase, ((1U << (base->shifterCount)) - 1U) << (base->shifterStartIdx)); + } +} + +void FLEXIO_CAMERA_EnableInterrupt(FLEXIO_CAMERA_Type *base) +{ + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << (base->shifterStartIdx)); +} + +void FLEXIO_CAMERA_DisableInterrupt(FLEXIO_CAMERA_Type *base) +{ + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << (base->shifterStartIdx)); +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera.h new file mode 100644 index 00000000000..e059f025eb1 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera.h @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_FLEXIO_CAMERA_H_ +#define _FSL_FLEXIO_CAMERA_H_ + +#include "fsl_common.h" +#include "fsl_flexio.h" + +/*! + * @addtogroup flexio_camera + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief FlexIO Camera driver version 2.1.0. */ +#define FSL_FLEXIO_CAMERA_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ + +/*! @brief Define the Camera CPI interface is constantly 8-bit width. */ +#define FLEXIO_CAMERA_PARALLEL_DATA_WIDTH (8U) + +/*! @brief Error codes for the Camera driver. */ +enum _flexio_camera_status +{ + kStatus_FLEXIO_CAMERA_RxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_CAMERA, 0), /*!< Receiver is busy. */ + kStatus_FLEXIO_CAMERA_RxIdle = MAKE_STATUS(kStatusGroup_FLEXIO_CAMERA, 1), /*!< Camera receiver is idle. */ +}; + +/*! @brief Define FlexIO Camera status mask. */ +enum _flexio_camera_status_flags +{ + kFLEXIO_CAMERA_RxDataRegFullFlag = 0x1U, /*!< Receive buffer full flag. */ + kFLEXIO_CAMERA_RxErrorFlag = 0x2U, /*!< Receive buffer error flag. */ +}; + +/*! + * @brief Define structure of configuring the FlexIO Camera device. + */ +typedef struct _flexio_camera_type +{ + FLEXIO_Type *flexioBase; /*!< FlexIO module base address. */ + uint32_t datPinStartIdx; /*!< First data pin (D0) index for flexio_camera. + Then the successive following FLEXIO_CAMERA_DATA_WIDTH-1 pins + are used as D1-D7.*/ + uint32_t pclkPinIdx; /*!< Pixel clock pin (PCLK) index for flexio_camera. */ + uint32_t hrefPinIdx; /*!< Horizontal sync pin (HREF) index for flexio_camera. */ + + uint32_t shifterStartIdx; /*!< First shifter index used for flexio_camera data FIFO. */ + uint32_t shifterCount; /*!< The count of shifters that are used as flexio_camera data FIFO. */ + uint32_t timerIdx; /*!< Timer index used for flexio_camera in FlexIO. */ +} FLEXIO_CAMERA_Type; + +/*! @brief Define FlexIO Camera user configuration structure. */ +typedef struct _flexio_camera_config +{ + bool enablecamera; /*!< Enable/disable FlexIO Camera TX & RX. */ + bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode*/ + bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode*/ + bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, + fast access requires the FlexIO clock to be at least + twice the frequency of the bus clock. */ +} flexio_camera_config_t; + +/*! @brief Define FlexIO Camera transfer structure. */ +typedef struct _flexio_camera_transfer +{ + uint32_t dataAddress; /*!< Transfer buffer*/ + uint32_t dataNum; /*!< Transfer num*/ +} flexio_camera_transfer_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name Initialization and configuration + * @{ + */ + +/*! + * @brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO Camera. + * + * @param base Pointer to FLEXIO_CAMERA_Type structure + * @param config Pointer to flexio_camera_config_t structure +*/ +void FLEXIO_CAMERA_Init(FLEXIO_CAMERA_Type *base, const flexio_camera_config_t *config); + +/*! + * @brief Disables the FlexIO Camera and gates the FlexIO clock. + * + * @note After calling this API, call FLEXO_CAMERA_Init to use the FlexIO Camera module. + * + * @param base Pointer to FLEXIO_CAMERA_Type structure +*/ +void FLEXIO_CAMERA_Deinit(FLEXIO_CAMERA_Type *base); + +/*! + * @brief Gets the default configuration to configure the FlexIO Camera. The configuration + * can be used directly for calling the FLEXIO_CAMERA_Init(). + * Example: + @code + flexio_camera_config_t config; + FLEXIO_CAMERA_GetDefaultConfig(&userConfig); + @endcode + * @param config Pointer to the flexio_camera_config_t structure +*/ +void FLEXIO_CAMERA_GetDefaultConfig(flexio_camera_config_t *config); + +/*! + * @brief Enables/disables the FlexIO Camera module operation. + * + * @param base Pointer to the FLEXIO_CAMERA_Type + * @param enable True to enable, false to disable. +*/ +static inline void FLEXIO_CAMERA_Enable(FLEXIO_CAMERA_Type *base, bool enable) +{ + if (enable) + { + base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +/*! @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the FlexIO Camera status flags. + * + * @param base Pointer to FLEXIO_CAMERA_Type structure + * @return FlexIO shifter status flags + * @arg FLEXIO_SHIFTSTAT_SSF_MASK + * @arg 0 +*/ +uint32_t FLEXIO_CAMERA_GetStatusFlags(FLEXIO_CAMERA_Type *base); + +/*! + * @brief Clears the receive buffer full flag manually. + * + * @param base Pointer to the device. + * @param mask status flag + * The parameter can be any combination of the following values: + * @arg kFLEXIO_CAMERA_RxDataRegFullFlag + * @arg kFLEXIO_CAMERA_RxErrorFlag + */ +void FLEXIO_CAMERA_ClearStatusFlags(FLEXIO_CAMERA_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Switches on the interrupt for receive buffer full event. + * + * @param base Pointer to the device. + */ +void FLEXIO_CAMERA_EnableInterrupt(FLEXIO_CAMERA_Type *base); + +/*! + * @brief Switches off the interrupt for receive buffer full event. + * + * @param base Pointer to the device. + * + */ +void FLEXIO_CAMERA_DisableInterrupt(FLEXIO_CAMERA_Type *base); + +/*! @} */ + +/*! + * @name DMA support + * @{ + */ + +/*! + * @brief Enables/disables the FlexIO Camera receive DMA. + * + * @param base Pointer to FLEXIO_CAMERA_Type structure + * @param enable True to enable, false to disable. + * + * The FlexIO Camera mode can't work without the DMA or eDMA support, + * Usually, it needs at least two DMA or eDMA channels, one for transferring data from + * Camera, such as 0V7670 to FlexIO buffer, another is for transferring data from FlexIO + * buffer to LCD. + * + */ +static inline void FLEXIO_CAMERA_EnableRxDMA(FLEXIO_CAMERA_Type *base, bool enable) +{ + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->shifterStartIdx, enable); +} + +/*! + * @brief Gets the data from the receive buffer. + * + * @param base Pointer to the device. + * @return data Pointer to the buffer that keeps the data with count of base->shifterCount . + */ +static inline uint32_t FLEXIO_CAMERA_GetRxBufferAddress(FLEXIO_CAMERA_Type *base) +{ + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBuffer, base->shifterStartIdx); +} + +/*! @} */ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ + +/*@}*/ + +#endif /*_FSL_FLEXIO_CAMERA_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera_edma.c new file mode 100644 index 00000000000..c9aa4a30f4c --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera_edma.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_camera_edma.h" +#include "fsl_dmamux.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*base, cameraPrivateHandle->handle); + + if (cameraPrivateHandle->handle->callback) + { + cameraPrivateHandle->handle->callback(cameraPrivateHandle->base, cameraPrivateHandle->handle, + kStatus_FLEXIO_CAMERA_RxIdle, cameraPrivateHandle->handle->userData); + } + } +} +status_t FLEXIO_CAMERA_TransferCreateHandleEDMA(FLEXIO_CAMERA_Type *base, + flexio_camera_edma_handle_t *handle, + flexio_camera_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *rxEdmaHandle) +{ + assert(handle); + + uint8_t index = 0; + + /* Find the an empty handle pointer to store the handle. */ + for (index = 0; index < FLEXIO_CAMERA_HANDLE_COUNT; index++) + { + if (s_edmaPrivateHandle[index].base == NULL) + { + s_edmaPrivateHandle[index].base = base; + s_edmaPrivateHandle[index].handle = handle; + break; + } + } + + if (index == FLEXIO_CAMERA_HANDLE_COUNT) + { + return kStatus_OutOfRange; + } + + s_edmaPrivateHandle[index].base = base; + s_edmaPrivateHandle[index].handle = handle; + + memset(handle, 0, sizeof(*handle)); + + handle->rxState = kFLEXIO_CAMERA_RxIdle; + handle->rxEdmaHandle = rxEdmaHandle; + + handle->callback = callback; + handle->userData = userData; + + /* Configure RX. */ + if (rxEdmaHandle) + { + EDMA_SetCallback(handle->rxEdmaHandle, FLEXIO_CAMERA_TransferReceiveEDMACallback, &s_edmaPrivateHandle); + } + + return kStatus_Success; +} + +status_t FLEXIO_CAMERA_TransferReceiveEDMA(FLEXIO_CAMERA_Type *base, + flexio_camera_edma_handle_t *handle, + flexio_camera_transfer_t *xfer) +{ + assert(handle->rxEdmaHandle); + + edma_transfer_config_t xferConfig; + status_t status; + + /* If previous RX not finished. */ + if (kFLEXIO_CAMERA_RxBusy == handle->rxState) + { + status = kStatus_FLEXIO_CAMERA_RxBusy; + } + else + { + handle->rxState = kFLEXIO_CAMERA_RxBusy; + + /* Prepare transfer. */ + EDMA_PrepareTransfer(&xferConfig, (void *)FLEXIO_CAMERA_GetRxBufferAddress(base), 32, (void *)xfer->dataAddress, + 32, 32, xfer->dataNum, kEDMA_PeripheralToMemory); + + /* Store the initially configured eDMA minor byte transfer count into the FLEXIO CAMERA handle */ + handle->nbytes = 32; + + /* Submit transfer. */ + EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig); + EDMA_StartTransfer(handle->rxEdmaHandle); + /* Enable CAMERA RX EDMA. */ + FLEXIO_CAMERA_EnableRxDMA(base, true); + status = kStatus_Success; + } + + return status; +} + +void FLEXIO_CAMERA_TransferAbortReceiveEDMA(FLEXIO_CAMERA_Type *base, flexio_camera_edma_handle_t *handle) +{ + assert(handle->rxEdmaHandle); + + /* Disable CAMERA RX EDMA. */ + FLEXIO_CAMERA_EnableRxDMA(base, false); + + /* Stop transfer. */ + EDMA_StopTransfer(handle->rxEdmaHandle); + + handle->rxState = kFLEXIO_CAMERA_RxIdle; +} + +status_t FLEXIO_CAMERA_TransferGetReceiveCountEDMA(FLEXIO_CAMERA_Type *base, + flexio_camera_edma_handle_t *handle, + size_t *count) +{ + assert(handle->rxEdmaHandle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + if (kFLEXIO_CAMERA_RxBusy == handle->rxState) + { + *count = (handle->rxSize - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel)); + } + else + { + *count = handle->rxSize; + } + + return kStatus_Success; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera_edma.h new file mode 100644 index 00000000000..a22f130297e --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_camera_edma.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_CAMERA_EDMA_H_ +#define _FSL_FLEXIO_CAMERA_EDMA_H_ + +#include "fsl_flexio_camera.h" +#include "fsl_dmamux.h" +#include "fsl_edma.h" + +/*! + * @addtogroup flexio_edma_camera + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Forward declaration of the handle typedef. */ +typedef struct _flexio_camera_edma_handle flexio_camera_edma_handle_t; + +/*! @brief Camera transfer callback function. */ +typedef void (*flexio_camera_edma_transfer_callback_t)(FLEXIO_CAMERA_Type *base, + flexio_camera_edma_handle_t *handle, + status_t status, + void *userData); + +/*! +* @brief Camera eDMA handle +*/ +struct _flexio_camera_edma_handle +{ + flexio_camera_edma_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< Camera callback function parameter.*/ + size_t rxSize; /*!< Total bytes to be received. */ + edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */ + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + volatile uint8_t rxState; /*!< RX transfer state */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name eDMA transactional + * @{ + */ + +/*! + * @brief Initializes the Camera handle, which is used in transactional functions. + * + * @param base Pointer to the FLEXIO_CAMERA_Type. + * @param handle Pointer to flexio_camera_edma_handle_t structure. + * @param callback The callback function. + * @param userData The parameter of the callback function. + * @param rxEdmaHandle User requested DMA handle for RX DMA transfer. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO Camera eDMA type/handle table out of range. + */ +status_t FLEXIO_CAMERA_TransferCreateHandleEDMA(FLEXIO_CAMERA_Type *base, + flexio_camera_edma_handle_t *handle, + flexio_camera_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *rxEdmaHandle); + +/*! + * @brief Receives data using eDMA. + * + * This function receives data using eDMA. This is a non-blocking function, which returns + * right away. When all data is received, the receive callback function is called. + * + * @param base Pointer to the FLEXIO_CAMERA_Type. + * @param handle Pointer to the flexio_camera_edma_handle_t structure. + * @param xfer Camera eDMA transfer structure, see #flexio_camera_transfer_t. + * @retval kStatus_Success if succeeded, others failed. + * @retval kStatus_CAMERA_RxBusy Previous transfer on going. + */ +status_t FLEXIO_CAMERA_TransferReceiveEDMA(FLEXIO_CAMERA_Type *base, + flexio_camera_edma_handle_t *handle, + flexio_camera_transfer_t *xfer); + +/*! + * @brief Aborts the receive data which used the eDMA. + * + * This function aborts the receive data which used the eDMA. + * + * @param base Pointer to the FLEXIO_CAMERA_Type. + * @param handle Pointer to the flexio_camera_edma_handle_t structure. + */ +void FLEXIO_CAMERA_TransferAbortReceiveEDMA(FLEXIO_CAMERA_Type *base, flexio_camera_edma_handle_t *handle); + +/*! + * @brief Gets the remaining bytes to be received. + * + * This function gets the number of bytes still not received. + * + * @param base Pointer to the FLEXIO_CAMERA_Type. + * @param handle Pointer to the flexio_camera_edma_handle_t structure. + * @param count Number of bytes sent so far by the non-blocking transaction. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_InvalidArgument The count parameter is invalid. + */ +status_t FLEXIO_CAMERA_TransferGetReceiveCountEDMA(FLEXIO_CAMERA_Type *base, + flexio_camera_edma_handle_t *handle, + size_t *count); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_CAMERA_EDMA_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2c_master.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2c_master.c new file mode 100644 index 00000000000..20d6ecc729c --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2c_master.c @@ -0,0 +1,804 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_i2c_master.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief FLEXIO I2C transfer state */ +enum _flexio_i2c_master_transfer_states +{ + kFLEXIO_I2C_Idle = 0x0U, /*!< I2C bus idle */ + kFLEXIO_I2C_CheckAddress = 0x1U, /*!< 7-bit address check state */ + kFLEXIO_I2C_SendCommand = 0x2U, /*!< Send command byte phase */ + kFLEXIO_I2C_SendData = 0x3U, /*!< Send data transfer phase*/ + kFLEXIO_I2C_ReceiveDataBegin = 0x4U, /*!< Receive data begin transfer phase*/ + kFLEXIO_I2C_ReceiveData = 0x5U, /*!< Receive data transfer phase*/ +}; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +extern const clock_ip_name_t s_flexioClocks[]; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +extern FLEXIO_Type *const s_flexioBases[]; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Set up master transfer, send slave address and decide the initial + * transfer state. + * + * @param base pointer to FLEXIO_I2C_Type structure + * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state + * @param transfer pointer to flexio_i2c_master_transfer_t structure + */ +static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_t *xfer); + +/*! + * @brief Master run transfer state machine to perform a byte of transfer. + * + * @param base pointer to FLEXIO_I2C_Type structure + * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state + * @param statusFlags flexio i2c hardware status + * @retval kStatus_Success Successfully run state machine + * @retval kStatus_FLEXIO_I2C_Nak Receive Nak during transfer + */ +static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + uint32_t statusFlags); + +/*! + * @brief Complete transfer, disable interrupt and call callback. + * + * @param base pointer to FLEXIO_I2C_Type structure + * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state + * @param status flexio transfer status + */ +static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + status_t status); + +/******************************************************************************* + * Codes + ******************************************************************************/ + +uint32_t FLEXIO_I2C_GetInstance(FLEXIO_I2C_Type *base) +{ + uint32_t instance; + FLEXIO_Type *flexioBase = base->flexioBase; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_FLEXIO_COUNT; instance++) + { + if (s_flexioBases[instance] == flexioBase) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_FLEXIO_COUNT); + + return instance; +} + +static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_t *xfer) +{ + bool needRestart; + uint32_t byteCount; + + /* Init the handle member. */ + handle->transfer.slaveAddress = xfer->slaveAddress; + handle->transfer.direction = xfer->direction; + handle->transfer.subaddress = xfer->subaddress; + handle->transfer.subaddressSize = xfer->subaddressSize; + handle->transfer.data = xfer->data; + handle->transfer.dataSize = xfer->dataSize; + handle->transfer.flags = xfer->flags; + handle->transferSize = xfer->dataSize; + + /* Initial state, i2c check address state. */ + handle->state = kFLEXIO_I2C_CheckAddress; + + /* Clear all status before transfer. */ + FLEXIO_I2C_MasterClearStatusFlags(base, kFLEXIO_I2C_ReceiveNakFlag); + + /* Calculate whether need to send re-start. */ + needRestart = (handle->transfer.subaddressSize != 0) && (handle->transfer.direction == kFLEXIO_I2C_Read); + + /* Calculate total byte count in a frame. */ + byteCount = 1; + + if (!needRestart) + { + byteCount += handle->transfer.dataSize; + } + + if (handle->transfer.subaddressSize != 0) + { + byteCount += handle->transfer.subaddressSize; + /* Next state, send command byte. */ + handle->state = kFLEXIO_I2C_SendCommand; + } + + /* Configure data count. */ + if (FLEXIO_I2C_MasterSetTransferCount(base, byteCount) != kStatus_Success) + { + return kStatus_InvalidArgument; + } + + while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])))) + { + } + + /* Send address byte first. */ + if (needRestart) + { + FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Write); + } + else + { + FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, handle->transfer.direction); + } + + return kStatus_Success; +} + +static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + uint32_t statusFlags) +{ + if (statusFlags & kFLEXIO_I2C_ReceiveNakFlag) + { + /* Clear receive nak flag. */ + FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]); + + if ((!((handle->state == kFLEXIO_I2C_SendData) && (handle->transfer.dataSize == 0U))) && + (!(((handle->state == kFLEXIO_I2C_ReceiveData) || (handle->state == kFLEXIO_I2C_ReceiveDataBegin)) && + (handle->transfer.dataSize == 1U)))) + { + FLEXIO_I2C_MasterReadByte(base); + + FLEXIO_I2C_MasterAbortStop(base); + + handle->state = kFLEXIO_I2C_Idle; + + return kStatus_FLEXIO_I2C_Nak; + } + } + + if (handle->state == kFLEXIO_I2C_CheckAddress) + { + if (handle->transfer.direction == kFLEXIO_I2C_Write) + { + /* Next state, send data. */ + handle->state = kFLEXIO_I2C_SendData; + } + else + { + /* Next state, receive data begin. */ + handle->state = kFLEXIO_I2C_ReceiveDataBegin; + } + } + + if ((statusFlags & kFLEXIO_I2C_RxFullFlag) && (handle->state != kFLEXIO_I2C_ReceiveData)) + { + FLEXIO_I2C_MasterReadByte(base); + } + + switch (handle->state) + { + case kFLEXIO_I2C_SendCommand: + if (statusFlags & kFLEXIO_I2C_TxEmptyFlag) + { + if (handle->transfer.subaddressSize > 0) + { + handle->transfer.subaddressSize--; + FLEXIO_I2C_MasterWriteByte( + base, ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize))); + + if (handle->transfer.subaddressSize == 0) + { + /* Load re-start in advance. */ + if (handle->transfer.direction == kFLEXIO_I2C_Read) + { + while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])))) + { + } + FLEXIO_I2C_MasterRepeatedStart(base); + } + } + } + else + { + if (handle->transfer.direction == kFLEXIO_I2C_Write) + { + /* Next state, send data. */ + handle->state = kFLEXIO_I2C_SendData; + + /* Send first byte of data. */ + if (handle->transfer.dataSize > 0) + { + FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data); + + handle->transfer.data++; + handle->transfer.dataSize--; + } + } + else + { + FLEXIO_I2C_MasterSetTransferCount(base, (handle->transfer.dataSize + 1)); + FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Read); + + /* Next state, receive data begin. */ + handle->state = kFLEXIO_I2C_ReceiveDataBegin; + } + } + } + break; + + /* Send command byte. */ + case kFLEXIO_I2C_SendData: + if (statusFlags & kFLEXIO_I2C_TxEmptyFlag) + { + /* Send one byte of data. */ + if (handle->transfer.dataSize > 0) + { + FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data); + + handle->transfer.data++; + handle->transfer.dataSize--; + } + else + { + FLEXIO_I2C_MasterStop(base); + + while (!(FLEXIO_I2C_MasterGetStatusFlags(base) & kFLEXIO_I2C_RxFullFlag)) + { + } + FLEXIO_I2C_MasterReadByte(base); + + handle->state = kFLEXIO_I2C_Idle; + } + } + break; + + case kFLEXIO_I2C_ReceiveDataBegin: + if (statusFlags & kFLEXIO_I2C_RxFullFlag) + { + handle->state = kFLEXIO_I2C_ReceiveData; + /* Send nak at the last receive byte. */ + if (handle->transfer.dataSize == 1) + { + FLEXIO_I2C_MasterEnableAck(base, false); + while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])))) + { + } + FLEXIO_I2C_MasterStop(base); + } + else + { + FLEXIO_I2C_MasterEnableAck(base, true); + } + } + else if (statusFlags & kFLEXIO_I2C_TxEmptyFlag) + { + /* Read one byte of data. */ + FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU); + } + else + { + } + break; + + case kFLEXIO_I2C_ReceiveData: + if (statusFlags & kFLEXIO_I2C_RxFullFlag) + { + *handle->transfer.data = FLEXIO_I2C_MasterReadByte(base); + handle->transfer.data++; + if (handle->transfer.dataSize--) + { + if (handle->transfer.dataSize == 0) + { + FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_RxFullInterruptEnable); + handle->state = kFLEXIO_I2C_Idle; + } + + /* Send nak at the last receive byte. */ + if (handle->transfer.dataSize == 1) + { + FLEXIO_I2C_MasterEnableAck(base, false); + while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])))) + { + } + FLEXIO_I2C_MasterStop(base); + } + } + } + else if (statusFlags & kFLEXIO_I2C_TxEmptyFlag) + { + if (handle->transfer.dataSize > 1) + { + FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU); + } + } + else + { + } + break; + + default: + break; + } + + return kStatus_Success; +} + +static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + status_t status) +{ + FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable); + + if (handle->completionCallback) + { + handle->completionCallback(base, handle, status, handle->userData); + } +} + +void FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz) +{ + assert(base && masterConfig); + + flexio_shifter_config_t shifterConfig; + flexio_timer_config_t timerConfig; + uint32_t controlVal = 0; + + memset(&shifterConfig, 0, sizeof(shifterConfig)); + memset(&timerConfig, 0, sizeof(timerConfig)); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate flexio clock. */ + CLOCK_EnableClock(s_flexioClocks[FLEXIO_I2C_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + FLEXIO_Reset(base->flexioBase); + + /* Do hardware configuration. */ + /* 1. Configure the shifter 0 for tx. */ + shifterConfig.timerSelect = base->timerIndex[1]; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection; + shifterConfig.pinSelect = base->SDAPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveLow; + shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow; + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); + + /* 2. Configure the shifter 1 for rx. */ + shifterConfig.timerSelect = base->timerIndex[1]; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + shifterConfig.pinSelect = base->SDAPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); + + /*3. Configure the timer 0 for generating bit clock. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection; + timerConfig.pinSelect = base->SCLPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; + timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; + timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + + /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1. */ + timerConfig.timerCompare = (srcClock_Hz / masterConfig->baudRate_Bps) / 2 - 1; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); + + /* 4. Configure the timer 1 for controlling shifters. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinSelect = base->SCLPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveLow; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable; + timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerCompare; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + + /* Set TIMCMP[15:0] = (number of bits x 2) - 1. */ + timerConfig.timerCompare = 8 * 2 - 1; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig); + + /* Configure FLEXIO I2C Master. */ + controlVal = base->flexioBase->CTRL; + controlVal &= + ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); + controlVal |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) | + FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster)); + if (!masterConfig->enableInDoze) + { + controlVal |= FLEXIO_CTRL_DOZEN_MASK; + } + + base->flexioBase->CTRL = controlVal; +} + +void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base) +{ + FLEXIO_Deinit(base->flexioBase); +} + +void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig) +{ + assert(masterConfig); + + masterConfig->enableMaster = true; + masterConfig->enableInDoze = false; + masterConfig->enableInDebug = true; + masterConfig->enableFastAccess = false; + + /* Default baud rate at 100kbps. */ + masterConfig->baudRate_Bps = 100000U; +} + +uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base) +{ + uint32_t status = 0; + + status = + ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]); + status |= + (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) + << 1U); + status |= + (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) + << 2U); + + return status; +} + +void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_I2C_TxEmptyFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]); + } + + if (mask & kFLEXIO_I2C_RxFullFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]); + } + + if (mask & kFLEXIO_I2C_ReceiveNakFlag) + { + FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]); + } + if (mask & kFLEXIO_I2C_RxFullInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]); + } + if (mask & kFLEXIO_I2C_RxFullInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) +{ + uint16_t timerDiv = 0; + uint16_t timerCmp = 0; + FLEXIO_Type *flexioBase = base->flexioBase; + + /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/ + timerDiv = srcClock_Hz / baudRate_Bps; + timerDiv = timerDiv / 2 - 1U; + + timerCmp = flexioBase->TIMCMP[base->timerIndex[0]]; + timerCmp &= 0xFF00; + timerCmp |= timerDiv; + + flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp; +} + +status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint8_t count) +{ + if (count > 14U) + { + return kStatus_InvalidArgument; + } + + uint16_t timerCmp = 0; + uint32_t timerConfig = 0; + FLEXIO_Type *flexioBase = base->flexioBase; + + timerCmp = flexioBase->TIMCMP[base->timerIndex[0]]; + timerCmp &= 0x00FFU; + timerCmp |= (count * 18 + 1U) << 8U; + flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp; + timerConfig = flexioBase->TIMCFG[base->timerIndex[0]]; + timerConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK; + timerConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare); + flexioBase->TIMCFG[base->timerIndex[0]] = timerConfig; + + return kStatus_Success; +} + +void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction) +{ + uint32_t data; + + data = ((uint32_t)address) << 1U | ((direction == kFLEXIO_I2C_Read) ? 1U : 0U); + + FLEXIO_I2C_MasterWriteByte(base, data); +} + +void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base) +{ + /* Prepare for RESTART condition, no stop.*/ + FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU); +} + +void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base) +{ + /* Prepare normal stop. */ + FLEXIO_I2C_MasterSetTransferCount(base, 0x0U); + FLEXIO_I2C_MasterWriteByte(base, 0x0U); +} + +void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base) +{ + uint32_t tmpConfig; + + /* Prepare abort stop. */ + tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[0]]; + tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK; + tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge); + base->flexioBase->TIMCFG[base->timerIndex[0]] = tmpConfig; +} + +void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable) +{ + uint32_t tmpConfig = 0; + + tmpConfig = base->flexioBase->SHIFTCFG[base->shifterIndex[0]]; + tmpConfig &= ~FLEXIO_SHIFTCFG_SSTOP_MASK; + if (enable) + { + tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitLow); + } + else + { + tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitHigh); + } + base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = tmpConfig; +} + +status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize) +{ + assert(txBuff); + assert(txSize); + + uint32_t status; + + while (txSize--) + { + FLEXIO_I2C_MasterWriteByte(base, *txBuff++); + + /* Wait until data transfer complete. */ + while (!((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & kFLEXIO_I2C_RxFullFlag)) + { + } + + if (status & kFLEXIO_I2C_ReceiveNakFlag) + { + FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]); + return kStatus_FLEXIO_I2C_Nak; + } + } + return kStatus_Success; +} + +void FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize) +{ + assert(rxBuff); + assert(rxSize); + + while (rxSize--) + { + /* Wait until data transfer complete. */ + while (!(FLEXIO_I2C_MasterGetStatusFlags(base) & kFLEXIO_I2C_RxFullFlag)) + { + } + + *rxBuff++ = FLEXIO_I2C_MasterReadByte(base); + } +} + +status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer) +{ + assert(xfer); + + flexio_i2c_master_handle_t tmpHandle; + uint32_t statusFlags; + uint32_t result = kStatus_Success; + + /* Zero the handle. */ + memset(&tmpHandle, 0, sizeof(tmpHandle)); + + /* Set up transfer machine. */ + FLEXIO_I2C_MasterTransferInitStateMachine(base, &tmpHandle, xfer); + + do + { + /* Wait either tx empty or rx full flag is asserted. */ + while (!((statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base)) & + (kFLEXIO_I2C_TxEmptyFlag | kFLEXIO_I2C_RxFullFlag))) + { + } + + result = FLEXIO_I2C_MasterTransferRunStateMachine(base, &tmpHandle, statusFlags); + + } while ((tmpHandle.state != kFLEXIO_I2C_Idle) && (result == kStatus_Success)); + + return result; +} + +status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + IRQn_Type flexio_irqs[] = FLEXIO_IRQS; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Register callback and userData. */ + handle->completionCallback = callback; + handle->userData = userData; + + /* Enable interrupt in NVIC. */ + EnableIRQ(flexio_irqs[FLEXIO_I2C_GetInstance(base)]); + + /* Save the context in global variables to support the double weak mechanism. */ + return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2C_MasterTransferHandleIRQ); +} + +status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + if (handle->state != kFLEXIO_I2C_Idle) + { + return kStatus_FLEXIO_I2C_Busy; + } + else + { + /* Set up transfer machine. */ + FLEXIO_I2C_MasterTransferInitStateMachine(base, handle, xfer); + + /* Enable both tx empty and rxfull interrupt. */ + FLEXIO_I2C_MasterEnableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable); + + return kStatus_Success; + } +} + +void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle) +{ + assert(handle); + + /* Disable interrupts. */ + FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable); + + /* Reset to idle state. */ + handle->state = kFLEXIO_I2C_Idle; +} + +status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count) +{ + if (!count) + { + return kStatus_InvalidArgument; + } + + *count = handle->transferSize - handle->transfer.dataSize; + + return kStatus_Success; +} + +void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle) +{ + FLEXIO_I2C_Type *base = (FLEXIO_I2C_Type *)i2cType; + flexio_i2c_master_handle_t *handle = (flexio_i2c_master_handle_t *)i2cHandle; + uint32_t statusFlags; + status_t result; + + statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base); + + result = FLEXIO_I2C_MasterTransferRunStateMachine(base, handle, statusFlags); + + if (handle->state == kFLEXIO_I2C_Idle) + { + FLEXIO_I2C_MasterTransferComplete(base, handle, result); + } +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2c_master.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2c_master.h new file mode 100644 index 00000000000..d6767d0c015 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2c_master.h @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_I2C_MASTER_H_ +#define _FSL_FLEXIO_I2C_MASTER_H_ + +#include "fsl_common.h" +#include "fsl_flexio.h" + +/*! + * @addtogroup flexio_i2c_master + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief FlexIO I2C master driver version 2.1.2. */ +#define FSL_FLEXIO_I2C_MASTER_DRIVER_VERSION (MAKE_VERSION(2, 1, 2)) +/*@}*/ + +/*! @brief FlexIO I2C transfer status*/ +enum _flexio_i2c_status +{ + kStatus_FLEXIO_I2C_Busy = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 0), /*!< I2C is busy doing transfer. */ + kStatus_FLEXIO_I2C_Idle = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 1), /*!< I2C is busy doing transfer. */ + kStatus_FLEXIO_I2C_Nak = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 2), /*!< NAK received during transfer. */ +}; + +/*! @brief Define FlexIO I2C master interrupt mask. */ +enum _flexio_i2c_master_interrupt +{ + kFLEXIO_I2C_TxEmptyInterruptEnable = 0x1U, /*!< Tx buffer empty interrupt enable. */ + kFLEXIO_I2C_RxFullInterruptEnable = 0x2U, /*!< Rx buffer full interrupt enable. */ +}; + +/*! @brief Define FlexIO I2C master status mask. */ +enum _flexio_i2c_master_status_flags +{ + kFLEXIO_I2C_TxEmptyFlag = 0x1U, /*!< Tx shifter empty flag. */ + kFLEXIO_I2C_RxFullFlag = 0x2U, /*!< Rx shifter full/Transfer complete flag. */ + kFLEXIO_I2C_ReceiveNakFlag = 0x4U, /*!< Receive NAK flag. */ +}; + +/*! @brief Direction of master transfer.*/ +typedef enum _flexio_i2c_direction +{ + kFLEXIO_I2C_Write = 0x0U, /*!< Master send to slave. */ + kFLEXIO_I2C_Read = 0x1U, /*!< Master receive from slave. */ +} flexio_i2c_direction_t; + +/*! @brief Define FlexIO I2C master access structure typedef. */ +typedef struct _flexio_i2c_type +{ + FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */ + uint8_t SDAPinIndex; /*!< Pin select for I2C SDA. */ + uint8_t SCLPinIndex; /*!< Pin select for I2C SCL. */ + uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO I2C. */ + uint8_t timerIndex[2]; /*!< Timer index used in FlexIO I2C. */ +} FLEXIO_I2C_Type; + +/*! @brief Define FlexIO I2C master user configuration structure. */ +typedef struct _flexio_i2c_master_config +{ + bool enableMaster; /*!< Enables the FlexIO I2C peripheral at initialization time. */ + bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode. */ + bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode. */ + bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, fast access requires + the FlexIO clock to be at least twice the frequency of the bus clock. */ + uint32_t baudRate_Bps; /*!< Baud rate in Bps. */ +} flexio_i2c_master_config_t; + +/*! @brief Define FlexIO I2C master transfer structure. */ +typedef struct _flexio_i2c_master_transfer +{ + uint32_t flags; /*!< Transfer flag which controls the transfer, reserved for FlexIO I2C. */ + uint8_t slaveAddress; /*!< 7-bit slave address. */ + flexio_i2c_direction_t direction; /*!< Transfer direction, read or write. */ + uint32_t subaddress; /*!< Sub address. Transferred MSB first. */ + uint8_t subaddressSize; /*!< Size of command buffer. */ + uint8_t volatile *data; /*!< Transfer buffer. */ + volatile size_t dataSize; /*!< Transfer size. */ +} flexio_i2c_master_transfer_t; + +/*! @brief FlexIO I2C master handle typedef. */ +typedef struct _flexio_i2c_master_handle flexio_i2c_master_handle_t; + +/*! @brief FlexIO I2C master transfer callback typedef. */ +typedef void (*flexio_i2c_master_transfer_callback_t)(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + status_t status, + void *userData); + +/*! @brief Define FlexIO I2C master handle structure. */ +struct _flexio_i2c_master_handle +{ + flexio_i2c_master_transfer_t transfer; /*!< FlexIO I2C master transfer copy. */ + size_t transferSize; /*!< Total bytes to be transferred. */ + uint8_t state; /*!< Transfer state maintained during transfer. */ + flexio_i2c_master_transfer_callback_t completionCallback; /*!< Callback function called at transfer event. */ + /*!< Callback function called at transfer event. */ + void *userData; /*!< Callback parameter passed to callback function. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO I2C + * hardware configuration. + * + * Example + @code + FLEXIO_I2C_Type base = { + .flexioBase = FLEXIO, + .SDAPinIndex = 0, + .SCLPinIndex = 1, + .shifterIndex = {0,1}, + .timerIndex = {0,1} + }; + flexio_i2c_master_config_t config = { + .enableInDoze = false, + .enableInDebug = true, + .enableFastAccess = false, + .baudRate_Bps = 100000 + }; + FLEXIO_I2C_MasterInit(base, &config, srcClock_Hz); + @endcode + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param masterConfig Pointer to flexio_i2c_master_config_t structure. + * @param srcClock_Hz FlexIO source clock in Hz. +*/ +void FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz); + +/*! + * @brief De-initializes the FlexIO I2C master peripheral. Calling this API gates the FlexIO clock + * and the FlexIO I2C master module can't work unless the FLEXIO_I2C_MasterInit is called. + * + * @param base pointer to FLEXIO_I2C_Type structure. + */ +void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base); + +/*! + * @brief Gets the default configuration to configure the FlexIO module. The configuration + * can be used directly for calling the FLEXIO_I2C_MasterInit(). + * + * Example: + @code + flexio_i2c_master_config_t config; + FLEXIO_I2C_MasterGetDefaultConfig(&config); + @endcode + * @param masterConfig Pointer to flexio_i2c_master_config_t structure. +*/ +void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig); + +/*! + * @brief Enables/disables the FlexIO module operation. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param enable Pass true to enable module, false to disable module. +*/ +static inline void FLEXIO_I2C_MasterEnable(FLEXIO_I2C_Type *base, bool enable) +{ + if (enable) + { + base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the FlexIO I2C master status flags. + * + * @param base Pointer to FLEXIO_I2C_Type structure + * @return Status flag, use status flag to AND #_flexio_i2c_master_status_flags can get the related status. +*/ + +uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base); + +/*! + * @brief Clears the FlexIO I2C master status flags. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param mask Status flag. + * The parameter can be any combination of the following values: + * @arg kFLEXIO_I2C_RxFullFlag + * @arg kFLEXIO_I2C_ReceiveNakFlag +*/ + +void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask); + +/*@}*/ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the FlexIO i2c master interrupt requests. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param mask Interrupt source. + * Currently only one interrupt request source: + * @arg kFLEXIO_I2C_TransferCompleteInterruptEnable + */ +void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask); + +/*! + * @brief Disables the FlexIO I2C master interrupt requests. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param mask Interrupt source. + */ +void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask); + +/*@}*/ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Sets the FlexIO I2C master transfer baudrate. + * + * @param base Pointer to FLEXIO_I2C_Type structure + * @param baudRate_Bps the baud rate value in HZ + * @param srcClock_Hz source clock in HZ + */ +void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); + +/*! + * @brief Sends START + 7-bit address to the bus. + * + * @note This API should be called when the transfer configuration is ready to send a START signal + * and 7-bit address to the bus. This is a non-blocking API, which returns directly after the address + * is put into the data register but the address transfer is not finished on the bus. Ensure that + * the kFLEXIO_I2C_RxFullFlag status is asserted before calling this API. + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param address 7-bit address. + * @param direction transfer direction. + * This parameter is one of the values in flexio_i2c_direction_t: + * @arg kFLEXIO_I2C_Write: Transmit + * @arg kFLEXIO_I2C_Read: Receive + */ + +void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction); + +/*! + * @brief Sends the stop signal on the bus. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + */ +void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base); + +/*! + * @brief Sends the repeated start signal on the bus. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + */ +void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base); + +/*! + * @brief Sends the stop signal when transfer is still on-going. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + */ +void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base); + +/*! + * @brief Configures the sent ACK/NAK for the following byte. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param enable True to configure send ACK, false configure to send NAK. + */ +void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable); + +/*! + * @brief Sets the number of bytes to be transferred from a start signal to a stop signal. + * + * @note Call this API before a transfer begins because the timer generates a number of clocks according + * to the number of bytes that need to be transferred. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param count Number of bytes need to be transferred from a start signal to a re-start/stop signal + * @retval kStatus_Success Successfully configured the count. + * @retval kStatus_InvalidArgument Input argument is invalid. +*/ +status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint8_t count); + +/*! + * @brief Writes one byte of data to the I2C bus. + * + * @note This is a non-blocking API, which returns directly after the data is put into the + * data register but the data transfer is not finished on the bus. Ensure that + * the TxEmptyFlag is asserted before calling this API. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param data a byte of data. + */ +static inline void FLEXIO_I2C_MasterWriteByte(FLEXIO_I2C_Type *base, uint32_t data) +{ + base->flexioBase->SHIFTBUFBBS[base->shifterIndex[0]] = data; +} + +/*! + * @brief Reads one byte of data from the I2C bus. + * + * @note This is a non-blocking API, which returns directly after the data is read from the + * data register. Ensure that the data is ready in the register. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @return data byte read. + */ +static inline uint8_t FLEXIO_I2C_MasterReadByte(FLEXIO_I2C_Type *base) +{ + return base->flexioBase->SHIFTBUFBIS[base->shifterIndex[1]]; +} + +/*! + * @brief Sends a buffer of data in bytes. + * + * @note This function blocks via polling until all bytes have been sent. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param txBuff The data bytes to send. + * @param txSize The number of data bytes to send. + * @retval kStatus_Success Successfully write data. + * @retval kStatus_FLEXIO_I2C_Nak Receive NAK during writing data. + */ +status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize); + +/*! + * @brief Receives a buffer of bytes. + * + * @note This function blocks via polling until all bytes have been received. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param rxBuff The buffer to store the received bytes. + * @param rxSize The number of data bytes to be received. + */ +void FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize); + +/*! + * @brief Performs a master polling transfer on the I2C bus. + * + * @note The API does not return until the transfer succeeds or fails due + * to receiving NAK. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param xfer pointer to flexio_i2c_master_transfer_t structure. + * @return status of status_t. + */ +status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer); +/*@}*/ + +/*Transactional APIs*/ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the I2C handle which is used in transactional functions. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param handle Pointer to flexio_i2c_master_handle_t structure to store the transfer state. + * @param callback Pointer to user callback function. + * @param userData User param passed to the callback function. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO type/handle/isr table out of range. + */ +status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_callback_t callback, + void *userData); + +/*! + * @brief Performs a master interrupt non-blocking transfer on the I2C bus. + * + * @note The API returns immediately after the transfer initiates. + * Call FLEXIO_I2C_MasterGetTransferCount to poll the transfer status to check whether + * the transfer is finished. If the return status is not kStatus_FLEXIO_I2C_Busy, the transfer + * is finished. + * + * @param base Pointer to FLEXIO_I2C_Type structure + * @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state + * @param xfer pointer to flexio_i2c_master_transfer_t structure + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_FLEXIO_I2C_Busy FlexIO I2C is not idle, is running another transfer. + */ +status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_t *xfer); + +/*! + * @brief Gets the master transfer status during a interrupt non-blocking transfer. + * + * @param base Pointer to FLEXIO_I2C_Type structure. + * @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state. + * @param count Number of bytes transferred so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count); + +/*! + * @brief Aborts an interrupt non-blocking transfer early. + * + * @note This API can be called at any time when an interrupt non-blocking transfer initiates + * to abort the transfer early. + * + * @param base Pointer to FLEXIO_I2C_Type structure + * @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state + */ +void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle); + +/*! + * @brief Master interrupt handler. + * + * @param i2cType Pointer to FLEXIO_I2C_Type structure + * @param i2cHandle Pointer to flexio_i2c_master_transfer_t structure + */ +void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ +/*@}*/ + +#endif /*_FSL_FLEXIO_I2C_MASTER_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s.c new file mode 100644 index 00000000000..76428841bef --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s.c @@ -0,0 +1,665 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_i2s.h" + +/******************************************************************************* +* Definitations +******************************************************************************/ +enum _sai_transfer_state +{ + kFLEXIO_I2S_Busy = 0x0U, /*!< FLEXIO_I2S is busy */ + kFLEXIO_I2S_Idle, /*!< Transfer is done. */ +}; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Receive a piece of data in non-blocking way. + * + * @param base FLEXIO I2S base pointer + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param buffer Pointer to the data to be read. + * @param size Bytes to be read. + */ +static void FLEXIO_I2S_ReadNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size); + +/*! + * @brief sends a piece of data in non-blocking way. + * + * @param base FLEXIO I2S base pointer + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param buffer Pointer to the data to be written. + * @param size Bytes to be written. + */ +static void FLEXIO_I2S_WriteNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size); +/******************************************************************************* + * Variables + ******************************************************************************/ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +extern const clock_ip_name_t s_flexioClocks[]; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +extern FLEXIO_Type *const s_flexioBases[]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +uint32_t FLEXIO_I2S_GetInstance(FLEXIO_I2S_Type *base) +{ + uint32_t instance; + FLEXIO_Type *flexioBase = base->flexioBase; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_FLEXIO_COUNT; instance++) + { + if (s_flexioBases[instance] == flexioBase) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_FLEXIO_COUNT); + + return instance; +} + +static void FLEXIO_I2S_WriteNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size) +{ + uint32_t i = 0; + uint8_t j = 0; + uint8_t bytesPerWord = bitWidth / 8U; + uint32_t data = 0; + uint32_t temp = 0; + + for (i = 0; i < size / bytesPerWord; i++) + { + for (j = 0; j < bytesPerWord; j++) + { + temp = (uint32_t)(*txData); + data |= (temp << (8U * j)); + txData++; + } + base->flexioBase->SHIFTBUFBIS[base->txShifterIndex] = (data << (32U - bitWidth)); + data = 0; + } +} + +static void FLEXIO_I2S_ReadNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size) +{ + uint32_t i = 0; + uint8_t j = 0; + uint8_t bytesPerWord = bitWidth / 8U; + uint32_t data = 0; + + for (i = 0; i < size / bytesPerWord; i++) + { + data = (base->flexioBase->SHIFTBUFBIS[base->rxShifterIndex] >> (32U - bitWidth)); + for (j = 0; j < bytesPerWord; j++) + { + *rxData = (data >> (8U * j)) & 0xFF; + rxData++; + } + } +} + +void FLEXIO_I2S_Init(FLEXIO_I2S_Type *base, const flexio_i2s_config_t *config) +{ + assert(base && config); + + flexio_shifter_config_t shifterConfig = {0}; + flexio_timer_config_t timerConfig = {0}; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate flexio clock. */ + CLOCK_EnableClock(s_flexioClocks[FLEXIO_I2S_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + FLEXIO_Reset(base->flexioBase); + + /* Set shifter for I2S Tx data */ + shifterConfig.timerSelect = base->bclkTimerIndex; + shifterConfig.pinSelect = base->txPinIndex; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + if (config->masterSlave == kFLEXIO_I2S_Master) + { + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift; + } + else + { + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + } + + FLEXIO_SetShifterConfig(base->flexioBase, base->txShifterIndex, &shifterConfig); + + /* Set shifter for I2S Rx Data */ + shifterConfig.timerSelect = base->bclkTimerIndex; + shifterConfig.pinSelect = base->rxPinIndex; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + + FLEXIO_SetShifterConfig(base->flexioBase, base->rxShifterIndex, &shifterConfig); + + /* Set Timer to I2S frame sync */ + if (config->masterSlave == kFLEXIO_I2S_Master) + { + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->txPinIndex); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceExternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutput; + timerConfig.pinSelect = base->fsPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveLow; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableNever; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + } + else + { + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->bclkPinIndex); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinSelect = base->fsPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveLow; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnTriggerInputShiftTriggerInput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdge; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + } + FLEXIO_SetTimerConfig(base->flexioBase, base->fsTimerIndex, &timerConfig); + + /* Set Timer to I2S bit clock */ + if (config->masterSlave == kFLEXIO_I2S_Master) + { + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->txShifterIndex); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinSelect = base->bclkPinIndex; + timerConfig.pinConfig = kFLEXIO_PinConfigOutput; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableNever; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + } + else + { + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->fsTimerIndex); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinSelect = base->bclkPinIndex; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompareTriggerLow; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdgeTriggerHigh; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + } + FLEXIO_SetTimerConfig(base->flexioBase, base->bclkTimerIndex, &timerConfig); + + /* If enable flexio I2S */ + if (config->enableI2S) + { + base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +void FLEXIO_I2S_GetDefaultConfig(flexio_i2s_config_t *config) +{ + config->masterSlave = kFLEXIO_I2S_Master; + config->enableI2S = true; +} + +void FLEXIO_I2S_Deinit(FLEXIO_I2S_Type *base) +{ + /* Disable FLEXIO I2S module. */ + FLEXIO_I2S_Enable(base, false); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate flexio clock. */ + CLOCK_DisableClock(kCLOCK_Flexio0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void FLEXIO_I2S_EnableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_I2S_TxDataRegEmptyInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->txShifterIndex); + } + if (mask & kFLEXIO_I2S_RxDataRegFullInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->rxShifterIndex); + } +} + +uint32_t FLEXIO_I2S_GetStatusFlags(FLEXIO_I2S_Type *base) +{ + uint32_t status = 0; + status = ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->txShifterIndex)) >> base->txShifterIndex); + status |= + (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->rxShifterIndex)) >> (base->rxShifterIndex)) + << 1U); + return status; +} + +void FLEXIO_I2S_DisableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_I2S_TxDataRegEmptyInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->txShifterIndex); + } + if (mask & kFLEXIO_I2S_RxDataRegFullInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->rxShifterIndex); + } +} + +void FLEXIO_I2S_MasterSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format, uint32_t srcClock_Hz) +{ + uint32_t timDiv = srcClock_Hz / (format->sampleRate_Hz * 32U * 2U); + uint32_t bclkDiv = 0; + + /* Set Frame sync timer cmp */ + base->flexioBase->TIMCMP[base->fsTimerIndex] = FLEXIO_TIMCMP_CMP(32U * timDiv - 1U); + + /* Set bit clock timer cmp */ + bclkDiv = ((timDiv / 2U - 1U) | (63U << 8U)); + base->flexioBase->TIMCMP[base->bclkTimerIndex] = FLEXIO_TIMCMP_CMP(bclkDiv); +} + +void FLEXIO_I2S_SlaveSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format) +{ + /* Set Frame sync timer cmp */ + base->flexioBase->TIMCMP[base->fsTimerIndex] = FLEXIO_TIMCMP_CMP(32U * 4U - 3U); + + /* Set bit clock timer cmp */ + base->flexioBase->TIMCMP[base->bclkTimerIndex] = FLEXIO_TIMCMP_CMP(32U * 2U - 1U); +} + +void FLEXIO_I2S_WriteBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size) +{ + uint32_t i = 0; + uint8_t bytesPerWord = bitWidth / 8U; + + for (i = 0; i < size / bytesPerWord; i++) + { + /* Wait until it can write data */ + while ((FLEXIO_I2S_GetStatusFlags(base) & kFLEXIO_I2S_TxDataRegEmptyFlag) == 0) + { + } + + FLEXIO_I2S_WriteNonBlocking(base, bitWidth, txData, bytesPerWord); + txData += bytesPerWord; + } + + /* Wait until the last data is sent */ + while ((FLEXIO_I2S_GetStatusFlags(base) & kFLEXIO_I2S_TxDataRegEmptyFlag) == 0) + { + } +} + +void FLEXIO_I2S_ReadBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size) +{ + uint32_t i = 0; + uint8_t bytesPerWord = bitWidth / 8U; + + for (i = 0; i < size / bytesPerWord; i++) + { + /* Wait until data is received */ + while (!(FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->rxShifterIndex))) + { + } + + FLEXIO_I2S_ReadNonBlocking(base, bitWidth, rxData, bytesPerWord); + rxData += bytesPerWord; + } +} + +void FLEXIO_I2S_TransferTxCreateHandle(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_callback_t callback, + void *userData) +{ + assert(handle); + + IRQn_Type flexio_irqs[] = FLEXIO_IRQS; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Store callback and user data. */ + handle->callback = callback; + handle->userData = userData; + + /* Save the context in global variables to support the double weak mechanism. */ + FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2S_TransferTxHandleIRQ); + + /* Set the TX/RX state. */ + handle->state = kFLEXIO_I2S_Idle; + + /* Enable interrupt in NVIC. */ + EnableIRQ(flexio_irqs[FLEXIO_I2S_GetInstance(base)]); +} + +void FLEXIO_I2S_TransferRxCreateHandle(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_callback_t callback, + void *userData) +{ + assert(handle); + + IRQn_Type flexio_irqs[] = FLEXIO_IRQS; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Store callback and user data. */ + handle->callback = callback; + handle->userData = userData; + + /* Save the context in global variables to support the double weak mechanism. */ + FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2S_TransferRxHandleIRQ); + + /* Set the TX/RX state. */ + handle->state = kFLEXIO_I2S_Idle; + + /* Enable interrupt in NVIC. */ + EnableIRQ(flexio_irqs[FLEXIO_I2S_GetInstance(base)]); +} + +void FLEXIO_I2S_TransferSetFormat(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_format_t *format, + uint32_t srcClock_Hz) +{ + assert(handle && format); + + /* Set the bitWidth to handle */ + handle->bitWidth = format->bitWidth; + + /* Set sample rate */ + if (srcClock_Hz != 0) + { + /* It is master */ + FLEXIO_I2S_MasterSetFormat(base, format, srcClock_Hz); + } + else + { + FLEXIO_I2S_SlaveSetFormat(base, format); + } +} + +status_t FLEXIO_I2S_TransferSendNonBlocking(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_transfer_t *xfer) +{ + assert(handle); + + /* Check if the queue is full */ + if (handle->queue[handle->queueUser].data) + { + return kStatus_FLEXIO_I2S_QueueFull; + } + if ((xfer->dataSize == 0) || (xfer->data == NULL)) + { + return kStatus_InvalidArgument; + } + + /* Add into queue */ + handle->queue[handle->queueUser].data = xfer->data; + handle->queue[handle->queueUser].dataSize = xfer->dataSize; + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + + /* Set the state to busy */ + handle->state = kFLEXIO_I2S_Busy; + + FLEXIO_I2S_EnableInterrupts(base, kFLEXIO_I2S_TxDataRegEmptyInterruptEnable); + + /* Enable Tx transfer */ + FLEXIO_I2S_Enable(base, true); + + return kStatus_Success; +} + +status_t FLEXIO_I2S_TransferReceiveNonBlocking(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_transfer_t *xfer) +{ + assert(handle); + + /* Check if the queue is full */ + if (handle->queue[handle->queueUser].data) + { + return kStatus_FLEXIO_I2S_QueueFull; + } + + if ((xfer->dataSize == 0) || (xfer->data == NULL)) + { + return kStatus_InvalidArgument; + } + + /* Add into queue */ + handle->queue[handle->queueUser].data = xfer->data; + handle->queue[handle->queueUser].dataSize = xfer->dataSize; + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + + /* Set state to busy */ + handle->state = kFLEXIO_I2S_Busy; + + /* Enable interrupt */ + FLEXIO_I2S_EnableInterrupts(base, kFLEXIO_I2S_RxDataRegFullInterruptEnable); + + /* Enable Rx transfer */ + FLEXIO_I2S_Enable(base, true); + + return kStatus_Success; +} + +void FLEXIO_I2S_TransferAbortSend(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle) +{ + assert(handle); + + /* Stop Tx transfer and disable interrupt */ + FLEXIO_I2S_DisableInterrupts(base, kFLEXIO_I2S_TxDataRegEmptyInterruptEnable); + handle->state = kFLEXIO_I2S_Idle; + + /* Clear the queue */ + memset(handle->queue, 0, sizeof(flexio_i2s_transfer_t) * FLEXIO_I2S_XFER_QUEUE_SIZE); + handle->queueDriver = 0; + handle->queueUser = 0; +} + +void FLEXIO_I2S_TransferAbortReceive(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle) +{ + assert(handle); + + /* Stop rx transfer and disable interrupt */ + FLEXIO_I2S_DisableInterrupts(base, kFLEXIO_I2S_RxDataRegFullInterruptEnable); + handle->state = kFLEXIO_I2S_Idle; + + /* Clear the queue */ + memset(handle->queue, 0, sizeof(flexio_i2s_transfer_t) * FLEXIO_I2S_XFER_QUEUE_SIZE); + handle->queueDriver = 0; + handle->queueUser = 0; +} + +status_t FLEXIO_I2S_TransferGetSendCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kFLEXIO_I2S_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = (handle->transferSize[handle->queueDriver] - handle->queue[handle->queueDriver].dataSize); + } + + return status; +} + +status_t FLEXIO_I2S_TransferGetReceiveCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kFLEXIO_I2S_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = (handle->transferSize[handle->queueDriver] - handle->queue[handle->queueDriver].dataSize); + } + + return status; +} + +void FLEXIO_I2S_TransferTxHandleIRQ(void *i2sBase, void *i2sHandle) +{ + assert(i2sHandle); + + flexio_i2s_handle_t *handle = (flexio_i2s_handle_t *)i2sHandle; + FLEXIO_I2S_Type *base = (FLEXIO_I2S_Type *)i2sBase; + uint8_t *buffer = handle->queue[handle->queueDriver].data; + uint8_t dataSize = handle->bitWidth / 8U; + + /* Handle error */ + if (FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->txShifterIndex)) + { + FLEXIO_ClearShifterErrorFlags(base->flexioBase, (1U << base->txShifterIndex)); + } + /* Handle transfer */ + if (((FLEXIO_I2S_GetStatusFlags(base) & kFLEXIO_I2S_TxDataRegEmptyFlag) != 0) && + (handle->queue[handle->queueDriver].data != NULL)) + { + FLEXIO_I2S_WriteNonBlocking(base, handle->bitWidth, buffer, dataSize); + + /* Update internal counter */ + handle->queue[handle->queueDriver].dataSize -= dataSize; + handle->queue[handle->queueDriver].data += dataSize; + } + + /* If finished a blcok, call the callback function */ + if ((handle->queue[handle->queueDriver].dataSize == 0U) && (handle->queue[handle->queueDriver].data != NULL)) + { + memset(&handle->queue[handle->queueDriver], 0, sizeof(flexio_i2s_transfer_t)); + handle->queueDriver = (handle->queueDriver + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_Success, handle->userData); + } + } + + /* If all data finished, just stop the transfer */ + if (handle->queue[handle->queueDriver].data == NULL) + { + FLEXIO_I2S_TransferAbortSend(base, handle); + } +} + +void FLEXIO_I2S_TransferRxHandleIRQ(void *i2sBase, void *i2sHandle) +{ + assert(i2sHandle); + + flexio_i2s_handle_t *handle = (flexio_i2s_handle_t *)i2sHandle; + FLEXIO_I2S_Type *base = (FLEXIO_I2S_Type *)i2sBase; + uint8_t *buffer = handle->queue[handle->queueDriver].data; + uint8_t dataSize = handle->bitWidth / 8U; + + /* Handle transfer */ + if (((FLEXIO_I2S_GetStatusFlags(base) & kFLEXIO_I2S_RxDataRegFullFlag) != 0) && + (handle->queue[handle->queueDriver].data != NULL)) + { + FLEXIO_I2S_ReadNonBlocking(base, handle->bitWidth, buffer, dataSize); + + /* Update internal state */ + handle->queue[handle->queueDriver].dataSize -= dataSize; + handle->queue[handle->queueDriver].data += dataSize; + } + + /* If finished a blcok, call the callback function */ + if ((handle->queue[handle->queueDriver].dataSize == 0U) && (handle->queue[handle->queueDriver].data != NULL)) + { + memset(&handle->queue[handle->queueDriver], 0, sizeof(flexio_i2s_transfer_t)); + handle->queueDriver = (handle->queueDriver + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_Success, handle->userData); + } + } + + /* If all data finished, just stop the transfer */ + if (handle->queue[handle->queueDriver].data == NULL) + { + FLEXIO_I2S_TransferAbortReceive(base, handle); + } +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s.h new file mode 100644 index 00000000000..0f88f750952 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s.h @@ -0,0 +1,569 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_I2S_H_ +#define _FSL_FLEXIO_I2S_H_ + +#include "fsl_common.h" +#include "fsl_flexio.h" + +/*! + * @addtogroup flexio_i2s + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief FlexIO I2S driver version 2.1.0. */ +#define FSL_FLEXIO_I2S_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) +/*@}*/ + +/*! @brief FlexIO I2S transfer status */ +enum _flexio_i2s_status +{ + kStatus_FLEXIO_I2S_Idle = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 0), /*!< FlexIO I2S is in idle state */ + kStatus_FLEXIO_I2S_TxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 1), /*!< FlexIO I2S Tx is busy */ + kStatus_FLEXIO_I2S_RxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 2), /*!< FlexIO I2S Tx is busy */ + kStatus_FLEXIO_I2S_Error = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 3), /*!< FlexIO I2S error occurred */ + kStatus_FLEXIO_I2S_QueueFull = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 4), /*!< FlexIO I2S transfer queue is full. */ +}; + +/*! @brief Define FlexIO I2S access structure typedef */ +typedef struct _flexio_i2s_type +{ + FLEXIO_Type *flexioBase; /*!< FlexIO base pointer */ + uint8_t txPinIndex; /*!< Tx data pin index in FlexIO pins */ + uint8_t rxPinIndex; /*!< Rx data pin index */ + uint8_t bclkPinIndex; /*!< Bit clock pin index */ + uint8_t fsPinIndex; /*!< Frame sync pin index */ + uint8_t txShifterIndex; /*!< Tx data shifter index */ + uint8_t rxShifterIndex; /*!< Rx data shifter index */ + uint8_t bclkTimerIndex; /*!< Bit clock timer index */ + uint8_t fsTimerIndex; /*!< Frame sync timer index */ +} FLEXIO_I2S_Type; + +/*! @brief Master or slave mode */ +typedef enum _flexio_i2s_master_slave +{ + kFLEXIO_I2S_Master = 0x0U, /*!< Master mode */ + kFLEXIO_I2S_Slave = 0x1U /*!< Slave mode */ +} flexio_i2s_master_slave_t; + +/*! @brief Define FlexIO FlexIO I2S interrupt mask. */ +enum _flexio_i2s_interrupt_enable +{ + kFLEXIO_I2S_TxDataRegEmptyInterruptEnable = 0x1U, /*!< Transmit buffer empty interrupt enable. */ + kFLEXIO_I2S_RxDataRegFullInterruptEnable = 0x2U, /*!< Receive buffer full interrupt enable. */ +}; + +/*! @brief Define FlexIO FlexIO I2S status mask. */ +enum _flexio_i2s_status_flags +{ + kFLEXIO_I2S_TxDataRegEmptyFlag = 0x1U, /*!< Transmit buffer empty flag. */ + kFLEXIO_I2S_RxDataRegFullFlag = 0x2U, /*!< Receive buffer full flag. */ +}; + +/*! @brief FlexIO I2S configure structure */ +typedef struct _flexio_i2s_config +{ + bool enableI2S; /*!< Enable FlexIO I2S */ + flexio_i2s_master_slave_t masterSlave; /*!< Master or slave */ +} flexio_i2s_config_t; + +/*! @brief FlexIO I2S audio format, FlexIO I2S only support the same format in Tx and Rx */ +typedef struct _flexio_i2s_format +{ + uint8_t bitWidth; /*!< Bit width of audio data, always 8/16/24/32 bits */ + uint32_t sampleRate_Hz; /*!< Sample rate of the audio data */ +} flexio_i2s_format_t; + +/*!@brief FlexIO I2S transfer queue size, user can refine it according to use case. */ +#define FLEXIO_I2S_XFER_QUEUE_SIZE (4) + +/*! @brief Audio sample rate */ +typedef enum _flexio_i2s_sample_rate +{ + kFLEXIO_I2S_SampleRate8KHz = 8000U, /*!< Sample rate 8000Hz */ + kFLEXIO_I2S_SampleRate11025Hz = 11025U, /*!< Sample rate 11025Hz */ + kFLEXIO_I2S_SampleRate12KHz = 12000U, /*!< Sample rate 12000Hz */ + kFLEXIO_I2S_SampleRate16KHz = 16000U, /*!< Sample rate 16000Hz */ + kFLEXIO_I2S_SampleRate22050Hz = 22050U, /*!< Sample rate 22050Hz */ + kFLEXIO_I2S_SampleRate24KHz = 24000U, /*!< Sample rate 24000Hz */ + kFLEXIO_I2S_SampleRate32KHz = 32000U, /*!< Sample rate 32000Hz */ + kFLEXIO_I2S_SampleRate44100Hz = 44100U, /*!< Sample rate 44100Hz */ + kFLEXIO_I2S_SampleRate48KHz = 48000U, /*!< Sample rate 48000Hz */ + kFLEXIO_I2S_SampleRate96KHz = 96000U /*!< Sample rate 96000Hz */ +} flexio_i2s_sample_rate_t; + +/*! @brief Audio word width */ +typedef enum _flexio_i2s_word_width +{ + kFLEXIO_I2S_WordWidth8bits = 8U, /*!< Audio data width 8 bits */ + kFLEXIO_I2S_WordWidth16bits = 16U, /*!< Audio data width 16 bits */ + kFLEXIO_I2S_WordWidth24bits = 24U, /*!< Audio data width 24 bits */ + kFLEXIO_I2S_WordWidth32bits = 32U /*!< Audio data width 32 bits */ +} flexio_i2s_word_width_t; + +/*! @brief Define FlexIO I2S transfer structure. */ +typedef struct _flexio_i2s_transfer +{ + uint8_t *data; /*!< Data buffer start pointer */ + size_t dataSize; /*!< Bytes to be transferred. */ +} flexio_i2s_transfer_t; + +typedef struct _flexio_i2s_handle flexio_i2s_handle_t; + +/*! @brief FlexIO I2S xfer callback prototype */ +typedef void (*flexio_i2s_callback_t)(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + status_t status, + void *userData); + +/*! @brief Define FlexIO I2S handle structure. */ +struct _flexio_i2s_handle +{ + uint32_t state; /*!< Internal state */ + flexio_i2s_callback_t callback; /*!< Callback function called at transfer event*/ + void *userData; /*!< Callback parameter passed to callback function*/ + uint8_t bitWidth; /*!< Bit width for transfer, 8/16/24/32bits */ + flexio_i2s_transfer_t queue[FLEXIO_I2S_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer */ + size_t transferSize[FLEXIO_I2S_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */ + volatile uint8_t queueUser; /*!< Index for user to queue transfer */ + volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes the FlexIO I2S. + * + * This API configures FlexIO pins and shifter to I2S and configures the FlexIO I2S with a configuration structure. + * The configuration structure can be filled by the user, or be set with default values by + * FLEXIO_I2S_GetDefaultConfig(). + * + * @note This API should be called at the beginning of the application to use + * the FlexIO I2S driver. Otherwise, any access to the FlexIO I2S module can cause hard fault + * because the clock is not enabled. + * + * @param base FlexIO I2S base pointer + * @param config FlexIO I2S configure structure. +*/ +void FLEXIO_I2S_Init(FLEXIO_I2S_Type *base, const flexio_i2s_config_t *config); + +/*! + * @brief Sets the FlexIO I2S configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in FLEXIO_I2S_Init(). + * Users may use the initialized structure unchanged in FLEXIO_I2S_Init() or modify + * some fields of the structure before calling FLEXIO_I2S_Init(). + * + * @param config pointer to master configuration structure + */ +void FLEXIO_I2S_GetDefaultConfig(flexio_i2s_config_t *config); + +/*! + * @brief De-initializes the FlexIO I2S. + * + * Calling this API gates the FlexIO i2s clock. After calling this API, call the FLEXO_I2S_Init to use the + * FlexIO I2S module. + * + * @param base FlexIO I2S base pointer +*/ +void FLEXIO_I2S_Deinit(FLEXIO_I2S_Type *base); + +/*! + * @brief Enables/disables the FlexIO I2S module operation. + * + * @param base Pointer to FLEXIO_I2S_Type + * @param enable True to enable, false to disable. +*/ +static inline void FLEXIO_I2S_Enable(FLEXIO_I2S_Type *base, bool enable) +{ + if (enable) + { + base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +/*! @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the FlexIO I2S status flags. + * + * @param base Pointer to FLEXIO_I2S_Type structure + * @return Status flag, which are ORed by the enumerators in the _flexio_i2s_status_flags. +*/ +uint32_t FLEXIO_I2S_GetStatusFlags(FLEXIO_I2S_Type *base); + +/*! @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the FlexIO I2S interrupt. + * + * This function enables the FlexIO UART interrupt. + * + * @param base Pointer to FLEXIO_I2S_Type structure + * @param mask interrupt source + */ +void FLEXIO_I2S_EnableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask); + +/*! + * @brief Disables the FlexIO I2S interrupt. + * + * This function enables the FlexIO UART interrupt. + * + * @param base pointer to FLEXIO_I2S_Type structure + * @param mask interrupt source + */ +void FLEXIO_I2S_DisableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask); + +/*! @} */ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Enables/disables the FlexIO I2S Tx DMA requests. + * + * @param base FlexIO I2S base pointer + * @param enable True means enable DMA, false means disable DMA. + */ +static inline void FLEXIO_I2S_TxEnableDMA(FLEXIO_I2S_Type *base, bool enable) +{ + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->txShifterIndex, enable); +} + +/*! + * @brief Enables/disables the FlexIO I2S Rx DMA requests. + * + * @param base FlexIO I2S base pointer + * @param enable True means enable DMA, false means disable DMA. + */ +static inline void FLEXIO_I2S_RxEnableDMA(FLEXIO_I2S_Type *base, bool enable) +{ + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->rxShifterIndex, enable); +} + +/*! + * @brief Gets the FlexIO I2S send data register address. + * + * This function returns the I2S data register address, mainly used by DMA/eDMA. + * + * @param base Pointer to FLEXIO_I2S_Type structure + * @return FlexIO i2s send data register address. + */ +static inline uint32_t FLEXIO_I2S_TxGetDataRegisterAddress(FLEXIO_I2S_Type *base) +{ + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferBitSwapped, base->txShifterIndex); +} + +/*! + * @brief Gets the FlexIO I2S receive data register address. + * + * This function returns the I2S data register address, mainly used by DMA/eDMA. + * + * @param base Pointer to FLEXIO_I2S_Type structure + * @return FlexIO i2s receive data register address. + */ +static inline uint32_t FLEXIO_I2S_RxGetDataRegisterAddress(FLEXIO_I2S_Type *base) +{ + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferBitSwapped, base->rxShifterIndex); +} + +/*! @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Configures the FlexIO I2S audio format in master mode. + * + * Audio format can be changed in run-time of FlexIO I2S. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base Pointer to FLEXIO_I2S_Type structure + * @param format Pointer to FlexIO I2S audio data format structure. + * @param srcClock_Hz I2S master clock source frequency in Hz. +*/ +void FLEXIO_I2S_MasterSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format, uint32_t srcClock_Hz); + +/*! + * @brief Configures the FlexIO I2S audio format in slave mode. + * + * Audio format can be changed in run-time of FlexIO I2S. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base Pointer to FLEXIO_I2S_Type structure + * @param format Pointer to FlexIO I2S audio data format structure. +*/ +void FLEXIO_I2S_SlaveSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format); + +/*! + * @brief Sends data using a blocking method. + * + * @note This function blocks via polling until data is ready to be sent. + * + * @param base FlexIO I2S base pointer. + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param txData Pointer to the data to be written. + * @param size Bytes to be written. + */ +void FLEXIO_I2S_WriteBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size); + +/*! + * @brief Writes data into a data register. + * + * @param base FlexIO I2S base pointer. + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param data Data to be written. + */ +static inline void FLEXIO_I2S_WriteData(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint32_t data) +{ + base->flexioBase->SHIFTBUFBIS[base->txShifterIndex] = (data << (32U - bitWidth)); +} + +/*! + * @brief Receives a piece of data using a blocking method. + * + * @note This function blocks via polling until data is ready to be sent. + * + * @param base FlexIO I2S base pointer + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param rxData Pointer to the data to be read. + * @param size Bytes to be read. + */ +void FLEXIO_I2S_ReadBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size); + +/*! + * @brief Reads a data from the data register. + * + * @param base FlexIO I2S base pointer + * @return Data read from data register. + */ +static inline uint32_t FLEXIO_I2S_ReadData(FLEXIO_I2S_Type *base) +{ + return base->flexioBase->SHIFTBUFBIS[base->rxShifterIndex]; +} + +/*! @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the FlexIO I2S handle. + * + * This function initializes the FlexIO I2S handle which can be used for other + * FlexIO I2S transactional APIs. Call this API once to get the + * initialized handle. + * + * @param base Pointer to FLEXIO_I2S_Type structure + * @param handle Pointer to flexio_i2s_handle_t structure to store the transfer state. + * @param callback FlexIO I2S callback function, which is called while finished a block. + * @param userData User parameter for the FlexIO I2S callback. + */ +void FLEXIO_I2S_TransferTxCreateHandle(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_callback_t callback, + void *userData); + +/*! + * @brief Configures the FlexIO I2S audio format. + * + * Audio format can be changed at run-time of FlexIO I2S. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base Pointer to FLEXIO_I2S_Type structure. + * @param handle FlexIO I2S handle pointer. + * @param format Pointer to audio data format structure. + * @param srcClock_Hz FlexIO I2S bit clock source frequency in Hz. This parameter should be 0 while in slave mode. +*/ +void FLEXIO_I2S_TransferSetFormat(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_format_t *format, + uint32_t srcClock_Hz); + +/*! + * @brief Initializes the FlexIO I2S receive handle. + * + * This function initializes the FlexIO I2S handle which can be used for other + * FlexIO I2S transactional APIs. Call this API once to get the + * initialized handle. + * + * @param base Pointer to FLEXIO_I2S_Type structure. + * @param handle Pointer to flexio_i2s_handle_t structure to store the transfer state. + * @param callback FlexIO I2S callback function, which is called while finished a block. + * @param userData User parameter for the FlexIO I2S callback. + */ +void FLEXIO_I2S_TransferRxCreateHandle(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_callback_t callback, + void *userData); + +/*! + * @brief Performs an interrupt non-blocking send transfer on FlexIO I2S. + * + * @note The API returns immediately after transfer initiates. + * Call FLEXIO_I2S_GetRemainingBytes to poll the transfer status and check whether + * the transfer is finished. If the return status is 0, the transfer is finished. + * + * @param base Pointer to FLEXIO_I2S_Type structure. + * @param handle Pointer to flexio_i2s_handle_t structure which stores the transfer state + * @param xfer Pointer to flexio_i2s_transfer_t structure + * @retval kStatus_Success Successfully start the data transmission. + * @retval kStatus_FLEXIO_I2S_TxBusy Previous transmission still not finished, data not all written to TX register yet. + * @retval kStatus_InvalidArgument The input parameter is invalid. + */ +status_t FLEXIO_I2S_TransferSendNonBlocking(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_transfer_t *xfer); + +/*! + * @brief Performs an interrupt non-blocking receive transfer on FlexIO I2S. + * + * @note The API returns immediately after transfer initiates. + * Call FLEXIO_I2S_GetRemainingBytes to poll the transfer status to check whether + * the transfer is finished. If the return status is 0, the transfer is finished. + * + * @param base Pointer to FLEXIO_I2S_Type structure. + * @param handle Pointer to flexio_i2s_handle_t structure which stores the transfer state + * @param xfer Pointer to flexio_i2s_transfer_t structure + * @retval kStatus_Success Successfully start the data receive. + * @retval kStatus_FLEXIO_I2S_RxBusy Previous receive still not finished. + * @retval kStatus_InvalidArgument The input parameter is invalid. + */ +status_t FLEXIO_I2S_TransferReceiveNonBlocking(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_transfer_t *xfer); + +/*! + * @brief Aborts the current send. + * + * @note This API can be called at any time when interrupt non-blocking transfer initiates + * to abort the transfer in a early time. + * + * @param base Pointer to FLEXIO_I2S_Type structure. + * @param handle Pointer to flexio_i2s_handle_t structure which stores the transfer state + */ +void FLEXIO_I2S_TransferAbortSend(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle); + +/*! + * @brief Aborts the current receive. + * + * @note This API can be called at any time when interrupt non-blocking transfer initiates + * to abort the transfer in a early time. + * + * @param base Pointer to FLEXIO_I2S_Type structure. + * @param handle Pointer to flexio_i2s_handle_t structure which stores the transfer state + */ +void FLEXIO_I2S_TransferAbortReceive(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle); + +/*! + * @brief Gets the remaining bytes to be sent. + * + * @param base Pointer to FLEXIO_I2S_Type structure. + * @param handle Pointer to flexio_i2s_handle_t structure which stores the transfer state + * @param count Bytes sent. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t FLEXIO_I2S_TransferGetSendCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count); + +/*! + * @brief Gets the remaining bytes to be received. + * + * @param base Pointer to FLEXIO_I2S_Type structure. + * @param handle Pointer to flexio_i2s_handle_t structure which stores the transfer state + * @return count Bytes received. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t FLEXIO_I2S_TransferGetReceiveCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count); + +/*! + * @brief Tx interrupt handler. + * + * @param i2sBase Pointer to FLEXIO_I2S_Type structure. + * @param i2sHandle Pointer to flexio_i2s_handle_t structure + */ +void FLEXIO_I2S_TransferTxHandleIRQ(void *i2sBase, void *i2sHandle); + +/*! + * @brief Rx interrupt handler. + * + * @param i2sBase Pointer to FLEXIO_I2S_Type structure. + * @param i2sHandle Pointer to flexio_i2s_handle_t structure. + */ +void FLEXIO_I2S_TransferRxHandleIRQ(void *i2sBase, void *i2sHandle); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ + +/*! @} */ + +#endif /* _FSL_FLEXIO_I2S_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s_edma.c new file mode 100644 index 00000000000..bebb7cf6b26 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s_edma.c @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_i2s_edma.h" + +/******************************************************************************* + * Definitations + ******************************************************************************/ +/* Used for 32byte aligned */ +#define STCD_ADDR(address) (edma_tcd_t *)(((uint32_t)address + 32) & ~0x1FU) + +/*handle; + + /* If finished a blcok, call the callback function */ + memset(&flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver], 0, sizeof(flexio_i2s_transfer_t)); + flexio_i2sHandle->queueDriver = (flexio_i2sHandle->queueDriver + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + if (flexio_i2sHandle->callback) + { + (flexio_i2sHandle->callback)(privHandle->base, flexio_i2sHandle, kStatus_Success, flexio_i2sHandle->userData); + } + + /* If all data finished, just stop the transfer */ + if (flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver].data == NULL) + { + FLEXIO_I2S_TransferAbortSendEDMA(privHandle->base, flexio_i2sHandle); + } +} + +static void FLEXIO_I2S_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds) +{ + flexio_i2s_edma_private_handle_t *privHandle = (flexio_i2s_edma_private_handle_t *)userData; + flexio_i2s_edma_handle_t *flexio_i2sHandle = privHandle->handle; + + /* If finished a blcok, call the callback function */ + memset(&flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver], 0, sizeof(flexio_i2s_transfer_t)); + flexio_i2sHandle->queueDriver = (flexio_i2sHandle->queueDriver + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + if (flexio_i2sHandle->callback) + { + (flexio_i2sHandle->callback)(privHandle->base, flexio_i2sHandle, kStatus_Success, flexio_i2sHandle->userData); + } + + /* If all data finished, just stop the transfer */ + if (flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver].data == NULL) + { + FLEXIO_I2S_TransferAbortReceiveEDMA(privHandle->base, flexio_i2sHandle); + } +} + +void FLEXIO_I2S_TransferTxCreateHandleEDMA(FLEXIO_I2S_Type *base, + flexio_i2s_edma_handle_t *handle, + flexio_i2s_edma_callback_t callback, + void *userData, + edma_handle_t *dmaHandle) +{ + assert(handle && dmaHandle); + + /* Set flexio_i2s base to handle */ + handle->dmaHandle = dmaHandle; + handle->callback = callback; + handle->userData = userData; + + /* Set FLEXIO I2S state to idle */ + handle->state = kFLEXIO_I2S_Idle; + + s_edmaPrivateHandle[0].base = base; + s_edmaPrivateHandle[0].handle = handle; + + /* Need to use scatter gather */ + EDMA_InstallTCDMemory(dmaHandle, STCD_ADDR(handle->tcd), FLEXIO_I2S_XFER_QUEUE_SIZE); + + /* Install callback for Tx dma channel */ + EDMA_SetCallback(dmaHandle, FLEXIO_I2S_TxEDMACallback, &s_edmaPrivateHandle[0]); +} + +void FLEXIO_I2S_TransferRxCreateHandleEDMA(FLEXIO_I2S_Type *base, + flexio_i2s_edma_handle_t *handle, + flexio_i2s_edma_callback_t callback, + void *userData, + edma_handle_t *dmaHandle) +{ + assert(handle && dmaHandle); + + /* Set flexio_i2s base to handle */ + handle->dmaHandle = dmaHandle; + handle->callback = callback; + handle->userData = userData; + + /* Set FLEXIO I2S state to idle */ + handle->state = kFLEXIO_I2S_Idle; + + s_edmaPrivateHandle[1].base = base; + s_edmaPrivateHandle[1].handle = handle; + + /* Need to use scatter gather */ + EDMA_InstallTCDMemory(dmaHandle, STCD_ADDR(handle->tcd), FLEXIO_I2S_XFER_QUEUE_SIZE); + + /* Install callback for Tx dma channel */ + EDMA_SetCallback(dmaHandle, FLEXIO_I2S_RxEDMACallback, &s_edmaPrivateHandle[1]); +} + +void FLEXIO_I2S_TransferSetFormatEDMA(FLEXIO_I2S_Type *base, + flexio_i2s_edma_handle_t *handle, + flexio_i2s_format_t *format, + uint32_t srcClock_Hz) +{ + assert(handle && format); + + /* Configure the audio format to FLEXIO I2S registers */ + if (srcClock_Hz != 0) + { + /* It is master */ + FLEXIO_I2S_MasterSetFormat(base, format, srcClock_Hz); + } + else + { + FLEXIO_I2S_SlaveSetFormat(base, format); + } + + /* Get the tranfer size from format, this should be used in EDMA configuration */ + handle->bytesPerFrame = format->bitWidth / 8U; +} + +status_t FLEXIO_I2S_TransferSendEDMA(FLEXIO_I2S_Type *base, + flexio_i2s_edma_handle_t *handle, + flexio_i2s_transfer_t *xfer) +{ + assert(handle && xfer); + + edma_transfer_config_t config = {0}; + uint32_t destAddr = FLEXIO_I2S_TxGetDataRegisterAddress(base) + (4U - handle->bytesPerFrame); + + /* Check if input parameter invalid */ + if ((xfer->data == NULL) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + if (handle->queue[handle->queueUser].data) + { + return kStatus_FLEXIO_I2S_QueueFull; + } + + /* Change the state of handle */ + handle->state = kFLEXIO_I2S_Busy; + + /* Update the queue state */ + handle->queue[handle->queueUser].data = xfer->data; + handle->queue[handle->queueUser].dataSize = xfer->dataSize; + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + + /* Prepare edma configure */ + EDMA_PrepareTransfer(&config, xfer->data, handle->bytesPerFrame, (void *)destAddr, handle->bytesPerFrame, + handle->bytesPerFrame, xfer->dataSize, kEDMA_MemoryToPeripheral); + + /* Store the initially configured eDMA minor byte transfer count into the FLEXIO I2S handle */ + handle->nbytes = handle->bytesPerFrame; + + EDMA_SubmitTransfer(handle->dmaHandle, &config); + + /* Start DMA transfer */ + EDMA_StartTransfer(handle->dmaHandle); + + /* Enable DMA enable bit */ + FLEXIO_I2S_TxEnableDMA(base, true); + + /* Enable FLEXIO I2S Tx clock */ + FLEXIO_I2S_Enable(base, true); + + return kStatus_Success; +} + +status_t FLEXIO_I2S_TransferReceiveEDMA(FLEXIO_I2S_Type *base, + flexio_i2s_edma_handle_t *handle, + flexio_i2s_transfer_t *xfer) +{ + assert(handle && xfer); + + edma_transfer_config_t config = {0}; + uint32_t srcAddr = FLEXIO_I2S_RxGetDataRegisterAddress(base) + (4U - handle->bytesPerFrame); + + /* Check if input parameter invalid */ + if ((xfer->data == NULL) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + if (handle->queue[handle->queueUser].data) + { + return kStatus_FLEXIO_I2S_QueueFull; + } + + /* Change the state of handle */ + handle->state = kFLEXIO_I2S_Busy; + + /* Update queue state */ + handle->queue[handle->queueUser].data = xfer->data; + handle->queue[handle->queueUser].dataSize = xfer->dataSize; + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + + /* Prepare edma configure */ + EDMA_PrepareTransfer(&config, (void *)srcAddr, handle->bytesPerFrame, xfer->data, handle->bytesPerFrame, + handle->bytesPerFrame, xfer->dataSize, kEDMA_PeripheralToMemory); + + /* Store the initially configured eDMA minor byte transfer count into the FLEXIO I2S handle */ + handle->nbytes = handle->bytesPerFrame; + + EDMA_SubmitTransfer(handle->dmaHandle, &config); + + /* Start DMA transfer */ + EDMA_StartTransfer(handle->dmaHandle); + + /* Enable DMA enable bit */ + FLEXIO_I2S_RxEnableDMA(base, true); + + /* Enable FLEXIO I2S Rx clock */ + FLEXIO_I2S_Enable(base, true); + + return kStatus_Success; +} + +void FLEXIO_I2S_TransferAbortSendEDMA(FLEXIO_I2S_Type *base, flexio_i2s_edma_handle_t *handle) +{ + assert(handle); + + /* Disable dma */ + EDMA_AbortTransfer(handle->dmaHandle); + + /* Disable DMA enable bit */ + FLEXIO_I2S_TxEnableDMA(base, false); + + /* Set the handle state */ + handle->state = kFLEXIO_I2S_Idle; +} + +void FLEXIO_I2S_TransferAbortReceiveEDMA(FLEXIO_I2S_Type *base, flexio_i2s_edma_handle_t *handle) +{ + assert(handle); + + /* Disable dma */ + EDMA_AbortTransfer(handle->dmaHandle); + + /* Disable DMA enable bit */ + FLEXIO_I2S_RxEnableDMA(base, false); + + /* Set the handle state */ + handle->state = kFLEXIO_I2S_Idle; +} + +status_t FLEXIO_I2S_TransferGetSendCountEDMA(FLEXIO_I2S_Type *base, flexio_i2s_edma_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kFLEXIO_I2S_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = handle->transferSize[handle->queueDriver] - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel); + } + + return status; +} + +status_t FLEXIO_I2S_TransferGetReceiveCountEDMA(FLEXIO_I2S_Type *base, flexio_i2s_edma_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kFLEXIO_I2S_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = handle->transferSize[handle->queueDriver] - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel); + } + + return status; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s_edma.h new file mode 100644 index 00000000000..150c985e593 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_i2s_edma.h @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_I2S_EDMA_H_ +#define _FSL_FLEXIO_I2S_EDMA_H_ + +#include "fsl_flexio_i2s.h" +#include "fsl_edma.h" + +/*! + * @addtogroup flexio_edma_i2s + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +typedef struct _flexio_i2s_edma_handle flexio_i2s_edma_handle_t; + +/*! @brief FlexIO I2S eDMA transfer callback function for finish and error */ +typedef void (*flexio_i2s_edma_callback_t)(FLEXIO_I2S_Type *base, + flexio_i2s_edma_handle_t *handle, + status_t status, + void *userData); + +/*! @brief FlexIO I2S DMA transfer handle, users should not touch the content of the handle.*/ +struct _flexio_i2s_edma_handle +{ + edma_handle_t *dmaHandle; /*!< DMA handler for FlexIO I2S send */ + uint8_t bytesPerFrame; /*!< Bytes in a frame */ + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + uint32_t state; /*!< Internal state for FlexIO I2S eDMA transfer */ + flexio_i2s_edma_callback_t callback; /*!< Callback for users while transfer finish or error occurred */ + void *userData; /*!< User callback parameter */ + edma_tcd_t tcd[FLEXIO_I2S_XFER_QUEUE_SIZE + 1U]; /*!< TCD pool for eDMA transfer. */ + flexio_i2s_transfer_t queue[FLEXIO_I2S_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer. */ + size_t transferSize[FLEXIO_I2S_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */ + volatile uint8_t queueUser; /*!< Index for user to queue transfer. */ + volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */ +}; + +/******************************************************************************* + * APIs + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name eDMA Transactional + * @{ + */ + +/*! + * @brief Initializes the FlexIO I2S eDMA handle. + * + * This function initializes the FlexIO I2S master DMA handle which can be used for other FlexIO I2S master + * transactional APIs. + * Usually, for a specified FlexIO I2S instance, call this API once to get the initialized handle. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S eDMA handle pointer. + * @param callback FlexIO I2S eDMA callback function called while finished a block. + * @param userData User parameter for callback. + * @param dmaHandle eDMA handle for FlexIO I2S. This handle is a static value allocated by users. + */ +void FLEXIO_I2S_TransferTxCreateHandleEDMA(FLEXIO_I2S_Type *base, + flexio_i2s_edma_handle_t *handle, + flexio_i2s_edma_callback_t callback, + void *userData, + edma_handle_t *dmaHandle); + +/*! + * @brief Initializes the FlexIO I2S Rx eDMA handle. + * + * This function initializes the FlexIO I2S slave DMA handle which can be used for other FlexIO I2S master transactional + * APIs. + * Usually, for a specified FlexIO I2S instance, call this API once to get the initialized handle. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S eDMA handle pointer. + * @param callback FlexIO I2S eDMA callback function called while finished a block. + * @param userData User parameter for callback. + * @param dmaHandle eDMA handle for FlexIO I2S. This handle is a static value allocated by users. + */ +void FLEXIO_I2S_TransferRxCreateHandleEDMA(FLEXIO_I2S_Type *base, + flexio_i2s_edma_handle_t *handle, + flexio_i2s_edma_callback_t callback, + void *userData, + edma_handle_t *dmaHandle); + +/*! + * @brief Configures the FlexIO I2S Tx audio format. + * + * Audio format can be changed in run-time of FlexIO I2S. This function configures the sample rate and audio data + * format to be transferred. This function also sets the eDMA parameter according to format. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S eDMA handle pointer + * @param format Pointer to FlexIO I2S audio data format structure. + * @param srcClock_Hz FlexIO I2S clock source frequency in Hz, it should be 0 while in slave mode. + * @retval kStatus_Success Audio format set successfully. + * @retval kStatus_InvalidArgument The input arguments is invalid. +*/ +void FLEXIO_I2S_TransferSetFormatEDMA(FLEXIO_I2S_Type *base, + flexio_i2s_edma_handle_t *handle, + flexio_i2s_format_t *format, + uint32_t srcClock_Hz); + +/*! + * @brief Performs a non-blocking FlexIO I2S transfer using DMA. + * + * @note This interface returned immediately after transfer initiates. Users should call + * FLEXIO_I2S_GetTransferStatus to poll the transfer status and check whether the FlexIO I2S transfer is finished. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + * @param xfer Pointer to DMA transfer structure. + * @retval kStatus_Success Start a FlexIO I2S eDMA send successfully. + * @retval kStatus_InvalidArgument The input arguments is invalid. + * @retval kStatus_TxBusy FlexIO I2S is busy sending data. + */ +status_t FLEXIO_I2S_TransferSendEDMA(FLEXIO_I2S_Type *base, + flexio_i2s_edma_handle_t *handle, + flexio_i2s_transfer_t *xfer); + +/*! + * @brief Performs a non-blocking FlexIO I2S receive using eDMA. + * + * @note This interface returned immediately after transfer initiates. Users should call + * FLEXIO_I2S_GetReceiveRemainingBytes to poll the transfer status and check whether the FlexIO I2S transfer is finished. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + * @param xfer Pointer to DMA transfer structure. + * @retval kStatus_Success Start a FlexIO I2S eDMA receive successfully. + * @retval kStatus_InvalidArgument The input arguments is invalid. + * @retval kStatus_RxBusy FlexIO I2S is busy receiving data. + */ +status_t FLEXIO_I2S_TransferReceiveEDMA(FLEXIO_I2S_Type *base, + flexio_i2s_edma_handle_t *handle, + flexio_i2s_transfer_t *xfer); + +/*! + * @brief Aborts a FlexIO I2S transfer using eDMA. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + */ +void FLEXIO_I2S_TransferAbortSendEDMA(FLEXIO_I2S_Type *base, flexio_i2s_edma_handle_t *handle); + +/*! + * @brief Aborts a FlexIO I2S receive using eDMA. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + */ +void FLEXIO_I2S_TransferAbortReceiveEDMA(FLEXIO_I2S_Type *base, flexio_i2s_edma_handle_t *handle); + +/*! + * @brief Gets the remaining bytes to be sent. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + * @param count Bytes sent. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t FLEXIO_I2S_TransferGetSendCountEDMA(FLEXIO_I2S_Type *base, flexio_i2s_edma_handle_t *handle, size_t *count); + +/*! + * @brief Get the remaining bytes to be received. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + * @param count Bytes received. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t FLEXIO_I2S_TransferGetReceiveCountEDMA(FLEXIO_I2S_Type *base, flexio_i2s_edma_handle_t *handle, size_t *count); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi.c new file mode 100644 index 00000000000..d4396dc5d22 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi.c @@ -0,0 +1,1012 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_spi.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief FLEXIO SPI transfer state, which is used for SPI transactiaonl APIs' internal state. */ +enum _flexio_spi_transfer_states +{ + kFLEXIO_SPI_Idle = 0x0U, /*!< Nothing in the transmitter/receiver's queue. */ + kFLEXIO_SPI_Busy, /*!< Transmiter/Receive's queue is not finished. */ +}; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +extern const clock_ip_name_t s_flexioClocks[]; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +extern FLEXIO_Type *const s_flexioBases[]; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Send a piece of data for SPI. + * + * This function computes the number of data to be written into D register or Tx FIFO, + * and write the data into it. At the same time, this function updates the values in + * master handle structure. + * + * @param base pointer to FLEXIO_SPI_Type structure + * @param handle Pointer to SPI master handle structure. + */ +static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle); + +/*! + * @brief Receive a piece of data for SPI master. + * + * This function computes the number of data to receive from D register or Rx FIFO, + * and write the data to destination address. At the same time, this function updates + * the values in master handle structure. + * + * @param base pointer to FLEXIO_SPI_Type structure + * @param handle Pointer to SPI master handle structure. + */ +static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Codes + ******************************************************************************/ + +uint32_t FLEXIO_SPI_GetInstance(FLEXIO_SPI_Type *base) +{ + uint32_t instance; + FLEXIO_Type *flexioBase = base->flexioBase; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_FLEXIO_COUNT; instance++) + { + if (s_flexioBases[instance] == flexioBase) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_FLEXIO_COUNT); + + return instance; +} + +static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle) +{ + uint16_t tmpData = FLEXIO_SPI_DUMMYDATA; + + if (handle->txData != NULL) + { + /* Transmit data and update tx size/buff. */ + if (handle->bytePerFrame == 1U) + { + tmpData = *(handle->txData); + handle->txData++; + } + else + { + if (handle->direction == kFLEXIO_SPI_MsbFirst) + { + tmpData = (uint32_t)(handle->txData[0]) << 8U; + tmpData += handle->txData[1]; + } + else + { + tmpData = (uint32_t)(handle->txData[1]) << 8U; + tmpData += handle->txData[0]; + } + handle->txData += 2U; + } + } + else + { + tmpData = FLEXIO_SPI_DUMMYDATA; + } + + handle->txRemainingBytes -= handle->bytePerFrame; + + FLEXIO_SPI_WriteData(base, handle->direction, tmpData); + + if (!handle->txRemainingBytes) + { + FLEXIO_SPI_DisableInterrupts(base, kFLEXIO_SPI_TxEmptyInterruptEnable); + } +} + +static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle) +{ + uint16_t tmpData; + + tmpData = FLEXIO_SPI_ReadData(base, handle->direction); + + if (handle->rxData != NULL) + { + if (handle->bytePerFrame == 1U) + { + *handle->rxData = tmpData; + handle->rxData++; + } + else + { + if (handle->direction == kFLEXIO_SPI_MsbFirst) + { + *((uint16_t *)(handle->rxData)) = tmpData; + } + else + { + *((uint16_t *)(handle->rxData)) = (((tmpData << 8) & 0xff00U) | ((tmpData >> 8) & 0x00ffU)); + } + handle->rxData += 2U; + } + } + handle->rxRemainingBytes -= handle->bytePerFrame; +} + +void FLEXIO_SPI_MasterInit(FLEXIO_SPI_Type *base, flexio_spi_master_config_t *masterConfig, uint32_t srcClock_Hz) +{ + assert(base); + assert(masterConfig); + + flexio_shifter_config_t shifterConfig; + flexio_timer_config_t timerConfig; + uint32_t ctrlReg = 0; + uint16_t timerDiv = 0; + uint16_t timerCmp = 0; + + /* Clear the shifterConfig & timerConfig struct. */ + memset(&shifterConfig, 0, sizeof(shifterConfig)); + memset(&timerConfig, 0, sizeof(timerConfig)); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate flexio clock. */ + CLOCK_EnableClock(s_flexioClocks[FLEXIO_SPI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Configure FLEXIO SPI Master */ + ctrlReg = base->flexioBase->CTRL; + ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); + ctrlReg |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) | + FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster)); + if (!masterConfig->enableInDoze) + { + ctrlReg |= FLEXIO_CTRL_DOZEN_MASK; + } + + base->flexioBase->CTRL = ctrlReg; + + /* Do hardware configuration. */ + /* 1. Configure the shifter 0 for tx. */ + shifterConfig.timerSelect = base->timerIndex[0]; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; + shifterConfig.pinSelect = base->SDOPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + } + else + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift; + } + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); + + /* 2. Configure the shifter 1 for rx. */ + shifterConfig.timerSelect = base->timerIndex[0]; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + shifterConfig.pinSelect = base->SDIPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + } + else + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + } + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); + + /*3. Configure the timer 0 for SCK. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutput; + timerConfig.pinSelect = base->SCKPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; + timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; + timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + + timerDiv = srcClock_Hz / masterConfig->baudRate_Bps; + timerDiv = timerDiv / 2 - 1; + + timerCmp = ((uint32_t)(masterConfig->dataMode * 2 - 1U)) << 8U; + timerCmp |= timerDiv; + + timerConfig.timerCompare = timerCmp; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); + + /* 4. Configure the timer 1 for CSn. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->timerIndex[0]); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutput; + timerConfig.pinSelect = base->CSnPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveLow; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + + timerConfig.timerCompare = 0xFFFFU; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig); +} + +void FLEXIO_SPI_MasterDeinit(FLEXIO_SPI_Type *base) +{ + /* Disable FLEXIO SPI module. */ + FLEXIO_SPI_Enable(base, false); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate flexio clock. */ + CLOCK_DisableClock(kCLOCK_Flexio0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void FLEXIO_SPI_MasterGetDefaultConfig(flexio_spi_master_config_t *masterConfig) +{ + assert(masterConfig); + + masterConfig->enableMaster = true; + masterConfig->enableInDoze = false; + masterConfig->enableInDebug = true; + masterConfig->enableFastAccess = false; + /* Default baud rate 500kbps. */ + masterConfig->baudRate_Bps = 500000U; + /* Default CPHA = 0. */ + masterConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge; + /* Default bit count at 8. */ + masterConfig->dataMode = kFLEXIO_SPI_8BitMode; +} + +void FLEXIO_SPI_SlaveInit(FLEXIO_SPI_Type *base, flexio_spi_slave_config_t *slaveConfig) +{ + assert(base && slaveConfig); + + flexio_shifter_config_t shifterConfig; + flexio_timer_config_t timerConfig; + uint32_t ctrlReg = 0; + + /* Clear the shifterConfig & timerConfig struct. */ + memset(&shifterConfig, 0, sizeof(shifterConfig)); + memset(&timerConfig, 0, sizeof(timerConfig)); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate flexio clock. */ + CLOCK_EnableClock(kCLOCK_Flexio0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Configure FLEXIO SPI Slave */ + ctrlReg = base->flexioBase->CTRL; + ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); + ctrlReg |= (FLEXIO_CTRL_DBGE(slaveConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(slaveConfig->enableFastAccess) | + FLEXIO_CTRL_FLEXEN(slaveConfig->enableSlave)); + if (!slaveConfig->enableInDoze) + { + ctrlReg |= FLEXIO_CTRL_DOZEN_MASK; + } + + base->flexioBase->CTRL = ctrlReg; + + /* Do hardware configuration. */ + /* 1. Configure the shifter 0 for tx. */ + shifterConfig.timerSelect = base->timerIndex[0]; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; + shifterConfig.pinSelect = base->SDOPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + } + else + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift; + } + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); + + /* 2. Configure the shifter 1 for rx. */ + shifterConfig.timerSelect = base->timerIndex[0]; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + shifterConfig.pinSelect = base->SDIPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + } + else + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + } + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); + + /*3. Configure the timer 0 for shift clock. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->CSnPinIndex); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinSelect = base->SCKPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerRisingEdge; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) + { + /* The configuration kFLEXIO_TimerDisableOnTimerCompare only support continuous + PCS access, change to kFLEXIO_TimerDisableNever to enable discontinuous PCS access. */ + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + } + else + { + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTriggerFallingEdge; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + } + + timerConfig.timerCompare = slaveConfig->dataMode * 2 - 1U; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); +} + +void FLEXIO_SPI_SlaveDeinit(FLEXIO_SPI_Type *base) +{ + FLEXIO_SPI_MasterDeinit(base); +} + +void FLEXIO_SPI_SlaveGetDefaultConfig(flexio_spi_slave_config_t *slaveConfig) +{ + assert(slaveConfig); + + slaveConfig->enableSlave = true; + slaveConfig->enableInDoze = false; + slaveConfig->enableInDebug = true; + slaveConfig->enableFastAccess = false; + /* Default CPHA = 0. */ + slaveConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge; + /* Default bit count at 8. */ + slaveConfig->dataMode = kFLEXIO_SPI_8BitMode; +} + +void FLEXIO_SPI_EnableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_SPI_TxEmptyInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1 << base->shifterIndex[0]); + } + if (mask & kFLEXIO_SPI_RxFullInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1 << base->shifterIndex[1]); + } +} + +void FLEXIO_SPI_DisableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_SPI_TxEmptyInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1 << base->shifterIndex[0]); + } + if (mask & kFLEXIO_SPI_RxFullInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1 << base->shifterIndex[1]); + } +} + +void FLEXIO_SPI_EnableDMA(FLEXIO_SPI_Type *base, uint32_t mask, bool enable) +{ + if (mask & kFLEXIO_SPI_TxDmaEnable) + { + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1U << base->shifterIndex[0], enable); + } + + if (mask & kFLEXIO_SPI_RxDmaEnable) + { + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1U << base->shifterIndex[1], enable); + } +} + +uint32_t FLEXIO_SPI_GetStatusFlags(FLEXIO_SPI_Type *base) +{ + uint32_t shifterStatus = FLEXIO_GetShifterStatusFlags(base->flexioBase); + uint32_t status = 0; + + status = ((shifterStatus & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]); + status |= (((shifterStatus & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) << 1U); + + return status; +} + +void FLEXIO_SPI_ClearStatusFlags(FLEXIO_SPI_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_SPI_TxBufferEmptyFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]); + } + if (mask & kFLEXIO_SPI_RxBufferFullFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +void FLEXIO_SPI_MasterSetBaudRate(FLEXIO_SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClockHz) +{ + uint16_t timerDiv = 0; + uint16_t timerCmp = 0; + FLEXIO_Type *flexioBase = base->flexioBase; + + /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/ + timerDiv = srcClockHz / baudRate_Bps; + timerDiv = timerDiv / 2 - 1U; + + timerCmp = flexioBase->TIMCMP[base->timerIndex[0]]; + timerCmp &= 0xFF00U; + timerCmp |= timerDiv; + + flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp; +} + +void FLEXIO_SPI_WriteBlocking(FLEXIO_SPI_Type *base, + flexio_spi_shift_direction_t direction, + const uint8_t *buffer, + size_t size) +{ + assert(buffer); + assert(size); + + while (size--) + { + /* Wait until data transfer complete. */ + while (!(FLEXIO_SPI_GetStatusFlags(base) & kFLEXIO_SPI_TxBufferEmptyFlag)) + { + } + FLEXIO_SPI_WriteData(base, direction, *buffer++); + } +} + +void FLEXIO_SPI_ReadBlocking(FLEXIO_SPI_Type *base, + flexio_spi_shift_direction_t direction, + uint8_t *buffer, + size_t size) +{ + assert(buffer); + assert(size); + + while (size--) + { + /* Wait until data transfer complete. */ + while (!(FLEXIO_SPI_GetStatusFlags(base) & kFLEXIO_SPI_RxBufferFullFlag)) + { + } + *buffer++ = FLEXIO_SPI_ReadData(base, direction); + } +} + +void FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_transfer_t *xfer) +{ + flexio_spi_shift_direction_t direction; + uint8_t bytesPerFrame; + uint32_t dataMode = 0; + uint16_t timerCmp = base->flexioBase->TIMCMP[base->timerIndex[0]]; + uint16_t tmpData = FLEXIO_SPI_DUMMYDATA; + + timerCmp &= 0x00FFU; + /* Configure the values in handle. */ + switch (xfer->flags) + { + case kFLEXIO_SPI_8bitMsb: + dataMode = (8 * 2 - 1U) << 8U; + bytesPerFrame = 1; + direction = kFLEXIO_SPI_MsbFirst; + break; + + case kFLEXIO_SPI_8bitLsb: + dataMode = (8 * 2 - 1U) << 8U; + bytesPerFrame = 1; + direction = kFLEXIO_SPI_LsbFirst; + break; + + case kFLEXIO_SPI_16bitMsb: + dataMode = (16 * 2 - 1U) << 8U; + bytesPerFrame = 2; + direction = kFLEXIO_SPI_MsbFirst; + break; + + case kFLEXIO_SPI_16bitLsb: + dataMode = (16 * 2 - 1U) << 8U; + bytesPerFrame = 2; + direction = kFLEXIO_SPI_LsbFirst; + break; + + default: + dataMode = (8 * 2 - 1U) << 8U; + bytesPerFrame = 1; + direction = kFLEXIO_SPI_MsbFirst; + assert(true); + break; + } + + dataMode |= timerCmp; + + /* Configure transfer size. */ + base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; + + while (xfer->dataSize) + { + /* Wait until data transfer complete. */ + while (!(FLEXIO_SPI_GetStatusFlags(base) & kFLEXIO_SPI_TxBufferEmptyFlag)) + { + } + if (xfer->txData != NULL) + { + /* Transmit data and update tx size/buff. */ + if (bytesPerFrame == 1U) + { + tmpData = *(xfer->txData); + xfer->txData++; + } + else + { + if (direction == kFLEXIO_SPI_MsbFirst) + { + tmpData = (uint32_t)(xfer->txData[0]) << 8U; + tmpData += xfer->txData[1]; + } + else + { + tmpData = (uint32_t)(xfer->txData[1]) << 8U; + tmpData += xfer->txData[0]; + } + xfer->txData += 2U; + } + } + else + { + tmpData = FLEXIO_SPI_DUMMYDATA; + } + + xfer->dataSize -= bytesPerFrame; + + FLEXIO_SPI_WriteData(base, direction, tmpData); + + while (!(FLEXIO_SPI_GetStatusFlags(base) & kFLEXIO_SPI_RxBufferFullFlag)) + { + } + tmpData = FLEXIO_SPI_ReadData(base, direction); + + if (xfer->rxData != NULL) + { + if (bytesPerFrame == 1U) + { + *xfer->rxData = tmpData; + xfer->rxData++; + } + else + { + if (direction == kFLEXIO_SPI_MsbFirst) + { + *((uint16_t *)(xfer->rxData)) = tmpData; + } + else + { + *((uint16_t *)(xfer->rxData)) = (((tmpData << 8) & 0xff00U) | ((tmpData >> 8) & 0x00ffU)); + } + xfer->rxData += 2U; + } + } + } +} + +status_t FLEXIO_SPI_MasterTransferCreateHandle(FLEXIO_SPI_Type *base, + flexio_spi_master_handle_t *handle, + flexio_spi_master_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + IRQn_Type flexio_irqs[] = FLEXIO_IRQS; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Register callback and userData. */ + handle->callback = callback; + handle->userData = userData; + + /* Enable interrupt in NVIC. */ + EnableIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]); + + /* Save the context in global variables to support the double weak mechanism. */ + return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_MasterTransferHandleIRQ); +} + +status_t FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type *base, + flexio_spi_master_handle_t *handle, + flexio_spi_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + uint32_t dataMode = 0; + uint16_t timerCmp = base->flexioBase->TIMCMP[base->timerIndex[0]]; + uint16_t tmpData = FLEXIO_SPI_DUMMYDATA; + + timerCmp &= 0x00FFU; + + /* Check if SPI is busy. */ + if (handle->state == kFLEXIO_SPI_Busy) + { + return kStatus_FLEXIO_SPI_Busy; + } + + /* Check if the argument is legal. */ + if ((xfer->txData == NULL) && (xfer->rxData == NULL)) + { + return kStatus_InvalidArgument; + } + + /* Configure the values in handle */ + switch (xfer->flags) + { + case kFLEXIO_SPI_8bitMsb: + dataMode = (8 * 2 - 1U) << 8U; + handle->bytePerFrame = 1U; + handle->direction = kFLEXIO_SPI_MsbFirst; + break; + case kFLEXIO_SPI_8bitLsb: + dataMode = (8 * 2 - 1U) << 8U; + handle->bytePerFrame = 1U; + handle->direction = kFLEXIO_SPI_LsbFirst; + break; + case kFLEXIO_SPI_16bitMsb: + dataMode = (16 * 2 - 1U) << 8U; + handle->bytePerFrame = 2U; + handle->direction = kFLEXIO_SPI_MsbFirst; + break; + case kFLEXIO_SPI_16bitLsb: + dataMode = (16 * 2 - 1U) << 8U; + handle->bytePerFrame = 2U; + handle->direction = kFLEXIO_SPI_LsbFirst; + break; + default: + dataMode = (8 * 2 - 1U) << 8U; + handle->bytePerFrame = 1U; + handle->direction = kFLEXIO_SPI_MsbFirst; + assert(true); + break; + } + + dataMode |= timerCmp; + + /* Configure transfer size. */ + base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; + + handle->state = kFLEXIO_SPI_Busy; + handle->txData = xfer->txData; + handle->rxData = xfer->rxData; + handle->rxRemainingBytes = xfer->dataSize; + + /* Save total transfer size. */ + handle->transferSize = xfer->dataSize; + + /* Send first byte of data to trigger the rx interrupt. */ + if (handle->txData != NULL) + { + /* Transmit data and update tx size/buff. */ + if (handle->bytePerFrame == 1U) + { + tmpData = *(handle->txData); + handle->txData++; + } + else + { + if (handle->direction == kFLEXIO_SPI_MsbFirst) + { + tmpData = (uint32_t)(handle->txData[0]) << 8U; + tmpData += handle->txData[1]; + } + else + { + tmpData = (uint32_t)(handle->txData[1]) << 8U; + tmpData += handle->txData[0]; + } + handle->txData += 2U; + } + } + else + { + tmpData = FLEXIO_SPI_DUMMYDATA; + } + + handle->txRemainingBytes = xfer->dataSize - handle->bytePerFrame; + + FLEXIO_SPI_WriteData(base, handle->direction, tmpData); + + /* Enable transmit and receive interrupt to handle rx. */ + FLEXIO_SPI_EnableInterrupts(base, kFLEXIO_SPI_RxFullInterruptEnable); + + return kStatus_Success; +} + +status_t FLEXIO_SPI_MasterTransferGetCount(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Return remaing bytes in different cases. */ + if (handle->rxData) + { + *count = handle->transferSize - handle->rxRemainingBytes; + } + else + { + *count = handle->transferSize - handle->txRemainingBytes; + } + + return kStatus_Success; +} + +void FLEXIO_SPI_MasterTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle) +{ + assert(handle); + + FLEXIO_SPI_DisableInterrupts(base, kFLEXIO_SPI_RxFullInterruptEnable); + FLEXIO_SPI_DisableInterrupts(base, kFLEXIO_SPI_TxEmptyInterruptEnable); + + /* Transfer finished, set the state to idle. */ + handle->state = kFLEXIO_SPI_Idle; + + /* Clear the internal state. */ + handle->rxRemainingBytes = 0; + handle->txRemainingBytes = 0; +} + +void FLEXIO_SPI_MasterTransferHandleIRQ(void *spiType, void *spiHandle) +{ + assert(spiHandle); + + flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle; + FLEXIO_SPI_Type *base; + uint32_t status; + + if (handle->state == kFLEXIO_SPI_Idle) + { + return; + } + + base = (FLEXIO_SPI_Type *)spiType; + status = FLEXIO_SPI_GetStatusFlags(base); + + /* Handle rx. */ + if ((status & kFLEXIO_SPI_RxBufferFullFlag) && (handle->rxRemainingBytes)) + { + FLEXIO_SPI_TransferReceiveTransaction(base, handle); + } + + /* Handle tx. */ + if ((status & kFLEXIO_SPI_TxBufferEmptyFlag) && (handle->txRemainingBytes)) + { + FLEXIO_SPI_TransferSendTransaction(base, handle); + } + + /* All the transfer finished. */ + if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U)) + { + FLEXIO_SPI_MasterTransferAbort(base, handle); + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData); + } + } +} + +status_t FLEXIO_SPI_SlaveTransferCreateHandle(FLEXIO_SPI_Type *base, + flexio_spi_slave_handle_t *handle, + flexio_spi_slave_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + IRQn_Type flexio_irqs[] = FLEXIO_IRQS; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Register callback and userData. */ + handle->callback = callback; + handle->userData = userData; + + /* Enable interrupt in NVIC. */ + EnableIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]); + + /* Save the context in global variables to support the double weak mechanism. */ + return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_SlaveTransferHandleIRQ); +} + +status_t FLEXIO_SPI_SlaveTransferNonBlocking(FLEXIO_SPI_Type *base, + flexio_spi_slave_handle_t *handle, + flexio_spi_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + uint32_t dataMode = 0; + + /* Check if SPI is busy. */ + if (handle->state == kFLEXIO_SPI_Busy) + { + return kStatus_FLEXIO_SPI_Busy; + } + + /* Check if the argument is legal. */ + if ((xfer->txData == NULL) && (xfer->rxData == NULL)) + { + return kStatus_InvalidArgument; + } + + /* Configure the values in handle */ + switch (xfer->flags) + { + case kFLEXIO_SPI_8bitMsb: + dataMode = 8 * 2 - 1U; + handle->bytePerFrame = 1U; + handle->direction = kFLEXIO_SPI_MsbFirst; + break; + case kFLEXIO_SPI_8bitLsb: + dataMode = 8 * 2 - 1U; + handle->bytePerFrame = 1U; + handle->direction = kFLEXIO_SPI_LsbFirst; + break; + case kFLEXIO_SPI_16bitMsb: + dataMode = 16 * 2 - 1U; + handle->bytePerFrame = 2U; + handle->direction = kFLEXIO_SPI_MsbFirst; + break; + case kFLEXIO_SPI_16bitLsb: + dataMode = 16 * 2 - 1U; + handle->bytePerFrame = 2U; + handle->direction = kFLEXIO_SPI_LsbFirst; + break; + default: + dataMode = 8 * 2 - 1U; + handle->bytePerFrame = 1U; + handle->direction = kFLEXIO_SPI_MsbFirst; + assert(true); + break; + } + + /* Configure transfer size. */ + base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; + + handle->state = kFLEXIO_SPI_Busy; + handle->txData = xfer->txData; + handle->rxData = xfer->rxData; + handle->txRemainingBytes = xfer->dataSize; + handle->rxRemainingBytes = xfer->dataSize; + + /* Save total transfer size. */ + handle->transferSize = xfer->dataSize; + + /* Enable transmit and receive interrupt to handle tx and rx. */ + FLEXIO_SPI_EnableInterrupts(base, kFLEXIO_SPI_TxEmptyInterruptEnable); + FLEXIO_SPI_EnableInterrupts(base, kFLEXIO_SPI_RxFullInterruptEnable); + + return kStatus_Success; +} + +void FLEXIO_SPI_SlaveTransferHandleIRQ(void *spiType, void *spiHandle) +{ + assert(spiHandle); + + flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle; + FLEXIO_SPI_Type *base; + uint32_t status; + + if (handle->state == kFLEXIO_SPI_Idle) + { + return; + } + + base = (FLEXIO_SPI_Type *)spiType; + status = FLEXIO_SPI_GetStatusFlags(base); + + /* Handle tx. */ + if ((status & kFLEXIO_SPI_TxBufferEmptyFlag) && (handle->txRemainingBytes)) + { + FLEXIO_SPI_TransferSendTransaction(base, handle); + } + + /* Handle rx. */ + if ((status & kFLEXIO_SPI_RxBufferFullFlag) && (handle->rxRemainingBytes)) + { + FLEXIO_SPI_TransferReceiveTransaction(base, handle); + } + + /* All the transfer finished. */ + if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U)) + { + FLEXIO_SPI_SlaveTransferAbort(base, handle); + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData); + } + } +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi.h new file mode 100644 index 00000000000..afec9628b4b --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi.h @@ -0,0 +1,707 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_FLEXIO_SPI_H_ +#define _FSL_FLEXIO_SPI_H_ + +#include "fsl_common.h" +#include "fsl_flexio.h" + +/*! + * @addtogroup flexio_spi + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief FlexIO SPI driver version 2.1.0. */ +#define FSL_FLEXIO_SPI_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ + +#ifndef FLEXIO_SPI_DUMMYDATA +/*! @brief FlexIO SPI dummy transfer data, the data is sent while txData is NULL. */ +#define FLEXIO_SPI_DUMMYDATA (0xFFFFU) +#endif + +/*! @brief Error codes for the FlexIO SPI driver. */ +enum _flexio_spi_status +{ + kStatus_FLEXIO_SPI_Busy = MAKE_STATUS(kStatusGroup_FLEXIO_SPI, 1), /*!< FlexIO SPI is busy. */ + kStatus_FLEXIO_SPI_Idle = MAKE_STATUS(kStatusGroup_FLEXIO_SPI, 2), /*!< SPI is idle */ + kStatus_FLEXIO_SPI_Error = MAKE_STATUS(kStatusGroup_FLEXIO_SPI, 3), /*!< FlexIO SPI error. */ +}; + +/*! @brief FlexIO SPI clock phase configuration. */ +typedef enum _flexio_spi_clock_phase +{ + kFLEXIO_SPI_ClockPhaseFirstEdge = 0x0U, /*!< First edge on SPSCK occurs at the middle of the first + * cycle of a data transfer. */ + kFLEXIO_SPI_ClockPhaseSecondEdge = 0x1U, /*!< First edge on SPSCK occurs at the start of the + * first cycle of a data transfer. */ +} flexio_spi_clock_phase_t; + +/*! @brief FlexIO SPI data shifter direction options. */ +typedef enum _flexio_spi_shift_direction +{ + kFLEXIO_SPI_MsbFirst = 0, /*!< Data transfers start with most significant bit. */ + kFLEXIO_SPI_LsbFirst = 1, /*!< Data transfers start with least significant bit. */ +} flexio_spi_shift_direction_t; + +/*! @brief FlexIO SPI data length mode options. */ +typedef enum _flexio_spi_data_bitcount_mode +{ + kFLEXIO_SPI_8BitMode = 0x08U, /*!< 8-bit data transmission mode. */ + kFLEXIO_SPI_16BitMode = 0x10U, /*!< 16-bit data transmission mode. */ +} flexio_spi_data_bitcount_mode_t; + +/*! @brief Define FlexIO SPI interrupt mask. */ +enum _flexio_spi_interrupt_enable +{ + kFLEXIO_SPI_TxEmptyInterruptEnable = 0x1U, /*!< Transmit buffer empty interrupt enable. */ + kFLEXIO_SPI_RxFullInterruptEnable = 0x2U, /*!< Receive buffer full interrupt enable. */ +}; + +/*! @brief Define FlexIO SPI status mask. */ +enum _flexio_spi_status_flags +{ + kFLEXIO_SPI_TxBufferEmptyFlag = 0x1U, /*!< Transmit buffer empty flag. */ + kFLEXIO_SPI_RxBufferFullFlag = 0x2U, /*!< Receive buffer full flag. */ +}; + +/*! @brief Define FlexIO SPI DMA mask. */ +enum _flexio_spi_dma_enable +{ + kFLEXIO_SPI_TxDmaEnable = 0x1U, /*!< Tx DMA request source */ + kFLEXIO_SPI_RxDmaEnable = 0x2U, /*!< Rx DMA request source */ + kFLEXIO_SPI_DmaAllEnable = 0x3U, /*!< All DMA request source*/ +}; + +/*! @brief Define FlexIO SPI transfer flags. */ +enum _flexio_spi_transfer_flags +{ + kFLEXIO_SPI_8bitMsb = 0x1U, /*!< FlexIO SPI 8-bit MSB first */ + kFLEXIO_SPI_8bitLsb = 0x2U, /*!< FlexIO SPI 8-bit LSB first */ + kFLEXIO_SPI_16bitMsb = 0x9U, /*!< FlexIO SPI 16-bit MSB first */ + kFLEXIO_SPI_16bitLsb = 0xaU, /*!< FlexIO SPI 16-bit LSB first */ +}; + +/*! @brief Define FlexIO SPI access structure typedef. */ +typedef struct _flexio_spi_type +{ + FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */ + uint8_t SDOPinIndex; /*!< Pin select for data output. */ + uint8_t SDIPinIndex; /*!< Pin select for data input. */ + uint8_t SCKPinIndex; /*!< Pin select for clock. */ + uint8_t CSnPinIndex; /*!< Pin select for enable. */ + uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO SPI. */ + uint8_t timerIndex[2]; /*!< Timer index used in FlexIO SPI. */ +} FLEXIO_SPI_Type; + +/*! @brief Define FlexIO SPI master configuration structure. */ +typedef struct _flexio_spi_master_config +{ + bool enableMaster; /*!< Enable/disable FlexIO SPI master after configuration. */ + bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode. */ + bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode. */ + bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, + fast access requires the FlexIO clock to be at least + twice the frequency of the bus clock. */ + uint32_t baudRate_Bps; /*!< Baud rate in Bps. */ + flexio_spi_clock_phase_t phase; /*!< Clock phase. */ + flexio_spi_data_bitcount_mode_t dataMode; /*!< 8bit or 16bit mode. */ +} flexio_spi_master_config_t; + +/*! @brief Define FlexIO SPI slave configuration structure. */ +typedef struct _flexio_spi_slave_config +{ + bool enableSlave; /*!< Enable/disable FlexIO SPI slave after configuration. */ + bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode. */ + bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode. */ + bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, + fast access requires the FlexIO clock to be at least + twice the frequency of the bus clock. */ + flexio_spi_clock_phase_t phase; /*!< Clock phase. */ + flexio_spi_data_bitcount_mode_t dataMode; /*!< 8bit or 16bit mode. */ +} flexio_spi_slave_config_t; + +/*! @brief Define FlexIO SPI transfer structure. */ +typedef struct _flexio_spi_transfer +{ + uint8_t *txData; /*!< Send buffer. */ + uint8_t *rxData; /*!< Receive buffer. */ + size_t dataSize; /*!< Transfer bytes. */ + uint8_t flags; /*!< FlexIO SPI control flag, MSB first or LSB first. */ +} flexio_spi_transfer_t; + +/*! @brief typedef for flexio_spi_master_handle_t in advance. */ +typedef struct _flexio_spi_master_handle flexio_spi_master_handle_t; + +/*! @brief Slave handle is the same with master handle. */ +typedef flexio_spi_master_handle_t flexio_spi_slave_handle_t; + +/*! @brief FlexIO SPI master callback for finished transmit */ +typedef void (*flexio_spi_master_transfer_callback_t)(FLEXIO_SPI_Type *base, + flexio_spi_master_handle_t *handle, + status_t status, + void *userData); + +/*! @brief FlexIO SPI slave callback for finished transmit */ +typedef void (*flexio_spi_slave_transfer_callback_t)(FLEXIO_SPI_Type *base, + flexio_spi_slave_handle_t *handle, + status_t status, + void *userData); + +/*! @brief Define FlexIO SPI handle structure. */ +struct _flexio_spi_master_handle +{ + uint8_t *txData; /*!< Transfer buffer. */ + uint8_t *rxData; /*!< Receive buffer. */ + size_t transferSize; /*!< Total bytes to be transferred. */ + volatile size_t txRemainingBytes; /*!< Send data remaining in bytes. */ + volatile size_t rxRemainingBytes; /*!< Receive data remaining in bytes. */ + volatile uint32_t state; /*!< FlexIO SPI internal state. */ + uint8_t bytePerFrame; /*!< SPI mode, 2bytes or 1byte in a frame */ + flexio_spi_shift_direction_t direction; /*!< Shift direction. */ + flexio_spi_master_transfer_callback_t callback; /*!< FlexIO SPI callback. */ + void *userData; /*!< Callback parameter. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name FlexIO SPI Configuration + * @{ + */ + +/*! + * @brief Ungates the FlexIO clock, resets the FlexIO module, configures the FlexIO SPI master hardware, + * and configures the FlexIO SPI with FlexIO SPI master configuration. The + * configuration structure can be filled by the user, or be set with default values + * by the FLEXIO_SPI_MasterGetDefaultConfig(). + * + * @note FlexIO SPI master only support CPOL = 0, which means clock inactive low. + * + * Example + @code + FLEXIO_SPI_Type spiDev = { + .flexioBase = FLEXIO, + .SDOPinIndex = 0, + .SDIPinIndex = 1, + .SCKPinIndex = 2, + .CSnPinIndex = 3, + .shifterIndex = {0,1}, + .timerIndex = {0,1} + }; + flexio_spi_master_config_t config = { + .enableMaster = true, + .enableInDoze = false, + .enableInDebug = true, + .enableFastAccess = false, + .baudRate_Bps = 500000, + .phase = kFLEXIO_SPI_ClockPhaseFirstEdge, + .direction = kFLEXIO_SPI_MsbFirst, + .dataMode = kFLEXIO_SPI_8BitMode + }; + FLEXIO_SPI_MasterInit(&spiDev, &config, srcClock_Hz); + @endcode + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param masterConfig Pointer to the flexio_spi_master_config_t structure. + * @param srcClock_Hz FlexIO source clock in Hz. +*/ +void FLEXIO_SPI_MasterInit(FLEXIO_SPI_Type *base, flexio_spi_master_config_t *masterConfig, uint32_t srcClock_Hz); + +/*! + * @brief Gates the FlexIO clock. + * + * @param base Pointer to the FLEXIO_SPI_Type. +*/ +void FLEXIO_SPI_MasterDeinit(FLEXIO_SPI_Type *base); + +/*! + * @brief Gets the default configuration to configure the FlexIO SPI master. The configuration + * can be used directly by calling the FLEXIO_SPI_MasterConfigure(). + * Example: + @code + flexio_spi_master_config_t masterConfig; + FLEXIO_SPI_MasterGetDefaultConfig(&masterConfig); + @endcode + * @param masterConfig Pointer to the flexio_spi_master_config_t structure. +*/ +void FLEXIO_SPI_MasterGetDefaultConfig(flexio_spi_master_config_t *masterConfig); + +/*! + * @brief Ungates the FlexIO clock, resets the FlexIO module, configures the FlexIO SPI slave hardware + * configuration, and configures the FlexIO SPI with FlexIO SPI slave configuration. The + * configuration structure can be filled by the user, or be set with default values + * by the FLEXIO_SPI_SlaveGetDefaultConfig(). + * + * @note Only one timer is needed in the FlexIO SPI slave. As a result, the second timer index is ignored. + * FlexIO SPI slave only support CPOL = 0, which means clock inactive low. + * Example + @code + FLEXIO_SPI_Type spiDev = { + .flexioBase = FLEXIO, + .SDOPinIndex = 0, + .SDIPinIndex = 1, + .SCKPinIndex = 2, + .CSnPinIndex = 3, + .shifterIndex = {0,1}, + .timerIndex = {0} + }; + flexio_spi_slave_config_t config = { + .enableSlave = true, + .enableInDoze = false, + .enableInDebug = true, + .enableFastAccess = false, + .phase = kFLEXIO_SPI_ClockPhaseFirstEdge, + .direction = kFLEXIO_SPI_MsbFirst, + .dataMode = kFLEXIO_SPI_8BitMode + }; + FLEXIO_SPI_SlaveInit(&spiDev, &config); + @endcode + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param slaveConfig Pointer to the flexio_spi_slave_config_t structure. +*/ +void FLEXIO_SPI_SlaveInit(FLEXIO_SPI_Type *base, flexio_spi_slave_config_t *slaveConfig); + +/*! + * @brief Gates the FlexIO clock. + * + * @param base Pointer to the FLEXIO_SPI_Type. +*/ +void FLEXIO_SPI_SlaveDeinit(FLEXIO_SPI_Type *base); + +/*! + * @brief Gets the default configuration to configure the FlexIO SPI slave. The configuration + * can be used directly for calling the FLEXIO_SPI_SlaveConfigure(). + * Example: + @code + flexio_spi_slave_config_t slaveConfig; + FLEXIO_SPI_SlaveGetDefaultConfig(&slaveConfig); + @endcode + * @param slaveConfig Pointer to the flexio_spi_slave_config_t structure. +*/ +void FLEXIO_SPI_SlaveGetDefaultConfig(flexio_spi_slave_config_t *slaveConfig); + +/*@}*/ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets FlexIO SPI status flags. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @return status flag; Use the status flag to AND the following flag mask and get the status. + * @arg kFLEXIO_SPI_TxEmptyFlag + * @arg kFLEXIO_SPI_RxEmptyFlag +*/ + +uint32_t FLEXIO_SPI_GetStatusFlags(FLEXIO_SPI_Type *base); + +/*! + * @brief Clears FlexIO SPI status flags. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param mask status flag + * The parameter can be any combination of the following values: + * @arg kFLEXIO_SPI_TxEmptyFlag + * @arg kFLEXIO_SPI_RxEmptyFlag +*/ + +void FLEXIO_SPI_ClearStatusFlags(FLEXIO_SPI_Type *base, uint32_t mask); + +/*@}*/ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the FlexIO SPI interrupt. + * + * This function enables the FlexIO SPI interrupt. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param mask interrupt source. The parameter can be any combination of the following values: + * @arg kFLEXIO_SPI_RxFullInterruptEnable + * @arg kFLEXIO_SPI_TxEmptyInterruptEnable + */ +void FLEXIO_SPI_EnableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask); + +/*! + * @brief Disables the FlexIO SPI interrupt. + * + * This function disables the FlexIO SPI interrupt. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param mask interrupt source The parameter can be any combination of the following values: + * @arg kFLEXIO_SPI_RxFullInterruptEnable + * @arg kFLEXIO_SPI_TxEmptyInterruptEnable + */ +void FLEXIO_SPI_DisableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask); + +/*@}*/ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Enables/disables the FlexIO SPI transmit DMA. This function enables/disables the FlexIO SPI Tx DMA, + * which means that asserting the kFLEXIO_SPI_TxEmptyFlag does/doesn't trigger the DMA request. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param mask SPI DMA source. + * @param enable True means enable DMA, false means disable DMA. + */ +void FLEXIO_SPI_EnableDMA(FLEXIO_SPI_Type *base, uint32_t mask, bool enable); + +/*! + * @brief Gets the FlexIO SPI transmit data register address for MSB first transfer. + * + * This function returns the SPI data register address, which is mainly used by DMA/eDMA. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param direction Shift direction of MSB first or LSB first. + * @return FlexIO SPI transmit data register address. + */ +static inline uint32_t FLEXIO_SPI_GetTxDataRegisterAddress(FLEXIO_SPI_Type *base, + flexio_spi_shift_direction_t direction) +{ + if (direction == kFLEXIO_SPI_MsbFirst) + { + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferBitSwapped, + base->shifterIndex[0]) + + 3U; + } + else + { + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBuffer, base->shifterIndex[0]); + } +} + +/*! + * @brief Gets the FlexIO SPI receive data register address for the MSB first transfer. + * + * This function returns the SPI data register address, which is mainly used by DMA/eDMA. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param direction Shift direction of MSB first or LSB first. + * @return FlexIO SPI receive data register address. + */ +static inline uint32_t FLEXIO_SPI_GetRxDataRegisterAddress(FLEXIO_SPI_Type *base, + flexio_spi_shift_direction_t direction) +{ + if (direction == kFLEXIO_SPI_MsbFirst) + { + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferBitSwapped, base->shifterIndex[1]); + } + else + { + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBuffer, base->shifterIndex[1]) + 3U; + } +} + +/*@}*/ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Enables/disables the FlexIO SPI module operation. + * + * @param base Pointer to the FLEXIO_SPI_Type. + * @param enable True to enable, false to disable. +*/ +static inline void FLEXIO_SPI_Enable(FLEXIO_SPI_Type *base, bool enable) +{ + if (enable) + { + base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +/*! + * @brief Sets baud rate for the FlexIO SPI transfer, which is only used for the master. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param baudRate_Bps Baud Rate needed in Hz. + * @param srcClockHz SPI source clock frequency in Hz. + */ +void FLEXIO_SPI_MasterSetBaudRate(FLEXIO_SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClockHz); + +/*! + * @brief Writes one byte of data, which is sent using the MSB method. + * + * @note This is a non-blocking API, which returns directly after the data is put into the + * data register but the data transfer is not finished on the bus. Ensure that + * the TxEmptyFlag is asserted before calling this API. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param direction Shift direction of MSB first or LSB first. + * @param data 8 bit/16 bit data. + */ +static inline void FLEXIO_SPI_WriteData(FLEXIO_SPI_Type *base, flexio_spi_shift_direction_t direction, uint16_t data) +{ + if (direction == kFLEXIO_SPI_MsbFirst) + { + base->flexioBase->SHIFTBUFBBS[base->shifterIndex[0]] = data; + } + else + { + base->flexioBase->SHIFTBUF[base->shifterIndex[0]] = data; + } +} + +/*! + * @brief Reads 8 bit/16 bit data. + * + * @note This is a non-blocking API, which returns directly after the data is read from the + * data register. Ensure that the RxFullFlag is asserted before calling this API. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param direction Shift direction of MSB first or LSB first. + * @return 8 bit/16 bit data received. + */ +static inline uint16_t FLEXIO_SPI_ReadData(FLEXIO_SPI_Type *base, flexio_spi_shift_direction_t direction) +{ + if (direction == kFLEXIO_SPI_MsbFirst) + { + return base->flexioBase->SHIFTBUFBIS[base->shifterIndex[1]]; + } + else + { + return base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]]; + } +} + +/*! + * @brief Sends a buffer of data bytes. + * + * @note This function blocks using the polling method until all bytes have been sent. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param direction Shift direction of MSB first or LSB first. + * @param buffer The data bytes to send. + * @param size The number of data bytes to send. + */ +void FLEXIO_SPI_WriteBlocking(FLEXIO_SPI_Type *base, + flexio_spi_shift_direction_t direction, + const uint8_t *buffer, + size_t size); + +/*! + * @brief Receives a buffer of bytes. + * + * @note This function blocks using the polling method until all bytes have been received. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param direction Shift direction of MSB first or LSB first. + * @param buffer The buffer to store the received bytes. + * @param size The number of data bytes to be received. + * @param direction Shift direction of MSB first or LSB first. + */ +void FLEXIO_SPI_ReadBlocking(FLEXIO_SPI_Type *base, + flexio_spi_shift_direction_t direction, + uint8_t *buffer, + size_t size); + +/*! + * @brief Receives a buffer of bytes. + * + * @note This function blocks via polling until all bytes have been received. + * + * @param base pointer to FLEXIO_SPI_Type structure + * @param xfer FlexIO SPI transfer structure, see #flexio_spi_transfer_t. + */ +void FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_transfer_t *xfer); + +/*Transactional APIs*/ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the FlexIO SPI Master handle, which is used in transactional functions. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. + * @param callback The callback function. + * @param userData The parameter of the callback function. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. + */ +status_t FLEXIO_SPI_MasterTransferCreateHandle(FLEXIO_SPI_Type *base, + flexio_spi_master_handle_t *handle, + flexio_spi_master_transfer_callback_t callback, + void *userData); + +/*! + * @brief Master transfer data using IRQ. + * + * This function sends data using IRQ. This is a non-blocking function, which returns + * right away. When all data is sent out/received, the callback function is called. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. + * @param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t. + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_FLEXIO_SPI_Busy SPI is not idle, is running another transfer. + */ +status_t FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type *base, + flexio_spi_master_handle_t *handle, + flexio_spi_transfer_t *xfer); + +/*! + * @brief Aborts the master data transfer, which used IRQ. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. + */ +void FLEXIO_SPI_MasterTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle); + +/*! + * @brief Gets the data transfer status which used IRQ. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. + * @param count Number of bytes transferred so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +status_t FLEXIO_SPI_MasterTransferGetCount(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle, size_t *count); + +/*! + * @brief FlexIO SPI master IRQ handler function. + * + * @param spiType Pointer to the FLEXIO_SPI_Type structure. + * @param spiHandle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. + */ +void FLEXIO_SPI_MasterTransferHandleIRQ(void *spiType, void *spiHandle); + +/*! + * @brief Initializes the FlexIO SPI Slave handle, which is used in transactional functions. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. + * @param callback The callback function. + * @param userData The parameter of the callback function. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. + */ +status_t FLEXIO_SPI_SlaveTransferCreateHandle(FLEXIO_SPI_Type *base, + flexio_spi_slave_handle_t *handle, + flexio_spi_slave_transfer_callback_t callback, + void *userData); + +/*! + * @brief Slave transfer data using IRQ. + * + * This function sends data using IRQ. This is a non-blocking function, which returns + * right away. When all data is sent out/received, the callback function is called. + * @param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t. + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_FLEXIO_SPI_Busy SPI is not idle; it is running another transfer. + */ +status_t FLEXIO_SPI_SlaveTransferNonBlocking(FLEXIO_SPI_Type *base, + flexio_spi_slave_handle_t *handle, + flexio_spi_transfer_t *xfer); + +/*! + * @brief Aborts the slave data transfer which used IRQ, share same API with master. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. + */ +static inline void FLEXIO_SPI_SlaveTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_slave_handle_t *handle) +{ + FLEXIO_SPI_MasterTransferAbort(base, handle); +} +/*! + * @brief Gets the data transfer status which used IRQ, share same API with master. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. + * @param count Number of bytes transferred so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +static inline status_t FLEXIO_SPI_SlaveTransferGetCount(FLEXIO_SPI_Type *base, + flexio_spi_slave_handle_t *handle, + size_t *count) +{ + return FLEXIO_SPI_MasterTransferGetCount(base, handle, count); +} + +/*! + * @brief FlexIO SPI slave IRQ handler function. + * + * @param spiType Pointer to the FLEXIO_SPI_Type structure. + * @param spiHandle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. + */ +void FLEXIO_SPI_SlaveTransferHandleIRQ(void *spiType, void *spiHandle); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ +/*@}*/ + +#endif /*_FSL_FLEXIO_SPI_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi_edma.c new file mode 100644 index 00000000000..b8b63630c3c --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi_edma.c @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_spi_edma.h" + +/******************************************************************************* + * Definitons + ******************************************************************************/ +/*base, kFLEXIO_SPI_TxDmaEnable, false); + + /* change the state */ + spiPrivateHandle->handle->txInProgress = false; + + /* All finished, call the callback */ + if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false)) + { + if (spiPrivateHandle->handle->callback) + { + (spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success, + spiPrivateHandle->handle->userData); + } + } + } +} + +static void FLEXIO_SPI_RxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) +{ + tcds = tcds; + flexio_spi_master_edma_private_handle_t *spiPrivateHandle = (flexio_spi_master_edma_private_handle_t *)param; + + if (transferDone) + { + /* Disable Rx dma */ + FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, kFLEXIO_SPI_RxDmaEnable, false); + + /* change the state */ + spiPrivateHandle->handle->rxInProgress = false; + + /* All finished, call the callback */ + if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false)) + { + if (spiPrivateHandle->handle->callback) + { + (spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success, + spiPrivateHandle->handle->userData); + } + } + } +} + +static void FLEXIO_SPI_EDMAConfig(FLEXIO_SPI_Type *base, + flexio_spi_master_edma_handle_t *handle, + flexio_spi_transfer_t *xfer) +{ + edma_transfer_config_t xferConfig; + flexio_spi_shift_direction_t direction; + uint8_t bytesPerFrame; + + /* Configure the values in handle. */ + switch (xfer->flags) + { + case kFLEXIO_SPI_8bitMsb: + bytesPerFrame = 1; + direction = kFLEXIO_SPI_MsbFirst; + break; + case kFLEXIO_SPI_8bitLsb: + bytesPerFrame = 1; + direction = kFLEXIO_SPI_LsbFirst; + break; + case kFLEXIO_SPI_16bitMsb: + bytesPerFrame = 2; + direction = kFLEXIO_SPI_MsbFirst; + break; + case kFLEXIO_SPI_16bitLsb: + bytesPerFrame = 2; + direction = kFLEXIO_SPI_LsbFirst; + break; + default: + bytesPerFrame = 1U; + direction = kFLEXIO_SPI_MsbFirst; + assert(true); + break; + } + + /* Save total transfer size. */ + handle->transferSize = xfer->dataSize; + + /* Configure tx transfer EDMA. */ + xferConfig.destAddr = FLEXIO_SPI_GetTxDataRegisterAddress(base, direction); + xferConfig.destOffset = 0; + if (bytesPerFrame == 1U) + { + xferConfig.srcTransferSize = kEDMA_TransferSize1Bytes; + xferConfig.destTransferSize = kEDMA_TransferSize1Bytes; + xferConfig.minorLoopBytes = 1; + } + else + { + if (direction == kFLEXIO_SPI_MsbFirst) + { + xferConfig.destAddr -= 1U; + } + xferConfig.srcTransferSize = kEDMA_TransferSize2Bytes; + xferConfig.destTransferSize = kEDMA_TransferSize2Bytes; + xferConfig.minorLoopBytes = 2; + } + + /* Configure DMA channel. */ + if (xfer->txData) + { + xferConfig.srcOffset = bytesPerFrame; + xferConfig.srcAddr = (uint32_t)(xfer->txData); + } + else + { + /* Disable the source increasement and source set to dummyData. */ + xferConfig.srcOffset = 0; + xferConfig.srcAddr = (uint32_t)(&s_dummyData); + } + + xferConfig.majorLoopCounts = (xfer->dataSize / xferConfig.minorLoopBytes); + + /* Store the initially configured eDMA minor byte transfer count into the FLEXIO SPI handle */ + handle->nbytes = xferConfig.minorLoopBytes; + + if (handle->txHandle) + { + EDMA_SubmitTransfer(handle->txHandle, &xferConfig); + } + + /* Configure tx transfer EDMA. */ + if (xfer->rxData) + { + xferConfig.srcAddr = FLEXIO_SPI_GetRxDataRegisterAddress(base, direction); + if (bytesPerFrame == 2U) + { + if (direction == kFLEXIO_SPI_LsbFirst) + { + xferConfig.srcAddr -= 1U; + } + } + xferConfig.srcOffset = 0; + xferConfig.destAddr = (uint32_t)(xfer->rxData); + xferConfig.destOffset = bytesPerFrame; + EDMA_SubmitTransfer(handle->rxHandle, &xferConfig); + handle->rxInProgress = true; + FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_RxDmaEnable, true); + EDMA_StartTransfer(handle->rxHandle); + } + + /* Always start Tx transfer. */ + if (handle->txHandle) + { + handle->txInProgress = true; + FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_TxDmaEnable, true); + EDMA_StartTransfer(handle->txHandle); + } +} + +status_t FLEXIO_SPI_MasterTransferCreateHandleEDMA(FLEXIO_SPI_Type *base, + flexio_spi_master_edma_handle_t *handle, + flexio_spi_master_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txHandle, + edma_handle_t *rxHandle) +{ + assert(handle); + + uint8_t index = 0; + + /* Find the an empty handle pointer to store the handle. */ + for (index = 0; index < FLEXIO_SPI_HANDLE_COUNT; index++) + { + if (s_edmaPrivateHandle[index].base == NULL) + { + s_edmaPrivateHandle[index].base = base; + s_edmaPrivateHandle[index].handle = handle; + break; + } + } + + if (index == FLEXIO_SPI_HANDLE_COUNT) + { + return kStatus_OutOfRange; + } + + /* Set spi base to handle. */ + handle->txHandle = txHandle; + handle->rxHandle = rxHandle; + + /* Register callback and userData. */ + handle->callback = callback; + handle->userData = userData; + + /* Set SPI state to idle. */ + handle->txInProgress = false; + handle->rxInProgress = false; + + /* Install callback for Tx/Rx dma channel. */ + if (handle->txHandle) + { + EDMA_SetCallback(handle->txHandle, FLEXIO_SPI_TxEDMACallback, &s_edmaPrivateHandle[index]); + } + if (handle->rxHandle) + { + EDMA_SetCallback(handle->rxHandle, FLEXIO_SPI_RxEDMACallback, &s_edmaPrivateHandle[index]); + } + + return kStatus_Success; +} + +status_t FLEXIO_SPI_MasterTransferEDMA(FLEXIO_SPI_Type *base, + flexio_spi_master_edma_handle_t *handle, + flexio_spi_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + uint32_t dataMode = 0; + uint16_t timerCmp = base->flexioBase->TIMCMP[base->timerIndex[0]]; + + timerCmp &= 0x00FFU; + + /* Check if the device is busy. */ + if ((handle->txInProgress) || (handle->rxInProgress)) + { + return kStatus_FLEXIO_SPI_Busy; + } + + /* Check if input parameter invalid. */ + if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + /* configure data mode. */ + if ((xfer->flags == kFLEXIO_SPI_8bitMsb) || (xfer->flags == kFLEXIO_SPI_8bitLsb)) + { + dataMode = (8 * 2 - 1U) << 8U; + } + else if ((xfer->flags == kFLEXIO_SPI_16bitMsb) || (xfer->flags == kFLEXIO_SPI_16bitLsb)) + { + dataMode = (16 * 2 - 1U) << 8U; + } + else + { + dataMode = 8 * 2 - 1U; + } + + dataMode |= timerCmp; + + base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; + + FLEXIO_SPI_EDMAConfig(base, handle, xfer); + + return kStatus_Success; +} + +status_t FLEXIO_SPI_MasterTransferGetCountEDMA(FLEXIO_SPI_Type *base, + flexio_spi_master_edma_handle_t *handle, + size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + if (handle->rxInProgress) + { + *count = (handle->transferSize - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->rxHandle->base, handle->rxHandle->channel)); + } + else + { + *count = (handle->transferSize - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->txHandle->base, handle->txHandle->channel)); + } + + return kStatus_Success; +} + +void FLEXIO_SPI_MasterTransferAbortEDMA(FLEXIO_SPI_Type *base, flexio_spi_master_edma_handle_t *handle) +{ + assert(handle); + + /* Disable dma. */ + EDMA_StopTransfer(handle->txHandle); + EDMA_StopTransfer(handle->rxHandle); + + /* Disable DMA enable bit. */ + FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_DmaAllEnable, false); + + /* Set the handle state. */ + handle->txInProgress = false; + handle->rxInProgress = false; +} + +status_t FLEXIO_SPI_SlaveTransferEDMA(FLEXIO_SPI_Type *base, + flexio_spi_slave_edma_handle_t *handle, + flexio_spi_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + uint32_t dataMode = 0; + + /* Check if the device is busy. */ + if ((handle->txInProgress) || (handle->rxInProgress)) + { + return kStatus_FLEXIO_SPI_Busy; + } + + /* Check if input parameter invalid. */ + if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + /* configure data mode. */ + if ((xfer->flags == kFLEXIO_SPI_8bitMsb) || (xfer->flags == kFLEXIO_SPI_8bitLsb)) + { + dataMode = 8 * 2 - 1U; + } + else if ((xfer->flags == kFLEXIO_SPI_16bitMsb) || (xfer->flags == kFLEXIO_SPI_16bitLsb)) + { + dataMode = 16 * 2 - 1U; + } + else + { + dataMode = 8 * 2 - 1U; + } + + base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; + + FLEXIO_SPI_EDMAConfig(base, handle, xfer); + + return kStatus_Success; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi_edma.h new file mode 100644 index 00000000000..6c2778c86f0 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_spi_edma.h @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_SPI_EDMA_H_ +#define _FSL_FLEXIO_SPI_EDMA_H_ + +#include "fsl_flexio_spi.h" +#include "fsl_edma.h" + +/*! + * @addtogroup flexio_edma_spi + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief typedef for flexio_spi_master_edma_handle_t in advance. */ +typedef struct _flexio_spi_master_edma_handle flexio_spi_master_edma_handle_t; + +/*! @brief Slave handle is the same with master handle. */ +typedef flexio_spi_master_edma_handle_t flexio_spi_slave_edma_handle_t; + +/*! @brief FlexIO SPI master callback for finished transmit */ +typedef void (*flexio_spi_master_edma_transfer_callback_t)(FLEXIO_SPI_Type *base, + flexio_spi_master_edma_handle_t *handle, + status_t status, + void *userData); + +/*! @brief FlexIO SPI slave callback for finished transmit */ +typedef void (*flexio_spi_slave_edma_transfer_callback_t)(FLEXIO_SPI_Type *base, + flexio_spi_slave_edma_handle_t *handle, + status_t status, + void *userData); + +/*! @brief FlexIO SPI eDMA transfer handle, users should not touch the content of the handle.*/ +struct _flexio_spi_master_edma_handle +{ + size_t transferSize; /*!< Total bytes to be transferred. */ + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + bool txInProgress; /*!< Send transfer in progress */ + bool rxInProgress; /*!< Receive transfer in progress */ + edma_handle_t *txHandle; /*!< DMA handler for SPI send */ + edma_handle_t *rxHandle; /*!< DMA handler for SPI receive */ + flexio_spi_master_edma_transfer_callback_t callback; /*!< Callback for SPI DMA transfer */ + void *userData; /*!< User Data for SPI DMA callback */ +}; + +/******************************************************************************* + * APIs + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name eDMA Transactional + * @{ + */ + +/*! + * @brief Initializes the FlexIO SPI master eDMA handle. + * + * This function initializes the FlexIO SPI master eDMA handle which can be used for other FlexIO SPI master transactional + * APIs. + * For a specified FlexIO SPI instance, call this API once to get the initialized handle. + * + * @param base Pointer to FLEXIO_SPI_Type structure. + * @param handle Pointer to flexio_spi_master_edma_handle_t structure to store the transfer state. + * @param callback SPI callback, NULL means no callback. + * @param userData callback function parameter. + * @param txHandle User requested eDMA handle for FlexIO SPI RX eDMA transfer. + * @param rxHandle User requested eDMA handle for FlexIO SPI TX eDMA transfer. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO SPI eDMA type/handle table out of range. + */ +status_t FLEXIO_SPI_MasterTransferCreateHandleEDMA(FLEXIO_SPI_Type *base, + flexio_spi_master_edma_handle_t *handle, + flexio_spi_master_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txHandle, + edma_handle_t *rxHandle); + +/*! + * @brief Performs a non-blocking FlexIO SPI transfer using eDMA. + * + * @note This interface returns immediately after transfer initiates. Call + * FLEXIO_SPI_MasterGetTransferCountEDMA to poll the transfer status and check + * whether the FlexIO SPI transfer is finished. + * + * @param base Pointer to FLEXIO_SPI_Type structure. + * @param handle Pointer to flexio_spi_master_edma_handle_t structure to store the transfer state. + * @param xfer Pointer to FlexIO SPI transfer structure. + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_FLEXIO_SPI_Busy FlexIO SPI is not idle, is running another transfer. + */ +status_t FLEXIO_SPI_MasterTransferEDMA(FLEXIO_SPI_Type *base, + flexio_spi_master_edma_handle_t *handle, + flexio_spi_transfer_t *xfer); + +/*! + * @brief Aborts a FlexIO SPI transfer using eDMA. + * + * @param base Pointer to FLEXIO_SPI_Type structure. + * @param handle FlexIO SPI eDMA handle pointer. + */ +void FLEXIO_SPI_MasterTransferAbortEDMA(FLEXIO_SPI_Type *base, flexio_spi_master_edma_handle_t *handle); + +/*! + * @brief Gets the remaining bytes for FlexIO SPI eDMA transfer. + * + * @param base Pointer to FLEXIO_SPI_Type structure. + * @param handle FlexIO SPI eDMA handle pointer. + * @param count Number of bytes transferred so far by the non-blocking transaction. + */ +status_t FLEXIO_SPI_MasterTransferGetCountEDMA(FLEXIO_SPI_Type *base, + flexio_spi_master_edma_handle_t *handle, + size_t *count); + +/*! + * @brief Initializes the FlexIO SPI slave eDMA handle. + * + * This function initializes the FlexIO SPI slave eDMA handle. + * + * @param base Pointer to FLEXIO_SPI_Type structure. + * @param handle Pointer to flexio_spi_slave_edma_handle_t structure to store the transfer state. + * @param callback SPI callback, NULL means no callback. + * @param userData callback function parameter. + * @param txHandle User requested eDMA handle for FlexIO SPI TX eDMA transfer. + * @param rxHandle User requested eDMA handle for FlexIO SPI RX eDMA transfer. + */ +static inline void FLEXIO_SPI_SlaveTransferCreateHandleEDMA(FLEXIO_SPI_Type *base, + flexio_spi_slave_edma_handle_t *handle, + flexio_spi_slave_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txHandle, + edma_handle_t *rxHandle) +{ + FLEXIO_SPI_MasterTransferCreateHandleEDMA(base, handle, callback, userData, txHandle, rxHandle); +} + +/*! + * @brief Performs a non-blocking FlexIO SPI transfer using eDMA. + * + * @note This interface returns immediately after transfer initiates. Call + * FLEXIO_SPI_SlaveGetTransferCountEDMA to poll the transfer status and + * check whether the FlexIO SPI transfer is finished. + * + * @param base Pointer to FLEXIO_SPI_Type structure. + * @param handle Pointer to flexio_spi_slave_edma_handle_t structure to store the transfer state. + * @param xfer Pointer to FlexIO SPI transfer structure. + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_FLEXIO_SPI_Busy FlexIO SPI is not idle, is running another transfer. + */ +status_t FLEXIO_SPI_SlaveTransferEDMA(FLEXIO_SPI_Type *base, + flexio_spi_slave_edma_handle_t *handle, + flexio_spi_transfer_t *xfer); + +/*! + * @brief Aborts a FlexIO SPI transfer using eDMA. + * + * @param base Pointer to FLEXIO_SPI_Type structure. + * @param handle Pointer to flexio_spi_slave_edma_handle_t structure to store the transfer state. + */ +static inline void FLEXIO_SPI_SlaveTransferAbortEDMA(FLEXIO_SPI_Type *base, flexio_spi_slave_edma_handle_t *handle) +{ + FLEXIO_SPI_MasterTransferAbortEDMA(base, handle); +} + +/*! + * @brief Gets the remaining bytes to be transferred for FlexIO SPI eDMA. + * + * @param base Pointer to FLEXIO_SPI_Type structure. + * @param handle FlexIO SPI eDMA handle pointer. + * @param count Number of bytes transferred so far by the non-blocking transaction. + */ +static inline status_t FLEXIO_SPI_SlaveTransferGetCountEDMA(FLEXIO_SPI_Type *base, + flexio_spi_slave_edma_handle_t *handle, + size_t *count) +{ + return FLEXIO_SPI_MasterTransferGetCountEDMA(base, handle, count); +} + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart.c new file mode 100644 index 00000000000..6b31e72e040 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart.c @@ -0,0 +1,734 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_uart.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*flexioBase; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_FLEXIO_COUNT; instance++) + { + if (s_flexioBases[instance] == flexioBase) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_FLEXIO_COUNT); + + return instance; +} + +static size_t FLEXIO_UART_TransferGetRxRingBufferLength(flexio_uart_handle_t *handle) +{ + size_t size; + + if (handle->rxRingBufferTail > handle->rxRingBufferHead) + { + size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail); + } + else + { + size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail); + } + + return size; +} + +static bool FLEXIO_UART_TransferIsRxRingBufferFull(flexio_uart_handle_t *handle) +{ + bool full; + + if (FLEXIO_UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U)) + { + full = true; + } + else + { + full = false; + } + + return full; +} + +status_t FLEXIO_UART_Init(FLEXIO_UART_Type *base, const flexio_uart_config_t *userConfig, uint32_t srcClock_Hz) +{ + assert(base && userConfig); + + flexio_shifter_config_t shifterConfig; + flexio_timer_config_t timerConfig; + uint32_t ctrlReg = 0; + uint16_t timerDiv = 0; + uint16_t timerCmp = 0; + status_t result = kStatus_Success; + + /* Clear the shifterConfig & timerConfig struct. */ + memset(&shifterConfig, 0, sizeof(shifterConfig)); + memset(&timerConfig, 0, sizeof(timerConfig)); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate flexio clock. */ + CLOCK_EnableClock(s_flexioClocks[FLEXIO_UART_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset FLEXIO before configuration. */ + FLEXIO_Reset(base->flexioBase); + + /* Configure FLEXIO UART */ + ctrlReg = base->flexioBase->CTRL; + ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); + ctrlReg |= (FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) | + FLEXIO_CTRL_FLEXEN(userConfig->enableUart)); + if (!userConfig->enableInDoze) + { + ctrlReg |= FLEXIO_CTRL_DOZEN_MASK; + } + + base->flexioBase->CTRL = ctrlReg; + + /* Do hardware configuration. */ + /* 1. Configure the shifter 0 for tx. */ + shifterConfig.timerSelect = base->timerIndex[0]; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; + shifterConfig.pinSelect = base->TxPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow; + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); + + /*2. Configure the timer 0 for tx. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinSelect = base->TxPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; + timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + + timerDiv = srcClock_Hz / userConfig->baudRate_Bps; + timerDiv = timerDiv / 2 - 1; + + if (timerDiv > 0xFFU) + { + result = kStatus_InvalidArgument; + } + + timerCmp = ((uint32_t)(userConfig->bitCountPerChar * 2 - 1)) << 8U; + timerCmp |= timerDiv; + + timerConfig.timerCompare = timerCmp; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); + + /* 3. Configure the shifter 1 for rx. */ + shifterConfig.timerSelect = base->timerIndex[1]; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + shifterConfig.pinSelect = base->RxPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow; + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); + + /* 4. Configure the timer 1 for rx. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->RxPinIndex); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceExternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinSelect = base->RxPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveLow; + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinRisingEdge; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdge; + timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + + timerConfig.timerCompare = timerCmp; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig); + + return result; +} + +void FLEXIO_UART_Deinit(FLEXIO_UART_Type *base) +{ + /* Disable FLEXIO UART module. */ + FLEXIO_UART_Enable(base, false); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate flexio clock. */ + CLOCK_DisableClock(kCLOCK_Flexio0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void FLEXIO_UART_GetDefaultConfig(flexio_uart_config_t *userConfig) +{ + assert(userConfig); + + userConfig->enableUart = true; + userConfig->enableInDoze = false; + userConfig->enableInDebug = true; + userConfig->enableFastAccess = false; + /* Default baud rate 115200. */ + userConfig->baudRate_Bps = 115200U; + /* Default bit count at 8. */ + userConfig->bitCountPerChar = kFLEXIO_UART_8BitsPerChar; +} + +void FLEXIO_UART_EnableInterrupts(FLEXIO_UART_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_UART_TxDataRegEmptyInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]); + } + if (mask & kFLEXIO_UART_RxDataRegFullInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +void FLEXIO_UART_DisableInterrupts(FLEXIO_UART_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_UART_TxDataRegEmptyInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]); + } + if (mask & kFLEXIO_UART_RxDataRegFullInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +uint32_t FLEXIO_UART_GetStatusFlags(FLEXIO_UART_Type *base) +{ + uint32_t status = 0; + status = + ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]); + status |= + (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) + << 1U); + status |= + (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) + << 2U); + return status; +} + +void FLEXIO_UART_ClearStatusFlags(FLEXIO_UART_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_UART_TxDataRegEmptyFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]); + } + if (mask & kFLEXIO_UART_RxDataRegFullFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]); + } + if (mask & kFLEXIO_UART_RxOverRunFlag) + { + FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +void FLEXIO_UART_WriteBlocking(FLEXIO_UART_Type *base, const uint8_t *txData, size_t txSize) +{ + assert(txData); + assert(txSize); + + while (txSize--) + { + /* Wait until data transfer complete. */ + while (!(FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))) + { + } + + base->flexioBase->SHIFTBUF[base->shifterIndex[0]] = *txData++; + } +} + +void FLEXIO_UART_ReadBlocking(FLEXIO_UART_Type *base, uint8_t *rxData, size_t rxSize) +{ + assert(rxData); + assert(rxSize); + + while (rxSize--) + { + /* Wait until data transfer complete. */ + while (!(FLEXIO_UART_GetStatusFlags(base) & kFLEXIO_UART_RxDataRegFullFlag)) + { + } + + *rxData++ = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]]; + } +} + +status_t FLEXIO_UART_TransferCreateHandle(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + flexio_uart_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + IRQn_Type flexio_irqs[] = FLEXIO_IRQS; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Set the TX/RX state. */ + handle->rxState = kFLEXIO_UART_RxIdle; + handle->txState = kFLEXIO_UART_TxIdle; + + /* Set the callback and user data. */ + handle->callback = callback; + handle->userData = userData; + + /* Enable interrupt in NVIC. */ + EnableIRQ(flexio_irqs[FLEXIO_UART_GetInstance(base)]); + + /* Save the context in global variables to support the double weak mechanism. */ + return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_UART_TransferHandleIRQ); +} + +void FLEXIO_UART_TransferStartRingBuffer(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + uint8_t *ringBuffer, + size_t ringBufferSize) +{ + assert(handle); + + /* Setup the ringbuffer address */ + if (ringBuffer) + { + handle->rxRingBuffer = ringBuffer; + handle->rxRingBufferSize = ringBufferSize; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; + + /* Enable the interrupt to accept the data when user need the ring buffer. */ + FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); + } +} + +void FLEXIO_UART_TransferStopRingBuffer(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle) +{ + assert(handle); + + if (handle->rxState == kFLEXIO_UART_RxIdle) + { + FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); + } + + handle->rxRingBuffer = NULL; + handle->rxRingBufferSize = 0U; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; +} + +status_t FLEXIO_UART_TransferSendNonBlocking(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + flexio_uart_transfer_t *xfer) +{ + status_t status; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* Return error if current TX busy. */ + if (kFLEXIO_UART_TxBusy == handle->txState) + { + status = kStatus_FLEXIO_UART_TxBusy; + } + else + { + handle->txData = xfer->data; + handle->txDataSize = xfer->dataSize; + handle->txDataSizeAll = xfer->dataSize; + handle->txState = kFLEXIO_UART_TxBusy; + + /* Enable transmiter interrupt. */ + FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable); + + status = kStatus_Success; + } + + return status; +} + +void FLEXIO_UART_TransferAbortSend(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle) +{ + /* Disable the transmitter and disable the interrupt. */ + FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable); + + handle->txDataSize = 0; + handle->txState = kFLEXIO_UART_TxIdle; +} + +status_t FLEXIO_UART_TransferGetSendCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count) +{ + assert(handle); + assert(count); + + if (kFLEXIO_UART_TxIdle == handle->txState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->txDataSizeAll - handle->txDataSize; + + return kStatus_Success; +} + +status_t FLEXIO_UART_TransferReceiveNonBlocking(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + flexio_uart_transfer_t *xfer, + size_t *receivedBytes) +{ + uint32_t i; + status_t status; + /* How many bytes to copy from ring buffer to user memory. */ + size_t bytesToCopy = 0U; + /* How many bytes to receive. */ + size_t bytesToReceive; + /* How many bytes currently have received. */ + size_t bytesCurrentReceived; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* How to get data: + 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize + to uart handle, enable interrupt to store received data to xfer->data. When + all data received, trigger callback. + 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. + If there are enough data in ring buffer, copy them to xfer->data and return. + If there are not enough data in ring buffer, copy all of them to xfer->data, + save the xfer->data remained empty space to uart handle, receive data + to this empty space and trigger callback when finished. */ + + if (kFLEXIO_UART_RxBusy == handle->rxState) + { + status = kStatus_FLEXIO_UART_RxBusy; + } + else + { + bytesToReceive = xfer->dataSize; + bytesCurrentReceived = 0U; + + /* If RX ring buffer is used. */ + if (handle->rxRingBuffer) + { + /* Disable FLEXIO_UART RX IRQ, protect ring buffer. */ + FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); + + /* How many bytes in RX ring buffer currently. */ + bytesToCopy = FLEXIO_UART_TransferGetRxRingBufferLength(handle); + + if (bytesToCopy) + { + bytesToCopy = MIN(bytesToReceive, bytesToCopy); + + bytesToReceive -= bytesToCopy; + + /* Copy data from ring buffer to user memory. */ + for (i = 0U; i < bytesToCopy; i++) + { + xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail]; + + /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + } + + /* If ring buffer does not have enough data, still need to read more data. */ + if (bytesToReceive) + { + /* No data in ring buffer, save the request to UART handle. */ + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = kFLEXIO_UART_RxBusy; + } + + /* Enable FLEXIO_UART RX IRQ if previously enabled. */ + FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); + } + /* Ring buffer not used. */ + else + { + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = kFLEXIO_UART_RxBusy; + + /* Enable RX interrupt. */ + FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); + } + + /* Return the how many bytes have read. */ + if (receivedBytes) + { + *receivedBytes = bytesCurrentReceived; + } + + status = kStatus_Success; + } + + return status; +} + +void FLEXIO_UART_TransferAbortReceive(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle) +{ + /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ + if (!handle->rxRingBuffer) + { + /* Disable RX interrupt. */ + FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); + } + + handle->rxDataSize = 0U; + handle->rxState = kFLEXIO_UART_RxIdle; +} + +status_t FLEXIO_UART_TransferGetReceiveCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count) +{ + assert(handle); + assert(count); + + if (kFLEXIO_UART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->rxDataSizeAll - handle->rxDataSize; + + return kStatus_Success; +} + +void FLEXIO_UART_TransferHandleIRQ(void *uartType, void *uartHandle) +{ + uint8_t count = 1; + FLEXIO_UART_Type *base = (FLEXIO_UART_Type *)uartType; + flexio_uart_handle_t *handle = (flexio_uart_handle_t *)uartHandle; + + /* Read the status back. */ + uint8_t status = FLEXIO_UART_GetStatusFlags(base); + + /* If RX overrun. */ + if (kFLEXIO_UART_RxOverRunFlag & status) + { + /* Clear Overrun flag. */ + FLEXIO_UART_ClearStatusFlags(base, kFLEXIO_UART_RxOverRunFlag); + + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_FLEXIO_UART_RxHardwareOverrun, handle->userData); + } + } + + /* Receive data register full */ + if ((kFLEXIO_UART_RxDataRegFullFlag & status) && (base->flexioBase->SHIFTSIEN & (1U << base->shifterIndex[1]))) + { + /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ + if (handle->rxDataSize) + { + /* Using non block API to read the data from the registers. */ + FLEXIO_UART_ReadByte(base, handle->rxData); + handle->rxDataSize--; + handle->rxData++; + count--; + + /* If all the data required for upper layer is ready, trigger callback. */ + if (!handle->rxDataSize) + { + handle->rxState = kFLEXIO_UART_RxIdle; + + if (handle->callback) + { + handle->callback(base, handle, kStatus_FLEXIO_UART_RxIdle, handle->userData); + } + } + } + + if (handle->rxRingBuffer) + { + if (count) + { + /* If RX ring buffer is full, trigger callback to notify over run. */ + if (FLEXIO_UART_TransferIsRxRingBufferFull(handle)) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_FLEXIO_UART_RxRingBufferOverrun, handle->userData); + } + } + + /* If ring buffer is still full after callback function, the oldest data is overrided. */ + if (FLEXIO_UART_TransferIsRxRingBufferFull(handle)) + { + /* Increase handle->rxRingBufferTail to make room for new data. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + + /* Read data. */ + handle->rxRingBuffer[handle->rxRingBufferHead] = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]]; + + /* Increase handle->rxRingBufferHead. */ + if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferHead = 0U; + } + else + { + handle->rxRingBufferHead++; + } + } + } + /* If no receive requst pending, stop RX interrupt. */ + else if (!handle->rxDataSize) + { + FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); + } + else + { + } + } + + /* Send data register empty and the interrupt is enabled. */ + if ((kFLEXIO_UART_TxDataRegEmptyFlag & status) && (base->flexioBase->SHIFTSIEN & (1U << base->shifterIndex[0]))) + { + if (handle->txDataSize) + { + /* Using non block API to write the data to the registers. */ + FLEXIO_UART_WriteByte(base, handle->txData); + handle->txData++; + handle->txDataSize--; + count--; + + /* If all the data are written to data register, TX finished. */ + if (!handle->txDataSize) + { + handle->txState = kFLEXIO_UART_TxIdle; + + /* Disable TX register empty interrupt. */ + FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable); + + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_FLEXIO_UART_TxIdle, handle->userData); + } + } + } + } +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart.h new file mode 100644 index 00000000000..7d33a87f7a6 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart.h @@ -0,0 +1,586 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_FLEXIO_UART_H_ +#define _FSL_FLEXIO_UART_H_ + +#include "fsl_common.h" +#include "fsl_flexio.h" + +/*! + * @addtogroup flexio_uart + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief FlexIO UART driver version 2.1.2. */ +#define FSL_FLEXIO_UART_DRIVER_VERSION (MAKE_VERSION(2, 1, 2)) +/*@}*/ + +/*! @brief Error codes for the UART driver. */ +enum _flexio_uart_status +{ + kStatus_FLEXIO_UART_TxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 0), /*!< Transmitter is busy. */ + kStatus_FLEXIO_UART_RxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 1), /*!< Receiver is busy. */ + kStatus_FLEXIO_UART_TxIdle = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 2), /*!< UART transmitter is idle. */ + kStatus_FLEXIO_UART_RxIdle = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 3), /*!< UART receiver is idle. */ + kStatus_FLEXIO_UART_ERROR = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 4), /*!< ERROR happens on UART. */ + kStatus_FLEXIO_UART_RxRingBufferOverrun = + MAKE_STATUS(kStatusGroup_FLEXIO_UART, 5), /*!< UART RX software ring buffer overrun. */ + kStatus_FLEXIO_UART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 6) /*!< UART RX receiver overrun. */ +}; + +/*! @brief FlexIO UART bit count per char. */ +typedef enum _flexio_uart_bit_count_per_char +{ + kFLEXIO_UART_7BitsPerChar = 7U, /*!< 7-bit data characters */ + kFLEXIO_UART_8BitsPerChar = 8U, /*!< 8-bit data characters */ + kFLEXIO_UART_9BitsPerChar = 9U, /*!< 9-bit data characters */ +} flexio_uart_bit_count_per_char_t; + +/*! @brief Define FlexIO UART interrupt mask. */ +enum _flexio_uart_interrupt_enable +{ + kFLEXIO_UART_TxDataRegEmptyInterruptEnable = 0x1U, /*!< Transmit buffer empty interrupt enable. */ + kFLEXIO_UART_RxDataRegFullInterruptEnable = 0x2U, /*!< Receive buffer full interrupt enable. */ +}; + +/*! @brief Define FlexIO UART status mask. */ +enum _flexio_uart_status_flags +{ + kFLEXIO_UART_TxDataRegEmptyFlag = 0x1U, /*!< Transmit buffer empty flag. */ + kFLEXIO_UART_RxDataRegFullFlag = 0x2U, /*!< Receive buffer full flag. */ + kFLEXIO_UART_RxOverRunFlag = 0x4U, /*!< Receive buffer over run flag. */ +}; + +/*! @brief Define FlexIO UART access structure typedef. */ +typedef struct _flexio_uart_type +{ + FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */ + uint8_t TxPinIndex; /*!< Pin select for UART_Tx. */ + uint8_t RxPinIndex; /*!< Pin select for UART_Rx. */ + uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO UART. */ + uint8_t timerIndex[2]; /*!< Timer index used in FlexIO UART. */ +} FLEXIO_UART_Type; + +/*! @brief Define FlexIO UART user configuration structure. */ +typedef struct _flexio_uart_config +{ + bool enableUart; /*!< Enable/disable FlexIO UART TX & RX. */ + bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode*/ + bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode*/ + bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, + fast access requires the FlexIO clock to be at least + twice the frequency of the bus clock. */ + uint32_t baudRate_Bps; /*!< Baud rate in Bps. */ + flexio_uart_bit_count_per_char_t bitCountPerChar; /*!< number of bits, 7/8/9 -bit */ +} flexio_uart_config_t; + +/*! @brief Define FlexIO UART transfer structure. */ +typedef struct _flexio_uart_transfer +{ + uint8_t *data; /*!< Transfer buffer*/ + size_t dataSize; /*!< Transfer size*/ +} flexio_uart_transfer_t; + +/* Forward declaration of the handle typedef. */ +typedef struct _flexio_uart_handle flexio_uart_handle_t; + +/*! @brief FlexIO UART transfer callback function. */ +typedef void (*flexio_uart_transfer_callback_t)(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + status_t status, + void *userData); + +/*! @brief Define FLEXIO UART handle structure*/ +struct _flexio_uart_handle +{ + uint8_t *volatile txData; /*!< Address of remaining data to send. */ + volatile size_t txDataSize; /*!< Size of the remaining data to send. */ + uint8_t *volatile rxData; /*!< Address of remaining data to receive. */ + volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */ + size_t txDataSizeAll; /*!< Total bytes to be sent. */ + size_t rxDataSizeAll; /*!< Total bytes to be received. */ + + uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */ + size_t rxRingBufferSize; /*!< Size of the ring buffer. */ + volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */ + volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */ + + flexio_uart_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< UART callback function parameter.*/ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the FlexIO clock, resets the FlexIO module, configures FlexIO UART + * hardware, and configures the FlexIO UART with FlexIO UART configuration. + * The configuration structure can be filled by the user or be set with + * default values by FLEXIO_UART_GetDefaultConfig(). + * + * Example + @code + FLEXIO_UART_Type base = { + .flexioBase = FLEXIO, + .TxPinIndex = 0, + .RxPinIndex = 1, + .shifterIndex = {0,1}, + .timerIndex = {0,1} + }; + flexio_uart_config_t config = { + .enableInDoze = false, + .enableInDebug = true, + .enableFastAccess = false, + .baudRate_Bps = 115200U, + .bitCountPerChar = 8 + }; + FLEXIO_UART_Init(base, &config, srcClock_Hz); + @endcode + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param userConfig Pointer to the flexio_uart_config_t structure. + * @param srcClock_Hz FlexIO source clock in Hz. + * @retval kStatus_Success Configuration success + * @retval kStatus_InvalidArgument Buadrate configuration out of range +*/ +status_t FLEXIO_UART_Init(FLEXIO_UART_Type *base, const flexio_uart_config_t *userConfig, uint32_t srcClock_Hz); + +/*! + * @brief Disables the FlexIO UART and gates the FlexIO clock. + * + * @note After calling this API, call the FLEXO_UART_Init to use the FlexIO UART module. + * + * @param base Pointer to FLEXIO_UART_Type structure +*/ +void FLEXIO_UART_Deinit(FLEXIO_UART_Type *base); + +/*! + * @brief Gets the default configuration to configure the FlexIO UART. The configuration + * can be used directly for calling the FLEXIO_UART_Init(). + * Example: + @code + flexio_uart_config_t config; + FLEXIO_UART_GetDefaultConfig(&userConfig); + @endcode + * @param userConfig Pointer to the flexio_uart_config_t structure. +*/ +void FLEXIO_UART_GetDefaultConfig(flexio_uart_config_t *userConfig); + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the FlexIO UART status flags. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @return FlexIO UART status flags. +*/ + +uint32_t FLEXIO_UART_GetStatusFlags(FLEXIO_UART_Type *base); + +/*! + * @brief Gets the FlexIO UART status flags. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param mask Status flag. + * The parameter can be any combination of the following values: + * @arg kFLEXIO_UART_TxDataRegEmptyFlag + * @arg kFLEXIO_UART_RxEmptyFlag + * @arg kFLEXIO_UART_RxOverRunFlag +*/ + +void FLEXIO_UART_ClearStatusFlags(FLEXIO_UART_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the FlexIO UART interrupt. + * + * This function enables the FlexIO UART interrupt. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param mask Interrupt source. + */ +void FLEXIO_UART_EnableInterrupts(FLEXIO_UART_Type *base, uint32_t mask); + +/*! + * @brief Disables the FlexIO UART interrupt. + * + * This function disables the FlexIO UART interrupt. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param mask Interrupt source. + */ +void FLEXIO_UART_DisableInterrupts(FLEXIO_UART_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Gets the FlexIO UARt transmit data register address. + * + * This function returns the UART data register address, which is mainly used by DMA/eDMA. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @return FlexIO UART transmit data register address. + */ +static inline uint32_t FLEXIO_UART_GetTxDataRegisterAddress(FLEXIO_UART_Type *base) +{ + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBuffer, base->shifterIndex[0]); +} + +/*! + * @brief Gets the FlexIO UART receive data register address. + * + * This function returns the UART data register address, which is mainly used by DMA/eDMA. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @return FlexIO UART receive data register address. + */ +static inline uint32_t FLEXIO_UART_GetRxDataRegisterAddress(FLEXIO_UART_Type *base) +{ + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferByteSwapped, base->shifterIndex[1]); +} + +/*! + * @brief Enables/disables the FlexIO UART transmit DMA. + * This function enables/disables the FlexIO UART Tx DMA, + * which means asserting the kFLEXIO_UART_TxDataRegEmptyFlag does/doesn't trigger the DMA request. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param enable True to enable, false to disable. + */ +static inline void FLEXIO_UART_EnableTxDMA(FLEXIO_UART_Type *base, bool enable) +{ + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->shifterIndex[0], enable); +} + +/*! + * @brief Enables/disables the FlexIO UART receive DMA. + * This function enables/disables the FlexIO UART Rx DMA, + * which means asserting kFLEXIO_UART_RxDataRegFullFlag does/doesn't trigger the DMA request. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param enable True to enable, false to disable. + */ +static inline void FLEXIO_UART_EnableRxDMA(FLEXIO_UART_Type *base, bool enable) +{ + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->shifterIndex[1], enable); +} + +/* @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Enables/disables the FlexIO UART module operation. + * + * @param base Pointer to the FLEXIO_UART_Type. + * @param enable True to enable, false to disable. +*/ +static inline void FLEXIO_UART_Enable(FLEXIO_UART_Type *base, bool enable) +{ + if (enable) + { + base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +/*! + * @brief Writes one byte of data. + * + * @note This is a non-blocking API, which returns directly after the data is put into the + * data register. Ensure that the TxEmptyFlag is asserted before calling + * this API. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param buffer The data bytes to send. + */ +static inline void FLEXIO_UART_WriteByte(FLEXIO_UART_Type *base, const uint8_t *buffer) +{ + base->flexioBase->SHIFTBUF[base->shifterIndex[0]] = *buffer; +} + +/*! + * @brief Reads one byte of data. + * + * @note This is a non-blocking API, which returns directly after the data is read from the + * data register. Ensure that the RxFullFlag is asserted before calling this API. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param buffer The buffer to store the received bytes. + */ +static inline void FLEXIO_UART_ReadByte(FLEXIO_UART_Type *base, uint8_t *buffer) +{ + *buffer = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]]; +} + +/*! + * @brief Sends a buffer of data bytes. + * + * @note This function blocks using the polling method until all bytes have been sent. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param txData The data bytes to send. + * @param txSize The number of data bytes to send. + */ +void FLEXIO_UART_WriteBlocking(FLEXIO_UART_Type *base, const uint8_t *txData, size_t txSize); + +/*! + * @brief Receives a buffer of bytes. + * + * @note This function blocks using the polling method until all bytes have been received. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param rxData The buffer to store the received bytes. + * @param rxSize The number of data bytes to be received. + */ +void FLEXIO_UART_ReadBlocking(FLEXIO_UART_Type *base, uint8_t *rxData, size_t rxSize); + +/* @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the UART handle. + * + * This function initializes the FlexIO UART handle, which can be used for other FlexIO + * UART transactional APIs. Call this API once to get the + * initialized handle. + * + * The UART driver supports the "background" receiving, which means that users can set up + * a RX ring buffer optionally. Data received is stored into the ring buffer even when + * the user doesn't call the FLEXIO_UART_TransferReceiveNonBlocking() API. If there is already data + * received in the ring buffer, users can get the received data from the ring buffer + * directly. The ring buffer is disabled if passing NULL as @p ringBuffer. + * + * @param base to FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + * @param callback The callback function. + * @param userData The parameter of the callback function. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. + */ +status_t FLEXIO_UART_TransferCreateHandle(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + flexio_uart_transfer_callback_t callback, + void *userData); + +/*! + * @brief Sets up the RX ring buffer. + * + * This function sets up the RX ring buffer to a specific UART handle. + * + * When the RX ring buffer is used, data received is stored into the ring buffer even when + * the user doesn't call the UART_ReceiveNonBlocking() API. If there is already data received + * in the ring buffer, users can get the received data from the ring buffer directly. + * + * @note When using the RX ring buffer, one byte is reserved for internal use. In other + * words, if @p ringBufferSize is 32, only 31 bytes are used for saving data. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + * @param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer. + * @param ringBufferSize Size of the ring buffer. + */ +void FLEXIO_UART_TransferStartRingBuffer(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + uint8_t *ringBuffer, + size_t ringBufferSize); + +/*! + * @brief Aborts the background transfer and uninstalls the ring buffer. + * + * This function aborts the background transfer and uninstalls the ring buffer. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + */ +void FLEXIO_UART_TransferStopRingBuffer(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle); + +/*! + * @brief Transmits a buffer of data using the interrupt method. + * + * This function sends data using an interrupt method. This is a non-blocking function, + * which returns directly without waiting for all data to be written to the TX register. When + * all data is written to the TX register in ISR, the FlexIO UART driver calls the callback + * function and passes the @ref kStatus_FLEXIO_UART_TxIdle as status parameter. + * + * @note The kStatus_FLEXIO_UART_TxIdle is passed to the upper layer when all data is written + * to the TX register. However, it does not ensure that all data is sent out. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + * @param xfer FlexIO UART transfer structure. See #flexio_uart_transfer_t. + * @retval kStatus_Success Successfully starts the data transmission. + * @retval kStatus_UART_TxBusy Previous transmission still not finished, data not written to the TX register. + */ +status_t FLEXIO_UART_TransferSendNonBlocking(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + flexio_uart_transfer_t *xfer); + +/*! + * @brief Aborts the interrupt-driven data transmit. + * + * This function aborts the interrupt-driven data sending. Get the remainBytes to find out + * how many bytes are still not sent out. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + */ +void FLEXIO_UART_TransferAbortSend(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle); + +/*! + * @brief Gets the number of bytes sent. + * + * This function gets the number of bytes sent driven by interrupt. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + * @param count Number of bytes sent so far by the non-blocking transaction. + * @retval kStatus_NoTransferInProgress transfer has finished or no transfer in progress. + * @retval kStatus_Success Successfully return the count. + */ +status_t FLEXIO_UART_TransferGetSendCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count); + +/*! + * @brief Receives a buffer of data using the interrupt method. + * + * This function receives data using the interrupt method. This is a non-blocking function, + * which returns without waiting for all data to be received. + * If the RX ring buffer is used and not empty, the data in ring buffer is copied and + * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer. + * After copying, if the data in ring buffer is not enough to read, the receive + * request is saved by the UART driver. When new data arrives, the receive request + * is serviced first. When all data is received, the UART driver notifies the upper layer + * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle. + * For example, if the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer, + * the 5 bytes are copied to xfer->data. This function returns with the + * parameter @p receivedBytes set to 5. For the last 5 bytes, newly arrived data is + * saved from the xfer->data[5]. When 5 bytes are received, the UART driver notifies upper layer. + * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt + * to receive data to xfer->data. When all data is received, the upper layer is notified. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + * @param xfer UART transfer structure. See #flexio_uart_transfer_t. + * @param receivedBytes Bytes received from the ring buffer directly. + * @retval kStatus_Success Successfully queue the transfer into the transmit queue. + * @retval kStatus_FLEXIO_UART_RxBusy Previous receive request is not finished. + */ +status_t FLEXIO_UART_TransferReceiveNonBlocking(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + flexio_uart_transfer_t *xfer, + size_t *receivedBytes); + +/*! + * @brief Aborts the receive data which was using IRQ. + * + * This function aborts the receive data which was using IRQ. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + */ +void FLEXIO_UART_TransferAbortReceive(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle); + +/*! + * @brief Gets the number of bytes received. + * + * This function gets the number of bytes received driven by interrupt. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + * @param count Number of bytes received so far by the non-blocking transaction. + * @retval kStatus_NoTransferInProgress transfer has finished or no transfer in progress. + * @retval kStatus_Success Successfully return the count. + */ +status_t FLEXIO_UART_TransferGetReceiveCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count); + +/*! + * @brief FlexIO UART IRQ handler function. + * + * This function processes the FlexIO UART transmit and receives the IRQ request. + * + * @param uartType Pointer to the FLEXIO_UART_Type structure. + * @param uartHandle Pointer to the flexio_uart_handle_t structure to store the transfer state. + */ +void FLEXIO_UART_TransferHandleIRQ(void *uartType, void *uartHandle); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ +/*@}*/ + +#endif /*_FSL_FLEXIO_UART_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart_edma.c new file mode 100644 index 00000000000..6367ed83dc4 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart_edma.c @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_uart_edma.h" +#include "fsl_dmamux.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*handle); + + /* Avoid the warning for unused variables. */ + handle = handle; + tcds = tcds; + + if (transferDone) + { + FLEXIO_UART_TransferAbortSendEDMA(uartPrivateHandle->base, uartPrivateHandle->handle); + + if (uartPrivateHandle->handle->callback) + { + uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle, + kStatus_FLEXIO_UART_TxIdle, uartPrivateHandle->handle->userData); + } + } +} + +static void FLEXIO_UART_TransferReceiveEDMACallback(edma_handle_t *handle, + void *param, + bool transferDone, + uint32_t tcds) +{ + flexio_uart_edma_private_handle_t *uartPrivateHandle = (flexio_uart_edma_private_handle_t *)param; + + assert(uartPrivateHandle->handle); + + /* Avoid the warning for unused variables. */ + handle = handle; + tcds = tcds; + + if (transferDone) + { + /* Disable transfer. */ + FLEXIO_UART_TransferAbortReceiveEDMA(uartPrivateHandle->base, uartPrivateHandle->handle); + + if (uartPrivateHandle->handle->callback) + { + uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle, + kStatus_FLEXIO_UART_RxIdle, uartPrivateHandle->handle->userData); + } + } +} + +status_t FLEXIO_UART_TransferCreateHandleEDMA(FLEXIO_UART_Type *base, + flexio_uart_edma_handle_t *handle, + flexio_uart_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txEdmaHandle, + edma_handle_t *rxEdmaHandle) +{ + assert(handle); + + uint8_t index = 0; + + /* Find the an empty handle pointer to store the handle. */ + for (index = 0; index < FLEXIO_UART_HANDLE_COUNT; index++) + { + if (s_edmaPrivateHandle[index].base == NULL) + { + s_edmaPrivateHandle[index].base = base; + s_edmaPrivateHandle[index].handle = handle; + break; + } + } + + if (index == FLEXIO_UART_HANDLE_COUNT) + { + return kStatus_OutOfRange; + } + + memset(handle, 0, sizeof(*handle)); + + handle->rxState = kFLEXIO_UART_RxIdle; + handle->txState = kFLEXIO_UART_TxIdle; + + handle->rxEdmaHandle = rxEdmaHandle; + handle->txEdmaHandle = txEdmaHandle; + + handle->callback = callback; + handle->userData = userData; + + /* Configure TX. */ + if (txEdmaHandle) + { + EDMA_SetCallback(handle->txEdmaHandle, FLEXIO_UART_TransferSendEDMACallback, &s_edmaPrivateHandle); + } + + /* Configure RX. */ + if (rxEdmaHandle) + { + EDMA_SetCallback(handle->rxEdmaHandle, FLEXIO_UART_TransferReceiveEDMACallback, &s_edmaPrivateHandle); + } + + return kStatus_Success; +} + +status_t FLEXIO_UART_TransferSendEDMA(FLEXIO_UART_Type *base, + flexio_uart_edma_handle_t *handle, + flexio_uart_transfer_t *xfer) +{ + assert(handle->txEdmaHandle); + + edma_transfer_config_t xferConfig; + status_t status; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* If previous TX not finished. */ + if (kFLEXIO_UART_TxBusy == handle->txState) + { + status = kStatus_FLEXIO_UART_TxBusy; + } + else + { + handle->txState = kFLEXIO_UART_TxBusy; + handle->txDataSizeAll = xfer->dataSize; + + /* Prepare transfer. */ + EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), + (void *)FLEXIO_UART_GetTxDataRegisterAddress(base), sizeof(uint8_t), sizeof(uint8_t), + xfer->dataSize, kEDMA_MemoryToPeripheral); + + /* Store the initially configured eDMA minor byte transfer count into the FLEXIO UART handle */ + handle->nbytes = sizeof(uint8_t); + + /* Submit transfer. */ + EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig); + EDMA_StartTransfer(handle->txEdmaHandle); + + /* Enable UART TX EDMA. */ + FLEXIO_UART_EnableTxDMA(base, true); + + status = kStatus_Success; + } + + return status; +} + +status_t FLEXIO_UART_TransferReceiveEDMA(FLEXIO_UART_Type *base, + flexio_uart_edma_handle_t *handle, + flexio_uart_transfer_t *xfer) +{ + assert(handle->rxEdmaHandle); + + edma_transfer_config_t xferConfig; + status_t status; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* If previous RX not finished. */ + if (kFLEXIO_UART_RxBusy == handle->rxState) + { + status = kStatus_FLEXIO_UART_RxBusy; + } + else + { + handle->rxState = kFLEXIO_UART_RxBusy; + handle->rxDataSizeAll = xfer->dataSize; + + /* Prepare transfer. */ + EDMA_PrepareTransfer(&xferConfig, (void *)FLEXIO_UART_GetRxDataRegisterAddress(base), sizeof(uint8_t), + xfer->data, sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory); + + /* Store the initially configured eDMA minor byte transfer count into the FLEXIO UART handle */ + handle->nbytes = sizeof(uint8_t); + + /* Submit transfer. */ + EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig); + EDMA_StartTransfer(handle->rxEdmaHandle); + + /* Enable UART RX EDMA. */ + FLEXIO_UART_EnableRxDMA(base, true); + + status = kStatus_Success; + } + + return status; +} + +void FLEXIO_UART_TransferAbortSendEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle) +{ + assert(handle->txEdmaHandle); + + /* Disable UART TX EDMA. */ + FLEXIO_UART_EnableTxDMA(base, false); + + /* Stop transfer. */ + EDMA_StopTransfer(handle->txEdmaHandle); + + handle->txState = kFLEXIO_UART_TxIdle; +} + +void FLEXIO_UART_TransferAbortReceiveEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle) +{ + assert(handle->rxEdmaHandle); + + /* Disable UART RX EDMA. */ + FLEXIO_UART_EnableRxDMA(base, false); + + /* Stop transfer. */ + EDMA_StopTransfer(handle->rxEdmaHandle); + + handle->rxState = kFLEXIO_UART_RxIdle; +} + +status_t FLEXIO_UART_TransferGetReceiveCountEDMA(FLEXIO_UART_Type *base, + flexio_uart_edma_handle_t *handle, + size_t *count) +{ + assert(handle); + assert(handle->rxEdmaHandle); + assert(count); + + if (kFLEXIO_UART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->rxDataSizeAll - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel); + + return kStatus_Success; +} + +status_t FLEXIO_UART_TransferGetSendCountEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle, size_t *count) +{ + assert(handle); + assert(handle->txEdmaHandle); + assert(count); + + if (kFLEXIO_UART_TxIdle == handle->txState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->txDataSizeAll - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel); + + return kStatus_Success; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart_edma.h new file mode 100644 index 00000000000..817392f3a01 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_flexio_uart_edma.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_UART_EDMA_H_ +#define _FSL_FLEXIO_UART_EDMA_H_ + +#include "fsl_flexio_uart.h" +#include "fsl_dmamux.h" +#include "fsl_edma.h" + +/*! + * @addtogroup flexio_edma_uart + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Forward declaration of the handle typedef. */ +typedef struct _flexio_uart_edma_handle flexio_uart_edma_handle_t; + +/*! @brief UART transfer callback function. */ +typedef void (*flexio_uart_edma_transfer_callback_t)(FLEXIO_UART_Type *base, + flexio_uart_edma_handle_t *handle, + status_t status, + void *userData); + +/*! +* @brief UART eDMA handle +*/ +struct _flexio_uart_edma_handle +{ + flexio_uart_edma_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< UART callback function parameter.*/ + + size_t txDataSizeAll; /*!< Total bytes to be sent. */ + size_t rxDataSizeAll; /*!< Total bytes to be received. */ + + edma_handle_t *txEdmaHandle; /*!< The eDMA TX channel used. */ + edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */ + + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name eDMA transactional + * @{ + */ + +/*! + * @brief Initializes the UART handle which is used in transactional functions. + * + * @param base Pointer to FLEXIO_UART_Type. + * @param handle Pointer to flexio_uart_edma_handle_t structure. + * @param callback The callback function. + * @param userData The parameter of the callback function. + * @param rxEdmaHandle User requested DMA handle for RX DMA transfer. + * @param txEdmaHandle User requested DMA handle for TX DMA transfer. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO SPI eDMA type/handle table out of range. + */ +status_t FLEXIO_UART_TransferCreateHandleEDMA(FLEXIO_UART_Type *base, + flexio_uart_edma_handle_t *handle, + flexio_uart_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txEdmaHandle, + edma_handle_t *rxEdmaHandle); + +/*! + * @brief Sends data using eDMA. + * + * This function sends data using eDMA. This is a non-blocking function, which returns + * right away. When all data is sent out, the send callback function is called. + * + * @param base Pointer to FLEXIO_UART_Type + * @param handle UART handle pointer. + * @param xfer UART eDMA transfer structure, see #flexio_uart_transfer_t. + * @retval kStatus_Success if succeed, others failed. + * @retval kStatus_FLEXIO_UART_TxBusy Previous transfer on going. + */ +status_t FLEXIO_UART_TransferSendEDMA(FLEXIO_UART_Type *base, + flexio_uart_edma_handle_t *handle, + flexio_uart_transfer_t *xfer); + +/*! + * @brief Receives data using eDMA. + * + * This function receives data using eDMA. This is a non-blocking function, which returns + * right away. When all data is received, the receive callback function is called. + * + * @param base Pointer to FLEXIO_UART_Type + * @param handle Pointer to flexio_uart_edma_handle_t structure + * @param xfer UART eDMA transfer structure, see #flexio_uart_transfer_t. + * @retval kStatus_Success if succeed, others failed. + * @retval kStatus_UART_RxBusy Previous transfer on going. + */ +status_t FLEXIO_UART_TransferReceiveEDMA(FLEXIO_UART_Type *base, + flexio_uart_edma_handle_t *handle, + flexio_uart_transfer_t *xfer); + +/*! + * @brief Aborts the sent data which using eDMA. + * + * This function aborts sent data which using eDMA. + * + * @param base Pointer to FLEXIO_UART_Type + * @param handle Pointer to flexio_uart_edma_handle_t structure + */ +void FLEXIO_UART_TransferAbortSendEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle); + +/*! + * @brief Aborts the receive data which using eDMA. + * + * This function aborts the receive data which using eDMA. + * + * @param base Pointer to FLEXIO_UART_Type + * @param handle Pointer to flexio_uart_edma_handle_t structure + */ +void FLEXIO_UART_TransferAbortReceiveEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle); + +/*! + * @brief Gets the number of bytes sent out. + * + * This function gets the number of bytes sent out. + * + * @param base Pointer to FLEXIO_UART_Type + * @param handle Pointer to flexio_uart_edma_handle_t structure + * @param count Number of bytes sent so far by the non-blocking transaction. + * @retval kStatus_NoTransferInProgress transfer has finished or no transfer in progress. + * @retval kStatus_Success Successfully return the count. + */ +status_t FLEXIO_UART_TransferGetSendCountEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle, size_t *count); + +/*! + * @brief Gets the number of bytes received. + * + * This function gets the number of bytes received. + * + * @param base Pointer to FLEXIO_UART_Type + * @param handle Pointer to flexio_uart_edma_handle_t structure + * @param count Number of bytes received so far by the non-blocking transaction. + * @retval kStatus_NoTransferInProgress transfer has finished or no transfer in progress. + * @retval kStatus_Success Successfully return the count. + */ +status_t FLEXIO_UART_TransferGetReceiveCountEDMA(FLEXIO_UART_Type *base, + flexio_uart_edma_handle_t *handle, + size_t *count); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_UART_EDMA_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ftm.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ftm.c new file mode 100644 index 00000000000..6907dda5b52 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ftm.c @@ -0,0 +1,908 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_ftm.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address + * + * @param base FTM peripheral base address + * + * @return The FTM instance + */ +static uint32_t FTM_GetInstance(FTM_Type *base); + +/*! + * @brief Sets the FTM register PWM synchronization method + * + * This function will set the necessary bits for the PWM synchronization mode that + * user wishes to use. + * + * @param base FTM peripheral base address + * @param syncMethod Syncronization methods to use to update buffered registers. This is a logical + * OR of members of the enumeration ::ftm_pwm_sync_method_t + */ +static void FTM_SetPwmSync(FTM_Type *base, uint32_t syncMethod); + +/*! + * @brief Sets the reload points used as loading points for register update + * + * This function will set the necessary bits based on what the user wishes to use as loading + * points for FTM register update. When using this it is not required to use PWM synchnronization. + * + * @param base FTM peripheral base address + * @param reloadPoints FTM reload points. This is a logical OR of members of the + * enumeration ::ftm_reload_point_t + */ +static void FTM_SetReloadPoints(FTM_Type *base, uint32_t reloadPoints); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to FTM bases for each instance. */ +static FTM_Type *const s_ftmBases[] = FTM_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to FTM clocks for each instance. */ +static const clock_ip_name_t s_ftmClocks[] = FTM_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t FTM_GetInstance(FTM_Type *base) +{ + uint32_t instance; + uint32_t ftmArrayCount = (sizeof(s_ftmBases) / sizeof(s_ftmBases[0])); + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ftmArrayCount; instance++) + { + if (s_ftmBases[instance] == base) + { + break; + } + } + + assert(instance < ftmArrayCount); + + return instance; +} + +static void FTM_SetPwmSync(FTM_Type *base, uint32_t syncMethod) +{ + uint8_t chnlNumber = 0; + uint32_t reg = 0, syncReg = 0; + + syncReg = base->SYNC; + /* Enable PWM synchronization of output mask register */ + syncReg |= FTM_SYNC_SYNCHOM_MASK; + + reg = base->COMBINE; + for (chnlNumber = 0; chnlNumber < (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2); chnlNumber++) + { + /* Enable PWM synchronization of registers C(n)V and C(n+1)V */ + reg |= (1U << (FTM_COMBINE_SYNCEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlNumber))); + } + base->COMBINE = reg; + + reg = base->SYNCONF; + + /* Use enhanced PWM synchronization method. Use PWM sync to update register values */ + reg |= (FTM_SYNCONF_SYNCMODE_MASK | FTM_SYNCONF_CNTINC_MASK | FTM_SYNCONF_INVC_MASK | FTM_SYNCONF_SWOC_MASK); + + if (syncMethod & FTM_SYNC_SWSYNC_MASK) + { + /* Enable needed bits for software trigger to update registers with its buffer value */ + reg |= (FTM_SYNCONF_SWRSTCNT_MASK | FTM_SYNCONF_SWWRBUF_MASK | FTM_SYNCONF_SWINVC_MASK | + FTM_SYNCONF_SWSOC_MASK | FTM_SYNCONF_SWOM_MASK); + } + + if (syncMethod & (FTM_SYNC_TRIG0_MASK | FTM_SYNC_TRIG1_MASK | FTM_SYNC_TRIG2_MASK)) + { + /* Enable needed bits for hardware trigger to update registers with its buffer value */ + reg |= (FTM_SYNCONF_HWRSTCNT_MASK | FTM_SYNCONF_HWWRBUF_MASK | FTM_SYNCONF_HWINVC_MASK | + FTM_SYNCONF_HWSOC_MASK | FTM_SYNCONF_HWOM_MASK); + + /* Enable the appropriate hardware trigger that is used for PWM sync */ + if (syncMethod & FTM_SYNC_TRIG0_MASK) + { + syncReg |= FTM_SYNC_TRIG0_MASK; + } + if (syncMethod & FTM_SYNC_TRIG1_MASK) + { + syncReg |= FTM_SYNC_TRIG1_MASK; + } + if (syncMethod & FTM_SYNC_TRIG2_MASK) + { + syncReg |= FTM_SYNC_TRIG2_MASK; + } + } + + /* Write back values to the SYNC register */ + base->SYNC = syncReg; + + /* Write the PWM synch values to the SYNCONF register */ + base->SYNCONF = reg; +} + +static void FTM_SetReloadPoints(FTM_Type *base, uint32_t reloadPoints) +{ + uint32_t chnlNumber = 0; + uint32_t reg = 0; + + /* Need CNTINC bit to be 1 for CNTIN register to update with its buffer value on reload */ + base->SYNCONF |= FTM_SYNCONF_CNTINC_MASK; + + reg = base->COMBINE; + for (chnlNumber = 0; chnlNumber < (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2); chnlNumber++) + { + /* Need SYNCEN bit to be 1 for CnV reg to update with its buffer value on reload */ + reg |= (1U << (FTM_COMBINE_SYNCEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlNumber))); + } + base->COMBINE = reg; + + /* Set the reload points */ + reg = base->PWMLOAD; + + /* Enable the selected channel match reload points */ + reg &= ~((1U << FSL_FEATURE_FTM_CHANNEL_COUNTn(base)) - 1); + reg |= (reloadPoints & ((1U << FSL_FEATURE_FTM_CHANNEL_COUNTn(base)) - 1)); + +#if defined(FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD) && (FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD) + /* Enable half cycle match as a reload point */ + if (reloadPoints & kFTM_HalfCycMatch) + { + reg |= FTM_PWMLOAD_HCSEL_MASK; + } + else + { + reg &= ~FTM_PWMLOAD_HCSEL_MASK; + } +#endif /* FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD */ + + base->PWMLOAD = reg; + + /* These reload points are used when counter is in up-down counting mode */ + reg = base->SYNC; + if (reloadPoints & kFTM_CntMax) + { + /* Reload when counter turns from up to down */ + reg |= FTM_SYNC_CNTMAX_MASK; + } + else + { + reg &= ~FTM_SYNC_CNTMAX_MASK; + } + + if (reloadPoints & kFTM_CntMin) + { + /* Reload when counter turns from down to up */ + reg |= FTM_SYNC_CNTMIN_MASK; + } + else + { + reg &= ~FTM_SYNC_CNTMIN_MASK; + } + base->SYNC = reg; +} + +status_t FTM_Init(FTM_Type *base, const ftm_config_t *config) +{ + assert(config); + + uint32_t reg; + + if (!(config->pwmSyncMode & + (FTM_SYNC_TRIG0_MASK | FTM_SYNC_TRIG1_MASK | FTM_SYNC_TRIG2_MASK | FTM_SYNC_SWSYNC_MASK))) + { + /* Invalid PWM sync mode */ + return kStatus_Fail; + } + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate the FTM clock*/ + CLOCK_EnableClock(s_ftmClocks[FTM_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Configure the fault mode, enable FTM mode and disable write protection */ + base->MODE = FTM_MODE_FAULTM(config->faultMode) | FTM_MODE_FTMEN_MASK | FTM_MODE_WPDIS_MASK; + + /* Configure the update mechanism for buffered registers */ + FTM_SetPwmSync(base, config->pwmSyncMode); + + /* Setup intermediate register reload points */ + FTM_SetReloadPoints(base, config->reloadPoints); + + /* Set the clock prescale factor */ + base->SC = FTM_SC_PS(config->prescale); + + /* Setup the counter operation */ + base->CONF = (FTM_CONF_BDMMODE(config->bdmMode) | FTM_CONF_GTBEEN(config->useGlobalTimeBase)); + + /* Initial state of channel output */ + base->OUTINIT = config->chnlInitState; + + /* Channel polarity */ + base->POL = config->chnlPolarity; + + /* Set the external trigger sources */ + base->EXTTRIG = config->extTriggers; +#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER) && (FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER) + if (config->extTriggers & kFTM_ReloadInitTrigger) + { + base->CONF |= FTM_CONF_ITRIGR_MASK; + } + else + { + base->CONF &= ~FTM_CONF_ITRIGR_MASK; + } +#endif /* FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER */ + + /* FTM deadtime insertion control */ + base->DEADTIME = (0u | +#if defined(FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE) && (FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE) + /* Has extended deadtime value register) */ + FTM_DEADTIME_DTVALEX(config->deadTimeValue >> 6) | +#endif /* FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE */ + FTM_DEADTIME_DTPS(config->deadTimePrescale) | + FTM_DEADTIME_DTVAL(config->deadTimeValue)); + + /* FTM fault filter value */ + reg = base->FLTCTRL; + reg &= ~FTM_FLTCTRL_FFVAL_MASK; + reg |= FTM_FLTCTRL_FFVAL(config->faultFilterValue); + base->FLTCTRL = reg; + + return kStatus_Success; +} + +void FTM_Deinit(FTM_Type *base) +{ + /* Set clock source to none to disable counter */ + base->SC &= ~(FTM_SC_CLKS_MASK); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate the FTM clock */ + CLOCK_DisableClock(s_ftmClocks[FTM_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void FTM_GetDefaultConfig(ftm_config_t *config) +{ + assert(config); + + /* Divide FTM clock by 1 */ + config->prescale = kFTM_Prescale_Divide_1; + /* FTM behavior in BDM mode */ + config->bdmMode = kFTM_BdmMode_0; + /* Software trigger will be used to update registers */ + config->pwmSyncMode = kFTM_SoftwareTrigger; + /* No intermediate register load */ + config->reloadPoints = 0; + /* Fault control disabled for all channels */ + config->faultMode = kFTM_Fault_Disable; + /* Disable the fault filter */ + config->faultFilterValue = 0; + /* Divide the system clock by 1 */ + config->deadTimePrescale = kFTM_Deadtime_Prescale_1; + /* No counts are inserted */ + config->deadTimeValue = 0; + /* No external trigger */ + config->extTriggers = 0; + /* Initialization value is 0 for all channels */ + config->chnlInitState = 0; + /* Active high polarity for all channels */ + config->chnlPolarity = 0; + /* Use internal FTM counter as timebase */ + config->useGlobalTimeBase = false; +} + +status_t FTM_SetupPwm(FTM_Type *base, + const ftm_chnl_pwm_signal_param_t *chnlParams, + uint8_t numOfChnls, + ftm_pwm_mode_t mode, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz) +{ + assert(chnlParams); + assert(srcClock_Hz); + assert(pwmFreq_Hz); + assert(numOfChnls); + + uint32_t mod, reg; + uint32_t ftmClock = (srcClock_Hz / (1U << (base->SC & FTM_SC_PS_MASK))); + uint16_t cnv, cnvFirstEdge; + uint8_t i; + + switch (mode) + { + case kFTM_EdgeAlignedPwm: + case kFTM_CombinedPwm: + base->SC &= ~FTM_SC_CPWMS_MASK; + mod = (ftmClock / pwmFreq_Hz) - 1; + break; + case kFTM_CenterAlignedPwm: + base->SC |= FTM_SC_CPWMS_MASK; + mod = ftmClock / (pwmFreq_Hz * 2); + break; + default: + return kStatus_Fail; + } + + /* Return an error in case we overflow the registers, probably would require changing + * clock source to get the desired frequency */ + if (mod > 65535U) + { + return kStatus_Fail; + } + /* Set the PWM period */ + base->MOD = mod; + + /* Setup each FTM channel */ + for (i = 0; i < numOfChnls; i++) + { + /* Return error if requested dutycycle is greater than the max allowed */ + if (chnlParams->dutyCyclePercent > 100) + { + return kStatus_Fail; + } + + if ((mode == kFTM_EdgeAlignedPwm) || (mode == kFTM_CenterAlignedPwm)) + { + /* Clear the current mode and edge level bits */ + reg = base->CONTROLS[chnlParams->chnlNumber].CnSC; + reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK); + + /* Setup the active level */ + reg |= (uint32_t)(chnlParams->level << FTM_CnSC_ELSA_SHIFT); + + /* Edge-aligned mode needs MSB to be 1, don't care for Center-aligned mode */ + reg |= FTM_CnSC_MSB(1U); + + /* Update the mode and edge level */ + base->CONTROLS[chnlParams->chnlNumber].CnSC = reg; + + if (chnlParams->dutyCyclePercent == 0) + { + /* Signal stays low */ + cnv = 0; + } + else + { + cnv = (mod * chnlParams->dutyCyclePercent) / 100; + /* For 100% duty cycle */ + if (cnv >= mod) + { + cnv = mod + 1; + } + } + + base->CONTROLS[chnlParams->chnlNumber].CnV = cnv; +#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) + /* Set to output mode */ + FTM_SetPwmOutputEnable(base, chnlParams->chnlNumber, true); +#endif + } + else + { + /* This check is added for combined mode as the channel number should be the pair number */ + if (chnlParams->chnlNumber >= (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2)) + { + return kStatus_Fail; + } + + /* Return error if requested value is greater than the max allowed */ + if (chnlParams->firstEdgeDelayPercent > 100) + { + return kStatus_Fail; + } + + /* Configure delay of the first edge */ + if (chnlParams->firstEdgeDelayPercent == 0) + { + /* No delay for the first edge */ + cnvFirstEdge = 0; + } + else + { + cnvFirstEdge = (mod * chnlParams->firstEdgeDelayPercent) / 100; + } + + /* Configure dutycycle */ + if (chnlParams->dutyCyclePercent == 0) + { + /* Signal stays low */ + cnv = 0; + cnvFirstEdge = 0; + } + else + { + cnv = (mod * chnlParams->dutyCyclePercent) / 100; + /* For 100% duty cycle */ + if (cnv >= mod) + { + cnv = mod + 1; + } + } + + /* Clear the current mode and edge level bits for channel n */ + reg = base->CONTROLS[chnlParams->chnlNumber * 2].CnSC; + reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK); + + /* Setup the active level for channel n */ + reg |= (uint32_t)(chnlParams->level << FTM_CnSC_ELSA_SHIFT); + + /* Update the mode and edge level for channel n */ + base->CONTROLS[chnlParams->chnlNumber * 2].CnSC = reg; + + /* Clear the current mode and edge level bits for channel n + 1 */ + reg = base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC; + reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK); + + /* Setup the active level for channel n + 1 */ + reg |= (uint32_t)(chnlParams->level << FTM_CnSC_ELSA_SHIFT); + + /* Update the mode and edge level for channel n + 1*/ + base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC = reg; + + /* Set the combine bit for the channel pair */ + base->COMBINE |= + (1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlParams->chnlNumber))); + + /* Set the channel pair values */ + base->CONTROLS[chnlParams->chnlNumber * 2].CnV = cnvFirstEdge; + base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv; + +#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) + /* Set to output mode */ + FTM_SetPwmOutputEnable(base, (ftm_chnl_t)((uint8_t)chnlParams->chnlNumber * 2), true); + FTM_SetPwmOutputEnable(base, (ftm_chnl_t)((uint8_t)chnlParams->chnlNumber * 2 + 1), true); +#endif + } + chnlParams++; + } + + return kStatus_Success; +} + +void FTM_UpdatePwmDutycycle(FTM_Type *base, + ftm_chnl_t chnlNumber, + ftm_pwm_mode_t currentPwmMode, + uint8_t dutyCyclePercent) +{ + uint16_t cnv, cnvFirstEdge = 0, mod; + + mod = base->MOD; + if ((currentPwmMode == kFTM_EdgeAlignedPwm) || (currentPwmMode == kFTM_CenterAlignedPwm)) + { + cnv = (mod * dutyCyclePercent) / 100; + /* For 100% duty cycle */ + if (cnv >= mod) + { + cnv = mod + 1; + } + base->CONTROLS[chnlNumber].CnV = cnv; + } + else + { + /* This check is added for combined mode as the channel number should be the pair number */ + if (chnlNumber >= (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2)) + { + return; + } + + cnv = (mod * dutyCyclePercent) / 100; + cnvFirstEdge = base->CONTROLS[chnlNumber * 2].CnV; + /* For 100% duty cycle */ + if (cnv >= mod) + { + cnv = mod + 1; + } + base->CONTROLS[(chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv; + } +} + +void FTM_UpdateChnlEdgeLevelSelect(FTM_Type *base, ftm_chnl_t chnlNumber, uint8_t level) +{ + uint32_t reg = base->CONTROLS[chnlNumber].CnSC; + + /* Clear the field and write the new level value */ + reg &= ~(FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK); + reg |= ((uint32_t)level << FTM_CnSC_ELSA_SHIFT) & (FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK); + + base->CONTROLS[chnlNumber].CnSC = reg; +} + +void FTM_SetupInputCapture(FTM_Type *base, + ftm_chnl_t chnlNumber, + ftm_input_capture_edge_t captureMode, + uint32_t filterValue) +{ + uint32_t reg; + + /* Clear the combine bit for the channel pair */ + base->COMBINE &= ~(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1)))); + /* Clear the dual edge capture mode because it's it's higher priority */ + base->COMBINE &= ~(1U << (FTM_COMBINE_DECAPEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1)))); + /* Clear the quadrature decoder mode beacause it's higher priority */ + base->QDCTRL &= ~FTM_QDCTRL_QUADEN_MASK; + + reg = base->CONTROLS[chnlNumber].CnSC; + reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK); + reg |= captureMode; + + /* Set the requested input capture mode */ + base->CONTROLS[chnlNumber].CnSC = reg; + /* Input filter available only for channels 0, 1, 2, 3 */ + if (chnlNumber < kFTM_Chnl_4) + { + reg = base->FILTER; + reg &= ~(FTM_FILTER_CH0FVAL_MASK << (FTM_FILTER_CH1FVAL_SHIFT * chnlNumber)); + reg |= (filterValue << (FTM_FILTER_CH1FVAL_SHIFT * chnlNumber)); + base->FILTER = reg; + } +#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) + /* Set to input mode */ + FTM_SetPwmOutputEnable(base, chnlNumber, false); +#endif +} + +void FTM_SetupOutputCompare(FTM_Type *base, + ftm_chnl_t chnlNumber, + ftm_output_compare_mode_t compareMode, + uint32_t compareValue) +{ + uint32_t reg; + + /* Clear the combine bit for the channel pair */ + base->COMBINE &= ~(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1)))); + /* Clear the dual edge capture mode because it's it's higher priority */ + base->COMBINE &= ~(1U << (FTM_COMBINE_DECAPEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1)))); + /* Clear the quadrature decoder mode beacause it's higher priority */ + base->QDCTRL &= ~FTM_QDCTRL_QUADEN_MASK; + + reg = base->CONTROLS[chnlNumber].CnSC; + reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK); + reg |= compareMode; + /* Setup the channel output behaviour when a match occurs with the compare value */ + base->CONTROLS[chnlNumber].CnSC = reg; + + /* Set output on match to the requested level */ + base->CONTROLS[chnlNumber].CnV = compareValue; + +#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) + /* Set to output mode */ + FTM_SetPwmOutputEnable(base, chnlNumber, true); +#endif +} + +void FTM_SetupDualEdgeCapture(FTM_Type *base, + ftm_chnl_t chnlPairNumber, + const ftm_dual_edge_capture_param_t *edgeParam, + uint32_t filterValue) +{ + assert(edgeParam); + + uint32_t reg; + + reg = base->COMBINE; + /* Clear the combine bit for the channel pair */ + reg &= ~(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber))); + /* Enable the DECAPEN bit */ + reg |= (1U << (FTM_COMBINE_DECAPEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber))); + reg |= (1U << (FTM_COMBINE_DECAP0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber))); + base->COMBINE = reg; + + /* Setup the edge detection from channel n and n + 1 */ + reg = base->CONTROLS[chnlPairNumber * 2].CnSC; + reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK); + reg |= ((uint32_t)edgeParam->mode | (uint32_t)edgeParam->currChanEdgeMode); + base->CONTROLS[chnlPairNumber * 2].CnSC = reg; + + reg = base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC; + reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK); + reg |= ((uint32_t)edgeParam->mode | (uint32_t)edgeParam->nextChanEdgeMode); + base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC = reg; + + /* Input filter available only for channels 0, 1, 2, 3 */ + if (chnlPairNumber < kFTM_Chnl_4) + { + reg = base->FILTER; + reg &= ~(FTM_FILTER_CH0FVAL_MASK << (FTM_FILTER_CH1FVAL_SHIFT * chnlPairNumber)); + reg |= (filterValue << (FTM_FILTER_CH1FVAL_SHIFT * chnlPairNumber)); + base->FILTER = reg; + } + +#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) + /* Set to input mode */ + FTM_SetPwmOutputEnable(base, chnlPairNumber, false); +#endif +} + +void FTM_SetupQuadDecode(FTM_Type *base, + const ftm_phase_params_t *phaseAParams, + const ftm_phase_params_t *phaseBParams, + ftm_quad_decode_mode_t quadMode) +{ + assert(phaseAParams); + assert(phaseBParams); + + uint32_t reg; + + /* Set Phase A filter value if phase filter is enabled */ + if (phaseAParams->enablePhaseFilter) + { + reg = base->FILTER; + reg &= ~(FTM_FILTER_CH0FVAL_MASK); + reg |= FTM_FILTER_CH0FVAL(phaseAParams->phaseFilterVal); + base->FILTER = reg; + } + + /* Set Phase B filter value if phase filter is enabled */ + if (phaseBParams->enablePhaseFilter) + { + reg = base->FILTER; + reg &= ~(FTM_FILTER_CH1FVAL_MASK); + reg |= FTM_FILTER_CH1FVAL(phaseBParams->phaseFilterVal); + base->FILTER = reg; + } + + /* Set Quadrature decode properties */ + reg = base->QDCTRL; + reg &= ~(FTM_QDCTRL_QUADMODE_MASK | FTM_QDCTRL_PHAFLTREN_MASK | FTM_QDCTRL_PHBFLTREN_MASK | FTM_QDCTRL_PHAPOL_MASK | + FTM_QDCTRL_PHBPOL_MASK); + reg |= (FTM_QDCTRL_QUADMODE(quadMode) | FTM_QDCTRL_PHAFLTREN(phaseAParams->enablePhaseFilter) | + FTM_QDCTRL_PHBFLTREN(phaseBParams->enablePhaseFilter) | FTM_QDCTRL_PHAPOL(phaseAParams->phasePolarity) | + FTM_QDCTRL_PHBPOL(phaseBParams->phasePolarity)); + base->QDCTRL = reg; + /* Enable Quad decode */ + base->QDCTRL |= FTM_QDCTRL_QUADEN_MASK; +} + +void FTM_SetupFault(FTM_Type *base, ftm_fault_input_t faultNumber, const ftm_fault_param_t *faultParams) +{ + assert(faultParams); + + uint32_t reg; + + reg = base->FLTCTRL; + if (faultParams->enableFaultInput) + { + /* Enable the fault input */ + reg |= (FTM_FLTCTRL_FAULT0EN_MASK << faultNumber); + } + else + { + /* Disable the fault input */ + reg &= ~(FTM_FLTCTRL_FAULT0EN_MASK << faultNumber); + } + + if (faultParams->useFaultFilter) + { + /* Enable the fault filter */ + reg |= (FTM_FLTCTRL_FFLTR0EN_MASK << (FTM_FLTCTRL_FFLTR0EN_SHIFT + faultNumber)); + } + else + { + /* Disable the fault filter */ + reg &= ~(FTM_FLTCTRL_FFLTR0EN_MASK << (FTM_FLTCTRL_FFLTR0EN_SHIFT + faultNumber)); + } + base->FLTCTRL = reg; + + if (faultParams->faultLevel) + { + /* Active low polarity for the fault input pin */ + base->FLTPOL |= (1U << faultNumber); + } + else + { + /* Active high polarity for the fault input pin */ + base->FLTPOL &= ~(1U << faultNumber); + } +} + +void FTM_EnableInterrupts(FTM_Type *base, uint32_t mask) +{ + uint32_t chnlInts = (mask & 0xFFU); + uint8_t chnlNumber = 0; + + /* Enable the timer overflow interrupt */ + if (mask & kFTM_TimeOverflowInterruptEnable) + { + base->SC |= FTM_SC_TOIE_MASK; + } + + /* Enable the fault interrupt */ + if (mask & kFTM_FaultInterruptEnable) + { + base->MODE |= FTM_MODE_FAULTIE_MASK; + } + +#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) + /* Enable the reload interrupt available only on certain SoC's */ + if (mask & kFTM_ReloadInterruptEnable) + { + base->SC |= FTM_SC_RIE_MASK; + } +#endif + + /* Enable the channel interrupts */ + while (chnlInts) + { + if (chnlInts & 0x1) + { + base->CONTROLS[chnlNumber].CnSC |= FTM_CnSC_CHIE_MASK; + } + chnlNumber++; + chnlInts = chnlInts >> 1U; + } +} + +void FTM_DisableInterrupts(FTM_Type *base, uint32_t mask) +{ + uint32_t chnlInts = (mask & 0xFF); + uint8_t chnlNumber = 0; + + /* Disable the timer overflow interrupt */ + if (mask & kFTM_TimeOverflowInterruptEnable) + { + base->SC &= ~FTM_SC_TOIE_MASK; + } + /* Disable the fault interrupt */ + if (mask & kFTM_FaultInterruptEnable) + { + base->MODE &= ~FTM_MODE_FAULTIE_MASK; + } + +#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) + /* Disable the reload interrupt available only on certain SoC's */ + if (mask & kFTM_ReloadInterruptEnable) + { + base->SC &= ~FTM_SC_RIE_MASK; + } +#endif + + /* Disable the channel interrupts */ + while (chnlInts) + { + if (chnlInts & 0x1) + { + base->CONTROLS[chnlNumber].CnSC &= ~FTM_CnSC_CHIE_MASK; + } + chnlNumber++; + chnlInts = chnlInts >> 1U; + } +} + +uint32_t FTM_GetEnabledInterrupts(FTM_Type *base) +{ + uint32_t enabledInterrupts = 0; + int8_t chnlCount = FSL_FEATURE_FTM_CHANNEL_COUNTn(base); + + /* The CHANNEL_COUNT macro returns -1 if it cannot match the FTM instance */ + assert(chnlCount != -1); + + /* Check if timer overflow interrupt is enabled */ + if (base->SC & FTM_SC_TOIE_MASK) + { + enabledInterrupts |= kFTM_TimeOverflowInterruptEnable; + } + /* Check if fault interrupt is enabled */ + if (base->MODE & FTM_MODE_FAULTIE_MASK) + { + enabledInterrupts |= kFTM_FaultInterruptEnable; + } + +#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) + /* Check if the reload interrupt is enabled */ + if (base->SC & FTM_SC_RIE_MASK) + { + enabledInterrupts |= kFTM_ReloadInterruptEnable; + } +#endif + + /* Check if the channel interrupts are enabled */ + while (chnlCount > 0) + { + chnlCount--; + if (base->CONTROLS[chnlCount].CnSC & FTM_CnSC_CHIE_MASK) + { + enabledInterrupts |= (1U << chnlCount); + } + } + + return enabledInterrupts; +} + +uint32_t FTM_GetStatusFlags(FTM_Type *base) +{ + uint32_t statusFlags = 0; + + /* Check the timer flag */ + if (base->SC & FTM_SC_TOF_MASK) + { + statusFlags |= kFTM_TimeOverflowFlag; + } + /* Check fault flag */ + if (base->FMS & FTM_FMS_FAULTF_MASK) + { + statusFlags |= kFTM_FaultFlag; + } + /* Check channel trigger flag */ + if (base->EXTTRIG & FTM_EXTTRIG_TRIGF_MASK) + { + statusFlags |= kFTM_ChnlTriggerFlag; + } +#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) + /* Check reload flag */ + if (base->SC & FTM_SC_RF_MASK) + { + statusFlags |= kFTM_ReloadFlag; + } +#endif + + /* Lower 8 bits contain the channel status flags */ + statusFlags |= (base->STATUS & 0xFFU); + + return statusFlags; +} + +void FTM_ClearStatusFlags(FTM_Type *base, uint32_t mask) +{ + /* Clear the timer overflow flag by writing a 0 to the bit while it is set */ + if (mask & kFTM_TimeOverflowFlag) + { + base->SC &= ~FTM_SC_TOF_MASK; + } + /* Clear fault flag by writing a 0 to the bit while it is set */ + if (mask & kFTM_FaultFlag) + { + base->FMS &= ~FTM_FMS_FAULTF_MASK; + } + /* Clear channel trigger flag */ + if (mask & kFTM_ChnlTriggerFlag) + { + base->EXTTRIG &= ~FTM_EXTTRIG_TRIGF_MASK; + } + +#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) + /* Check reload flag by writing a 0 to the bit while it is set */ + if (mask & kFTM_ReloadFlag) + { + base->SC &= ~FTM_SC_RF_MASK; + } +#endif + /* Clear the channel status flags by writing a 0 to the bit */ + base->STATUS &= ~(mask & 0xFFU); +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ftm.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ftm.h new file mode 100644 index 00000000000..6fcc8e395ca --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ftm.h @@ -0,0 +1,931 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FTM_H_ +#define _FSL_FTM_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup ftm + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_FTM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2 */ + /*@}*/ + +/*! + * @brief List of FTM channels + * @note Actual number of available channels is SoC dependent + */ +typedef enum _ftm_chnl +{ + kFTM_Chnl_0 = 0U, /*!< FTM channel number 0*/ + kFTM_Chnl_1, /*!< FTM channel number 1 */ + kFTM_Chnl_2, /*!< FTM channel number 2 */ + kFTM_Chnl_3, /*!< FTM channel number 3 */ + kFTM_Chnl_4, /*!< FTM channel number 4 */ + kFTM_Chnl_5, /*!< FTM channel number 5 */ + kFTM_Chnl_6, /*!< FTM channel number 6 */ + kFTM_Chnl_7 /*!< FTM channel number 7 */ +} ftm_chnl_t; + +/*! @brief List of FTM faults */ +typedef enum _ftm_fault_input +{ + kFTM_Fault_0 = 0U, /*!< FTM fault 0 input pin */ + kFTM_Fault_1, /*!< FTM fault 1 input pin */ + kFTM_Fault_2, /*!< FTM fault 2 input pin */ + kFTM_Fault_3 /*!< FTM fault 3 input pin */ +} ftm_fault_input_t; + +/*! @brief FTM PWM operation modes */ +typedef enum _ftm_pwm_mode +{ + kFTM_EdgeAlignedPwm = 0U, /*!< Edge-aligned PWM */ + kFTM_CenterAlignedPwm, /*!< Center-aligned PWM */ + kFTM_CombinedPwm /*!< Combined PWM */ +} ftm_pwm_mode_t; + +/*! @brief FTM PWM output pulse mode: high-true, low-true or no output */ +typedef enum _ftm_pwm_level_select +{ + kFTM_NoPwmSignal = 0U, /*!< No PWM output on pin */ + kFTM_LowTrue, /*!< Low true pulses */ + kFTM_HighTrue /*!< High true pulses */ +} ftm_pwm_level_select_t; + +/*! @brief Options to configure a FTM channel's PWM signal */ +typedef struct _ftm_chnl_pwm_signal_param +{ + ftm_chnl_t chnlNumber; /*!< The channel/channel pair number. + In combined mode, this represents the channel pair number. */ + ftm_pwm_level_select_t level; /*!< PWM output active level select. */ + uint8_t dutyCyclePercent; /*!< PWM pulse width, value should be between 0 to 100 + 0 = inactive signal(0% duty cycle)... + 100 = always active signal (100% duty cycle).*/ + uint8_t firstEdgeDelayPercent; /*!< Used only in combined PWM mode to generate an asymmetrical PWM. + Specifies the delay to the first edge in a PWM period. + If unsure leave as 0; Should be specified as a + percentage of the PWM period */ +} ftm_chnl_pwm_signal_param_t; + +/*! @brief FlexTimer output compare mode */ +typedef enum _ftm_output_compare_mode +{ + kFTM_NoOutputSignal = (1U << FTM_CnSC_MSA_SHIFT), /*!< No channel output when counter reaches CnV */ + kFTM_ToggleOnMatch = ((1U << FTM_CnSC_MSA_SHIFT) | (1U << FTM_CnSC_ELSA_SHIFT)), /*!< Toggle output */ + kFTM_ClearOnMatch = ((1U << FTM_CnSC_MSA_SHIFT) | (2U << FTM_CnSC_ELSA_SHIFT)), /*!< Clear output */ + kFTM_SetOnMatch = ((1U << FTM_CnSC_MSA_SHIFT) | (3U << FTM_CnSC_ELSA_SHIFT)) /*!< Set output */ +} ftm_output_compare_mode_t; + +/*! @brief FlexTimer input capture edge */ +typedef enum _ftm_input_capture_edge +{ + kFTM_RisingEdge = (1U << FTM_CnSC_ELSA_SHIFT), /*!< Capture on rising edge only*/ + kFTM_FallingEdge = (2U << FTM_CnSC_ELSA_SHIFT), /*!< Capture on falling edge only*/ + kFTM_RiseAndFallEdge = (3U << FTM_CnSC_ELSA_SHIFT) /*!< Capture on rising or falling edge */ +} ftm_input_capture_edge_t; + +/*! @brief FlexTimer dual edge capture modes */ +typedef enum _ftm_dual_edge_capture_mode +{ + kFTM_OneShot = 0U, /*!< One-shot capture mode */ + kFTM_Continuous = (1U << FTM_CnSC_MSA_SHIFT) /*!< Continuous capture mode */ +} ftm_dual_edge_capture_mode_t; + +/*! @brief FlexTimer dual edge capture parameters */ +typedef struct _ftm_dual_edge_capture_param +{ + ftm_dual_edge_capture_mode_t mode; /*!< Dual Edge Capture mode */ + ftm_input_capture_edge_t currChanEdgeMode; /*!< Input capture edge select for channel n */ + ftm_input_capture_edge_t nextChanEdgeMode; /*!< Input capture edge select for channel n+1 */ +} ftm_dual_edge_capture_param_t; + +/*! @brief FlexTimer quadrature decode modes */ +typedef enum _ftm_quad_decode_mode +{ + kFTM_QuadPhaseEncode = 0U, /*!< Phase A and Phase B encoding mode */ + kFTM_QuadCountAndDir /*!< Count and direction encoding mode */ +} ftm_quad_decode_mode_t; + +/*! @brief FlexTimer quadrature phase polarities */ +typedef enum _ftm_phase_polarity +{ + kFTM_QuadPhaseNormal = 0U, /*!< Phase input signal is not inverted */ + kFTM_QuadPhaseInvert /*!< Phase input signal is inverted */ +} ftm_phase_polarity_t; + +/*! @brief FlexTimer quadrature decode phase parameters */ +typedef struct _ftm_phase_param +{ + bool enablePhaseFilter; /*!< True: enable phase filter; false: disable filter */ + uint32_t phaseFilterVal; /*!< Filter value, used only if phase filter is enabled */ + ftm_phase_polarity_t phasePolarity; /*!< Phase polarity */ +} ftm_phase_params_t; + +/*! @brief Structure is used to hold the parameters to configure a FTM fault */ +typedef struct _ftm_fault_param +{ + bool enableFaultInput; /*!< True: Fault input is enabled; false: Fault input is disabled */ + bool faultLevel; /*!< True: Fault polarity is active low; in other words, '0' indicates a fault; + False: Fault polarity is active high */ + bool useFaultFilter; /*!< True: Use the filtered fault signal; + False: Use the direct path from fault input */ +} ftm_fault_param_t; + +/*! @brief FlexTimer pre-scaler factor for the dead time insertion*/ +typedef enum _ftm_deadtime_prescale +{ + kFTM_Deadtime_Prescale_1 = 1U, /*!< Divide by 1 */ + kFTM_Deadtime_Prescale_4, /*!< Divide by 4 */ + kFTM_Deadtime_Prescale_16 /*!< Divide by 16 */ +} ftm_deadtime_prescale_t; + +/*! @brief FlexTimer clock source selection*/ +typedef enum _ftm_clock_source +{ + kFTM_SystemClock = 1U, /*!< System clock selected */ + kFTM_FixedClock, /*!< Fixed frequency clock */ + kFTM_ExternalClock /*!< External clock */ +} ftm_clock_source_t; + +/*! @brief FlexTimer pre-scaler factor selection for the clock source*/ +typedef enum _ftm_clock_prescale +{ + kFTM_Prescale_Divide_1 = 0U, /*!< Divide by 1 */ + kFTM_Prescale_Divide_2, /*!< Divide by 2 */ + kFTM_Prescale_Divide_4, /*!< Divide by 4 */ + kFTM_Prescale_Divide_8, /*!< Divide by 8 */ + kFTM_Prescale_Divide_16, /*!< Divide by 16 */ + kFTM_Prescale_Divide_32, /*!< Divide by 32 */ + kFTM_Prescale_Divide_64, /*!< Divide by 64 */ + kFTM_Prescale_Divide_128 /*!< Divide by 128 */ +} ftm_clock_prescale_t; + +/*! @brief Options for the FlexTimer behaviour in BDM Mode */ +typedef enum _ftm_bdm_mode +{ + kFTM_BdmMode_0 = 0U, + /*!< FTM counter stopped, CH(n)F bit can be set, FTM channels in functional mode, writes to MOD,CNTIN and C(n)V + registers bypass the register buffers */ + kFTM_BdmMode_1, + /*!< FTM counter stopped, CH(n)F bit is not set, FTM channels outputs are forced to their safe value , writes to + MOD,CNTIN and C(n)V registers bypass the register buffers */ + kFTM_BdmMode_2, + /*!< FTM counter stopped, CH(n)F bit is not set, FTM channels outputs are frozen when chip enters in BDM mode, + writes to MOD,CNTIN and C(n)V registers bypass the register buffers */ + kFTM_BdmMode_3 + /*!< FTM counter in functional mode, CH(n)F bit can be set, FTM channels in functional mode, writes to MOD,CNTIN and + C(n)V registers is in fully functional mode */ +} ftm_bdm_mode_t; + +/*! @brief Options for the FTM fault control mode */ +typedef enum _ftm_fault_mode +{ + kFTM_Fault_Disable = 0U, /*!< Fault control is disabled for all channels */ + kFTM_Fault_EvenChnls, /*!< Enabled for even channels only(0,2,4,6) with manual fault clearing */ + kFTM_Fault_AllChnlsMan, /*!< Enabled for all channels with manual fault clearing */ + kFTM_Fault_AllChnlsAuto /*!< Enabled for all channels with automatic fault clearing */ +} ftm_fault_mode_t; + +/*! + * @brief FTM external trigger options + * @note Actual available external trigger sources are SoC-specific + */ +typedef enum _ftm_external_trigger +{ + kFTM_Chnl0Trigger = (1U << 4), /*!< Generate trigger when counter equals chnl 0 CnV reg */ + kFTM_Chnl1Trigger = (1U << 5), /*!< Generate trigger when counter equals chnl 1 CnV reg */ + kFTM_Chnl2Trigger = (1U << 0), /*!< Generate trigger when counter equals chnl 2 CnV reg */ + kFTM_Chnl3Trigger = (1U << 1), /*!< Generate trigger when counter equals chnl 3 CnV reg */ + kFTM_Chnl4Trigger = (1U << 2), /*!< Generate trigger when counter equals chnl 4 CnV reg */ + kFTM_Chnl5Trigger = (1U << 3), /*!< Generate trigger when counter equals chnl 5 CnV reg */ + kFTM_Chnl6Trigger = + (1U << 8), /*!< Available on certain SoC's, generate trigger when counter equals chnl 6 CnV reg */ + kFTM_Chnl7Trigger = + (1U << 9), /*!< Available on certain SoC's, generate trigger when counter equals chnl 7 CnV reg */ + kFTM_InitTrigger = (1U << 6), /*!< Generate Trigger when counter is updated with CNTIN */ + kFTM_ReloadInitTrigger = (1U << 7) /*!< Available on certain SoC's, trigger on reload point */ +} ftm_external_trigger_t; + +/*! @brief FlexTimer PWM sync options to update registers with buffer */ +typedef enum _ftm_pwm_sync_method +{ + kFTM_SoftwareTrigger = FTM_SYNC_SWSYNC_MASK, /*!< Software triggers PWM sync */ + kFTM_HardwareTrigger_0 = FTM_SYNC_TRIG0_MASK, /*!< Hardware trigger 0 causes PWM sync */ + kFTM_HardwareTrigger_1 = FTM_SYNC_TRIG1_MASK, /*!< Hardware trigger 1 causes PWM sync */ + kFTM_HardwareTrigger_2 = FTM_SYNC_TRIG2_MASK /*!< Hardware trigger 2 causes PWM sync */ +} ftm_pwm_sync_method_t; + +/*! + * @brief FTM options available as loading point for register reload + * @note Actual available reload points are SoC-specific + */ +typedef enum _ftm_reload_point +{ + kFTM_Chnl0Match = (1U << 0), /*!< Channel 0 match included as a reload point */ + kFTM_Chnl1Match = (1U << 1), /*!< Channel 1 match included as a reload point */ + kFTM_Chnl2Match = (1U << 2), /*!< Channel 2 match included as a reload point */ + kFTM_Chnl3Match = (1U << 3), /*!< Channel 3 match included as a reload point */ + kFTM_Chnl4Match = (1U << 4), /*!< Channel 4 match included as a reload point */ + kFTM_Chnl5Match = (1U << 5), /*!< Channel 5 match included as a reload point */ + kFTM_Chnl6Match = (1U << 6), /*!< Channel 6 match included as a reload point */ + kFTM_Chnl7Match = (1U << 7), /*!< Channel 7 match included as a reload point */ + kFTM_CntMax = (1U << 8), /*!< Use in up-down count mode only, reload when counter reaches the maximum value */ + kFTM_CntMin = (1U << 9), /*!< Use in up-down count mode only, reload when counter reaches the minimum value */ + kFTM_HalfCycMatch = (1U << 10) /*!< Available on certain SoC's, half cycle match reload point */ +} ftm_reload_point_t; + +/*! + * @brief List of FTM interrupts + * @note Actual available interrupts are SoC-specific + */ +typedef enum _ftm_interrupt_enable +{ + kFTM_Chnl0InterruptEnable = (1U << 0), /*!< Channel 0 interrupt */ + kFTM_Chnl1InterruptEnable = (1U << 1), /*!< Channel 1 interrupt */ + kFTM_Chnl2InterruptEnable = (1U << 2), /*!< Channel 2 interrupt */ + kFTM_Chnl3InterruptEnable = (1U << 3), /*!< Channel 3 interrupt */ + kFTM_Chnl4InterruptEnable = (1U << 4), /*!< Channel 4 interrupt */ + kFTM_Chnl5InterruptEnable = (1U << 5), /*!< Channel 5 interrupt */ + kFTM_Chnl6InterruptEnable = (1U << 6), /*!< Channel 6 interrupt */ + kFTM_Chnl7InterruptEnable = (1U << 7), /*!< Channel 7 interrupt */ + kFTM_FaultInterruptEnable = (1U << 8), /*!< Fault interrupt */ + kFTM_TimeOverflowInterruptEnable = (1U << 9), /*!< Time overflow interrupt */ + kFTM_ReloadInterruptEnable = (1U << 10) /*!< Reload interrupt; Available only on certain SoC's */ +} ftm_interrupt_enable_t; + +/*! + * @brief List of FTM flags + * @note Actual available flags are SoC-specific + */ +typedef enum _ftm_status_flags +{ + kFTM_Chnl0Flag = (1U << 0), /*!< Channel 0 Flag */ + kFTM_Chnl1Flag = (1U << 1), /*!< Channel 1 Flag */ + kFTM_Chnl2Flag = (1U << 2), /*!< Channel 2 Flag */ + kFTM_Chnl3Flag = (1U << 3), /*!< Channel 3 Flag */ + kFTM_Chnl4Flag = (1U << 4), /*!< Channel 4 Flag */ + kFTM_Chnl5Flag = (1U << 5), /*!< Channel 5 Flag */ + kFTM_Chnl6Flag = (1U << 6), /*!< Channel 6 Flag */ + kFTM_Chnl7Flag = (1U << 7), /*!< Channel 7 Flag */ + kFTM_FaultFlag = (1U << 8), /*!< Fault Flag */ + kFTM_TimeOverflowFlag = (1U << 9), /*!< Time overflow Flag */ + kFTM_ChnlTriggerFlag = (1U << 10), /*!< Channel trigger Flag */ + kFTM_ReloadFlag = (1U << 11) /*!< Reload Flag; Available only on certain SoC's */ +} ftm_status_flags_t; + +/*! + * @brief List of FTM Quad Decoder flags. + */ +enum _ftm_quad_decoder_flags +{ + kFTM_QuadDecoderCountingIncreaseFlag = FTM_QDCTRL_QUADIR_MASK, /*!< Counting direction is increasing (FTM counter + increment), or the direction is decreasing. */ + kFTM_QuadDecoderCountingOverflowOnTopFlag = FTM_QDCTRL_TOFDIR_MASK, /*!< Indicates if the TOF bit was set on the top + or the bottom of counting. */ +}; + +/*! + * @brief FTM configuration structure + * + * This structure holds the configuration settings for the FTM peripheral. To initialize this + * structure to reasonable defaults, call the FTM_GetDefaultConfig() function and pass a + * pointer to the configuration structure instance. + * + * The configuration structure can be made constant so as to reside in flash. + */ +typedef struct _ftm_config +{ + ftm_clock_prescale_t prescale; /*!< FTM clock prescale value */ + ftm_bdm_mode_t bdmMode; /*!< FTM behavior in BDM mode */ + uint32_t pwmSyncMode; /*!< Synchronization methods to use to update buffered registers; Multiple + update modes can be used by providing an OR'ed list of options + available in enumeration ::ftm_pwm_sync_method_t. */ + uint32_t reloadPoints; /*!< FTM reload points; When using this, the PWM + synchronization is not required. Multiple reload points can be used by providing + an OR'ed list of options available in + enumeration ::ftm_reload_point_t. */ + ftm_fault_mode_t faultMode; /*!< FTM fault control mode */ + uint8_t faultFilterValue; /*!< Fault input filter value */ + ftm_deadtime_prescale_t deadTimePrescale; /*!< The dead time prescalar value */ + uint32_t deadTimeValue; /*!< The dead time value + deadTimeValue's available range is 0-1023 when register has DTVALEX, + otherwise its available range is 0-63. */ + uint32_t extTriggers; /*!< External triggers to enable. Multiple trigger sources can be + enabled by providing an OR'ed list of options available in + enumeration ::ftm_external_trigger_t. */ + uint8_t chnlInitState; /*!< Defines the initialization value of the channels in OUTINT register */ + uint8_t chnlPolarity; /*!< Defines the output polarity of the channels in POL register */ + bool useGlobalTimeBase; /*!< True: Use of an external global time base is enabled; + False: disabled */ +} ftm_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the FTM clock and configures the peripheral for basic operation. + * + * @note This API should be called at the beginning of the application which is using the FTM driver. + * + * @param base FTM peripheral base address + * @param config Pointer to the user configuration structure. + * + * @return kStatus_Success indicates success; Else indicates failure. + */ +status_t FTM_Init(FTM_Type *base, const ftm_config_t *config); + +/*! + * @brief Gates the FTM clock. + * + * @param base FTM peripheral base address + */ +void FTM_Deinit(FTM_Type *base); + +/*! + * @brief Fills in the FTM configuration structure with the default settings. + * + * The default values are: + * @code + * config->prescale = kFTM_Prescale_Divide_1; + * config->bdmMode = kFTM_BdmMode_0; + * config->pwmSyncMode = kFTM_SoftwareTrigger; + * config->reloadPoints = 0; + * config->faultMode = kFTM_Fault_Disable; + * config->faultFilterValue = 0; + * config->deadTimePrescale = kFTM_Deadtime_Prescale_1; + * config->deadTimeValue = 0; + * config->extTriggers = 0; + * config->chnlInitState = 0; + * config->chnlPolarity = 0; + * config->useGlobalTimeBase = false; + * @endcode + * @param config Pointer to the user configuration structure. + */ +void FTM_GetDefaultConfig(ftm_config_t *config); + +/*! @}*/ + +/*! + * @name Channel mode operations + * @{ + */ + +/*! + * @brief Configures the PWM signal parameters. + * + * Call this function to configure the PWM signal period, mode, duty cycle, and edge. Use this + * function to configure all FTM channels that are used to output a PWM signal. + * + * @param base FTM peripheral base address + * @param chnlParams Array of PWM channel parameters to configure the channel(s) + * @param numOfChnls Number of channels to configure; This should be the size of the array passed in + * @param mode PWM operation mode, options available in enumeration ::ftm_pwm_mode_t + * @param pwmFreq_Hz PWM signal frequency in Hz + * @param srcClock_Hz FTM counter clock in Hz + * + * @return kStatus_Success if the PWM setup was successful + * kStatus_Error on failure + */ +status_t FTM_SetupPwm(FTM_Type *base, + const ftm_chnl_pwm_signal_param_t *chnlParams, + uint8_t numOfChnls, + ftm_pwm_mode_t mode, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz); + +/*! + * @brief Updates the duty cycle of an active PWM signal. + * + * @param base FTM peripheral base address + * @param chnlNumber The channel/channel pair number. In combined mode, this represents + * the channel pair number + * @param currentPwmMode The current PWM mode set during PWM setup + * @param dutyCyclePercent New PWM pulse width; The value should be between 0 to 100 + * 0=inactive signal(0% duty cycle)... + * 100=active signal (100% duty cycle) + */ +void FTM_UpdatePwmDutycycle(FTM_Type *base, + ftm_chnl_t chnlNumber, + ftm_pwm_mode_t currentPwmMode, + uint8_t dutyCyclePercent); + +/*! + * @brief Updates the edge level selection for a channel. + * + * @param base FTM peripheral base address + * @param chnlNumber The channel number + * @param level The level to be set to the ELSnB:ELSnA field; Valid values are 00, 01, 10, 11. + * See the Kinetis SoC reference manual for details about this field. + */ +void FTM_UpdateChnlEdgeLevelSelect(FTM_Type *base, ftm_chnl_t chnlNumber, uint8_t level); + +/*! + * @brief Enables capturing an input signal on the channel using the function parameters. + * + * When the edge specified in the captureMode argument occurs on the channel, the FTM counter is + * captured into the CnV register. The user has to read the CnV register separately to get this + * value. The filter function is disabled if the filterVal argument passed in is 0. The filter + * function is available only for channels 0, 1, 2, 3. + * + * @param base FTM peripheral base address + * @param chnlNumber The channel number + * @param captureMode Specifies which edge to capture + * @param filterValue Filter value, specify 0 to disable filter. Available only for channels 0-3. + */ +void FTM_SetupInputCapture(FTM_Type *base, + ftm_chnl_t chnlNumber, + ftm_input_capture_edge_t captureMode, + uint32_t filterValue); + +/*! + * @brief Configures the FTM to generate timed pulses. + * + * When the FTM counter matches the value of compareVal argument (this is written into CnV reg), + * the channel output is changed based on what is specified in the compareMode argument. + * + * @param base FTM peripheral base address + * @param chnlNumber The channel number + * @param compareMode Action to take on the channel output when the compare condition is met + * @param compareValue Value to be programmed in the CnV register. + */ +void FTM_SetupOutputCompare(FTM_Type *base, + ftm_chnl_t chnlNumber, + ftm_output_compare_mode_t compareMode, + uint32_t compareValue); + +/*! + * @brief Configures the dual edge capture mode of the FTM. + * + * This function sets up the dual edge capture mode on a channel pair. The capture edge for the + * channel pair and the capture mode (one-shot or continuous) is specified in the parameter + * argument. The filter function is disabled if the filterVal argument passed is zero. The filter + * function is available only on channels 0 and 2. The user has to read the channel CnV registers + * separately to get the capture values. + * + * @param base FTM peripheral base address + * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3 + * @param edgeParam Sets up the dual edge capture function + * @param filterValue Filter value, specify 0 to disable filter. Available only for channel pair 0 and 1. + */ +void FTM_SetupDualEdgeCapture(FTM_Type *base, + ftm_chnl_t chnlPairNumber, + const ftm_dual_edge_capture_param_t *edgeParam, + uint32_t filterValue); + +/*! @}*/ + +/*! + * @brief Sets up the working of the FTM fault protection. + * + * FTM can have up to 4 fault inputs. This function sets up fault parameters, fault level, and a filter. + * + * @param base FTM peripheral base address + * @param faultNumber FTM fault to configure. + * @param faultParams Parameters passed in to set up the fault + */ +void FTM_SetupFault(FTM_Type *base, ftm_fault_input_t faultNumber, const ftm_fault_param_t *faultParams); + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected FTM interrupts. + * + * @param base FTM peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::ftm_interrupt_enable_t + */ +void FTM_EnableInterrupts(FTM_Type *base, uint32_t mask); + +/*! + * @brief Disables the selected FTM interrupts. + * + * @param base FTM peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::ftm_interrupt_enable_t + */ +void FTM_DisableInterrupts(FTM_Type *base, uint32_t mask); + +/*! + * @brief Gets the enabled FTM interrupts. + * + * @param base FTM peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::ftm_interrupt_enable_t + */ +uint32_t FTM_GetEnabledInterrupts(FTM_Type *base); + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the FTM status flags. + * + * @param base FTM peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::ftm_status_flags_t + */ +uint32_t FTM_GetStatusFlags(FTM_Type *base); + +/*! + * @brief Clears the FTM status flags. + * + * @param base FTM peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::ftm_status_flags_t + */ +void FTM_ClearStatusFlags(FTM_Type *base, uint32_t mask); + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ + +/*! + * @brief Starts the FTM counter. + * + * @param base FTM peripheral base address + * @param clockSource FTM clock source; After the clock source is set, the counter starts running. + */ +static inline void FTM_StartTimer(FTM_Type *base, ftm_clock_source_t clockSource) +{ + uint32_t reg = base->SC; + + reg &= ~(FTM_SC_CLKS_MASK); + reg |= FTM_SC_CLKS(clockSource); + base->SC = reg; +} + +/*! + * @brief Stops the FTM counter. + * + * @param base FTM peripheral base address + */ +static inline void FTM_StopTimer(FTM_Type *base) +{ + /* Set clock source to none to disable counter */ + base->SC &= ~(FTM_SC_CLKS_MASK); +} + +/*! @}*/ + +/*! + * @name Software output control + * @{ + */ + +/*! + * @brief Enables or disables the channel software output control. + * + * @param base FTM peripheral base address + * @param chnlNumber Channel to be enabled or disabled + * @param value true: channel output is affected by software output control + false: channel output is unaffected by software output control + */ +static inline void FTM_SetSoftwareCtrlEnable(FTM_Type *base, ftm_chnl_t chnlNumber, bool value) +{ + if (value) + { + base->SWOCTRL |= (1U << chnlNumber); + } + else + { + base->SWOCTRL &= ~(1U << chnlNumber); + } +} + +/*! + * @brief Sets the channel software output control value. + * + * @param base FTM peripheral base address. + * @param chnlNumber Channel to be configured + * @param value true to set 1, false to set 0 + */ +static inline void FTM_SetSoftwareCtrlVal(FTM_Type *base, ftm_chnl_t chnlNumber, bool value) +{ + if (value) + { + base->SWOCTRL |= (1U << (chnlNumber + FTM_SWOCTRL_CH0OCV_SHIFT)); + } + else + { + base->SWOCTRL &= ~(1U << (chnlNumber + FTM_SWOCTRL_CH0OCV_SHIFT)); + } +} + +/*! @}*/ + +/*! + * @brief Enables or disables the FTM global time base signal generation to other FTMs. + * + * @param base FTM peripheral base address + * @param enable true to enable, false to disable + */ +static inline void FTM_SetGlobalTimeBaseOutputEnable(FTM_Type *base, bool enable) +{ + if (enable) + { + base->CONF |= FTM_CONF_GTBEOUT_MASK; + } + else + { + base->CONF &= ~FTM_CONF_GTBEOUT_MASK; + } +} + +/*! + * @brief Sets the FTM peripheral timer channel output mask. + * + * @param base FTM peripheral base address + * @param chnlNumber Channel to be configured + * @param mask true: masked, channel is forced to its inactive state; false: unmasked + */ +static inline void FTM_SetOutputMask(FTM_Type *base, ftm_chnl_t chnlNumber, bool mask) +{ + if (mask) + { + base->OUTMASK |= (1U << chnlNumber); + } + else + { + base->OUTMASK &= ~(1U << chnlNumber); + } +} + +#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) +/*! + * @brief Allows users to enable an output on an FTM channel. + * + * To enable the PWM channel output call this function with val=true. For input mode, + * call this function with val=false. + * + * @param base FTM peripheral base address + * @param chnlNumber Channel to be configured + * @param value true: enable output; false: output is disabled, used in input mode + */ +static inline void FTM_SetPwmOutputEnable(FTM_Type *base, ftm_chnl_t chnlNumber, bool value) +{ + if (value) + { + base->SC |= (1U << (chnlNumber + FTM_SC_PWMEN0_SHIFT)); + } + else + { + base->SC &= ~(1U << (chnlNumber + FTM_SC_PWMEN0_SHIFT)); + } +} +#endif + +/*! + * @name Channel pair operations + * @{ + */ + +/*! + * @brief This function enables/disables the fault control in a channel pair. + * + * @param base FTM peripheral base address + * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3 + * @param value true: Enable fault control for this channel pair; false: No fault control + */ +static inline void FTM_SetFaultControlEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber, bool value) +{ + if (value) + { + base->COMBINE |= (1U << (FTM_COMBINE_FAULTEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber))); + } + else + { + base->COMBINE &= ~(1U << (FTM_COMBINE_FAULTEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber))); + } +} + +/*! + * @brief This function enables/disables the dead time insertion in a channel pair. + * + * @param base FTM peripheral base address + * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3 + * @param value true: Insert dead time in this channel pair; false: No dead time inserted + */ +static inline void FTM_SetDeadTimeEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber, bool value) +{ + if (value) + { + base->COMBINE |= (1U << (FTM_COMBINE_DTEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber))); + } + else + { + base->COMBINE &= ~(1U << (FTM_COMBINE_DTEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber))); + } +} + +/*! + * @brief This function enables/disables complementary mode in a channel pair. + * + * @param base FTM peripheral base address + * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3 + * @param value true: enable complementary mode; false: disable complementary mode + */ +static inline void FTM_SetComplementaryEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber, bool value) +{ + if (value) + { + base->COMBINE |= (1U << (FTM_COMBINE_COMP0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber))); + } + else + { + base->COMBINE &= ~(1U << (FTM_COMBINE_COMP0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber))); + } +} + +/*! + * @brief This function enables/disables inverting control in a channel pair. + * + * @param base FTM peripheral base address + * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3 + * @param value true: enable inverting; false: disable inverting + */ +static inline void FTM_SetInvertEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber, bool value) +{ + if (value) + { + base->INVCTRL |= (1U << chnlPairNumber); + } + else + { + base->INVCTRL &= ~(1U << chnlPairNumber); + } +} + +/*! @}*/ + +/*! + * @name Quad Decoder + * @{ + */ + +/*! + * @brief Configures the parameters and activates the quadrature decoder mode. + * + * @param base FTM peripheral base address + * @param phaseAParams Phase A configuration parameters + * @param phaseBParams Phase B configuration parameters + * @param quadMode Selects encoding mode used in quadrature decoder mode + */ +void FTM_SetupQuadDecode(FTM_Type *base, + const ftm_phase_params_t *phaseAParams, + const ftm_phase_params_t *phaseBParams, + ftm_quad_decode_mode_t quadMode); + +/*! + * @brief Gets the FTM Quad Decoder flags. + * + * @param base FTM peripheral base address. + * @return Flag mask of FTM Quad Decoder, see #_ftm_quad_decoder_flags. + */ +static inline uint32_t FTM_GetQuadDecoderFlags(FTM_Type *base) +{ + return base->QDCTRL & (FTM_QDCTRL_QUADIR_MASK | FTM_QDCTRL_TOFDIR_MASK); +} + +/*! + * @brief Sets the modulo values for Quad Decoder. + * + * The modulo values configure the minimum and maximum values that the Quad decoder counter can reach. After the counter goes + * over, the counter value goes to the other side and decrease/increase again. + * + * @param base FTM peripheral base address. + * @param startValue The low limit value for Quad Decoder counter. + * @param overValue The high limit value for Quad Decoder counter. + */ +static inline void FTM_SetQuadDecoderModuloValue(FTM_Type *base, uint32_t startValue, uint32_t overValue) +{ + base->CNTIN = startValue; + base->MOD = overValue; +} + +/*! + * @brief Gets the current Quad Decoder counter value. + * + * @param base FTM peripheral base address. + * @return Current quad Decoder counter value. + */ +static inline uint32_t FTM_GetQuadDecoderCounterValue(FTM_Type *base) +{ + return base->CNT; +} + +/*! + * @brief Clears the current Quad Decoder counter value. + * + * The counter is set as the initial value. + * + * @param base FTM peripheral base address. + */ +static inline void FTM_ClearQuadDecoderCounterValue(FTM_Type *base) +{ + base->CNT = base->CNTIN; +} + +/*! @}*/ + +/*! + * @brief Enables or disables the FTM software trigger for PWM synchronization. + * + * @param base FTM peripheral base address + * @param enable true: software trigger is selected, false: software trigger is not selected + */ +static inline void FTM_SetSoftwareTrigger(FTM_Type *base, bool enable) +{ + if (enable) + { + base->SYNC |= FTM_SYNC_SWSYNC_MASK; + } + else + { + base->SYNC &= ~FTM_SYNC_SWSYNC_MASK; + } +} + +/*! + * @brief Enables or disables the FTM write protection. + * + * @param base FTM peripheral base address + * @param enable true: Write-protection is enabled, false: Write-protection is disabled + */ +static inline void FTM_SetWriteProtection(FTM_Type *base, bool enable) +{ + /* Configure write protection */ + if (enable) + { + base->FMS |= FTM_FMS_WPEN_MASK; + } + else + { + base->MODE |= FTM_MODE_WPDIS_MASK; + } +} + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_FTM_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_gpio.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_gpio.c new file mode 100644 index 00000000000..a0790dea6ed --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_gpio.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_gpio.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ +static PORT_Type *const s_portBases[] = PORT_BASE_PTRS; +static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS; + +/******************************************************************************* +* Prototypes +******************************************************************************/ + +/*! +* @brief Gets the GPIO instance according to the GPIO base +* +* @param base GPIO peripheral base pointer(PTA, PTB, PTC, etc.) +* @retval GPIO instance +*/ +static uint32_t GPIO_GetInstance(GPIO_Type *base); + +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t GPIO_GetInstance(GPIO_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_GPIO_COUNT; instance++) + { + if (s_gpioBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_GPIO_COUNT); + + return instance; +} + +void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config) +{ + assert(config); + + if (config->pinDirection == kGPIO_DigitalInput) + { + base->PDDR &= ~(1U << pin); + } + else + { + GPIO_WritePinOutput(base, pin, config->outputLogic); + base->PDDR |= (1U << pin); + } +} + +uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base) +{ + uint8_t instance; + PORT_Type *portBase; + instance = GPIO_GetInstance(base); + portBase = s_portBases[instance]; + return portBase->ISFR; +} + +void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask) +{ + uint8_t instance; + PORT_Type *portBase; + instance = GPIO_GetInstance(base); + portBase = s_portBases[instance]; + portBase->ISFR = mask; +} + +#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER +void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute) +{ + base->GACR = ((uint32_t)attribute << GPIO_GACR_ACB0_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB1_SHIFT) | + ((uint32_t)attribute << GPIO_GACR_ACB2_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB3_SHIFT); +} +#endif + +#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ +static FGPIO_Type *const s_fgpioBases[] = FGPIO_BASE_PTRS; + +/******************************************************************************* +* Prototypes +******************************************************************************/ +/*! +* @brief Gets the FGPIO instance according to the GPIO base +* +* @param base FGPIO peripheral base pointer(PTA, PTB, PTC, etc.) +* @retval FGPIO instance +*/ +static uint32_t FGPIO_GetInstance(FGPIO_Type *base); + +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t FGPIO_GetInstance(FGPIO_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_FGPIO_COUNT; instance++) + { + if (s_fgpioBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_FGPIO_COUNT); + + return instance; +} + +void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config) +{ + assert(config); + + if (config->pinDirection == kGPIO_DigitalInput) + { + base->PDDR &= ~(1U << pin); + } + else + { + FGPIO_WritePinOutput(base, pin, config->outputLogic); + base->PDDR |= (1U << pin); + } +} + +uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base) +{ + uint8_t instance; + instance = FGPIO_GetInstance(base); + PORT_Type *portBase; + portBase = s_portBases[instance]; + return portBase->ISFR; +} + +void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask) +{ + uint8_t instance; + instance = FGPIO_GetInstance(base); + PORT_Type *portBase; + portBase = s_portBases[instance]; + portBase->ISFR = mask; +} + +#if defined(FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER +void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute) +{ + base->GACR = (attribute << FGPIO_GACR_ACB0_SHIFT) | (attribute << FGPIO_GACR_ACB1_SHIFT) | + (attribute << FGPIO_GACR_ACB2_SHIFT) | (attribute << FGPIO_GACR_ACB3_SHIFT); +} +#endif + +#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_gpio.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_gpio.h new file mode 100644 index 00000000000..56a4ba09850 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_gpio.h @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SDRVL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_GPIO_H_ +#define _FSL_GPIO_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup gpio + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief GPIO driver version 2.1.1. */ +#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) +/*@}*/ + +/*! @brief GPIO direction definition */ +typedef enum _gpio_pin_direction +{ + kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/ + kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/ +} gpio_pin_direction_t; + +#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER +/*! @brief GPIO checker attribute */ +typedef enum _gpio_checker_attribute +{ + kGPIO_UsernonsecureRWUsersecureRWPrivilegedsecureRW = + 0x00U, /*!< User nonsecure:Read+Write; User Secure:Read+Write; Privileged Secure:Read+Write */ + kGPIO_UsernonsecureRUsersecureRWPrivilegedsecureRW = + 0x01U, /*!< User nonsecure:Read; User Secure:Read+Write; Privileged Secure:Read+Write */ + kGPIO_UsernonsecureNUsersecureRWPrivilegedsecureRW = + 0x02U, /*!< User nonsecure:None; User Secure:Read+Write; Privileged Secure:Read+Write */ + kGPIO_UsernonsecureRUsersecureRPrivilegedsecureRW = + 0x03U, /*!< User nonsecure:Read; User Secure:Read; Privileged Secure:Read+Write */ + kGPIO_UsernonsecureNUsersecureRPrivilegedsecureRW = + 0x04U, /*!< User nonsecure:None; User Secure:Read; Privileged Secure:Read+Write */ + kGPIO_UsernonsecureNUsersecureNPrivilegedsecureRW = + 0x05U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:Read+Write */ + kGPIO_UsernonsecureNUsersecureNPrivilegedsecureR = + 0x06U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:Read */ + kGPIO_UsernonsecureNUsersecureNPrivilegedsecureN = + 0x07U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:None */ + kGPIO_IgnoreAttributeCheck = 0x10U, /*!< Ignores the attribute check */ +} gpio_checker_attribute_t; +#endif + +/*! + * @brief The GPIO pin configuration structure. + * + * Each pin can only be configured as either an output pin or an input pin at a time. + * If configured as an input pin, leave the outputConfig unused. + * Note that in some use cases, the corresponding port property should be configured in advance + * with the PORT_SetPinConfig(). + */ +typedef struct _gpio_pin_config +{ + gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */ + /* Output configurations; ignore if configured as an input pin */ + uint8_t outputLogic; /*!< Set a default output logic, which has no use in input */ +} gpio_pin_config_t; + +/*! @} */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @addtogroup gpio_driver + * @{ + */ + +/*! @name GPIO Configuration */ +/*@{*/ + +/*! + * @brief Initializes a GPIO pin used by the board. + * + * To initialize the GPIO, define a pin configuration, as either input or output, in the user file. + * Then, call the GPIO_PinInit() function. + * + * This is an example to define an input pin or an output pin configuration. + * @code + * // Define a digital input pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalInput, + * 0, + * } + * //Define a digital output pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalOutput, + * 0, + * } + * @endcode + * + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param pin GPIO port pin number + * @param config GPIO pin configuration pointer + */ +void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config); + +/*@}*/ + +/*! @name GPIO Output Operations */ +/*@{*/ + +/*! + * @brief Sets the output level of the multiple GPIO pins to the logic 1 or 0. + * + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param pin GPIO pin number + * @param output GPIO pin output logic level. + * - 0: corresponding pin output low-logic level. + * - 1: corresponding pin output high-logic level. + */ +static inline void GPIO_WritePinOutput(GPIO_Type *base, uint32_t pin, uint8_t output) +{ + if (output == 0U) + { + base->PCOR = 1U << pin; + } + else + { + base->PSOR = 1U << pin; + } +} + +/*! + * @brief Sets the output level of the multiple GPIO pins to the logic 1. + * + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pin number macro + */ +static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask) +{ + base->PSOR = mask; +} + +/*! + * @brief Sets the output level of the multiple GPIO pins to the logic 0. + * + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pin number macro + */ +static inline void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask) +{ + base->PCOR = mask; +} + +/*! + * @brief Reverses the current output logic of the multiple GPIO pins. + * + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pin number macro + */ +static inline void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t mask) +{ + base->PTOR = mask; +} +/*@}*/ + +/*! @name GPIO Input Operations */ +/*@{*/ + +/*! + * @brief Reads the current input value of the GPIO port. + * + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param pin GPIO pin number + * @retval GPIO port input value + * - 0: corresponding pin input low-logic level. + * - 1: corresponding pin input high-logic level. + */ +static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin) +{ + return (((base->PDIR) >> pin) & 0x01U); +} +/*@}*/ + +/*! @name GPIO Interrupt */ +/*@{*/ + +/*! + * @brief Reads the GPIO port interrupt status flag. + * + * If a pin is configured to generate the DMA request, the corresponding flag + * is cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic one is written to that flag. + * If configured for a level sensitive interrupt that remains asserted, the flag + * is set again immediately. + * + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @retval The current GPIO port interrupt status flag, for example, 0x00010001 means the + * pin 0 and 17 have the interrupt. + */ +uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base); + +/*! + * @brief Clears multiple GPIO pin interrupt status flags. + * + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pin number macro + */ +void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask); + +#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER +/*! + * @brief The GPIO module supports a device-specific number of data ports, organized as 32-bit + * words. Each 32-bit data port includes a GACR register, which defines the byte-level + * attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data + * bytes in the GACR follow a standard little endian + * data convention. + * + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pin number macro + */ +void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute); +#endif + +/*@}*/ +/*! @} */ + +/*! + * @addtogroup fgpio_driver + * @{ + */ + +/* + * Introduces the FGPIO feature. + * + * The FGPIO features are only support on some Kinetis MCUs. The FGPIO registers are aliased to the IOPORT + * interface. Accesses via the IOPORT interface occur in parallel with any instruction fetches and + * complete in a single cycle. This aliased Fast GPIO memory map is called FGPIO. + */ + +#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT + +/*! @name FGPIO Configuration */ +/*@{*/ + +/*! + * @brief Initializes a FGPIO pin used by the board. + * + * To initialize the FGPIO driver, define a pin configuration, as either input or output, in the user file. + * Then, call the FGPIO_PinInit() function. + * + * This is an example to define an input pin or an output pin configuration: + * @code + * // Define a digital input pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalInput, + * 0, + * } + * //Define a digital output pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalOutput, + * 0, + * } + * @endcode + * + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param pin FGPIO port pin number + * @param config FGPIO pin configuration pointer + */ +void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config); + +/*@}*/ + +/*! @name FGPIO Output Operations */ +/*@{*/ + +/*! + * @brief Sets the output level of the multiple FGPIO pins to the logic 1 or 0. + * + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param pin FGPIO pin number + * @param output FGPIOpin output logic level. + * - 0: corresponding pin output low-logic level. + * - 1: corresponding pin output high-logic level. + */ +static inline void FGPIO_WritePinOutput(FGPIO_Type *base, uint32_t pin, uint8_t output) +{ + if (output == 0U) + { + base->PCOR = 1 << pin; + } + else + { + base->PSOR = 1 << pin; + } +} + +/*! + * @brief Sets the output level of the multiple FGPIO pins to the logic 1. + * + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param mask FGPIO pin number macro + */ +static inline void FGPIO_SetPinsOutput(FGPIO_Type *base, uint32_t mask) +{ + base->PSOR = mask; +} + +/*! + * @brief Sets the output level of the multiple FGPIO pins to the logic 0. + * + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param mask FGPIO pin number macro + */ +static inline void FGPIO_ClearPinsOutput(FGPIO_Type *base, uint32_t mask) +{ + base->PCOR = mask; +} + +/*! + * @brief Reverses the current output logic of the multiple FGPIO pins. + * + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param mask FGPIO pin number macro + */ +static inline void FGPIO_TogglePinsOutput(FGPIO_Type *base, uint32_t mask) +{ + base->PTOR = mask; +} +/*@}*/ + +/*! @name FGPIO Input Operations */ +/*@{*/ + +/*! + * @brief Reads the current input value of the FGPIO port. + * + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param pin FGPIO pin number + * @retval FGPIO port input value + * - 0: corresponding pin input low-logic level. + * - 1: corresponding pin input high-logic level. + */ +static inline uint32_t FGPIO_ReadPinInput(FGPIO_Type *base, uint32_t pin) +{ + return (((base->PDIR) >> pin) & 0x01U); +} +/*@}*/ + +/*! @name FGPIO Interrupt */ +/*@{*/ + +/*! + * @brief Reads the FGPIO port interrupt status flag. + * + * If a pin is configured to generate the DMA request, the corresponding flag + * is cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic one is written to that flag. + * If configured for a level-sensitive interrupt that remains asserted, the flag + * is set again immediately. + * + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @retval The current FGPIO port interrupt status flags, for example, 0x00010001 means the + * pin 0 and 17 have the interrupt. + */ +uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base); + +/*! + * @brief Clears the multiple FGPIO pin interrupt status flag. + * + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param mask FGPIO pin number macro + */ +void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask); + +#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER +/*! + * @brief The FGPIO module supports a device-specific number of data ports, organized as 32-bit + * words. Each 32-bit data port includes a GACR register, which defines the byte-level + * attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data + * bytes in the GACR follow a standard little endian + * data convention. + * + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param mask FGPIO pin number macro + */ +void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute); +#endif + +/*@}*/ + +#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ + +#endif /* _FSL_GPIO_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c.c new file mode 100644 index 00000000000..c3032d0026a --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c.c @@ -0,0 +1,1750 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_i2c.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief i2c transfer state. */ +enum _i2c_transfer_states +{ + kIdleState = 0x0U, /*!< I2C bus idle. */ + kCheckAddressState = 0x1U, /*!< 7-bit address check state. */ + kSendCommandState = 0x2U, /*!< Send command byte phase. */ + kSendDataState = 0x3U, /*!< Send data transfer phase. */ + kReceiveDataBeginState = 0x4U, /*!< Receive data transfer phase begin. */ + kReceiveDataState = 0x5U, /*!< Receive data transfer phase. */ +}; + +/*! @brief Common sets of flags used by the driver. */ +enum _i2c_flag_constants +{ +/*! All flags which are cleared by the driver upon starting a transfer. */ +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StartDetectFlag | kI2C_StopDetectFlag, + kIrqFlags = kI2C_GlobalInterruptEnable | kI2C_StartStopDetectInterruptEnable, +#elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT + kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StopDetectFlag, + kIrqFlags = kI2C_GlobalInterruptEnable | kI2C_StopDetectInterruptEnable, +#else + kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag, + kIrqFlags = kI2C_GlobalInterruptEnable, +#endif + +}; + +/*! @brief Typedef for interrupt handler. */ +typedef void (*i2c_isr_t)(I2C_Type *base, void *i2cHandle); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get instance number for I2C module. + * + * @param base I2C peripheral base address. + */ +uint32_t I2C_GetInstance(I2C_Type *base); + +/*! +* @brief Set SCL/SDA hold time, this API receives SCL stop hold time, calculate the +* closest SCL divider and MULT value for the SDA hold time, SCL start and SCL stop +* hold time. To reduce the ROM size, SDA/SCL hold value mapping table is not provided, +* assume SCL divider = SCL stop hold value *2 to get the closest SCL divider value and MULT +* value, then the related SDA hold time, SCL start and SCL stop hold time is used. +* +* @param base I2C peripheral base address. +* @param sourceClock_Hz I2C functional clock frequency in Hertz. +* @param sclStopHoldTime_ns SCL stop hold time in ns. +*/ +static void I2C_SetHoldTime(I2C_Type *base, uint32_t sclStopHoldTime_ns, uint32_t sourceClock_Hz); + +/*! + * @brief Set up master transfer, send slave address and decide the initial + * transfer state. + * + * @param base I2C peripheral base address. + * @param handle pointer to i2c_master_handle_t structure which stores the transfer state. + * @param xfer pointer to i2c_master_transfer_t structure. + */ +static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer); + +/*! + * @brief Check and clear status operation. + * + * @param base I2C peripheral base address. + * @param status current i2c hardware status. + * @retval kStatus_Success No error found. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStatus_I2C_Nak Received Nak error. + */ +static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status); + +/*! + * @brief Master run transfer state machine to perform a byte of transfer. + * + * @param base I2C peripheral base address. + * @param handle pointer to i2c_master_handle_t structure which stores the transfer state + * @param isDone input param to get whether the thing is done, true is done + * @retval kStatus_Success No error found. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStatus_I2C_Nak Received Nak error. + * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. + */ +static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone); + +/*! + * @brief I2C common interrupt handler. + * + * @param base I2C peripheral base address. + * @param handle pointer to i2c_master_handle_t structure which stores the transfer state + */ +static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Pointers to i2c handles for each instance. */ +static void *s_i2cHandle[FSL_FEATURE_SOC_I2C_COUNT] = {NULL}; + +/*! @brief SCL clock divider used to calculate baudrate. */ +static const uint16_t s_i2cDividerTable[] = { + 20, 22, 24, 26, 28, 30, 34, 40, 28, 32, 36, 40, 44, 48, 56, 68, + 48, 56, 64, 72, 80, 88, 104, 128, 80, 96, 112, 128, 144, 160, 192, 240, + 160, 192, 224, 256, 288, 320, 384, 480, 320, 384, 448, 512, 576, 640, 768, 960, + 640, 768, 896, 1024, 1152, 1280, 1536, 1920, 1280, 1536, 1792, 2048, 2304, 2560, 3072, 3840}; + +/*! @brief Pointers to i2c bases for each instance. */ +static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS; + +/*! @brief Pointers to i2c IRQ number for each instance. */ +static const IRQn_Type s_i2cIrqs[] = I2C_IRQS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to i2c clocks for each instance. */ +static const clock_ip_name_t s_i2cClocks[] = I2C_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Pointer to master IRQ handler for each instance. */ +static i2c_isr_t s_i2cMasterIsr; + +/*! @brief Pointer to slave IRQ handler for each instance. */ +static i2c_isr_t s_i2cSlaveIsr; + +/******************************************************************************* + * Codes + ******************************************************************************/ + +uint32_t I2C_GetInstance(I2C_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_I2C_COUNT; instance++) + { + if (s_i2cBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_I2C_COUNT); + + return instance; +} + +static void I2C_SetHoldTime(I2C_Type *base, uint32_t sclStopHoldTime_ns, uint32_t sourceClock_Hz) +{ + uint32_t multiplier; + uint32_t computedSclHoldTime; + uint32_t absError; + uint32_t bestError = UINT32_MAX; + uint32_t bestMult = 0u; + uint32_t bestIcr = 0u; + uint8_t mult; + uint8_t i; + + /* Search for the settings with the lowest error. Mult is the MULT field of the I2C_F register, + * and ranges from 0-2. It selects the multiplier factor for the divider. */ + /* SDA hold time = bus period (s) * mul * SDA hold value. */ + /* SCL start hold time = bus period (s) * mul * SCL start hold value. */ + /* SCL stop hold time = bus period (s) * mul * SCL stop hold value. */ + + for (mult = 0u; (mult <= 2u) && (bestError != 0); ++mult) + { + multiplier = 1u << mult; + + /* Scan table to find best match. */ + for (i = 0u; i < sizeof(s_i2cDividerTable) / sizeof(s_i2cDividerTable[0]); ++i) + { + /* Assume SCL hold(stop) value = s_i2cDividerTable[i]/2. */ + computedSclHoldTime = ((multiplier * s_i2cDividerTable[i]) * 500000000U) / sourceClock_Hz; + absError = sclStopHoldTime_ns > computedSclHoldTime ? (sclStopHoldTime_ns - computedSclHoldTime) : + (computedSclHoldTime - sclStopHoldTime_ns); + + if (absError < bestError) + { + bestMult = mult; + bestIcr = i; + bestError = absError; + + /* If the error is 0, then we can stop searching because we won't find a better match. */ + if (absError == 0) + { + break; + } + } + } + } + + /* Set frequency register based on best settings. */ + base->F = I2C_F_MULT(bestMult) | I2C_F_ICR(bestIcr); +} + +static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer) +{ + status_t result = kStatus_Success; + i2c_direction_t direction = xfer->direction; + + /* Initialize the handle transfer information. */ + handle->transfer = *xfer; + + /* Save total transfer size. */ + handle->transferSize = xfer->dataSize; + + /* Initial transfer state. */ + if (handle->transfer.subaddressSize > 0) + { + if (xfer->direction == kI2C_Read) + { + direction = kI2C_Write; + } + } + + handle->state = kCheckAddressState; + + /* Clear all status before transfer. */ + I2C_MasterClearStatusFlags(base, kClearFlags); + + /* If repeated start is requested, send repeated start. */ + if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag) + { + result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction); + } + else /* For normal transfer, send start. */ + { + result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction); + } + + return result; +} + +static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status) +{ + status_t result = kStatus_Success; + + /* Check arbitration lost. */ + if (status & kI2C_ArbitrationLostFlag) + { + /* Clear arbitration lost flag. */ + base->S = kI2C_ArbitrationLostFlag; + result = kStatus_I2C_ArbitrationLost; + } + /* Check NAK */ + else if (status & kI2C_ReceiveNakFlag) + { + result = kStatus_I2C_Nak; + } + else + { + } + + return result; +} + +static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone) +{ + status_t result = kStatus_Success; + uint32_t statusFlags = base->S; + *isDone = false; + volatile uint8_t dummy = 0; + bool ignoreNak = ((handle->state == kSendDataState) && (handle->transfer.dataSize == 0U)) || + ((handle->state == kReceiveDataState) && (handle->transfer.dataSize == 1U)); + + /* Add this to avoid build warning. */ + dummy++; + + /* Check & clear error flags. */ + result = I2C_CheckAndClearError(base, statusFlags); + + /* Ignore Nak when it's appeared for last byte. */ + if ((result == kStatus_I2C_Nak) && ignoreNak) + { + result = kStatus_Success; + } + + /* Handle Check address state to check the slave address is Acked in slave + probe application. */ + if (handle->state == kCheckAddressState) + { + if (statusFlags & kI2C_ReceiveNakFlag) + { + result = kStatus_I2C_Addr_Nak; + } + else + { + if (handle->transfer.subaddressSize > 0) + { + handle->state = kSendCommandState; + } + else + { + if (handle->transfer.direction == kI2C_Write) + { + /* Next state, send data. */ + handle->state = kSendDataState; + } + else + { + /* Next state, receive data begin. */ + handle->state = kReceiveDataBeginState; + } + } + } + } + + if (result) + { + return result; + } + + /* Run state machine. */ + switch (handle->state) + { + /* Send I2C command. */ + case kSendCommandState: + if (handle->transfer.subaddressSize) + { + handle->transfer.subaddressSize--; + base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize)); + } + else + { + if (handle->transfer.direction == kI2C_Write) + { + /* Next state, send data. */ + handle->state = kSendDataState; + + /* Send first byte of data. */ + if (handle->transfer.dataSize > 0) + { + base->D = *handle->transfer.data; + handle->transfer.data++; + handle->transfer.dataSize--; + } + } + else + { + /* Send repeated start and slave address. */ + result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read); + + /* Next state, receive data begin. */ + handle->state = kReceiveDataBeginState; + } + } + break; + + /* Send I2C data. */ + case kSendDataState: + /* Send one byte of data. */ + if (handle->transfer.dataSize > 0) + { + base->D = *handle->transfer.data; + handle->transfer.data++; + handle->transfer.dataSize--; + } + else + { + *isDone = true; + } + break; + + /* Start I2C data receive. */ + case kReceiveDataBeginState: + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* Send nak at the last receive byte. */ + if (handle->transfer.dataSize == 1) + { + base->C1 |= I2C_C1_TXAK_MASK; + } + + /* Read dummy to release the bus. */ + dummy = base->D; + + /* Next state, receive data. */ + handle->state = kReceiveDataState; + break; + + /* Receive I2C data. */ + case kReceiveDataState: + /* Receive one byte of data. */ + if (handle->transfer.dataSize--) + { + if (handle->transfer.dataSize == 0) + { + *isDone = true; + + /* Send stop if kI2C_TransferNoStop is not asserted. */ + if (!(handle->transfer.flags & kI2C_TransferNoStopFlag)) + { + result = I2C_MasterStop(base); + } + else + { + base->C1 |= I2C_C1_TX_MASK; + } + } + + /* Send NAK at the last receive byte. */ + if (handle->transfer.dataSize == 1) + { + base->C1 |= I2C_C1_TXAK_MASK; + } + + /* Read the data byte into the transfer buffer. */ + *handle->transfer.data = base->D; + handle->transfer.data++; + } + break; + + default: + break; + } + + return result; +} + +static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle) +{ + /* Check if master interrupt. */ + if ((base->S & kI2C_ArbitrationLostFlag) || (base->C1 & I2C_C1_MST_MASK)) + { + s_i2cMasterIsr(base, handle); + } + else + { + s_i2cSlaveIsr(base, handle); + } + __DSB(); +} + +void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz) +{ + assert(masterConfig && srcClock_Hz); + + /* Temporary register for filter read. */ + uint8_t fltReg; +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + uint8_t c2Reg; +#endif +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + uint8_t s2Reg; +#endif +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable I2C clock. */ + CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Disable I2C prior to configuring it. */ + base->C1 &= ~(I2C_C1_IICEN_MASK); + + /* Clear all flags. */ + I2C_MasterClearStatusFlags(base, kClearFlags); + + /* Configure baud rate. */ + I2C_MasterSetBaudRate(base, masterConfig->baudRate_Bps, srcClock_Hz); + +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + /* Configure high drive feature. */ + c2Reg = base->C2; + c2Reg &= ~(I2C_C2_HDRS_MASK); + c2Reg |= I2C_C2_HDRS(masterConfig->enableHighDrive); + base->C2 = c2Reg; +#endif + + /* Read out the FLT register. */ + fltReg = base->FLT; + +#if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF + /* Configure the stop / hold enable. */ + fltReg &= ~(I2C_FLT_SHEN_MASK); + fltReg |= I2C_FLT_SHEN(masterConfig->enableStopHold); +#endif + + /* Configure the glitch filter value. */ + fltReg &= ~(I2C_FLT_FLT_MASK); + fltReg |= I2C_FLT_FLT(masterConfig->glitchFilterWidth); + + /* Write the register value back to the filter register. */ + base->FLT = fltReg; + +/* Enable/Disable double buffering. */ +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + s2Reg = base->S2 & (~I2C_S2_DFEN_MASK); + base->S2 = s2Reg | I2C_S2_DFEN(masterConfig->enableDoubleBuffering); +#endif + + /* Enable the I2C peripheral based on the configuration. */ + base->C1 = I2C_C1_IICEN(masterConfig->enableMaster); +} + +void I2C_MasterDeinit(I2C_Type *base) +{ + /* Disable I2C module. */ + I2C_Enable(base, false); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable I2C clock. */ + CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig) +{ + assert(masterConfig); + + /* Default baud rate at 100kbps. */ + masterConfig->baudRate_Bps = 100000U; + +/* Default pin high drive is disabled. */ +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + masterConfig->enableHighDrive = false; +#endif + +/* Default stop hold enable is disabled. */ +#if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF + masterConfig->enableStopHold = false; +#endif + + /* Default glitch filter value is no filter. */ + masterConfig->glitchFilterWidth = 0U; + +/* Default enable double buffering. */ +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + masterConfig->enableDoubleBuffering = true; +#endif + + /* Enable the I2C peripheral. */ + masterConfig->enableMaster = true; +} + +void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask) +{ +#ifdef I2C_HAS_STOP_DETECT + uint8_t fltReg; +#endif + + if (mask & kI2C_GlobalInterruptEnable) + { + base->C1 |= I2C_C1_IICIE_MASK; + } + +#if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT + if (mask & kI2C_StopDetectInterruptEnable) + { + fltReg = base->FLT; + + /* Keep STOPF flag. */ + fltReg &= ~I2C_FLT_STOPF_MASK; + + /* Stop detect enable. */ + fltReg |= I2C_FLT_STOPIE_MASK; + base->FLT = fltReg; + } +#endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */ + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + if (mask & kI2C_StartStopDetectInterruptEnable) + { + fltReg = base->FLT; + + /* Keep STARTF and STOPF flags. */ + fltReg &= ~(I2C_FLT_STOPF_MASK | I2C_FLT_STARTF_MASK); + + /* Start and stop detect enable. */ + fltReg |= I2C_FLT_SSIE_MASK; + base->FLT = fltReg; + } +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ +} + +void I2C_DisableInterrupts(I2C_Type *base, uint32_t mask) +{ + if (mask & kI2C_GlobalInterruptEnable) + { + base->C1 &= ~I2C_C1_IICIE_MASK; + } + +#if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT + if (mask & kI2C_StopDetectInterruptEnable) + { + base->FLT &= ~(I2C_FLT_STOPIE_MASK | I2C_FLT_STOPF_MASK); + } +#endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */ + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + if (mask & kI2C_StartStopDetectInterruptEnable) + { + base->FLT &= ~(I2C_FLT_SSIE_MASK | I2C_FLT_STOPF_MASK | I2C_FLT_STARTF_MASK); + } +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ +} + +void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) +{ + uint32_t multiplier; + uint32_t computedRate; + uint32_t absError; + uint32_t bestError = UINT32_MAX; + uint32_t bestMult = 0u; + uint32_t bestIcr = 0u; + uint8_t mult; + uint8_t i; + + /* Search for the settings with the lowest error. Mult is the MULT field of the I2C_F register, + * and ranges from 0-2. It selects the multiplier factor for the divider. */ + for (mult = 0u; (mult <= 2u) && (bestError != 0); ++mult) + { + multiplier = 1u << mult; + + /* Scan table to find best match. */ + for (i = 0u; i < sizeof(s_i2cDividerTable) / sizeof(uint16_t); ++i) + { + computedRate = srcClock_Hz / (multiplier * s_i2cDividerTable[i]); + absError = baudRate_Bps > computedRate ? (baudRate_Bps - computedRate) : (computedRate - baudRate_Bps); + + if (absError < bestError) + { + bestMult = mult; + bestIcr = i; + bestError = absError; + + /* If the error is 0, then we can stop searching because we won't find a better match. */ + if (absError == 0) + { + break; + } + } + } + } + + /* Set frequency register based on best settings. */ + base->F = I2C_F_MULT(bestMult) | I2C_F_ICR(bestIcr); +} + +status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction) +{ + status_t result = kStatus_Success; + uint32_t statusFlags = I2C_MasterGetStatusFlags(base); + + /* Return an error if the bus is already in use. */ + if (statusFlags & kI2C_BusBusyFlag) + { + result = kStatus_I2C_Busy; + } + else + { + /* Send the START signal. */ + base->C1 |= I2C_C1_MST_MASK | I2C_C1_TX_MASK; + +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING + while (!(base->S2 & I2C_S2_EMPTY_MASK)) + { + } +#endif /* FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING */ + + base->D = (((uint32_t)address) << 1U | ((direction == kI2C_Read) ? 1U : 0U)); + } + + return result; +} + +status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction) +{ + status_t result = kStatus_Success; + uint8_t savedMult; + uint32_t statusFlags = I2C_MasterGetStatusFlags(base); + uint8_t timeDelay = 6; + + /* Return an error if the bus is already in use, but not by us. */ + if ((statusFlags & kI2C_BusBusyFlag) && ((base->C1 & I2C_C1_MST_MASK) == 0)) + { + result = kStatus_I2C_Busy; + } + else + { + savedMult = base->F; + base->F = savedMult & (~I2C_F_MULT_MASK); + + /* We are already in a transfer, so send a repeated start. */ + base->C1 |= I2C_C1_RSTA_MASK | I2C_C1_TX_MASK; + + /* Restore the multiplier factor. */ + base->F = savedMult; + + /* Add some delay to wait the Re-Start signal. */ + while (timeDelay--) + { + __NOP(); + } + +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING + while (!(base->S2 & I2C_S2_EMPTY_MASK)) + { + } +#endif /* FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING */ + + base->D = (((uint32_t)address) << 1U | ((direction == kI2C_Read) ? 1U : 0U)); + } + + return result; +} + +status_t I2C_MasterStop(I2C_Type *base) +{ + status_t result = kStatus_Success; + uint16_t timeout = UINT16_MAX; + + /* Issue the STOP command on the bus. */ + base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* Wait until data transfer complete. */ + while ((base->S & kI2C_BusBusyFlag) && (--timeout)) + { + } + + if (timeout == 0) + { + result = kStatus_I2C_Timeout; + } + + return result; +} + +uint32_t I2C_MasterGetStatusFlags(I2C_Type *base) +{ + uint32_t statusFlags = base->S; + +#ifdef I2C_HAS_STOP_DETECT + /* Look up the STOPF bit from the filter register. */ + if (base->FLT & I2C_FLT_STOPF_MASK) + { + statusFlags |= kI2C_StopDetectFlag; + } +#endif + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + /* Look up the STARTF bit from the filter register. */ + if (base->FLT & I2C_FLT_STARTF_MASK) + { + statusFlags |= kI2C_StartDetectFlag; + } +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ + + return statusFlags; +} + +status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize, uint32_t flags) +{ + status_t result = kStatus_Success; + uint8_t statusFlags = 0; + + /* Wait until the data register is ready for transmit. */ + while (!(base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Setup the I2C peripheral to transmit data. */ + base->C1 |= I2C_C1_TX_MASK; + + while (txSize--) + { + /* Send a byte of data. */ + base->D = *txBuff++; + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + statusFlags = base->S; + + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Check if arbitration lost or no acknowledgement (NAK), return failure status. */ + if (statusFlags & kI2C_ArbitrationLostFlag) + { + base->S = kI2C_ArbitrationLostFlag; + result = kStatus_I2C_ArbitrationLost; + } + + if ((statusFlags & kI2C_ReceiveNakFlag) && txSize) + { + base->S = kI2C_ReceiveNakFlag; + result = kStatus_I2C_Nak; + } + + if (result != kStatus_Success) + { + /* Breaking out of the send loop. */ + break; + } + } + + if (((result == kStatus_Success) && (!(flags & kI2C_TransferNoStopFlag))) || (result == kStatus_I2C_Nak)) + { + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Send stop. */ + result = I2C_MasterStop(base); + } + + return result; +} + +status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize, uint32_t flags) +{ + status_t result = kStatus_Success; + volatile uint8_t dummy = 0; + + /* Add this to avoid build warning. */ + dummy++; + + /* Wait until the data register is ready for transmit. */ + while (!(base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Setup the I2C peripheral to receive data. */ + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* If rxSize equals 1, configure to send NAK. */ + if (rxSize == 1) + { + /* Issue NACK on read. */ + base->C1 |= I2C_C1_TXAK_MASK; + } + + /* Do dummy read. */ + dummy = base->D; + + while ((rxSize--)) + { + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Single byte use case. */ + if (rxSize == 0) + { + if (!(flags & kI2C_TransferNoStopFlag)) + { + /* Issue STOP command before reading last byte. */ + result = I2C_MasterStop(base); + } + else + { + /* Change direction to Tx to avoid extra clocks. */ + base->C1 |= I2C_C1_TX_MASK; + } + } + + if (rxSize == 1) + { + /* Issue NACK on read. */ + base->C1 |= I2C_C1_TXAK_MASK; + } + + /* Read from the data register. */ + *rxBuff++ = base->D; + } + + return result; +} + +status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer) +{ + assert(xfer); + + i2c_direction_t direction = xfer->direction; + status_t result = kStatus_Success; + + /* Clear all status before transfer. */ + I2C_MasterClearStatusFlags(base, kClearFlags); + + /* Wait until ready to complete. */ + while (!(base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Change to send write address when it's a read operation with command. */ + if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read)) + { + direction = kI2C_Write; + } + + /* If repeated start is requested, send repeated start. */ + if (xfer->flags & kI2C_TransferRepeatedStartFlag) + { + result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, direction); + } + else /* For normal transfer, send start. */ + { + result = I2C_MasterStart(base, xfer->slaveAddress, direction); + } + + /* Return if error. */ + if (result) + { + return result; + } + + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + /* Return if error. */ + if (result) + { + if (result == kStatus_I2C_Nak) + { + result = kStatus_I2C_Addr_Nak; + + I2C_MasterStop(base); + } + + return result; + } + + /* Send subaddress. */ + if (xfer->subaddressSize) + { + do + { + /* Clear interrupt pending flag. */ + base->S = kI2C_IntPendingFlag; + + xfer->subaddressSize--; + base->D = ((xfer->subaddress) >> (8 * xfer->subaddressSize)); + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + if (result) + { + if (result == kStatus_I2C_Nak) + { + I2C_MasterStop(base); + } + + return result; + } + + } while ((xfer->subaddressSize > 0) && (result == kStatus_Success)); + + if (xfer->direction == kI2C_Read) + { + /* Clear pending flag. */ + base->S = kI2C_IntPendingFlag; + + /* Send repeated start and slave address. */ + result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, kI2C_Read); + + /* Return if error. */ + if (result) + { + return result; + } + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + if (result) + { + if (result == kStatus_I2C_Nak) + { + result = kStatus_I2C_Addr_Nak; + + I2C_MasterStop(base); + } + + return result; + } + } + } + + /* Transmit data. */ + if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0)) + { + /* Send Data. */ + result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize, xfer->flags); + } + + /* Receive Data. */ + if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0)) + { + result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize, xfer->flags); + } + + return result; +} + +void I2C_MasterTransferCreateHandle(I2C_Type *base, + i2c_master_handle_t *handle, + i2c_master_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + uint32_t instance = I2C_GetInstance(base); + + /* Zero handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Set callback and userData. */ + handle->completionCallback = callback; + handle->userData = userData; + + /* Save the context in global variables to support the double weak mechanism. */ + s_i2cHandle[instance] = handle; + + /* Save master interrupt handler. */ + s_i2cMasterIsr = I2C_MasterTransferHandleIRQ; + + /* Enable NVIC interrupt. */ + EnableIRQ(s_i2cIrqs[instance]); +} + +status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + status_t result = kStatus_Success; + + /* Check if the I2C bus is idle - if not return busy status. */ + if (handle->state != kIdleState) + { + result = kStatus_I2C_Busy; + } + else + { + /* Start up the master transfer state machine. */ + result = I2C_InitTransferStateMachine(base, handle, xfer); + + if (result == kStatus_Success) + { + /* Enable the I2C interrupts. */ + I2C_EnableInterrupts(base, kI2C_GlobalInterruptEnable); + } + } + + return result; +} + +void I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle) +{ + assert(handle); + + volatile uint8_t dummy = 0; + + /* Add this to avoid build warning. */ + dummy++; + + /* Disable interrupt. */ + I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable); + + /* Reset the state to idle. */ + handle->state = kIdleState; + + /* Send STOP signal. */ + if (handle->transfer.direction == kI2C_Read) + { + base->C1 |= I2C_C1_TXAK_MASK; + while (!(base->S & kI2C_IntPendingFlag)) + { + } + base->S = kI2C_IntPendingFlag; + + base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + dummy = base->D; + } + else + { + while (!(base->S & kI2C_IntPendingFlag)) + { + } + base->S = kI2C_IntPendingFlag; + base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + } +} + +status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + *count = handle->transferSize - handle->transfer.dataSize; + + return kStatus_Success; +} + +void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle) +{ + assert(i2cHandle); + + i2c_master_handle_t *handle = (i2c_master_handle_t *)i2cHandle; + status_t result = kStatus_Success; + bool isDone; + + /* Clear the interrupt flag. */ + base->S = kI2C_IntPendingFlag; + + /* Check transfer complete flag. */ + result = I2C_MasterTransferRunStateMachine(base, handle, &isDone); + + if (isDone || result) + { + /* Send stop command if transfer done or received Nak. */ + if ((!(handle->transfer.flags & kI2C_TransferNoStopFlag)) || (result == kStatus_I2C_Nak) || + (result == kStatus_I2C_Addr_Nak)) + { + /* Ensure stop command is a need. */ + if ((base->C1 & I2C_C1_MST_MASK)) + { + if (I2C_MasterStop(base) != kStatus_Success) + { + result = kStatus_I2C_Timeout; + } + } + } + + /* Restore handle to idle state. */ + handle->state = kIdleState; + + /* Disable interrupt. */ + I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable); + + /* Call the callback function after the function has completed. */ + if (handle->completionCallback) + { + handle->completionCallback(base, handle, result, handle->userData); + } + } +} + +void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz) +{ + assert(slaveConfig); + + uint8_t tmpReg; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Configure addressing mode. */ + switch (slaveConfig->addressingMode) + { + case kI2C_Address7bit: + base->A1 = ((uint32_t)(slaveConfig->slaveAddress)) << 1U; + break; + + case kI2C_RangeMatch: + assert(slaveConfig->slaveAddress < slaveConfig->upperAddress); + base->A1 = ((uint32_t)(slaveConfig->slaveAddress)) << 1U; + base->RA = ((uint32_t)(slaveConfig->upperAddress)) << 1U; + base->C2 |= I2C_C2_RMEN_MASK; + break; + + default: + break; + } + + /* Configure low power wake up feature. */ + tmpReg = base->C1; + tmpReg &= ~I2C_C1_WUEN_MASK; + base->C1 = tmpReg | I2C_C1_WUEN(slaveConfig->enableWakeUp) | I2C_C1_IICEN(slaveConfig->enableSlave); + + /* Configure general call & baud rate control & high drive feature. */ + tmpReg = base->C2; + tmpReg &= ~(I2C_C2_SBRC_MASK | I2C_C2_GCAEN_MASK); + tmpReg |= I2C_C2_SBRC(slaveConfig->enableBaudRateCtl) | I2C_C2_GCAEN(slaveConfig->enableGeneralCall); +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + tmpReg &= ~I2C_C2_HDRS_MASK; + tmpReg |= I2C_C2_HDRS(slaveConfig->enableHighDrive); +#endif + base->C2 = tmpReg; + +/* Enable/Disable double buffering. */ +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + tmpReg = base->S2 & (~I2C_S2_DFEN_MASK); + base->S2 = tmpReg | I2C_S2_DFEN(slaveConfig->enableDoubleBuffering); +#endif + + /* Set hold time. */ + I2C_SetHoldTime(base, slaveConfig->sclStopHoldTime_ns, srcClock_Hz); +} + +void I2C_SlaveDeinit(I2C_Type *base) +{ + /* Disable I2C module. */ + I2C_Enable(base, false); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable I2C clock. */ + CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig) +{ + assert(slaveConfig); + + /* By default slave is addressed with 7-bit address. */ + slaveConfig->addressingMode = kI2C_Address7bit; + + /* General call mode is disabled by default. */ + slaveConfig->enableGeneralCall = false; + + /* Slave address match waking up MCU from low power mode is disabled. */ + slaveConfig->enableWakeUp = false; + +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + /* Default pin high drive is disabled. */ + slaveConfig->enableHighDrive = false; +#endif + + /* Independent slave mode baud rate at maximum frequency is disabled. */ + slaveConfig->enableBaudRateCtl = false; + +/* Default enable double buffering. */ +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + slaveConfig->enableDoubleBuffering = true; +#endif + + /* Set default SCL stop hold time to 4us which is minimum requirement in I2C spec. */ + slaveConfig->sclStopHoldTime_ns = 4000; + + /* Enable the I2C peripheral. */ + slaveConfig->enableSlave = true; +} + +status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize) +{ + status_t result = kStatus_Success; + volatile uint8_t dummy = 0; + + /* Add this to avoid build warning. */ + dummy++; + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + /* Check start flag. */ + while (!(base->FLT & I2C_FLT_STARTF_MASK)) + { + } + /* Clear STARTF flag. */ + base->FLT |= I2C_FLT_STARTF_MASK; + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ + + /* Wait for address match flag. */ + while (!(base->S & kI2C_AddressMatchFlag)) + { + } + + /* Read dummy to release bus. */ + dummy = base->D; + + result = I2C_MasterWriteBlocking(base, txBuff, txSize, kI2C_TransferDefaultFlag); + + /* Switch to receive mode. */ + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* Read dummy to release bus. */ + dummy = base->D; + + return result; +} + +void I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize) +{ + volatile uint8_t dummy = 0; + + /* Add this to avoid build warning. */ + dummy++; + +/* Wait until address match. */ +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + /* Check start flag. */ + while (!(base->FLT & I2C_FLT_STARTF_MASK)) + { + } + /* Clear STARTF flag. */ + base->FLT |= I2C_FLT_STARTF_MASK; + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ + + /* Wait for address match and int pending flag. */ + while (!(base->S & kI2C_AddressMatchFlag)) + { + } + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Read dummy to release bus. */ + dummy = base->D; + + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Setup the I2C peripheral to receive data. */ + base->C1 &= ~(I2C_C1_TX_MASK); + + while (rxSize--) + { + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Read from the data register. */ + *rxBuff++ = base->D; + } +} + +void I2C_SlaveTransferCreateHandle(I2C_Type *base, + i2c_slave_handle_t *handle, + i2c_slave_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + uint32_t instance = I2C_GetInstance(base); + + /* Zero handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Set callback and userData. */ + handle->callback = callback; + handle->userData = userData; + + /* Save the context in global variables to support the double weak mechanism. */ + s_i2cHandle[instance] = handle; + + /* Save slave interrupt handler. */ + s_i2cSlaveIsr = I2C_SlaveTransferHandleIRQ; + + /* Enable NVIC interrupt. */ + EnableIRQ(s_i2cIrqs[instance]); +} + +status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask) +{ + assert(handle); + + /* Check if the I2C bus is idle - if not return busy status. */ + if (handle->isBusy) + { + return kStatus_I2C_Busy; + } + else + { + /* Disable LPI2C IRQ sources while we configure stuff. */ + I2C_DisableInterrupts(base, kIrqFlags); + + /* Clear transfer in handle. */ + memset(&handle->transfer, 0, sizeof(handle->transfer)); + + /* Record that we're busy. */ + handle->isBusy = true; + + /* Set up event mask. tx and rx are always enabled. */ + handle->eventMask = eventMask | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent | kI2C_SlaveGenaralcallEvent; + + /* Clear all flags. */ + I2C_SlaveClearStatusFlags(base, kClearFlags); + + /* Enable I2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */ + I2C_EnableInterrupts(base, kIrqFlags); + } + + return kStatus_Success; +} + +void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle) +{ + assert(handle); + + if (handle->isBusy) + { + /* Disable interrupts. */ + I2C_DisableInterrupts(base, kIrqFlags); + + /* Reset transfer info. */ + memset(&handle->transfer, 0, sizeof(handle->transfer)); + + /* Reset the state to idle. */ + handle->isBusy = false; + } +} + +status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (!handle->isBusy) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + /* For an active transfer, just return the count from the handle. */ + *count = handle->transfer.transferredCount; + + return kStatus_Success; +} + +void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle) +{ + assert(i2cHandle); + + uint16_t status; + bool doTransmit = false; + i2c_slave_handle_t *handle = (i2c_slave_handle_t *)i2cHandle; + i2c_slave_transfer_t *xfer; + volatile uint8_t dummy = 0; + + /* Add this to avoid build warning. */ + dummy++; + + status = I2C_SlaveGetStatusFlags(base); + xfer = &(handle->transfer); + +#ifdef I2C_HAS_STOP_DETECT + /* Check stop flag. */ + if (status & kI2C_StopDetectFlag) + { + I2C_MasterClearStatusFlags(base, kI2C_StopDetectFlag); + + /* Clear the interrupt flag. */ + base->S = kI2C_IntPendingFlag; + + /* Call slave callback if this is the STOP of the transfer. */ + if (handle->isBusy) + { + xfer->event = kI2C_SlaveCompletionEvent; + xfer->completionStatus = kStatus_Success; + handle->isBusy = false; + + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + } + + return; + } +#endif /* I2C_HAS_STOP_DETECT */ + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + /* Check start flag. */ + if (status & kI2C_StartDetectFlag) + { + I2C_MasterClearStatusFlags(base, kI2C_StartDetectFlag); + + /* Clear the interrupt flag. */ + base->S = kI2C_IntPendingFlag; + + xfer->event = kI2C_SlaveStartEvent; + + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + + if (!(status & kI2C_AddressMatchFlag)) + { + return; + } + } +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ + + /* Clear the interrupt flag. */ + base->S = kI2C_IntPendingFlag; + + /* Check NAK */ + if (status & kI2C_ReceiveNakFlag) + { + /* Set receive mode. */ + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* Read dummy. */ + dummy = base->D; + + if (handle->transfer.dataSize != 0) + { + xfer->event = kI2C_SlaveCompletionEvent; + xfer->completionStatus = kStatus_I2C_Nak; + handle->isBusy = false; + + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + } + else + { +#ifndef I2C_HAS_STOP_DETECT + xfer->event = kI2C_SlaveCompletionEvent; + xfer->completionStatus = kStatus_Success; + handle->isBusy = false; + + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } +#endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */ + } + } + /* Check address match. */ + else if (status & kI2C_AddressMatchFlag) + { + handle->isBusy = true; + xfer->event = kI2C_SlaveAddressMatchEvent; + + /* Slave transmit, master reading from slave. */ + if (status & kI2C_TransferDirectionFlag) + { + /* Change direction to send data. */ + base->C1 |= I2C_C1_TX_MASK; + + doTransmit = true; + } + else + { + /* Slave receive, master writing to slave. */ + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* Read dummy to release the bus. */ + dummy = base->D; + + if (dummy == 0) + { + xfer->event = kI2C_SlaveGenaralcallEvent; + } + } + + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + } + /* Check transfer complete flag. */ + else if (status & kI2C_TransferCompleteFlag) + { + /* Slave transmit, master reading from slave. */ + if (status & kI2C_TransferDirectionFlag) + { + doTransmit = true; + } + else + { + /* If we're out of data, invoke callback to get more. */ + if ((!xfer->data) || (!xfer->dataSize)) + { + xfer->event = kI2C_SlaveReceiveEvent; + + if (handle->callback) + { + handle->callback(base, xfer, handle->userData); + } + + /* Clear the transferred count now that we have a new buffer. */ + xfer->transferredCount = 0; + } + + /* Slave receive, master writing to slave. */ + uint8_t data = base->D; + + if (handle->transfer.dataSize) + { + /* Receive data. */ + *handle->transfer.data++ = data; + handle->transfer.dataSize--; + xfer->transferredCount++; + if (!handle->transfer.dataSize) + { +#ifndef I2C_HAS_STOP_DETECT + xfer->event = kI2C_SlaveCompletionEvent; + xfer->completionStatus = kStatus_Success; + handle->isBusy = false; + + /* Proceed receive complete event. */ + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } +#endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */ + } + } + } + } + else + { + /* Read dummy to release bus. */ + dummy = base->D; + } + + /* Send data if there is the need. */ + if (doTransmit) + { + /* If we're out of data, invoke callback to get more. */ + if ((!xfer->data) || (!xfer->dataSize)) + { + xfer->event = kI2C_SlaveTransmitEvent; + + if (handle->callback) + { + handle->callback(base, xfer, handle->userData); + } + + /* Clear the transferred count now that we have a new buffer. */ + xfer->transferredCount = 0; + } + + if (handle->transfer.dataSize) + { + /* Send data. */ + base->D = *handle->transfer.data++; + handle->transfer.dataSize--; + xfer->transferredCount++; + } + else + { + /* Switch to receive mode. */ + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* Read dummy to release bus. */ + dummy = base->D; + +#ifndef I2C_HAS_STOP_DETECT + xfer->event = kI2C_SlaveCompletionEvent; + xfer->completionStatus = kStatus_Success; + handle->isBusy = false; + + /* Proceed txdone event. */ + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } +#endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */ + } + } +} + +void I2C0_DriverIRQHandler(void) +{ + I2C_TransferCommonIRQHandler(I2C0, s_i2cHandle[0]); +} + +#if (FSL_FEATURE_SOC_I2C_COUNT > 1) +void I2C1_DriverIRQHandler(void) +{ + I2C_TransferCommonIRQHandler(I2C1, s_i2cHandle[1]); +} +#endif /* I2C COUNT > 1 */ + +#if (FSL_FEATURE_SOC_I2C_COUNT > 2) +void I2C2_DriverIRQHandler(void) +{ + I2C_TransferCommonIRQHandler(I2C2, s_i2cHandle[2]); +} +#endif /* I2C COUNT > 2 */ +#if (FSL_FEATURE_SOC_I2C_COUNT > 3) +void I2C3_DriverIRQHandler(void) +{ + I2C_TransferCommonIRQHandler(I2C3, s_i2cHandle[3]); +} +#endif /* I2C COUNT > 3 */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c.h new file mode 100644 index 00000000000..797c2a0162f --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c.h @@ -0,0 +1,800 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_I2C_H_ +#define _FSL_I2C_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup i2c_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief I2C driver version 2.0.2. */ +#define FSL_I2C_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) +/*@}*/ + +#if (defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT || \ + defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT) +#define I2C_HAS_STOP_DETECT +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT / FSL_FEATURE_I2C_HAS_STOP_DETECT */ + +/*! @brief I2C status return codes. */ +enum _i2c_status +{ + kStatus_I2C_Busy = MAKE_STATUS(kStatusGroup_I2C, 0), /*!< I2C is busy with current transfer. */ + kStatus_I2C_Idle = MAKE_STATUS(kStatusGroup_I2C, 1), /*!< Bus is Idle. */ + kStatus_I2C_Nak = MAKE_STATUS(kStatusGroup_I2C, 2), /*!< NAK received during transfer. */ + kStatus_I2C_ArbitrationLost = MAKE_STATUS(kStatusGroup_I2C, 3), /*!< Arbitration lost during transfer. */ + kStatus_I2C_Timeout = MAKE_STATUS(kStatusGroup_I2C, 4), /*!< Wait event timeout. */ + kStatus_I2C_Addr_Nak = MAKE_STATUS(kStatusGroup_I2C, 5), /*!< NAK received during the address probe. */ +}; + +/*! + * @brief I2C peripheral flags + * + * The following status register flags can be cleared: + * - #kI2C_ArbitrationLostFlag + * - #kI2C_IntPendingFlag + * - #kI2C_StartDetectFlag + * - #kI2C_StopDetectFlag + * + * @note These enumerations are meant to be OR'd together to form a bit mask. + * + */ +enum _i2c_flags +{ + kI2C_ReceiveNakFlag = I2C_S_RXAK_MASK, /*!< I2C receive NAK flag. */ + kI2C_IntPendingFlag = I2C_S_IICIF_MASK, /*!< I2C interrupt pending flag. */ + kI2C_TransferDirectionFlag = I2C_S_SRW_MASK, /*!< I2C transfer direction flag. */ + kI2C_RangeAddressMatchFlag = I2C_S_RAM_MASK, /*!< I2C range address match flag. */ + kI2C_ArbitrationLostFlag = I2C_S_ARBL_MASK, /*!< I2C arbitration lost flag. */ + kI2C_BusBusyFlag = I2C_S_BUSY_MASK, /*!< I2C bus busy flag. */ + kI2C_AddressMatchFlag = I2C_S_IAAS_MASK, /*!< I2C address match flag. */ + kI2C_TransferCompleteFlag = I2C_S_TCF_MASK, /*!< I2C transfer complete flag. */ +#ifdef I2C_HAS_STOP_DETECT + kI2C_StopDetectFlag = I2C_FLT_STOPF_MASK << 8, /*!< I2C stop detect flag. */ +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT / FSL_FEATURE_I2C_HAS_STOP_DETECT */ + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + kI2C_StartDetectFlag = I2C_FLT_STARTF_MASK << 8, /*!< I2C start detect flag. */ +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ +}; + +/*! @brief I2C feature interrupt source. */ +enum _i2c_interrupt_enable +{ + kI2C_GlobalInterruptEnable = I2C_C1_IICIE_MASK, /*!< I2C global interrupt. */ + +#if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT + kI2C_StopDetectInterruptEnable = I2C_FLT_STOPIE_MASK, /*!< I2C stop detect interrupt. */ +#endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */ + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + kI2C_StartStopDetectInterruptEnable = I2C_FLT_SSIE_MASK, /*!< I2C start&stop detect interrupt. */ +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ +}; + +/*! @brief The direction of master and slave transfers. */ +typedef enum _i2c_direction +{ + kI2C_Write = 0x0U, /*!< Master transmits to the slave. */ + kI2C_Read = 0x1U, /*!< Master receives from the slave. */ +} i2c_direction_t; + +/*! @brief Addressing mode. */ +typedef enum _i2c_slave_address_mode +{ + kI2C_Address7bit = 0x0U, /*!< 7-bit addressing mode. */ + kI2C_RangeMatch = 0X2U, /*!< Range address match addressing mode. */ +} i2c_slave_address_mode_t; + +/*! @brief I2C transfer control flag. */ +enum _i2c_master_transfer_flags +{ + kI2C_TransferDefaultFlag = 0x0U, /*!< A transfer starts with a start signal, stops with a stop signal. */ + kI2C_TransferNoStartFlag = 0x1U, /*!< A transfer starts without a start signal. */ + kI2C_TransferRepeatedStartFlag = 0x2U, /*!< A transfer starts with a repeated start signal. */ + kI2C_TransferNoStopFlag = 0x4U, /*!< A transfer ends without a stop signal. */ +}; + +/*! + * @brief Set of events sent to the callback for nonblocking slave transfers. + * + * These event enumerations are used for two related purposes. First, a bit mask created by OR'ing together + * events is passed to I2C_SlaveTransferNonBlocking() to specify which events to enable. + * Then, when the slave callback is invoked, it is passed the current event through its @a transfer + * parameter. + * + * @note These enumerations are meant to be OR'd together to form a bit mask of events. + */ +typedef enum _i2c_slave_transfer_event +{ + kI2C_SlaveAddressMatchEvent = 0x01U, /*!< Received the slave address after a start or repeated start. */ + kI2C_SlaveTransmitEvent = 0x02U, /*!< A callback is requested to provide data to transmit + (slave-transmitter role). */ + kI2C_SlaveReceiveEvent = 0x04U, /*!< A callback is requested to provide a buffer in which to place received + data (slave-receiver role). */ + kI2C_SlaveTransmitAckEvent = 0x08U, /*!< A callback needs to either transmit an ACK or NACK. */ +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + kI2C_SlaveStartEvent = 0x10U, /*!< A start/repeated start was detected. */ +#endif + kI2C_SlaveCompletionEvent = 0x20U, /*!< A stop was detected or finished transfer, completing the transfer. */ + kI2C_SlaveGenaralcallEvent = 0x40U, /*!< Received the general call address after a start or repeated start. */ + + /*! A bit mask of all available events. */ + kI2C_SlaveAllEvents = kI2C_SlaveAddressMatchEvent | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent | +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + kI2C_SlaveStartEvent | +#endif + kI2C_SlaveCompletionEvent | kI2C_SlaveGenaralcallEvent, +} i2c_slave_transfer_event_t; + +/*! @brief I2C master user configuration. */ +typedef struct _i2c_master_config +{ + bool enableMaster; /*!< Enables the I2C peripheral at initialization time. */ +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + bool enableHighDrive; /*!< Controls the drive capability of the I2C pads. */ +#endif +#if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF + bool enableStopHold; /*!< Controls the stop hold enable. */ +#endif +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + bool enableDoubleBuffering; /*!< Controls double buffer enable; notice that + enabling the double buffer disables the clock stretch. */ +#endif + uint32_t baudRate_Bps; /*!< Baud rate configuration of I2C peripheral. */ + uint8_t glitchFilterWidth; /*!< Controls the width of the glitch. */ +} i2c_master_config_t; + +/*! @brief I2C slave user configuration. */ +typedef struct _i2c_slave_config +{ + bool enableSlave; /*!< Enables the I2C peripheral at initialization time. */ + bool enableGeneralCall; /*!< Enables the general call addressing mode. */ + bool enableWakeUp; /*!< Enables/disables waking up MCU from low-power mode. */ +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + bool enableHighDrive; /*!< Controls the drive capability of the I2C pads. */ +#endif +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + bool enableDoubleBuffering; /*!< Controls a double buffer enable; notice that + enabling the double buffer disables the clock stretch. */ +#endif + bool enableBaudRateCtl; /*!< Enables/disables independent slave baud rate on SCL in very fast I2C modes. */ + uint16_t slaveAddress; /*!< A slave address configuration. */ + uint16_t upperAddress; /*!< A maximum boundary slave address used in a range matching mode. */ + i2c_slave_address_mode_t + addressingMode; /*!< An addressing mode configuration of i2c_slave_address_mode_config_t. */ + uint32_t sclStopHoldTime_ns; /*!< the delay from the rising edge of SCL (I2C clock) to the rising edge of SDA (I2C + data) while SCL is high (stop condition), SDA hold time and SCL start hold time + are also configured according to the SCL stop hold time. */ +} i2c_slave_config_t; + +/*! @brief I2C master handle typedef. */ +typedef struct _i2c_master_handle i2c_master_handle_t; + +/*! @brief I2C master transfer callback typedef. */ +typedef void (*i2c_master_transfer_callback_t)(I2C_Type *base, + i2c_master_handle_t *handle, + status_t status, + void *userData); + +/*! @brief I2C slave handle typedef. */ +typedef struct _i2c_slave_handle i2c_slave_handle_t; + +/*! @brief I2C master transfer structure. */ +typedef struct _i2c_master_transfer +{ + uint32_t flags; /*!< A transfer flag which controls the transfer. */ + uint8_t slaveAddress; /*!< 7-bit slave address. */ + i2c_direction_t direction; /*!< A transfer direction, read or write. */ + uint32_t subaddress; /*!< A sub address. Transferred MSB first. */ + uint8_t subaddressSize; /*!< A size of the command buffer. */ + uint8_t *volatile data; /*!< A transfer buffer. */ + volatile size_t dataSize; /*!< A transfer size. */ +} i2c_master_transfer_t; + +/*! @brief I2C master handle structure. */ +struct _i2c_master_handle +{ + i2c_master_transfer_t transfer; /*!< I2C master transfer copy. */ + size_t transferSize; /*!< Total bytes to be transferred. */ + uint8_t state; /*!< A transfer state maintained during transfer. */ + i2c_master_transfer_callback_t completionCallback; /*!< A callback function called when the transfer is finished. */ + void *userData; /*!< A callback parameter passed to the callback function. */ +}; + +/*! @brief I2C slave transfer structure. */ +typedef struct _i2c_slave_transfer +{ + i2c_slave_transfer_event_t event; /*!< A reason that the callback is invoked. */ + uint8_t *volatile data; /*!< A transfer buffer. */ + volatile size_t dataSize; /*!< A transfer size. */ + status_t completionStatus; /*!< Success or error code describing how the transfer completed. Only applies for + #kI2C_SlaveCompletionEvent. */ + size_t transferredCount; /*!< A number of bytes actually transferred since the start or since the last repeated + start. */ +} i2c_slave_transfer_t; + +/*! @brief I2C slave transfer callback typedef. */ +typedef void (*i2c_slave_transfer_callback_t)(I2C_Type *base, i2c_slave_transfer_t *xfer, void *userData); + +/*! @brief I2C slave handle structure. */ +struct _i2c_slave_handle +{ + volatile bool isBusy; /*!< Indicates whether a transfer is busy. */ + i2c_slave_transfer_t transfer; /*!< I2C slave transfer copy. */ + uint32_t eventMask; /*!< A mask of enabled events. */ + i2c_slave_transfer_callback_t callback; /*!< A callback function called at the transfer event. */ + void *userData; /*!< A callback parameter passed to the callback. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus. */ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock + * and configure the I2C with master configuration. + * + * @note This API should be called at the beginning of the application. + * Otherwise, any operation to the I2C module can cause a hard fault + * because the clock is not enabled. The configuration structure can be custom filled + * or it can be set with default values by using the I2C_MasterGetDefaultConfig(). + * After calling this API, the master is ready to transfer. + * This is an example. + * @code + * i2c_master_config_t config = { + * .enableMaster = true, + * .enableStopHold = false, + * .highDrive = false, + * .baudRate_Bps = 100000, + * .glitchFilterWidth = 0 + * }; + * I2C_MasterInit(I2C0, &config, 12000000U); + * @endcode + * + * @param base I2C base pointer + * @param masterConfig A pointer to the master configuration structure + * @param srcClock_Hz I2C peripheral clock frequency in Hz + */ +void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz); + +/*! + * @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock + * and initialize the I2C with the slave configuration. + * + * @note This API should be called at the beginning of the application. + * Otherwise, any operation to the I2C module can cause a hard fault + * because the clock is not enabled. The configuration structure can partly be set + * with default values by I2C_SlaveGetDefaultConfig() or it can be custom filled by the user. + * This is an example. + * @code + * i2c_slave_config_t config = { + * .enableSlave = true, + * .enableGeneralCall = false, + * .addressingMode = kI2C_Address7bit, + * .slaveAddress = 0x1DU, + * .enableWakeUp = false, + * .enablehighDrive = false, + * .enableBaudRateCtl = false, + * .sclStopHoldTime_ns = 4000 + * }; + * I2C_SlaveInit(I2C0, &config, 12000000U); + * @endcode + * + * @param base I2C base pointer + * @param slaveConfig A pointer to the slave configuration structure + * @param srcClock_Hz I2C peripheral clock frequency in Hz + */ +void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz); + +/*! + * @brief De-initializes the I2C master peripheral. Call this API to gate the I2C clock. + * The I2C master module can't work unless the I2C_MasterInit is called. + * @param base I2C base pointer + */ +void I2C_MasterDeinit(I2C_Type *base); + +/*! + * @brief De-initializes the I2C slave peripheral. Calling this API gates the I2C clock. + * The I2C slave module can't work unless the I2C_SlaveInit is called to enable the clock. + * @param base I2C base pointer + */ +void I2C_SlaveDeinit(I2C_Type *base); + +/*! + * @brief Sets the I2C master configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in the I2C_MasterConfigure(). + * Use the initialized structure unchanged in the I2C_MasterConfigure() or modify + * the structure before calling the I2C_MasterConfigure(). + * This is an example. + * @code + * i2c_master_config_t config; + * I2C_MasterGetDefaultConfig(&config); + * @endcode + * @param masterConfig A pointer to the master configuration structure. +*/ +void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig); + +/*! + * @brief Sets the I2C slave configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in the I2C_SlaveConfigure(). + * Modify fields of the structure before calling the I2C_SlaveConfigure(). + * This is an example. + * @code + * i2c_slave_config_t config; + * I2C_SlaveGetDefaultConfig(&config); + * @endcode + * @param slaveConfig A pointer to the slave configuration structure. + */ +void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig); + +/*! + * @brief Enables or disabless the I2C peripheral operation. + * + * @param base I2C base pointer + * @param enable Pass true to enable and false to disable the module. + */ +static inline void I2C_Enable(I2C_Type *base, bool enable) +{ + if (enable) + { + base->C1 |= I2C_C1_IICEN_MASK; + } + else + { + base->C1 &= ~I2C_C1_IICEN_MASK; + } +} + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the I2C status flags. + * + * @param base I2C base pointer + * @return status flag, use status flag to AND #_i2c_flags to get the related status. + */ +uint32_t I2C_MasterGetStatusFlags(I2C_Type *base); + +/*! + * @brief Gets the I2C status flags. + * + * @param base I2C base pointer + * @return status flag, use status flag to AND #_i2c_flags to get the related status. + */ +static inline uint32_t I2C_SlaveGetStatusFlags(I2C_Type *base) +{ + return I2C_MasterGetStatusFlags(base); +} + +/*! + * @brief Clears the I2C status flag state. + * + * The following status register flags can be cleared kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag. + * + * @param base I2C base pointer + * @param statusMask The status flag mask, defined in type i2c_status_flag_t. + * The parameter can be any combination of the following values: + * @arg kI2C_StartDetectFlag (if available) + * @arg kI2C_StopDetectFlag (if available) + * @arg kI2C_ArbitrationLostFlag + * @arg kI2C_IntPendingFlagFlag + */ +static inline void I2C_MasterClearStatusFlags(I2C_Type *base, uint32_t statusMask) +{ +/* Must clear the STARTF / STOPF bits prior to clearing IICIF */ +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + if (statusMask & kI2C_StartDetectFlag) + { + /* Shift the odd-ball flags back into place. */ + base->FLT |= (uint8_t)(statusMask >> 8U); + } +#endif + +#ifdef I2C_HAS_STOP_DETECT + if (statusMask & kI2C_StopDetectFlag) + { + /* Shift the odd-ball flags back into place. */ + base->FLT |= (uint8_t)(statusMask >> 8U); + } +#endif + + base->S = (uint8_t)statusMask; +} + +/*! + * @brief Clears the I2C status flag state. + * + * The following status register flags can be cleared kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag + * + * @param base I2C base pointer + * @param statusMask The status flag mask, defined in type i2c_status_flag_t. + * The parameter can be any combination of the following values: + * @arg kI2C_StartDetectFlag (if available) + * @arg kI2C_StopDetectFlag (if available) + * @arg kI2C_ArbitrationLostFlag + * @arg kI2C_IntPendingFlagFlag + */ +static inline void I2C_SlaveClearStatusFlags(I2C_Type *base, uint32_t statusMask) +{ + I2C_MasterClearStatusFlags(base, statusMask); +} + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables I2C interrupt requests. + * + * @param base I2C base pointer + * @param mask interrupt source + * The parameter can be combination of the following source if defined: + * @arg kI2C_GlobalInterruptEnable + * @arg kI2C_StopDetectInterruptEnable/kI2C_StartDetectInterruptEnable + * @arg kI2C_SdaTimeoutInterruptEnable + */ +void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask); + +/*! + * @brief Disables I2C interrupt requests. + * + * @param base I2C base pointer + * @param mask interrupt source + * The parameter can be combination of the following source if defined: + * @arg kI2C_GlobalInterruptEnable + * @arg kI2C_StopDetectInterruptEnable/kI2C_StartDetectInterruptEnable + * @arg kI2C_SdaTimeoutInterruptEnable + */ +void I2C_DisableInterrupts(I2C_Type *base, uint32_t mask); + +/*! + * @name DMA Control + * @{ + */ +#if defined(FSL_FEATURE_I2C_HAS_DMA_SUPPORT) && FSL_FEATURE_I2C_HAS_DMA_SUPPORT +/*! + * @brief Enables/disables the I2C DMA interrupt. + * + * @param base I2C base pointer + * @param enable true to enable, false to disable +*/ +static inline void I2C_EnableDMA(I2C_Type *base, bool enable) +{ + if (enable) + { + base->C1 |= I2C_C1_DMAEN_MASK; + } + else + { + base->C1 &= ~I2C_C1_DMAEN_MASK; + } +} + +#endif /* FSL_FEATURE_I2C_HAS_DMA_SUPPORT */ + +/*! + * @brief Gets the I2C tx/rx data register address. This API is used to provide a transfer address + * for I2C DMA transfer configuration. + * + * @param base I2C base pointer + * @return data register address + */ +static inline uint32_t I2C_GetDataRegAddr(I2C_Type *base) +{ + return (uint32_t)(&(base->D)); +} + +/* @} */ +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Sets the I2C master transfer baud rate. + * + * @param base I2C base pointer + * @param baudRate_Bps the baud rate value in bps + * @param srcClock_Hz Source clock + */ +void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); + +/*! + * @brief Sends a START on the I2C bus. + * + * This function is used to initiate a new master mode transfer by sending the START signal. + * The slave address is sent following the I2C START signal. + * + * @param base I2C peripheral base pointer + * @param address 7-bit slave device address. + * @param direction Master transfer directions(transmit/receive). + * @retval kStatus_Success Successfully send the start signal. + * @retval kStatus_I2C_Busy Current bus is busy. + */ +status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction); + +/*! + * @brief Sends a STOP signal on the I2C bus. + * + * @retval kStatus_Success Successfully send the stop signal. + * @retval kStatus_I2C_Timeout Send stop signal failed, timeout. + */ +status_t I2C_MasterStop(I2C_Type *base); + +/*! + * @brief Sends a REPEATED START on the I2C bus. + * + * @param base I2C peripheral base pointer + * @param address 7-bit slave device address. + * @param direction Master transfer directions(transmit/receive). + * @retval kStatus_Success Successfully send the start signal. + * @retval kStatus_I2C_Busy Current bus is busy but not occupied by current I2C master. + */ +status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction); + +/*! + * @brief Performs a polling send transaction on the I2C bus. + * + * @param base The I2C peripheral base pointer. + * @param txBuff The pointer to the data to be transferred. + * @param txSize The length in bytes of the data to be transferred. + * @param flags Transfer control flag to decide whether need to send a stop, use kI2C_TransferDefaultFlag +* to issue a stop and kI2C_TransferNoStop to not send a stop. + * @retval kStatus_Success Successfully complete the data transmission. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. + */ +status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize, uint32_t flags); + +/*! + * @brief Performs a polling receive transaction on the I2C bus. + * + * @note The I2C_MasterReadBlocking function stops the bus before reading the final byte. + * Without stopping the bus prior for the final read, the bus issues another read, resulting + * in garbage data being read into the data register. + * + * @param base I2C peripheral base pointer. + * @param rxBuff The pointer to the data to store the received data. + * @param rxSize The length in bytes of the data to be received. + * @param flags Transfer control flag to decide whether need to send a stop, use kI2C_TransferDefaultFlag +* to issue a stop and kI2C_TransferNoStop to not send a stop. + * @retval kStatus_Success Successfully complete the data transmission. + * @retval kStatus_I2C_Timeout Send stop signal failed, timeout. + */ +status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize, uint32_t flags); + +/*! + * @brief Performs a polling send transaction on the I2C bus. + * + * @param base The I2C peripheral base pointer. + * @param txBuff The pointer to the data to be transferred. + * @param txSize The length in bytes of the data to be transferred. + * @retval kStatus_Success Successfully complete the data transmission. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. + */ +status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize); + +/*! + * @brief Performs a polling receive transaction on the I2C bus. + * + * @param base I2C peripheral base pointer. + * @param rxBuff The pointer to the data to store the received data. + * @param rxSize The length in bytes of the data to be received. + */ +void I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize); + +/*! + * @brief Performs a master polling transfer on the I2C bus. + * + * @note The API does not return until the transfer succeeds or fails due + * to arbitration lost or receiving a NAK. + * + * @param base I2C peripheral base address. + * @param xfer Pointer to the transfer structure. + * @retval kStatus_Success Successfully complete the data transmission. + * @retval kStatus_I2C_Busy Previous transmission still not finished. + * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. + */ +status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer); + +/* @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the I2C handle which is used in transactional functions. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_master_handle_t structure to store the transfer state. + * @param callback pointer to user callback function. + * @param userData user parameter passed to the callback function. + */ +void I2C_MasterTransferCreateHandle(I2C_Type *base, + i2c_master_handle_t *handle, + i2c_master_transfer_callback_t callback, + void *userData); + +/*! + * @brief Performs a master interrupt non-blocking transfer on the I2C bus. + * + * @note Calling the API returns immediately after transfer initiates. The user needs + * to call I2C_MasterGetTransferCount to poll the transfer status to check whether + * the transfer is finished. If the return status is not kStatus_I2C_Busy, the transfer + * is finished. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_master_handle_t structure which stores the transfer state. + * @param xfer pointer to i2c_master_transfer_t structure. + * @retval kStatus_Success Successfully start the data transmission. + * @retval kStatus_I2C_Busy Previous transmission still not finished. + * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. + */ +status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer); + +/*! + * @brief Gets the master transfer status during a interrupt non-blocking transfer. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_master_handle_t structure which stores the transfer state. + * @param count Number of bytes transferred so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count); + +/*! + * @brief Aborts an interrupt non-blocking transfer early. + * + * @note This API can be called at any time when an interrupt non-blocking transfer initiates + * to abort the transfer early. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_master_handle_t structure which stores the transfer state + */ +void I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle); + +/*! + * @brief Master interrupt handler. + * + * @param base I2C base pointer. + * @param i2cHandle pointer to i2c_master_handle_t structure. + */ +void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle); + +/*! + * @brief Initializes the I2C handle which is used in transactional functions. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_slave_handle_t structure to store the transfer state. + * @param callback pointer to user callback function. + * @param userData user parameter passed to the callback function. + */ +void I2C_SlaveTransferCreateHandle(I2C_Type *base, + i2c_slave_handle_t *handle, + i2c_slave_transfer_callback_t callback, + void *userData); + +/*! + * @brief Starts accepting slave transfers. + * + * Call this API after calling the I2C_SlaveInit() and I2C_SlaveTransferCreateHandle() to start processing + * transactions driven by an I2C master. The slave monitors the I2C bus and passes events to the + * callback that was passed into the call to I2C_SlaveTransferCreateHandle(). The callback is always invoked + * from the interrupt context. + * + * The set of events received by the callback is customizable. To do so, set the @a eventMask parameter to + * the OR'd combination of #i2c_slave_transfer_event_t enumerators for the events you wish to receive. + * The #kI2C_SlaveTransmitEvent and #kLPI2C_SlaveReceiveEvent events are always enabled and do not need + * to be included in the mask. Alternatively, pass 0 to get a default set of only the transmit and + * receive events that are always enabled. In addition, the #kI2C_SlaveAllEvents constant is provided as + * a convenient way to enable all events. + * + * @param base The I2C peripheral base address. + * @param handle Pointer to #i2c_slave_handle_t structure which stores the transfer state. + * @param eventMask Bit mask formed by OR'ing together #i2c_slave_transfer_event_t enumerators to specify + * which events to send to the callback. Other accepted values are 0 to get a default set of + * only the transmit and receive events, and #kI2C_SlaveAllEvents to enable all events. + * + * @retval #kStatus_Success Slave transfers were successfully started. + * @retval #kStatus_I2C_Busy Slave transfers have already been started on this handle. + */ +status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask); + +/*! + * @brief Aborts the slave transfer. + * + * @note This API can be called at any time to stop slave for handling the bus events. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_slave_handle_t structure which stores the transfer state. + */ +void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle); + +/*! + * @brief Gets the slave transfer remaining bytes during a interrupt non-blocking transfer. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_slave_handle_t structure. + * @param count Number of bytes transferred so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count); + +/*! + * @brief Slave interrupt handler. + * + * @param base I2C base pointer. + * @param i2cHandle pointer to i2c_slave_handle_t structure which stores the transfer state + */ +void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle); + +/* @} */ +#if defined(__cplusplus) +} +#endif /*_cplusplus. */ +/*@}*/ + +#endif /* _FSL_I2C_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c_edma.c new file mode 100644 index 00000000000..5a8df41c80f --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c_edma.c @@ -0,0 +1,568 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_i2c_edma.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*base, false); + + /* Send stop if kI2C_TransferNoStop flag is not asserted. */ + if (!(i2cPrivateHandle->handle->transfer.flags & kI2C_TransferNoStopFlag)) + { + if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read) + { + /* Change to send NAK at the last byte. */ + i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK; + + /* Wait the last data to be received. */ + while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Send stop signal. */ + result = I2C_MasterStop(i2cPrivateHandle->base); + + /* Read the last data byte. */ + *(i2cPrivateHandle->handle->transfer.data + i2cPrivateHandle->handle->transfer.dataSize - 1) = + i2cPrivateHandle->base->D; + } + else + { + /* Wait the last data to be sent. */ + while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Send stop signal. */ + result = I2C_MasterStop(i2cPrivateHandle->base); + } + } + else + { + if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read) + { + /* Change to send NAK at the last byte. */ + i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK; + + /* Wait the last data to be received. */ + while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Change direction to send. */ + i2cPrivateHandle->base->C1 |= I2C_C1_TX_MASK; + + /* Read the last data byte. */ + *(i2cPrivateHandle->handle->transfer.data + i2cPrivateHandle->handle->transfer.dataSize - 1) = + i2cPrivateHandle->base->D; + } + } + + i2cPrivateHandle->handle->state = kIdleState; + + if (i2cPrivateHandle->handle->completionCallback) + { + i2cPrivateHandle->handle->completionCallback(i2cPrivateHandle->base, i2cPrivateHandle->handle, result, + i2cPrivateHandle->handle->userData); + } +} + +static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status) +{ + status_t result = kStatus_Success; + + /* Check arbitration lost. */ + if (status & kI2C_ArbitrationLostFlag) + { + /* Clear arbitration lost flag. */ + base->S = kI2C_ArbitrationLostFlag; + result = kStatus_I2C_ArbitrationLost; + } + /* Check NAK */ + else if (status & kI2C_ReceiveNakFlag) + { + result = kStatus_I2C_Nak; + } + else + { + } + + return result; +} + +static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base, + i2c_master_edma_handle_t *handle, + i2c_master_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + status_t result = kStatus_Success; + + if (handle->state != kIdleState) + { + return kStatus_I2C_Busy; + } + else + { + i2c_direction_t direction = xfer->direction; + + /* Init the handle member. */ + handle->transfer = *xfer; + + /* Save total transfer size. */ + handle->transferSize = xfer->dataSize; + + handle->state = kTransferDataState; + + /* Clear all status before transfer. */ + I2C_MasterClearStatusFlags(base, kClearFlags); + + /* Change to send write address when it's a read operation with command. */ + if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read)) + { + direction = kI2C_Write; + } + + /* If repeated start is requested, send repeated start. */ + if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag) + { + result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction); + } + else /* For normal transfer, send start. */ + { + result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction); + } + + if (result) + { + return result; + } + + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + /* Return if error. */ + if (result) + { + if (result == kStatus_I2C_Nak) + { + result = kStatus_I2C_Addr_Nak; + + if (I2C_MasterStop(base) != kStatus_Success) + { + result = kStatus_I2C_Timeout; + } + + if (handle->completionCallback) + { + (handle->completionCallback)(base, handle, result, handle->userData); + } + } + + return result; + } + + /* Send subaddress. */ + if (handle->transfer.subaddressSize) + { + do + { + /* Clear interrupt pending flag. */ + base->S = kI2C_IntPendingFlag; + + handle->transfer.subaddressSize--; + base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize)); + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + if (result) + { + return result; + } + + } while ((handle->transfer.subaddressSize > 0) && (result == kStatus_Success)); + + if (handle->transfer.direction == kI2C_Read) + { + /* Clear pending flag. */ + base->S = kI2C_IntPendingFlag; + + /* Send repeated start and slave address. */ + result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read); + + if (result) + { + return result; + } + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + if (result) + { + return result; + } + } + } + + /* Clear pending flag. */ + base->S = kI2C_IntPendingFlag; + } + + return result; +} + +static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_t *handle) +{ + edma_transfer_config_t transfer_config; + + if (handle->transfer.direction == kI2C_Read) + { + transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base); + transfer_config.destAddr = (uint32_t)(handle->transfer.data); + transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1); + transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes; + transfer_config.srcOffset = 0; + transfer_config.destTransferSize = kEDMA_TransferSize1Bytes; + transfer_config.destOffset = 1; + transfer_config.minorLoopBytes = 1; + } + else + { + transfer_config.srcAddr = (uint32_t)(handle->transfer.data + 1); + transfer_config.destAddr = (uint32_t)I2C_GetDataRegAddr(base); + transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1); + transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes; + transfer_config.srcOffset = 1; + transfer_config.destTransferSize = kEDMA_TransferSize1Bytes; + transfer_config.destOffset = 0; + transfer_config.minorLoopBytes = 1; + } + + /* Store the initially configured eDMA minor byte transfer count into the I2C handle */ + handle->nbytes = transfer_config.minorLoopBytes; + + EDMA_SubmitTransfer(handle->dmaHandle, &transfer_config); + EDMA_StartTransfer(handle->dmaHandle); +} + +void I2C_MasterCreateEDMAHandle(I2C_Type *base, + i2c_master_edma_handle_t *handle, + i2c_master_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *edmaHandle) +{ + assert(handle); + assert(edmaHandle); + + uint32_t instance = I2C_GetInstance(base); + + /* Zero handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Set the user callback and userData. */ + handle->completionCallback = callback; + handle->userData = userData; + + /* Set the base for the handle. */ + base = base; + + /* Set the handle for EDMA. */ + handle->dmaHandle = edmaHandle; + + s_edmaPrivateHandle[instance].base = base; + s_edmaPrivateHandle[instance].handle = handle; + + EDMA_SetCallback(edmaHandle, (edma_callback)I2C_MasterTransferCallbackEDMA, &s_edmaPrivateHandle[instance]); +} + +status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, i2c_master_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + status_t result; + uint8_t tmpReg; + volatile uint8_t dummy = 0; + + /* Add this to avoid build warning. */ + dummy++; + + /* Disable dma xfer. */ + I2C_EnableDMA(base, false); + + /* Send address and command buffer(if there is), until senddata phase or receive data phase. */ + result = I2C_InitTransferStateMachineEDMA(base, handle, xfer); + + if (result) + { + /* Send stop if received Nak. */ + if (result == kStatus_I2C_Nak) + { + if (I2C_MasterStop(base) != kStatus_Success) + { + result = kStatus_I2C_Timeout; + } + } + + /* Reset the state to idle state. */ + handle->state = kIdleState; + + return result; + } + + /* Configure dma transfer. */ + /* For i2c send, need to send 1 byte first to trigger the dma, for i2c read, + need to send stop before reading the last byte, so the dma transfer size should + be (xSize - 1). */ + if (handle->transfer.dataSize > 1) + { + I2C_MasterTransferEDMAConfig(base, handle); + if (handle->transfer.direction == kI2C_Read) + { + /* Change direction for receive. */ + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* Read dummy to release the bus. */ + dummy = base->D; + + /* Enabe dma transfer. */ + I2C_EnableDMA(base, true); + } + else + { + /* Enabe dma transfer. */ + I2C_EnableDMA(base, true); + + /* Send the first data. */ + base->D = *handle->transfer.data; + } + } + else /* If transfer size is 1, use polling method. */ + { + if (handle->transfer.direction == kI2C_Read) + { + tmpReg = base->C1; + + /* Change direction to Rx. */ + tmpReg &= ~I2C_C1_TX_MASK; + + /* Configure send NAK */ + tmpReg |= I2C_C1_TXAK_MASK; + + base->C1 = tmpReg; + + /* Read dummy to release the bus. */ + dummy = base->D; + } + else + { + base->D = *handle->transfer.data; + } + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Clear pending flag. */ + base->S = kI2C_IntPendingFlag; + + /* Send stop if kI2C_TransferNoStop flag is not asserted. */ + if (!(handle->transfer.flags & kI2C_TransferNoStopFlag)) + { + result = I2C_MasterStop(base); + } + else + { + /* Change direction to send. */ + base->C1 |= I2C_C1_TX_MASK; + } + + /* Read the last byte of data. */ + if (handle->transfer.direction == kI2C_Read) + { + *handle->transfer.data = base->D; + } + + /* Reset the state to idle. */ + handle->state = kIdleState; + } + + return result; +} + +status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, size_t *count) +{ + assert(handle->dmaHandle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + if (kIdleState != handle->state) + { + *count = (handle->transferSize - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel)); + } + else + { + *count = handle->transferSize; + } + + return kStatus_Success; +} + +void I2C_MasterTransferAbortEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle) +{ + EDMA_AbortTransfer(handle->dmaHandle); + + /* Disable dma transfer. */ + I2C_EnableDMA(base, false); + + /* Reset the state to idle. */ + handle->state = kIdleState; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c_edma.h new file mode 100644 index 00000000000..2e46b073f47 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_i2c_edma.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_I2C_DMA_H_ +#define _FSL_I2C_DMA_H_ + +#include "fsl_i2c.h" +#include "fsl_dmamux.h" +#include "fsl_edma.h" + +/*! + * @addtogroup i2c_edma_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief I2C master eDMA handle typedef. */ +typedef struct _i2c_master_edma_handle i2c_master_edma_handle_t; + +/*! @brief I2C master eDMA transfer callback typedef. */ +typedef void (*i2c_master_edma_transfer_callback_t)(I2C_Type *base, + i2c_master_edma_handle_t *handle, + status_t status, + void *userData); + +/*! @brief I2C master eDMA transfer structure. */ +struct _i2c_master_edma_handle +{ + i2c_master_transfer_t transfer; /*!< I2C master transfer structure. */ + size_t transferSize; /*!< Total bytes to be transferred. */ + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + uint8_t state; /*!< I2C master transfer status. */ + edma_handle_t *dmaHandle; /*!< The eDMA handler used. */ + i2c_master_edma_transfer_callback_t + completionCallback; /*!< A callback function called after the eDMA transfer is finished. */ + void *userData; /*!< A callback parameter passed to the callback function. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus. */ + +/*! + * @name I2C Block eDMA Transfer Operation + * @{ + */ + +/*! + * @brief Initializes the I2C handle which is used in transcational functions. + * + * @param base I2C peripheral base address. + * @param handle A pointer to the i2c_master_edma_handle_t structure. + * @param callback A pointer to the user callback function. + * @param userData A user parameter passed to the callback function. + * @param edmaHandle eDMA handle pointer. + */ +void I2C_MasterCreateEDMAHandle(I2C_Type *base, + i2c_master_edma_handle_t *handle, + i2c_master_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *edmaHandle); + +/*! + * @brief Performs a master eDMA non-blocking transfer on the I2C bus. + * + * @param base I2C peripheral base address. + * @param handle A pointer to the i2c_master_edma_handle_t structure. + * @param xfer A pointer to the transfer structure of i2c_master_transfer_t. + * @retval kStatus_Success Sucessfully completed the data transmission. + * @retval kStatus_I2C_Busy A previous transmission is still not finished. + * @retval kStatus_I2C_Timeout Transfer error, waits for a signal timeout. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. + */ +status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, i2c_master_transfer_t *xfer); + +/*! + * @brief Gets a master transfer status during the eDMA non-blocking transfer. + * + * @param base I2C peripheral base address. + * @param handle A pointer to the i2c_master_edma_handle_t structure. + * @param count A number of bytes transferred by the non-blocking transaction. + */ +status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, size_t *count); + +/*! + * @brief Aborts a master eDMA non-blocking transfer early. + * + * @param base I2C peripheral base address. + * @param handle A pointer to the i2c_master_edma_handle_t structure. + */ +void I2C_MasterTransferAbortEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle); + +/* @} */ +#if defined(__cplusplus) +} +#endif /*_cplusplus. */ +/*@}*/ +#endif /*_FSL_I2C_DMA_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_llwu.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_llwu.c new file mode 100644 index 00000000000..c27b91e9f04 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_llwu.c @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_llwu.h" + +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) +void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_external_pin_mode_t pinMode) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + volatile uint32_t *regBase; + uint32_t regOffset; + uint32_t reg; + + switch (pinIndex >> 4U) + { + case 0U: + regBase = &base->PE1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + case 1U: + regBase = &base->PE2; + break; +#endif + default: + regBase = NULL; + break; + } +#else + volatile uint8_t *regBase; + uint8_t regOffset; + uint8_t reg; + switch (pinIndex >> 2U) + { + case 0U: + regBase = &base->PE1; + break; + case 1U: + regBase = &base->PE2; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8)) + case 2U: + regBase = &base->PE3; + break; +#endif +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 12)) + case 3U: + regBase = &base->PE4; + break; +#endif +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + case 4U: + regBase = &base->PE5; + break; +#endif +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 20)) + case 5U: + regBase = &base->PE6; + break; +#endif +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24)) + case 6U: + regBase = &base->PE7; + break; +#endif +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 28)) + case 7U: + regBase = &base->PE8; + break; +#endif + default: + regBase = NULL; + break; + } +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH == 32 */ + + if (regBase) + { + reg = *regBase; +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + regOffset = ((pinIndex & 0x0FU) << 1U); +#else + regOffset = ((pinIndex & 0x03U) << 1U); +#endif + reg &= ~(0x3U << regOffset); + reg |= ((uint32_t)pinMode << regOffset); + *regBase = reg; + } +} + +bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + return (bool)(base->PF & (1U << pinIndex)); +#else + volatile uint8_t *regBase; + + switch (pinIndex >> 3U) + { +#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF) + case 0U: + regBase = &base->PF1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8)) + case 1U: + regBase = &base->PF2; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + case 2U: + regBase = &base->PF3; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24)) + case 3U: + regBase = &base->PF4; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#else + case 0U: + regBase = &base->F1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8)) + case 1U: + regBase = &base->F2; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + case 2U: + regBase = &base->F3; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24)) + case 3U: + regBase = &base->F4; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#endif /* FSL_FEATURE_LLWU_HAS_PF */ + default: + regBase = NULL; + break; + } + + if (regBase) + { + return (bool)(*regBase & (1U << pinIndex % 8)); + } + else + { + return false; + } +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +} + +void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + base->PF = (1U << pinIndex); +#else + volatile uint8_t *regBase; + switch (pinIndex >> 3U) + { +#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF) + case 0U: + regBase = &base->PF1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8)) + case 1U: + regBase = &base->PF2; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + case 2U: + regBase = &base->PF3; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24)) + case 3U: + regBase = &base->PF4; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#else + case 0U: + regBase = &base->F1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8)) + case 1U: + regBase = &base->F2; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + case 2U: + regBase = &base->F3; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24)) + case 3U: + regBase = &base->F4; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#endif /* FSL_FEATURE_LLWU_HAS_PF */ + default: + regBase = NULL; + break; + } + if (regBase) + { + *regBase = (1U << pinIndex % 8U); + } +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +} +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ + +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER) +void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_pin_filter_mode_t filterMode) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + uint32_t reg; + + reg = base->FILT; + reg &= ~((LLWU_FILT_FILTSEL1_MASK | LLWU_FILT_FILTE1_MASK) << (filterIndex * 8U - 1U)); + reg |= (((filterMode.pinIndex << LLWU_FILT_FILTSEL1_SHIFT) | (filterMode.filterMode << LLWU_FILT_FILTE1_SHIFT) + /* Clear the Filter Detect Flag */ + | LLWU_FILT_FILTF1_MASK) + << (filterIndex * 8U - 1U)); + base->FILT = reg; +#else + volatile uint8_t *regBase; + uint8_t reg; + + switch (filterIndex) + { + case 1: + regBase = &base->FILT1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1)) + case 2: + regBase = &base->FILT2; + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2)) + case 3: + regBase = &base->FILT3; + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3)) + case 4: + regBase = &base->FILT4; + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ + default: + regBase = NULL; + break; + } + + if (regBase) + { + reg = *regBase; + reg &= ~(LLWU_FILT1_FILTSEL_MASK | LLWU_FILT1_FILTE_MASK); + reg |= ((uint32_t)filterMode.pinIndex << LLWU_FILT1_FILTSEL_SHIFT); + reg |= ((uint32_t)filterMode.filterMode << LLWU_FILT1_FILTE_SHIFT); + /* Clear the Filter Detect Flag */ + reg |= LLWU_FILT1_FILTF_MASK; + *regBase = reg; + } +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +} + +bool LLWU_GetPinFilterFlag(LLWU_Type *base, uint32_t filterIndex) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + return (bool)(base->FILT & (1U << (filterIndex * 8U - 1))); +#else + bool status = false; + + switch (filterIndex) + { + case 1: + status = (base->FILT1 & LLWU_FILT1_FILTF_MASK); + break; +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1)) + case 2: + status = (base->FILT2 & LLWU_FILT2_FILTF_MASK); + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2)) + case 3: + status = (base->FILT3 & LLWU_FILT3_FILTF_MASK); + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3)) + case 4: + status = (base->FILT4 & LLWU_FILT4_FILTF_MASK); + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ + default: + break; + } + + return status; +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +} + +void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + uint32_t reg; + + reg = base->FILT; + switch (filterIndex) + { + case 1: + reg |= LLWU_FILT_FILTF1_MASK; + break; + case 2: + reg |= LLWU_FILT_FILTF2_MASK; + break; + case 3: + reg |= LLWU_FILT_FILTF3_MASK; + break; + case 4: + reg |= LLWU_FILT_FILTF4_MASK; + break; + default: + break; + } + base->FILT = reg; +#else + volatile uint8_t *regBase; + uint8_t reg; + + switch (filterIndex) + { + case 1: + regBase = &base->FILT1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1)) + case 2: + regBase = &base->FILT2; + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2)) + case 3: + regBase = &base->FILT3; + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3)) + case 4: + regBase = &base->FILT4; + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ + default: + regBase = NULL; + break; + } + + if (regBase) + { + reg = *regBase; + reg |= LLWU_FILT1_FILTF_MASK; + *regBase = reg; + } +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +} +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ + +#if (defined(FSL_FEATURE_LLWU_HAS_RESET_ENABLE) && FSL_FEATURE_LLWU_HAS_RESET_ENABLE) +void LLWU_SetResetPinMode(LLWU_Type *base, bool pinEnable, bool enableInLowLeakageMode) +{ + uint8_t reg; + + reg = base->RST; + reg &= ~(LLWU_RST_LLRSTE_MASK | LLWU_RST_RSTFILT_MASK); + reg |= + (((uint32_t)pinEnable << LLWU_RST_LLRSTE_SHIFT) | ((uint32_t)enableInLowLeakageMode << LLWU_RST_RSTFILT_SHIFT)); + base->RST = reg; +} +#endif /* FSL_FEATURE_LLWU_HAS_RESET_ENABLE */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_llwu.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_llwu.h new file mode 100644 index 00000000000..385577abdd1 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_llwu.h @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_LLWU_H_ +#define _FSL_LLWU_H_ + +#include "fsl_common.h" + +/*! @addtogroup llwu */ +/*! @{ */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief LLWU driver version 2.0.1. */ +#define FSL_LLWU_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! + * @brief External input pin control modes + */ +typedef enum _llwu_external_pin_mode +{ + kLLWU_ExternalPinDisable = 0U, /*!< Pin disabled as a wakeup input. */ + kLLWU_ExternalPinRisingEdge = 1U, /*!< Pin enabled with the rising edge detection. */ + kLLWU_ExternalPinFallingEdge = 2U, /*!< Pin enabled with the falling edge detection.*/ + kLLWU_ExternalPinAnyEdge = 3U /*!< Pin enabled with any change detection. */ +} llwu_external_pin_mode_t; + +/*! + * @brief Digital filter control modes + */ +typedef enum _llwu_pin_filter_mode +{ + kLLWU_PinFilterDisable = 0U, /*!< Filter disabled. */ + kLLWU_PinFilterRisingEdge = 1U, /*!< Filter positive edge detection.*/ + kLLWU_PinFilterFallingEdge = 2U, /*!< Filter negative edge detection.*/ + kLLWU_PinFilterAnyEdge = 3U /*!< Filter any edge detection. */ +} llwu_pin_filter_mode_t; + +#if (defined(FSL_FEATURE_LLWU_HAS_VERID) && FSL_FEATURE_LLWU_HAS_VERID) +/*! + * @brief IP version ID definition. + */ +typedef struct _llwu_version_id +{ + uint16_t feature; /*!< A feature specification number. */ + uint8_t minor; /*!< The minor version number. */ + uint8_t major; /*!< The major version number. */ +} llwu_version_id_t; +#endif /* FSL_FEATURE_LLWU_HAS_VERID */ + +#if (defined(FSL_FEATURE_LLWU_HAS_PARAM) && FSL_FEATURE_LLWU_HAS_PARAM) +/*! + * @brief IP parameter definition. + */ +typedef struct _llwu_param +{ + uint8_t filters; /*!< A number of the pin filter. */ + uint8_t dmas; /*!< A number of the wakeup DMA. */ + uint8_t modules; /*!< A number of the wakeup module. */ + uint8_t pins; /*!< A number of the wake up pin. */ +} llwu_param_t; +#endif /* FSL_FEATURE_LLWU_HAS_PARAM */ + +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER) +/*! + * @brief An external input pin filter control structure + */ +typedef struct _llwu_external_pin_filter_mode +{ + uint32_t pinIndex; /*!< A pin number */ + llwu_pin_filter_mode_t filterMode; /*!< Filter mode */ +} llwu_external_pin_filter_mode_t; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Low-Leakage Wakeup Unit Control APIs + * @{ + */ + +#if (defined(FSL_FEATURE_LLWU_HAS_VERID) && FSL_FEATURE_LLWU_HAS_VERID) +/*! + * @brief Gets the LLWU version ID. + * + * This function gets the LLWU version ID, including the major version number, + * the minor version number, and the feature specification number. + * + * @param base LLWU peripheral base address. + * @param versionId A pointer to the version ID structure. + */ +static inline void LLWU_GetVersionId(LLWU_Type *base, llwu_version_id_t *versionId) +{ + *((uint32_t *)versionId) = base->VERID; +} +#endif /* FSL_FEATURE_LLWU_HAS_VERID */ + +#if (defined(FSL_FEATURE_LLWU_HAS_PARAM) && FSL_FEATURE_LLWU_HAS_PARAM) +/*! + * @brief Gets the LLWU parameter. + * + * This function gets the LLWU parameter, including a wakeup pin number, a module + * number, a DMA number, and a pin filter number. + * + * @param base LLWU peripheral base address. + * @param param A pointer to the LLWU parameter structure. + */ +static inline void LLWU_GetParam(LLWU_Type *base, llwu_param_t *param) +{ + *((uint32_t *)param) = base->PARAM; +} +#endif /* FSL_FEATURE_LLWU_HAS_PARAM */ + +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) +/*! + * @brief Sets the external input pin source mode. + * + * This function sets the external input pin source mode that is used + * as a wake up source. + * + * @param base LLWU peripheral base address. + * @param pinIndex A pin index to be enabled as an external wakeup source starting from 1. + * @param pinMode A pin configuration mode defined in the llwu_external_pin_modes_t. + */ +void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_external_pin_mode_t pinMode); + +/*! + * @brief Gets the external wakeup source flag. + * + * This function checks the external pin flag to detect whether the MCU is + * woken up by the specific pin. + * + * @param base LLWU peripheral base address. + * @param pinIndex A pin index, which starts from 1. + * @return True if the specific pin is a wakeup source. + */ +bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex); + +/*! + * @brief Clears the external wakeup source flag. + * + * This function clears the external wakeup source flag for a specific pin. + * + * @param base LLWU peripheral base address. + * @param pinIndex A pin index, which starts from 1. + */ +void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex); +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ + +#if (defined(FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE) && FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE) +/*! + * @brief Enables/disables the internal module source. + * + * This function enables/disables the internal module source mode that is used + * as a wake up source. + * + * @param base LLWU peripheral base address. + * @param moduleIndex A module index to be enabled as an internal wakeup source starting from 1. + * @param enable An enable or a disable setting + */ +static inline void LLWU_EnableInternalModuleInterruptWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable) +{ + if (enable) + { + base->ME |= 1U << moduleIndex; + } + else + { + base->ME &= ~(1U << moduleIndex); + } +} + +/*! + * @brief Gets the external wakeup source flag. + * + * This function checks the external pin flag to detect whether the system is + * woken up by the specific pin. + * + * @param base LLWU peripheral base address. + * @param moduleIndex A module index, which starts from 1. + * @return True if the specific pin is a wake up source. + */ +static inline bool LLWU_GetInternalWakeupModuleFlag(LLWU_Type *base, uint32_t moduleIndex) +{ +#if (defined(FSL_FEATURE_LLWU_HAS_MF) && FSL_FEATURE_LLWU_HAS_MF) +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + return (bool)(base->MF & (1U << moduleIndex)); +#else + return (bool)(base->MF5 & (1U << moduleIndex)); +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +#else +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + return (bool)(base->F5 & (1U << moduleIndex)); +#else +#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF) + return (bool)(base->PF3 & (1U << moduleIndex)); +#else + return (bool)(base->F3 & (1U << moduleIndex)); +#endif /* FSL_FEATURE_LLWU_HAS_PF */ +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#endif /* FSL_FEATURE_LLWU_HAS_MF */ +} +#endif /* FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE */ + +#if (defined(FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG) && FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG) +/*! + * @brief Enables/disables the internal module DMA wakeup source. + * + * This function enables/disables the internal DMA that is used as a wake up source. + * + * @param base LLWU peripheral base address. + * @param moduleIndex An internal module index which is used as a DMA request source, starting from 1. + * @param enable Enable or disable the DMA request source + */ +static inline void LLWU_EnableInternalModuleDmaRequestWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable) +{ + if (enable) + { + base->DE |= 1U << moduleIndex; + } + else + { + base->DE &= ~(1U << moduleIndex); + } +} +#endif /* FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG */ + +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER) +/*! + * @brief Sets the pin filter configuration. + * + * This function sets the pin filter configuration. + * + * @param base LLWU peripheral base address. + * @param filterIndex A pin filter index used to enable/disable the digital filter, starting from 1. + * @param filterMode A filter mode configuration + */ +void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_pin_filter_mode_t filterMode); + +/*! + * @brief Gets the pin filter configuration. + * + * This function gets the pin filter flag. + * + * @param base LLWU peripheral base address. + * @param filterIndex A pin filter index, which starts from 1. + * @return True if the flag is a source of the existing low-leakage power mode. + */ +bool LLWU_GetPinFilterFlag(LLWU_Type *base, uint32_t filterIndex); + +/*! + * @brief Clears the pin filter configuration. + * + * This function clears the pin filter flag. + * + * @param base LLWU peripheral base address. + * @param filterIndex A pin filter index to clear the flag, starting from 1. + */ +void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex); + +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ + +#if (defined(FSL_FEATURE_LLWU_HAS_RESET_ENABLE) && FSL_FEATURE_LLWU_HAS_RESET_ENABLE) +/*! + * @brief Sets the reset pin mode. + * + * This function determines how the reset pin is used as a low leakage mode exit source. + * + * @param pinEnable Enable reset the pin filter + * @param pinFilterEnable Specify whether the pin filter is enabled in Low-Leakage power mode. + */ +void LLWU_SetResetPinMode(LLWU_Type *base, bool pinEnable, bool enableInLowLeakageMode); +#endif /* FSL_FEATURE_LLWU_HAS_RESET_ENABLE */ + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ +#endif /* _FSL_LLWU_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lmem_cache.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lmem_cache.c new file mode 100644 index 00000000000..a56ad7701c7 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lmem_cache.c @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_lmem_cache.h" +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define LMEM_CACHEMODE_WIDTH (2U) +#define LMEM_CACHEMODE_MASK_UNIT (0x3U) + +/******************************************************************************* + * Code + ******************************************************************************/ + +void LMEM_EnableCodeCache(LMEM_Type *base, bool enable) +{ + if (enable) + { + /* First, invalidate the entire cache. */ + LMEM_CodeCacheInvalidateAll(base); + + /* Now enable the cache. */ + base->PCCCR |= LMEM_PCCCR_ENCACHE_MASK; + } + else + { + /* First, push any modified contents. */ + LMEM_CodeCachePushAll(base); + + /* Now disable the cache. */ + base->PCCCR &= ~LMEM_PCCCR_ENCACHE_MASK; + } +} + +void LMEM_CodeCacheInvalidateAll(LMEM_Type *base) +{ + /* Enables the processor code bus to invalidate all lines in both ways. + and Initiate the processor code bus code cache command. */ + base->PCCCR |= LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_GO_MASK; + + /* Wait until the cache command completes. */ + while (base->PCCCR & LMEM_PCCCR_GO_MASK) + { + } + + /* As a precaution clear the bits to avoid inadvertently re-running this command. */ + base->PCCCR &= ~(LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK); +} + +void LMEM_CodeCachePushAll(LMEM_Type *base) +{ + /* Enable the processor code bus to push all modified lines. */ + base->PCCCR |= LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_GO_MASK; + + /* Wait until the cache command completes. */ + while (base->PCCCR & LMEM_PCCCR_GO_MASK) + { + } + + /* As a precaution clear the bits to avoid inadvertently re-running this command. */ + base->PCCCR &= ~(LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK); +} + +void LMEM_CodeCacheClearAll(LMEM_Type *base) +{ + /* Push and invalidate all. */ + base->PCCCR |= LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK | + LMEM_PCCCR_GO_MASK; + + /* Wait until the cache command completes. */ + while (base->PCCCR & LMEM_PCCCR_GO_MASK) + { + } + + /* As a precaution clear the bits to avoid inadvertently re-running this command. */ + base->PCCCR &= ~(LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_CodeCacheInvalidateLine + * Description : This function invalidates a specific line in the Processor Code bus cache. + * + * This function invalidates a specific line in the cache. The function invalidates a + * line in cache based on the physical address passed in by the user. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + *END**************************************************************************/ +void LMEM_CodeCacheInvalidateLine(LMEM_Type *base, uint32_t address) +{ + uint32_t pccReg = 0; + + /* Set the invalidate by line command and use the physical address. */ + pccReg = + (base->PCCLCR & ~LMEM_PCCLCR_LCMD_MASK) | LMEM_PCCLCR_LCMD(kLMEM_CacheLineInvalidate) | LMEM_PCCLCR_LADSEL_MASK; + base->PCCLCR = pccReg; + + /* Set the address and initiate the command. */ + base->PCCSAR = (address & LMEM_PCCSAR_PHYADDR_MASK) | LMEM_PCCSAR_LGO_MASK; + + /* Wait until the cache command completes. */ + while (base->PCCSAR & LMEM_PCCSAR_LGO_MASK) + { + } + + /* No need to clear this command since future line commands will overwrite + the line command field. */ +} + +void LMEM_CodeCacheInvalidateMultiLines(LMEM_Type *base, uint32_t address, uint32_t length) +{ + uint32_t endAddr = address + length; + /* Align address to cache line size. */ + address = address & ~(LMEM_CACHE_LINE_SIZE - 1U); + /* If the length exceeds 4KB, invalidate all. */ + if (length >= LMEM_CACHE_SIZE_ONEWAY) + { + LMEM_CodeCacheInvalidateAll(base); + } + else + { /* Proceed with multi-line invalidate. */ + while (address < endAddr) + { + LMEM_CodeCacheInvalidateLine(base, address); + address = address + LMEM_CACHE_LINE_SIZE; + } + } +} + +void LMEM_CodeCachePushLine(LMEM_Type *base, uint32_t address) +{ + uint32_t pccReg = 0; + + /* Set the push by line command. */ + pccReg = (base->PCCLCR & ~LMEM_PCCLCR_LCMD_MASK) | LMEM_PCCLCR_LCMD(kLMEM_CacheLinePush) | LMEM_PCCLCR_LADSEL_MASK; + base->PCCLCR = pccReg; + + /* Set the address and initiate the command. */ + base->PCCSAR = (address & LMEM_PCCSAR_PHYADDR_MASK) | LMEM_PCCSAR_LGO_MASK; + + /* Wait until the cache command completes. */ + while (base->PCCSAR & LMEM_PCCSAR_LGO_MASK) + { + } + + /* No need to clear this command since future line commands will overwrite + the line command field. */ +} + +void LMEM_CodeCachePushMultiLines(LMEM_Type *base, uint32_t address, uint32_t length) +{ + uint32_t endAddr = address + length; + /* Align address to cache line size. */ + address = address & ~(LMEM_CACHE_LINE_SIZE - 1U); + + /* If the length exceeds 4KB, push all. */ + if (length >= LMEM_CACHE_SIZE_ONEWAY) + { + LMEM_CodeCachePushAll(base); + } + else + { /* Proceed with multi-line push. */ + while (address < endAddr) + { + LMEM_CodeCachePushLine(base, address); + address = address + LMEM_CACHE_LINE_SIZE; + } + } +} + +void LMEM_CodeCacheClearLine(LMEM_Type *base, uint32_t address) +{ + uint32_t pccReg = 0; + + /* Set the push by line command. */ + pccReg = (base->PCCLCR & ~LMEM_PCCLCR_LCMD_MASK) | LMEM_PCCLCR_LCMD(kLMEM_CacheLineClear) | LMEM_PCCLCR_LADSEL_MASK; + base->PCCLCR = pccReg; + + /* Set the address and initiate the command. */ + base->PCCSAR = (address & LMEM_PCCSAR_PHYADDR_MASK) | LMEM_PCCSAR_LGO_MASK; + + /* Wait until the cache command completes. */ + while (base->PCCSAR & LMEM_PCCSAR_LGO_MASK) + { + } + + /* No need to clear this command since future line commands will overwrite + the line command field. */ +} + +void LMEM_CodeCacheClearMultiLines(LMEM_Type *base, uint32_t address, uint32_t length) +{ + uint32_t endAddr = address + length; + /* Align address to cache line size. */ + address = address & ~(LMEM_CACHE_LINE_SIZE - 1U); + + /* If the length exceeds 4KB, clear all. */ + if (length >= LMEM_CACHE_SIZE_ONEWAY) + { + LMEM_CodeCacheClearAll(base); + } + else /* Proceed with multi-line clear. */ + { + while (address < endAddr) + { + LMEM_CodeCacheClearLine(base, address); + address = address + LMEM_CACHE_LINE_SIZE; + } + } +} +#if (!defined(FSL_FEATURE_LMEM_SUPPORT_ICACHE_DEMOTE_REMOVE)) || !FSL_FEATURE_LMEM_SUPPORT_ICACHE_DEMOTE_REMOVE +status_t LMEM_CodeCacheDemoteRegion(LMEM_Type *base, lmem_cache_region_t region, lmem_cache_mode_t cacheMode) +{ + uint32_t mode = base->PCCRMR; + uint32_t shift = LMEM_CACHEMODE_WIDTH * (uint32_t)region; /* Region shift. */ + uint32_t mask = LMEM_CACHEMODE_MASK_UNIT << shift; /* Region mask. */ + + /* If the current cache mode is higher than the requested mode, return error. */ + if ((uint32_t)cacheMode >= ((mode & mask) >> shift)) + { + return kStatus_Fail; + } + else + { /* Proceed to demote the region. */ + LMEM_CodeCacheClearAll(base); + base->PCCRMR = (mode & ~mask) | cacheMode << shift; + return kStatus_Success; + } +} +#endif /* FSL_FEATURE_LMEM_SUPPORT_ICACHE_DEMOTE_REMOVE */ + +#if FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE +void LMEM_EnableSystemCache(LMEM_Type *base, bool enable) +{ + if (enable) + { + /* First, invalidate the entire cache. */ + LMEM_SystemCacheInvalidateAll(base); + + /* Now enable the cache. */ + base->PSCCR |= LMEM_PSCCR_ENCACHE_MASK ; + } + else + { + /* First, push any modified contents. */ + LMEM_SystemCachePushAll(base); + + /* Now disable the cache. */ + base->PSCCR &= ~LMEM_PSCCR_ENCACHE_MASK; + } +} + +void LMEM_SystemCacheInvalidateAll(LMEM_Type *base) +{ + /* Enables the processor system bus to invalidate all lines in both ways. + and Initiate the processor system bus cache command. */ + base->PSCCR |= LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_GO_MASK; + + /* Wait until the cache command completes */ + while (base->PSCCR & LMEM_PSCCR_GO_MASK) + { + } + + /* As a precaution clear the bits to avoid inadvertently re-running this command. */ + base->PSCCR &= ~(LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK); +} + +void LMEM_SystemCachePushAll(LMEM_Type *base) +{ + /* Enable the processor system bus to push all modified lines. */ + base->PSCCR |= LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_GO_MASK; + + /* Wait until the cache command completes. */ + while (base->PSCCR & LMEM_PSCCR_GO_MASK) + { + } + + /* As a precaution clear the bits to avoid inadvertently re-running this command. */ + base->PSCCR &= ~(LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK); +} + +void LMEM_SystemCacheClearAll(LMEM_Type *base) +{ + /* Push and invalidate all. */ + base->PSCCR |= LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK | + LMEM_PSCCR_GO_MASK; + + /* Wait until the cache command completes. */ + while (base->PSCCR & LMEM_PSCCR_GO_MASK) + { + } + + /* As a precaution clear the bits to avoid inadvertently re-running this command. */ + base->PSCCR &= ~(LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK); +} + +void LMEM_SystemCacheInvalidateLine(LMEM_Type *base, uint32_t address) +{ + uint32_t pscReg = 0; + + /* Set the invalidate by line command and use the physical address. */ + pscReg = + (base->PSCLCR & ~LMEM_PSCLCR_LCMD_MASK) | LMEM_PSCLCR_LCMD(kLMEM_CacheLineInvalidate) | LMEM_PSCLCR_LADSEL_MASK; + base->PSCLCR = pscReg; + + /* Set the address and initiate the command. */ + base->PSCSAR = (address & LMEM_PSCSAR_PHYADDR_MASK) | LMEM_PSCSAR_LGO_MASK; + + /* Wait until the cache command completes. */ + while (base->PSCSAR & LMEM_PSCSAR_LGO_MASK) + { + } + + /* No need to clear this command since future line commands will overwrite + the line command field. */ +} + +void LMEM_SystemCacheInvalidateMultiLines(LMEM_Type *base, uint32_t address, uint32_t length) +{ + uint32_t endAddr = address + length; + address = address & ~(LMEM_CACHE_LINE_SIZE - 1U); /* Align address to cache line size */ + + /* If the length exceeds 4KB, invalidate all. */ + if (length >= LMEM_CACHE_SIZE_ONEWAY) + { + LMEM_SystemCacheInvalidateAll(base); + } + else /* Proceed with multi-line invalidate. */ + { + while (address < endAddr) + { + LMEM_SystemCacheInvalidateLine(base, address); + address = address + LMEM_CACHE_LINE_SIZE; + } + } +} + +void LMEM_SystemCachePushLine(LMEM_Type *base, uint32_t address) +{ + uint32_t pscReg = 0; + + /* Set the push by line command. */ + pscReg = (base->PSCLCR & ~LMEM_PSCLCR_LCMD_MASK) | LMEM_PSCLCR_LCMD(kLMEM_CacheLinePush) | LMEM_PSCLCR_LADSEL_MASK; + base->PSCLCR = pscReg; + + /* Set the address and initiate the command. */ + base->PSCSAR = (address & LMEM_PSCSAR_PHYADDR_MASK) | LMEM_PSCSAR_LGO_MASK; + + /* Wait until the cache command completes. */ + while (base->PSCSAR & LMEM_PSCSAR_LGO_MASK) + { + } + + /* No need to clear this command since future line commands will overwrite + the line command field. */ +} + +void LMEM_SystemCachePushMultiLines(LMEM_Type *base, uint32_t address, uint32_t length) +{ + uint32_t endAddr = address + length; + address = address & ~(LMEM_CACHE_LINE_SIZE - 1U); /* Align address to cache line size. */ + + /* If the length exceeds 4KB, push all. */ + if (length >= LMEM_CACHE_SIZE_ONEWAY) + { + LMEM_SystemCachePushAll(base); + } + else + { /* Proceed with multi-line push. */ + while (address < endAddr) + { + LMEM_SystemCachePushLine(base, address); + address = address + LMEM_CACHE_LINE_SIZE; + } + } +} + +void LMEM_SystemCacheClearLine(LMEM_Type *base, uint32_t address) +{ + uint32_t pscReg = 0; + + /* Set the push by line command. */ + pscReg = (base->PSCLCR & ~LMEM_PSCLCR_LCMD_MASK) | LMEM_PSCLCR_LCMD(kLMEM_CacheLineClear) | LMEM_PSCLCR_LADSEL_MASK; + base->PSCLCR = pscReg; + + /* Set the address and initiate the command. */ + base->PSCSAR = (address & LMEM_PSCSAR_PHYADDR_MASK) | LMEM_PSCSAR_LGO_MASK; + + /* Wait until the cache command completes. */ + while (base->PSCSAR & LMEM_PSCSAR_LGO_MASK) + { + } + + /* No need to clear this command since future line commands will overwrite + the line command field. */ +} + +void LMEM_SystemCacheClearMultiLines(LMEM_Type *base, uint32_t address, uint32_t length) +{ + uint32_t endAddr = address + length; + address = address & ~(LMEM_CACHE_LINE_SIZE - 1U); /* Align address to cache line size. */ + + /* If the length exceeds 4KB, clear all. */ + if (length >= LMEM_CACHE_SIZE_ONEWAY) + { + LMEM_SystemCacheClearAll(base); + } + else /* Proceed with multi-line clear. */ + { + while (address < endAddr) + { + LMEM_SystemCacheClearLine(base, address); + address = address + LMEM_CACHE_LINE_SIZE; + } + } +} + +status_t LMEM_SystemCacheDemoteRegion(LMEM_Type *base, lmem_cache_region_t region, lmem_cache_mode_t cacheMode) +{ + uint32_t mode = base->PSCRMR; + uint32_t shift = LMEM_CACHEMODE_WIDTH * (uint32_t)region; /* Region shift. */ + uint32_t mask = LMEM_CACHEMODE_MASK_UNIT << shift; /* Region mask. */ + + /* If the current cache mode is higher than the requested mode, return error. */ + if ((uint32_t)cacheMode >= ((mode & mask) >> shift)) + { + return kStatus_Fail; + } + else + { /* Proceed to demote the region. */ + LMEM_SystemCacheClearAll(base); + base->PSCRMR = (mode & ~mask) | (cacheMode << shift); + return kStatus_Success; + } +} +#endif /* FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lmem_cache.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lmem_cache.h new file mode 100644 index 00000000000..f696a5105df --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lmem_cache.h @@ -0,0 +1,488 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_LMEM_CACHE_H_ +#define _FSL_LMEM_CACHE_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup lmem_cache + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief LMEM controller driver version 2.1.0. */ +#define FSL_LMEM_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ + +#define LMEM_CACHE_LINE_SIZE (0x10U) /*!< Cache line is 16-bytes. */ +#define LMEM_CACHE_SIZE_ONEWAY (4096U) /*!< Cache size is 4K-bytes one way. */ + +/*! @brief LMEM cache mode options. */ +typedef enum _lmem_cache_mode +{ + kLMEM_NonCacheable = 0x0U, /*!< Cache mode: non-cacheable. */ + kLMEM_CacheWriteThrough = 0x2U, /*!< Cache mode: write-through. */ + kLMEM_CacheWriteBack = 0x3U /*!< Cache mode: write-back. */ +} lmem_cache_mode_t; + +/*! @brief LMEM cache regions. */ +typedef enum _lmem_cache_region +{ + kLMEM_CacheRegion15 = 0U, /*!< Cache Region 15. */ + kLMEM_CacheRegion14, /*!< Cache Region 14. */ + kLMEM_CacheRegion13, /*!< Cache Region 13. */ + kLMEM_CacheRegion12, /*!< Cache Region 12. */ + kLMEM_CacheRegion11, /*!< Cache Region 11. */ + kLMEM_CacheRegion10, /*!< Cache Region 10. */ + kLMEM_CacheRegion9, /*!< Cache Region 9. */ + kLMEM_CacheRegion8, /*!< Cache Region 8. */ + kLMEM_CacheRegion7, /*!< Cache Region 7. */ + kLMEM_CacheRegion6, /*!< Cache Region 6. */ + kLMEM_CacheRegion5, /*!< Cache Region 5. */ + kLMEM_CacheRegion4, /*!< Cache Region 4. */ + kLMEM_CacheRegion3, /*!< Cache Region 3. */ + kLMEM_CacheRegion2, /*!< Cache Region 2. */ + kLMEM_CacheRegion1, /*!< Cache Region 1. */ + kLMEM_CacheRegion0 /*!< Cache Region 0. */ +} lmem_cache_region_t; + +/*! @brief LMEM cache line command. */ +typedef enum _lmem_cache_line_command +{ + kLMEM_CacheLineSearchReadOrWrite = 0U, /*!< Cache line search and read or write. */ + kLMEM_CacheLineInvalidate, /*!< Cache line invalidate. */ + kLMEM_CacheLinePush, /*!< Cache line push. */ + kLMEM_CacheLineClear, /*!< Cache line clear. */ +} lmem_cache_line_command_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Local Memory Processor Code Bus Cache Control + *@{ + */ + +/*! + * @brief Enables/disables the processor code bus cache. + * This function enables/disables the cache. The function first invalidates the entire cache + * and then enables/disables both the cache and write buffers. + * + * @param base LMEM peripheral base address. + * @param enable The enable or disable flag. + * true - enable the code cache. + * false - disable the code cache. + */ +void LMEM_EnableCodeCache(LMEM_Type *base, bool enable); + +/*! + * @brief Enables/disables the processor code bus write buffer. + * + * @param base LMEM peripheral base address. + * @param enable The enable or disable flag. + * true - enable the code bus write buffer. + * false - disable the code bus write buffer. + */ +static inline void LMEM_EnableCodeWriteBuffer(LMEM_Type *base, bool enable) +{ + if (enable) + { + base->PCCCR |= LMEM_PCCCR_ENWRBUF_MASK; + } + else + { + base->PCCCR &= ~LMEM_PCCCR_ENWRBUF_MASK; + } +} + +/*! + * @brief Invalidates the processor code bus cache. + * This function invalidates the cache both ways, which means that + * it unconditionally clears valid bits and modifies bits of a cache entry. + * + * @param base LMEM peripheral base address. + */ +void LMEM_CodeCacheInvalidateAll(LMEM_Type *base); + +/*! + * @brief Pushes all modified lines in the processor code bus cache. + * This function pushes all modified lines in both ways in the entire cache. + * It pushes a cache entry if it is valid and modified and clears the modified bit. If + * the entry is not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + * @param base LMEM peripheral base address. + */ +void LMEM_CodeCachePushAll(LMEM_Type *base); + +/*! + * @brief Clears the processor code bus cache. + * This function clears the entire cache and pushes (flushes) and + * invalidates the operation. + * Clear - Pushes a cache entry if it is valid and modified, then clears the valid and + * modified bits. If the entry is not valid or not modified, clear the valid bit. + * + * @param base LMEM peripheral base address. + */ +void LMEM_CodeCacheClearAll(LMEM_Type *base); + +/*! + * @brief Invalidates a specific line in the processor code bus cache. + * This function invalidates a specific line in the cache + * based on the physical address passed in by the user. + * Invalidate - Unconditionally clears valid and modified bits of a cache entry. + * + * @param base LMEM peripheral base address. + * @param address The physical address of the cache line. Should be 16-byte aligned address. + * If not, it is changed to the 16-byte aligned memory address. + */ +void LMEM_CodeCacheInvalidateLine(LMEM_Type *base, uint32_t address); + +/*! + * @brief Invalidates multiple lines in the processor code bus cache. + * This function invalidates multiple lines in the cache + * based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half the + * cache, the function performs an entire cache invalidate function, which is + * more efficient than invalidating the cache line-by-line. + * Because the cache consists of two ways and line commands based on the physical address searches both ways, + * check half the total amount of cache. + * Invalidate - Unconditionally clear valid and modified bits of a cache entry. + * + * @param base LMEM peripheral base address. + * @param address The physical address of the cache line. Should be 16-byte aligned address. + * If not, it is changed to the 16-byte aligned memory address. + * @param length The length in bytes of the total amount of cache lines. + */ +void LMEM_CodeCacheInvalidateMultiLines(LMEM_Type *base, uint32_t address, uint32_t length); + +/*! + * @brief Pushes a specific modified line in the processor code bus cache. + * This function pushes a specific modified line based on the physical address passed in + * by the user. + * Push - Push a cache entry if it is valid and modified, then clear the modified bit. If the + * entry is not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + * @param base LMEM peripheral base address. + * @param address The physical address of the cache line. Should be 16-byte aligned address. + * If not, it is changed to the 16-byte aligned memory address. + */ +void LMEM_CodeCachePushLine(LMEM_Type *base, uint32_t address); + +/*! + * @brief Pushes multiple modified lines in the processor code bus cache. + * This function pushes multiple modified lines in the cache + * based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half of the + * cache, the function performs an cache push function, which is + * more efficient than pushing the modified lines in the cache line-by-line. + * Because the cache consists of two ways and line commands based on the physical address searches both ways, + * check half the total amount of cache. + * Push - Push a cache entry if it is valid and modified, then clear the modified bit. If + * the entry is not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + * @param base LMEM peripheral base address. + * @param address The physical address of the cache line. Should be 16-byte aligned address. + * If not, it is changed to the 16-byte aligned memory address. + * @param length The length in bytes of the total amount of cache lines. + */ +void LMEM_CodeCachePushMultiLines(LMEM_Type *base, uint32_t address, uint32_t length); + +/*! + * @brief Clears a specific line in the processor code bus cache. + * This function clears a specific line based on the physical address passed in + * by the user. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + * @param base LMEM peripheral base address. + * @param address The physical address of the cache line. Should be 16-byte aligned address. + * If not, it is changed to the 16-byte aligned memory address. + */ +void LMEM_CodeCacheClearLine(LMEM_Type *base, uint32_t address); + +/*! + * @brief Clears multiple lines in the processor code bus cache. + * This function clears multiple lines in the cache + * based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half the total amount of + * cache, the function performs a cache clear function which is + * more efficient than clearing the lines in the cache line-by-line. + * Because the cache consists of two ways and line commands based on the physical address searches both ways, + * check half the total amount of cache. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + * @param base LMEM peripheral base address. + * @param address The physical address of the cache line. Should be 16-byte aligned address. + * If not, it is changed to the 16-byte aligned memory address. + * @param length The length in bytes of the total amount of cache lines. + */ +void LMEM_CodeCacheClearMultiLines(LMEM_Type *base, uint32_t address, uint32_t length); + +#if (!defined(FSL_FEATURE_LMEM_SUPPORT_ICACHE_DEMOTE_REMOVE)) || !FSL_FEATURE_LMEM_SUPPORT_ICACHE_DEMOTE_REMOVE +/*! + * @brief Demotes the cache mode of a region in processor code bus cache. + * This function allows the user to demote the cache mode of a region within the device's + * memory map. Demoting the cache mode reduces the cache function applied to a memory + * region from write-back to write-through to non-cacheable. The function checks to see + * if the requested cache mode is higher than or equal to the current cache mode, and if + * so, returns an error. After a region is demoted, its cache mode can only be raised + * by a reset, which returns it to its default state which is the highest cache configure for + * each region. + * To maintain cache coherency, changes to the cache mode should be completed while the + * address space being changed is not being accessed or the cache is disabled. Before a + * cache mode change, this function completes a cache clear all command to push and invalidate any + * cache entries that may have changed. + * + * @param base LMEM peripheral base address. + * @param region The desired region to demote of type lmem_cache_region_t. + * @param cacheMode The new, demoted cache mode of type lmem_cache_mode_t. + * @return The execution result. + * kStatus_Success The cache demote operation is successful. + * kStatus_Fail The cache demote operation is failure. + */ +status_t LMEM_CodeCacheDemoteRegion(LMEM_Type *base, lmem_cache_region_t region, lmem_cache_mode_t cacheMode); +#endif /* FSL_FEATURE_LMEM_SUPPORT_ICACHE_DEMOTE_REMOVE */ + +/*@}*/ + +#if FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE +/*! + * @name Local Memory Processor System Bus Cache Control + *@{ + */ + +/*! + * @brief Enables/disables the processor system bus cache. + * This function enables/disables the cache. It first invalidates the entire cache, + * then enables /disable both the cache and write buffer. + * + * @param base LMEM peripheral base address. + * @param The enable or disable flag. + * true - enable the system cache. + * false - disable the system cache. + */ +void LMEM_EnableSystemCache(LMEM_Type *base, bool enable); + +/*! + * @brief Enables/disables the processor system bus write buffer. + * + * @param base LMEM peripheral base address. + * @param enable The enable or disable flag. + * true - enable the system bus write buffer. + * false - disable the system bus write buffer. + */ +static inline void LMEM_EnableSystemWriteBuffer(LMEM_Type *base, bool enable) +{ + if (enable) + { + base->PSCCR |= LMEM_PSCCR_ENWRBUF_MASK; + } + else + { + base->PSCCR &= ~LMEM_PSCCR_ENWRBUF_MASK; + } +} + +/*! + * @brief Invalidates the processor system bus cache. + * This function invalidates the entire cache both ways. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + * @param base LMEM peripheral base address. + */ +void LMEM_SystemCacheInvalidateAll(LMEM_Type *base); + +/*! + * @brief Pushes all modified lines in the processor system bus cache. + * This function pushes all modified lines in both ways (the entire cache). + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * the entry is not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + * @param base LMEM peripheral base address. + */ +void LMEM_SystemCachePushAll(LMEM_Type *base); + +/*! + * @brief Clears the entire processor system bus cache. + * This function clears the entire cache, which is a push (flush) and + * invalidate operation. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If the entry is not valid or not modified, clear the valid bit. + * + * @param base LMEM peripheral base address. + */ +void LMEM_SystemCacheClearAll(LMEM_Type *base); + +/*! + * @brief Invalidates a specific line in the processor system bus cache. + * This function invalidates a specific line in the cache + * based on the physical address passed in by the user. + * Invalidate - Unconditionally clears valid and modify bits of a cache entry. + * + * @param base LMEM peripheral base address. Should be 16-byte aligned address. + * If not, it is changed to the 16-byte aligned memory address. + * @param address The physical address of the cache line. + */ +void LMEM_SystemCacheInvalidateLine(LMEM_Type *base, uint32_t address); + +/*! + * @brief Invalidates multiple lines in the processor system bus cache. + * This function invalidates multiple lines in the cache + * based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half of the + * cache, the function performs an entire cache invalidate function (which is + * more efficient than invalidating the cache line-by-line). + * Because the cache consists of two ways and line commands based on the physical address searches both ways, + * check half the total amount of cache. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + * @param base LMEM peripheral base address. + * @param address The physical address of the cache line. Should be 16-byte aligned address. + * If not, it is changed to the 16-byte aligned memory address. + * @param length The length in bytes of the total amount of cache lines. + */ +void LMEM_SystemCacheInvalidateMultiLines(LMEM_Type *base, uint32_t address, uint32_t length); + +/*! + * @brief Pushes a specific modified line in the processor system bus cache. + * This function pushes a specific modified line based on the physical address passed in + * by the user. + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * the entry is not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + * @param base LMEM peripheral base address. + * @param address The physical address of the cache line. Should be 16-byte aligned address. + * If not, it is changed to the 16-byte aligned memory address. + */ +void LMEM_SystemCachePushLine(LMEM_Type *base, uint32_t address); + +/*! + * @brief Pushes multiple modified lines in the processor system bus cache. + * This function pushes multiple modified lines in the cache + * based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half of the + * cache, the function performs an entire cache push function (which is + * more efficient than pushing the modified lines in the cache line-by-line). + * Because the cache consists of two ways and line commands based on the physical address searches both ways, + * check half the total amount of cache. + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * the entry is not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + * @param base LMEM peripheral base address. + * @param address The physical address of the cache line. Should be 16-byte aligned address. + * If not, it is changed to the 16-byte aligned memory address. + * @param length The length in bytes of the total amount of cache lines. + */ +void LMEM_SystemCachePushMultiLines(LMEM_Type *base, uint32_t address, uint32_t length); + +/*! + * @brief Clears a specific line in the processor system bus cache. + * This function clears a specific line based on the physical address passed in + * by the user. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If the entry is not valid or not modified, clear the valid bit. + * + * @param base LMEM peripheral base address. + * @param address The physical address of the cache line. Should be 16-byte aligned address. + * If not, it is changed to the 16-byte aligned memory address. + */ +void LMEM_SystemCacheClearLine(LMEM_Type *base, uint32_t address); + +/*! + * @brief Clears multiple lines in the processor system bus cache. + * This function clears multiple lines in the cache + * based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half of the + * cache, the function performs an entire cache clear function (which is + * more efficient than clearing the lines in the cache line-by-line). + * Because the cache consists of two ways and line commands based on the physical address searches both ways, + * check half the total amount of cache. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If the entry is not valid or not modified, clear the valid bit. + * + * @param base LMEM peripheral base address. + * @param address The physical address of the cache line. Should be 16-byte aligned address. + * If not, it is changed to the 16-byte aligned memory address. + * @param length The length in bytes of the total amount of cache lines. + */ +void LMEM_SystemCacheClearMultiLines(LMEM_Type *base, uint32_t address, uint32_t length); + +/*! + * @brief Demotes the cache mode of a region in the processor system bus cache. + * This function allows the user to demote the cache mode of a region within the device's + * memory map. Demoting the cache mode reduces the cache function applied to a memory + * region from write-back to write-through to non-cacheable. The function checks to see + * if the requested cache mode is higher than or equal to the current cache mode, and if + * so, returns an error. After a region is demoted, its cache mode can only be raised + * by a reset, which returns it to its default state which is the highest cache configure + * for each region. + * To maintain cache coherency, changes to the cache mode should be completed while the + * address space being changed is not being accessed or the cache is disabled. Before a + * cache mode change, this function completes a cache clear all command to push and invalidate any + * cache entries that may have changed. + * + * @param base LMEM peripheral base address. + * @param region The desired region to demote of type lmem_cache_region_t. + * @param cacheMode The new, demoted cache mode of type lmem_cache_mode_t. + * @return The execution result. + * kStatus_Success The cache demote operation is successful. + * kStatus_Fail The cache demote operation is failure. + */ +status_t LMEM_SystemCacheDemoteRegion(LMEM_Type *base, lmem_cache_region_t region, lmem_cache_mode_t cacheMode); + +/*@}*/ +#endif /* FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_LMEM_CACHE_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lptmr.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lptmr.c new file mode 100644 index 00000000000..2c6d66db489 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lptmr.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_lptmr.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address to be used to gate or ungate the module clock + * + * @param base LPTMR peripheral base address + * + * @return The LPTMR instance + */ +static uint32_t LPTMR_GetInstance(LPTMR_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to LPTMR bases for each instance. */ +static LPTMR_Type *const s_lptmrBases[] = LPTMR_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to LPTMR clocks for each instance. */ +static const clock_ip_name_t s_lptmrClocks[] = LPTMR_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t LPTMR_GetInstance(LPTMR_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_LPTMR_COUNT; instance++) + { + if (s_lptmrBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_LPTMR_COUNT); + + return instance; +} + +void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config) +{ + assert(config); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate the LPTMR clock*/ + CLOCK_EnableClock(s_lptmrClocks[LPTMR_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Configure the timers operation mode and input pin setup */ + base->CSR = (LPTMR_CSR_TMS(config->timerMode) | LPTMR_CSR_TFC(config->enableFreeRunning) | + LPTMR_CSR_TPP(config->pinPolarity) | LPTMR_CSR_TPS(config->pinSelect)); + + /* Configure the prescale value and clock source */ + base->PSR = (LPTMR_PSR_PRESCALE(config->value) | LPTMR_PSR_PBYP(config->bypassPrescaler) | + LPTMR_PSR_PCS(config->prescalerClockSource)); +} + +void LPTMR_Deinit(LPTMR_Type *base) +{ + /* Disable the LPTMR and reset the internal logic */ + base->CSR &= ~LPTMR_CSR_TEN_MASK; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate the LPTMR clock*/ + CLOCK_DisableClock(s_lptmrClocks[LPTMR_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void LPTMR_GetDefaultConfig(lptmr_config_t *config) +{ + assert(config); + + /* Use time counter mode */ + config->timerMode = kLPTMR_TimerModeTimeCounter; + /* Use input 0 as source in pulse counter mode */ + config->pinSelect = kLPTMR_PinSelectInput_0; + /* Pulse input pin polarity is active-high */ + config->pinPolarity = kLPTMR_PinPolarityActiveHigh; + /* Counter resets whenever TCF flag is set */ + config->enableFreeRunning = false; + /* Bypass the prescaler */ + config->bypassPrescaler = true; + /* LPTMR clock source */ + config->prescalerClockSource = kLPTMR_PrescalerClock_1; + /* Divide the prescaler clock by 2 */ + config->value = kLPTMR_Prescale_Glitch_0; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lptmr.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lptmr.h new file mode 100644 index 00000000000..eaae77ed8fc --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lptmr.h @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_LPTMR_H_ +#define _FSL_LPTMR_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup lptmr + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_LPTMR_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +/*@}*/ + +/*! @brief LPTMR pin selection used in pulse counter mode.*/ +typedef enum _lptmr_pin_select +{ + kLPTMR_PinSelectInput_0 = 0x0U, /*!< Pulse counter input 0 is selected */ + kLPTMR_PinSelectInput_1 = 0x1U, /*!< Pulse counter input 1 is selected */ + kLPTMR_PinSelectInput_2 = 0x2U, /*!< Pulse counter input 2 is selected */ + kLPTMR_PinSelectInput_3 = 0x3U /*!< Pulse counter input 3 is selected */ +} lptmr_pin_select_t; + +/*! @brief LPTMR pin polarity used in pulse counter mode.*/ +typedef enum _lptmr_pin_polarity +{ + kLPTMR_PinPolarityActiveHigh = 0x0U, /*!< Pulse Counter input source is active-high */ + kLPTMR_PinPolarityActiveLow = 0x1U /*!< Pulse Counter input source is active-low */ +} lptmr_pin_polarity_t; + +/*! @brief LPTMR timer mode selection.*/ +typedef enum _lptmr_timer_mode +{ + kLPTMR_TimerModeTimeCounter = 0x0U, /*!< Time Counter mode */ + kLPTMR_TimerModePulseCounter = 0x1U /*!< Pulse Counter mode */ +} lptmr_timer_mode_t; + +/*! @brief LPTMR prescaler/glitch filter values*/ +typedef enum _lptmr_prescaler_glitch_value +{ + kLPTMR_Prescale_Glitch_0 = 0x0U, /*!< Prescaler divide 2, glitch filter does not support this setting */ + kLPTMR_Prescale_Glitch_1 = 0x1U, /*!< Prescaler divide 4, glitch filter 2 */ + kLPTMR_Prescale_Glitch_2 = 0x2U, /*!< Prescaler divide 8, glitch filter 4 */ + kLPTMR_Prescale_Glitch_3 = 0x3U, /*!< Prescaler divide 16, glitch filter 8 */ + kLPTMR_Prescale_Glitch_4 = 0x4U, /*!< Prescaler divide 32, glitch filter 16 */ + kLPTMR_Prescale_Glitch_5 = 0x5U, /*!< Prescaler divide 64, glitch filter 32 */ + kLPTMR_Prescale_Glitch_6 = 0x6U, /*!< Prescaler divide 128, glitch filter 64 */ + kLPTMR_Prescale_Glitch_7 = 0x7U, /*!< Prescaler divide 256, glitch filter 128 */ + kLPTMR_Prescale_Glitch_8 = 0x8U, /*!< Prescaler divide 512, glitch filter 256 */ + kLPTMR_Prescale_Glitch_9 = 0x9U, /*!< Prescaler divide 1024, glitch filter 512*/ + kLPTMR_Prescale_Glitch_10 = 0xAU, /*!< Prescaler divide 2048 glitch filter 1024 */ + kLPTMR_Prescale_Glitch_11 = 0xBU, /*!< Prescaler divide 4096, glitch filter 2048 */ + kLPTMR_Prescale_Glitch_12 = 0xCU, /*!< Prescaler divide 8192, glitch filter 4096 */ + kLPTMR_Prescale_Glitch_13 = 0xDU, /*!< Prescaler divide 16384, glitch filter 8192 */ + kLPTMR_Prescale_Glitch_14 = 0xEU, /*!< Prescaler divide 32768, glitch filter 16384 */ + kLPTMR_Prescale_Glitch_15 = 0xFU /*!< Prescaler divide 65536, glitch filter 32768 */ +} lptmr_prescaler_glitch_value_t; + +/*! + * @brief LPTMR prescaler/glitch filter clock select. + * @note Clock connections are SoC-specific + */ +typedef enum _lptmr_prescaler_clock_select +{ + kLPTMR_PrescalerClock_0 = 0x0U, /*!< Prescaler/glitch filter clock 0 selected. */ + kLPTMR_PrescalerClock_1 = 0x1U, /*!< Prescaler/glitch filter clock 1 selected. */ + kLPTMR_PrescalerClock_2 = 0x2U, /*!< Prescaler/glitch filter clock 2 selected. */ + kLPTMR_PrescalerClock_3 = 0x3U, /*!< Prescaler/glitch filter clock 3 selected. */ +} lptmr_prescaler_clock_select_t; + +/*! @brief List of the LPTMR interrupts */ +typedef enum _lptmr_interrupt_enable +{ + kLPTMR_TimerInterruptEnable = LPTMR_CSR_TIE_MASK, /*!< Timer interrupt enable */ +} lptmr_interrupt_enable_t; + +/*! @brief List of the LPTMR status flags */ +typedef enum _lptmr_status_flags +{ + kLPTMR_TimerCompareFlag = LPTMR_CSR_TCF_MASK, /*!< Timer compare flag */ +} lptmr_status_flags_t; + +/*! + * @brief LPTMR config structure + * + * This structure holds the configuration settings for the LPTMR peripheral. To initialize this + * structure to reasonable defaults, call the LPTMR_GetDefaultConfig() function and pass a + * pointer to your configuration structure instance. + * + * The configuration struct can be made constant so it resides in flash. + */ +typedef struct _lptmr_config +{ + lptmr_timer_mode_t timerMode; /*!< Time counter mode or pulse counter mode */ + lptmr_pin_select_t pinSelect; /*!< LPTMR pulse input pin select; used only in pulse counter mode */ + lptmr_pin_polarity_t pinPolarity; /*!< LPTMR pulse input pin polarity; used only in pulse counter mode */ + bool enableFreeRunning; /*!< True: enable free running, counter is reset on overflow + False: counter is reset when the compare flag is set */ + bool bypassPrescaler; /*!< True: bypass prescaler; false: use clock from prescaler */ + lptmr_prescaler_clock_select_t prescalerClockSource; /*!< LPTMR clock source */ + lptmr_prescaler_glitch_value_t value; /*!< Prescaler or glitch filter value */ +} lptmr_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the LPTMR clock and configures the peripheral for a basic operation. + * + * @note This API should be called at the beginning of the application using the LPTMR driver. + * + * @param base LPTMR peripheral base address + * @param config A pointer to the LPTMR configuration structure. + */ +void LPTMR_Init(LPTMR_Type* base, const lptmr_config_t* config); + +/*! + * @brief Gates the LPTMR clock. + * + * @param base LPTMR peripheral base address + */ +void LPTMR_Deinit(LPTMR_Type* base); + +/*! + * @brief Fills in the LPTMR configuration structure with default settings. + * + * The default values are as follows. + * @code + * config->timerMode = kLPTMR_TimerModeTimeCounter; + * config->pinSelect = kLPTMR_PinSelectInput_0; + * config->pinPolarity = kLPTMR_PinPolarityActiveHigh; + * config->enableFreeRunning = false; + * config->bypassPrescaler = true; + * config->prescalerClockSource = kLPTMR_PrescalerClock_1; + * config->value = kLPTMR_Prescale_Glitch_0; + * @endcode + * @param config A pointer to the LPTMR configuration structure. + */ +void LPTMR_GetDefaultConfig(lptmr_config_t* config); + +/*! @}*/ + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected LPTMR interrupts. + * + * @param base LPTMR peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::lptmr_interrupt_enable_t + */ +static inline void LPTMR_EnableInterrupts(LPTMR_Type* base, uint32_t mask) +{ + uint32_t reg = base->CSR; + + /* Clear the TCF bit so that we don't clear this w1c bit when writing back */ + reg &= ~(LPTMR_CSR_TCF_MASK); + reg |= mask; + base->CSR = reg; +} + +/*! + * @brief Disables the selected LPTMR interrupts. + * + * @param base LPTMR peripheral base address + * @param mask The interrupts to disable. This is a logical OR of members of the + * enumeration ::lptmr_interrupt_enable_t. + */ +static inline void LPTMR_DisableInterrupts(LPTMR_Type* base, uint32_t mask) +{ + uint32_t reg = base->CSR; + + /* Clear the TCF bit so that we don't clear this w1c bit when writing back */ + reg &= ~(LPTMR_CSR_TCF_MASK); + reg &= ~mask; + base->CSR = reg; +} + +/*! + * @brief Gets the enabled LPTMR interrupts. + * + * @param base LPTMR peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::lptmr_interrupt_enable_t + */ +static inline uint32_t LPTMR_GetEnabledInterrupts(LPTMR_Type* base) +{ + return (base->CSR & LPTMR_CSR_TIE_MASK); +} + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the LPTMR status flags. + * + * @param base LPTMR peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::lptmr_status_flags_t + */ +static inline uint32_t LPTMR_GetStatusFlags(LPTMR_Type* base) +{ + return (base->CSR & LPTMR_CSR_TCF_MASK); +} + +/*! + * @brief Clears the LPTMR status flags. + * + * @param base LPTMR peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::lptmr_status_flags_t. + */ +static inline void LPTMR_ClearStatusFlags(LPTMR_Type* base, uint32_t mask) +{ + base->CSR |= mask; +} + +/*! @}*/ + +/*! + * @name Read and write the timer period + * @{ + */ + +/*! + * @brief Sets the timer period in units of count. + * + * Timers counts from 0 until it equals the count value set here. The count value is written to + * the CMR register. + * + * @note + * 1. The TCF flag is set with the CNR equals the count provided here and then increments. + * 2. Call the utility macros provided in the fsl_common.h to convert to ticks. + * + * @param base LPTMR peripheral base address + * @param ticks A timer period in units of ticks, which should be equal or greater than 1. + */ +static inline void LPTMR_SetTimerPeriod(LPTMR_Type* base, uint16_t ticks) +{ + base->CMR = ticks - 1; +} + +/*! + * @brief Reads the current timer counting value. + * + * This function returns the real-time timer counting value in a range from 0 to a + * timer period. + * + * @note Call the utility macros provided in the fsl_common.h to convert ticks to usec or msec. + * + * @param base LPTMR peripheral base address + * + * @return The current counter value in ticks + */ +static inline uint16_t LPTMR_GetCurrentTimerCount(LPTMR_Type* base) +{ + /* Must first write any value to the CNR. This synchronizes and registers the current value + * of the CNR into a temporary register which can then be read + */ + base->CNR = 0U; + return (uint16_t)base->CNR; +} + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ + +/*! + * @brief Starts the timer. + * + * After calling this function, the timer counts up to the CMR register value. + * Each time the timer reaches the CMR value and then increments, it generates a + * trigger pulse and sets the timeout interrupt flag. An interrupt is also + * triggered if the timer interrupt is enabled. + * + * @param base LPTMR peripheral base address + */ +static inline void LPTMR_StartTimer(LPTMR_Type* base) +{ + uint32_t reg = base->CSR; + + /* Clear the TCF bit to avoid clearing the w1c bit when writing back. */ + reg &= ~(LPTMR_CSR_TCF_MASK); + reg |= LPTMR_CSR_TEN_MASK; + base->CSR = reg; +} + +/*! + * @brief Stops the timer. + * + * This function stops the timer and resets the timer's counter register. + * + * @param base LPTMR peripheral base address + */ +static inline void LPTMR_StopTimer(LPTMR_Type* base) +{ + uint32_t reg = base->CSR; + + /* Clear the TCF bit to avoid clearing the w1c bit when writing back. */ + reg &= ~(LPTMR_CSR_TCF_MASK); + reg &= ~LPTMR_CSR_TEN_MASK; + base->CSR = reg; +} + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_LPTMR_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart.c new file mode 100644 index 00000000000..1772e797c34 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart.c @@ -0,0 +1,1276 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_lpuart.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* LPUART transfer state. */ +enum _lpuart_transfer_states +{ + kLPUART_TxIdle, /*!< TX idle. */ + kLPUART_TxBusy, /*!< TX busy. */ + kLPUART_RxIdle, /*!< RX idle. */ + kLPUART_RxBusy /*!< RX busy. */ +}; + +/* Typedef for interrupt handler. */ +typedef void (*lpuart_isr_t)(LPUART_Type *base, lpuart_handle_t *handle); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get the LPUART instance from peripheral base address. + * + * @param base LPUART peripheral base address. + * @return LPUART instance. + */ +uint32_t LPUART_GetInstance(LPUART_Type *base); + +/*! + * @brief Get the length of received data in RX ring buffer. + * + * @userData handle LPUART handle pointer. + * @return Length of received data in RX ring buffer. + */ +static size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Check whether the RX ring buffer is full. + * + * @userData handle LPUART handle pointer. + * @retval true RX ring buffer is full. + * @retval false RX ring buffer is not full. + */ +static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Write to TX register using non-blocking method. + * + * This function writes data to the TX register directly, upper layer must make + * sure the TX register is empty or TX FIFO has empty room before calling this function. + * + * @note This function does not check whether all the data has been sent out to bus, + * so before disable TX, check kLPUART_TransmissionCompleteFlag to ensure the TX is + * finished. + * + * @param base LPUART peripheral base address. + * @param data Start addresss of the data to write. + * @param length Size of the buffer to be sent. + */ +static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length); + +/*! + * @brief Read RX register using non-blocking method. + * + * This function reads data from the TX register directly, upper layer must make + * sure the RX register is full or TX FIFO has data before calling this function. + * + * @param base LPUART peripheral base address. + * @param data Start addresss of the buffer to store the received data. + * @param length Size of the buffer. + */ +static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Array of LPUART handle. */ +static lpuart_handle_t *s_lpuartHandle[FSL_FEATURE_SOC_LPUART_COUNT]; +/* Array of LPUART peripheral base address. */ +static LPUART_Type *const s_lpuartBases[] = LPUART_BASE_PTRS; +/* Array of LPUART IRQ number. */ +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +static const IRQn_Type s_lpuartRxIRQ[] = LPUART_RX_IRQS; +static const IRQn_Type s_lpuartTxIRQ[] = LPUART_TX_IRQS; +#else +static const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS; +#endif +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/* Array of LPUART clock name. */ +static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +/* LPUART ISR for transactional APIs. */ +static lpuart_isr_t s_lpuartIsr; + +/******************************************************************************* + * Code + ******************************************************************************/ +uint32_t LPUART_GetInstance(LPUART_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_LPUART_COUNT; instance++) + { + if (s_lpuartBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_LPUART_COUNT); + + return instance; +} + +static size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle) +{ + assert(handle); + + size_t size; + + if (handle->rxRingBufferTail > handle->rxRingBufferHead) + { + size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail); + } + else + { + size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail); + } + + return size; +} + +static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle) +{ + assert(handle); + + bool full; + + if (LPUART_TransferGetRxRingBufferLength(base, handle) == (handle->rxRingBufferSize - 1U)) + { + full = true; + } + else + { + full = false; + } + return full; +} + +static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length) +{ + assert(data); + + size_t i; + + /* The Non Blocking write data API assume user have ensured there is enough space in + peripheral to write. */ + for (i = 0; i < length; i++) + { + base->DATA = data[i]; + } +} + +static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length) +{ + assert(data); + + size_t i; +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + uint32_t ctrl = base->CTRL; + bool isSevenDataBits = + ((ctrl & LPUART_CTRL_M7_MASK) || + ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); +#endif + + /* The Non Blocking read data API assume user have ensured there is enough space in + peripheral to write. */ + for (i = 0; i < length; i++) + { +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + if (isSevenDataBits) + { + data[i] = (base->DATA & 0x7F); + } + else + { + data[i] = base->DATA; + } +#else + data[i] = base->DATA; +#endif + } +} + +status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz) +{ + assert(config); + assert(config->baudRate_Bps); +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->txFifoWatermark); + assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->rxFifoWatermark); +#endif + + uint32_t temp; + uint16_t sbr, sbrTemp; + uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff; + + /* This LPUART instantiation uses a slightly different baud rate calculation + * The idea is to use the best OSR (over-sampling rate) possible + * Note, OSR is typically hard-set to 16 in other LPUART instantiations + * loop to find the best OSR value possible, one that generates minimum baudDiff + * iterate through the rest of the supported values of OSR */ + + baudDiff = config->baudRate_Bps; + osr = 0; + sbr = 0; + for (osrTemp = 4; osrTemp <= 32; osrTemp++) + { + /* calculate the temporary sbr value */ + sbrTemp = (srcClock_Hz / (config->baudRate_Bps * osrTemp)); + /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/ + if (sbrTemp == 0) + { + sbrTemp = 1; + } + /* Calculate the baud rate based on the temporary OSR and SBR values */ + calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp)); + + tempDiff = calculatedBaud - config->baudRate_Bps; + + /* Select the better value between srb and (sbr + 1) */ + if (tempDiff > (config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))))) + { + tempDiff = config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))); + sbrTemp++; + } + + if (tempDiff <= baudDiff) + { + baudDiff = tempDiff; + osr = osrTemp; /* update and store the best OSR value calculated */ + sbr = sbrTemp; /* update store the best SBR value calculated */ + } + } + + /* Check to see if actual baud rate is within 3% of desired baud rate + * based on the best calculate OSR value */ + if (baudDiff > ((config->baudRate_Bps / 100) * 3)) + { + /* Unacceptable baud rate difference of more than 3%*/ + return kStatus_LPUART_BaudrateNotSupport; + } + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable lpuart clock */ + CLOCK_EnableClock(s_lpuartClock[LPUART_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL + /*Reset all internal logic and registers, except the Global Register */ + LPUART_SoftwareReset(base); +#else + /* Disable LPUART TX RX before setting. */ + base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); +#endif + + temp = base->BAUD; + + /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. + * If so, then "BOTHEDGE" sampling must be turned on */ + if ((osr > 3) && (osr < 8)) + { + temp |= LPUART_BAUD_BOTHEDGE_MASK; + } + + /* program the osr value (bit value is one less than actual value) */ + temp &= ~LPUART_BAUD_OSR_MASK; + temp |= LPUART_BAUD_OSR(osr - 1); + + /* write the sbr value to the BAUD registers */ + temp &= ~LPUART_BAUD_SBR_MASK; + base->BAUD = temp | LPUART_BAUD_SBR(sbr); + + /* Set bit count and parity mode. */ + base->BAUD &= ~LPUART_BAUD_M10_MASK; + + temp = base->CTRL & ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK); + + temp |= (uint8_t)config->parityMode; + +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + if (kLPUART_SevenDataBits == config->dataBitsCount) + { + if (kLPUART_ParityDisabled != config->parityMode) + { + temp &= ~LPUART_CTRL_M7_MASK; /* Seven data bits and one parity bit */ + } + else + { + temp |= LPUART_CTRL_M7_MASK; + } + } + else +#endif + { + if (kLPUART_ParityDisabled != config->parityMode) + { + temp |= LPUART_CTRL_M_MASK; /* Eight data bits and one parity bit */ + } + } + + base->CTRL = temp; + +#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT + /* set stop bit per char */ + temp = base->BAUD & ~LPUART_BAUD_SBNS_MASK; + base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)config->stopBitCount); +#endif + +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + /* Set tx/rx WATER watermark */ + base->WATER = (((uint32_t)(config->rxFifoWatermark) << 16) | config->txFifoWatermark); + + /* Enable tx/rx FIFO */ + base->FIFO |= (LPUART_FIFO_TXFE_MASK | LPUART_FIFO_RXFE_MASK); + + /* Flush FIFO */ + base->FIFO |= (LPUART_FIFO_TXFLUSH_MASK | LPUART_FIFO_RXFLUSH_MASK); +#endif + + /* Clear all status flags */ + temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); + +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + temp |= LPUART_STAT_LBKDIF_MASK; +#endif + +#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING + temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK); +#endif + + /* Set data bits order. */ + if (config->isMsb) + { + temp |= LPUART_STAT_MSBF_MASK; + } + else + { + temp &= ~LPUART_STAT_MSBF_MASK; + } + + base->STAT |= temp; + + /* Enable TX/RX base on configure structure. */ + temp = base->CTRL; + if (config->enableTx) + { + temp |= LPUART_CTRL_TE_MASK; + } + + if (config->enableRx) + { + temp |= LPUART_CTRL_RE_MASK; + } + + base->CTRL = temp; + + return kStatus_Success; +} +void LPUART_Deinit(LPUART_Type *base) +{ + uint32_t temp; + +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + /* Wait tx FIFO send out*/ + while (0 != ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXWATER_SHIFT)) + { + } +#endif + /* Wait last char shoft out */ + while (0 == (base->STAT & LPUART_STAT_TC_MASK)) + { + } + + /* Clear all status flags */ + temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); + +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + temp |= LPUART_STAT_LBKDIF_MASK; +#endif + +#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING + temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK); +#endif + + base->STAT |= temp; + + /* Disable the module. */ + base->CTRL = 0; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable lpuart clock */ + CLOCK_DisableClock(s_lpuartClock[LPUART_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void LPUART_GetDefaultConfig(lpuart_config_t *config) +{ + assert(config); + + config->baudRate_Bps = 115200U; + config->parityMode = kLPUART_ParityDisabled; + config->dataBitsCount = kLPUART_EightDataBits; + config->isMsb = false; +#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT + config->stopBitCount = kLPUART_OneStopBit; +#endif +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + config->txFifoWatermark = 0; + config->rxFifoWatermark = 0; +#endif + config->enableTx = false; + config->enableRx = false; +} + +status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) +{ + assert(baudRate_Bps); + + uint32_t temp, oldCtrl; + uint16_t sbr, sbrTemp; + uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff; + + /* This LPUART instantiation uses a slightly different baud rate calculation + * The idea is to use the best OSR (over-sampling rate) possible + * Note, OSR is typically hard-set to 16 in other LPUART instantiations + * loop to find the best OSR value possible, one that generates minimum baudDiff + * iterate through the rest of the supported values of OSR */ + + baudDiff = baudRate_Bps; + osr = 0; + sbr = 0; + for (osrTemp = 4; osrTemp <= 32; osrTemp++) + { + /* calculate the temporary sbr value */ + sbrTemp = (srcClock_Hz / (baudRate_Bps * osrTemp)); + /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/ + if (sbrTemp == 0) + { + sbrTemp = 1; + } + /* Calculate the baud rate based on the temporary OSR and SBR values */ + calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp)); + + tempDiff = calculatedBaud - baudRate_Bps; + + /* Select the better value between srb and (sbr + 1) */ + if (tempDiff > (baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))))) + { + tempDiff = baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))); + sbrTemp++; + } + + if (tempDiff <= baudDiff) + { + baudDiff = tempDiff; + osr = osrTemp; /* update and store the best OSR value calculated */ + sbr = sbrTemp; /* update store the best SBR value calculated */ + } + } + + /* Check to see if actual baud rate is within 3% of desired baud rate + * based on the best calculate OSR value */ + if (baudDiff < ((baudRate_Bps / 100) * 3)) + { + /* Store CTRL before disable Tx and Rx */ + oldCtrl = base->CTRL; + + /* Disable LPUART TX RX before setting. */ + base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); + + temp = base->BAUD; + + /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. + * If so, then "BOTHEDGE" sampling must be turned on */ + if ((osr > 3) && (osr < 8)) + { + temp |= LPUART_BAUD_BOTHEDGE_MASK; + } + + /* program the osr value (bit value is one less than actual value) */ + temp &= ~LPUART_BAUD_OSR_MASK; + temp |= LPUART_BAUD_OSR(osr - 1); + + /* write the sbr value to the BAUD registers */ + temp &= ~LPUART_BAUD_SBR_MASK; + base->BAUD = temp | LPUART_BAUD_SBR(sbr); + + /* Restore CTRL. */ + base->CTRL = oldCtrl; + + return kStatus_Success; + } + else + { + /* Unacceptable baud rate difference of more than 3%*/ + return kStatus_LPUART_BaudrateNotSupport; + } +} + +void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask) +{ + base->BAUD |= ((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)); +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) | + ((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); +#endif + mask &= 0xFFFFFF00U; + base->CTRL |= mask; +} + +void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask) +{ + base->BAUD &= ~((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)); +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) & + ~((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); +#endif + mask &= 0xFFFFFF00U; + base->CTRL &= ~mask; +} + +uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base) +{ + uint32_t temp; + temp = (base->BAUD & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)) >> 8; +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + temp |= (base->FIFO & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)) >> 8; +#endif + temp |= (base->CTRL & 0xFF0C000); + + return temp; +} + +uint32_t LPUART_GetStatusFlags(LPUART_Type *base) +{ + uint32_t temp; + temp = base->STAT; +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + temp |= (base->FIFO & + (LPUART_FIFO_TXEMPT_MASK | LPUART_FIFO_RXEMPT_MASK | LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) >> + 16; +#endif + return temp; +} + +status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask) +{ + uint32_t temp; + status_t status; +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + temp = (uint32_t)base->FIFO; + temp &= (uint32_t)(~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)); + temp |= (mask << 16) & (LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK); + base->FIFO = temp; +#endif + temp = (uint32_t)base->STAT; +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + temp &= (uint32_t)(~(LPUART_STAT_LBKDIF_MASK)); + temp |= mask & LPUART_STAT_LBKDIF_MASK; +#endif + temp &= (uint32_t)(~(LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK)); + temp |= mask & (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); +#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING + temp &= (uint32_t)(~(LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK)); + temp |= mask & (LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK); +#endif + base->STAT = temp; + /* If some flags still pending. */ + if (mask & LPUART_GetStatusFlags(base)) + { + /* Some flags can only clear or set by the hardware itself, these flags are: kLPUART_TxDataRegEmptyFlag, + kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, kLPUART_RxActiveFlag, + kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag, + kLPUART_TxFifoEmptyFlag, kLPUART_RxFifoEmptyFlag. */ + status = kStatus_LPUART_FlagCannotClearManually; /* flags can not clear manually */ + } + else + { + status = kStatus_Success; + } + + return status; +} + +void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length) +{ + assert(data); + + /* This API can only ensure that the data is written into the data buffer but can't + ensure all data in the data buffer are sent into the transmit shift buffer. */ + while (length--) + { + while (!(base->STAT & LPUART_STAT_TDRE_MASK)) + { + } + base->DATA = *(data++); + } +} + +status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length) +{ + assert(data); + + uint32_t statusFlag; +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + uint32_t ctrl = base->CTRL; + bool isSevenDataBits = + ((ctrl & LPUART_CTRL_M7_MASK) || + ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); +#endif + + while (length--) + { +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + while (0 == ((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)) +#else + while (!(base->STAT & LPUART_STAT_RDRF_MASK)) +#endif + { + statusFlag = LPUART_GetStatusFlags(base); + + if (statusFlag & kLPUART_RxOverrunFlag) + { + LPUART_ClearStatusFlags(base, kLPUART_RxOverrunFlag); + return kStatus_LPUART_RxHardwareOverrun; + } + + if (statusFlag & kLPUART_NoiseErrorFlag) + { + LPUART_ClearStatusFlags(base, kLPUART_NoiseErrorFlag); + return kStatus_LPUART_NoiseError; + } + + if (statusFlag & kLPUART_FramingErrorFlag) + { + LPUART_ClearStatusFlags(base, kLPUART_FramingErrorFlag); + return kStatus_LPUART_FramingError; + } + + if (statusFlag & kLPUART_ParityErrorFlag) + { + LPUART_ClearStatusFlags(base, kLPUART_ParityErrorFlag); + return kStatus_LPUART_ParityError; + } + } +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + if (isSevenDataBits) + { + *(data++) = (base->DATA & 0x7F); + } + else + { + *(data++) = base->DATA; + } +#else + *(data++) = base->DATA; +#endif + } + + return kStatus_Success; +} + +void LPUART_TransferCreateHandle(LPUART_Type *base, + lpuart_handle_t *handle, + lpuart_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + uint32_t instance; +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + uint32_t ctrl = base->CTRL; + bool isSevenDataBits = + ((ctrl & LPUART_CTRL_M7_MASK) || + ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); +#endif + + /* Zero the handle. */ + memset(handle, 0, sizeof(lpuart_handle_t)); + + /* Set the TX/RX state. */ + handle->rxState = kLPUART_RxIdle; + handle->txState = kLPUART_TxIdle; + + /* Set the callback and user data. */ + handle->callback = callback; + handle->userData = userData; + +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + /* Initial seven data bits flag */ + handle->isSevenDataBits = isSevenDataBits; +#endif + +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + /* Note: + Take care of the RX FIFO, RX interrupt request only assert when received bytes + equal or more than RX water mark, there is potential issue if RX water + mark larger than 1. + For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and + 5 bytes are received. the last byte will be saved in FIFO but not trigger + RX interrupt because the water mark is 2. + */ + base->WATER &= (~LPUART_WATER_RXWATER_MASK); +#endif + + /* Get instance from peripheral base address. */ + instance = LPUART_GetInstance(base); + + /* Save the handle in global variables to support the double weak mechanism. */ + s_lpuartHandle[instance] = handle; + + s_lpuartIsr = LPUART_TransferHandleIRQ; + +/* Enable interrupt in NVIC. */ +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ + EnableIRQ(s_lpuartRxIRQ[instance]); + EnableIRQ(s_lpuartTxIRQ[instance]); +#else + EnableIRQ(s_lpuartIRQ[instance]); +#endif +} + +void LPUART_TransferStartRingBuffer(LPUART_Type *base, + lpuart_handle_t *handle, + uint8_t *ringBuffer, + size_t ringBufferSize) +{ + assert(handle); + assert(ringBuffer); + + /* Setup the ring buffer address */ + handle->rxRingBuffer = ringBuffer; + handle->rxRingBufferSize = ringBufferSize; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; + + /* Enable the interrupt to accept the data when user need the ring buffer. */ + LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); +} + +void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle) +{ + assert(handle); + + if (handle->rxState == kLPUART_RxIdle) + { + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + } + + handle->rxRingBuffer = NULL; + handle->rxRingBufferSize = 0U; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; +} + +status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); + + status_t status; + + /* Return error if current TX busy. */ + if (kLPUART_TxBusy == handle->txState) + { + status = kStatus_LPUART_TxBusy; + } + else + { + handle->txData = xfer->data; + handle->txDataSize = xfer->dataSize; + handle->txDataSizeAll = xfer->dataSize; + handle->txState = kLPUART_TxBusy; + + /* Enable transmiter interrupt. */ + LPUART_EnableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable); + + status = kStatus_Success; + } + + return status; +} + +void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle) +{ + assert(handle); + + LPUART_DisableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_TransmissionCompleteInterruptEnable); + + handle->txDataSize = 0; + handle->txState = kLPUART_TxIdle; +} + +status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count) +{ + assert(handle); + assert(count); + + if (kLPUART_TxIdle == handle->txState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->txDataSizeAll - handle->txDataSize; + + return kStatus_Success; +} + +status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, + lpuart_handle_t *handle, + lpuart_transfer_t *xfer, + size_t *receivedBytes) +{ + assert(handle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); + + uint32_t i; + status_t status; + /* How many bytes to copy from ring buffer to user memory. */ + size_t bytesToCopy = 0U; + /* How many bytes to receive. */ + size_t bytesToReceive; + /* How many bytes currently have received. */ + size_t bytesCurrentReceived; + + /* How to get data: + 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize + to lpuart handle, enable interrupt to store received data to xfer->data. When + all data received, trigger callback. + 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. + If there are enough data in ring buffer, copy them to xfer->data and return. + If there are not enough data in ring buffer, copy all of them to xfer->data, + save the xfer->data remained empty space to lpuart handle, receive data + to this empty space and trigger callback when finished. */ + + if (kLPUART_RxBusy == handle->rxState) + { + status = kStatus_LPUART_RxBusy; + } + else + { + bytesToReceive = xfer->dataSize; + bytesCurrentReceived = 0; + + /* If RX ring buffer is used. */ + if (handle->rxRingBuffer) + { + /* Disable LPUART RX IRQ, protect ring buffer. */ + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable); + + /* How many bytes in RX ring buffer currently. */ + bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle); + + if (bytesToCopy) + { + bytesToCopy = MIN(bytesToReceive, bytesToCopy); + + bytesToReceive -= bytesToCopy; + + /* Copy data from ring buffer to user memory. */ + for (i = 0U; i < bytesToCopy; i++) + { + xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail]; + + /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + } + + /* If ring buffer does not have enough data, still need to read more data. */ + if (bytesToReceive) + { + /* No data in ring buffer, save the request to LPUART handle. */ + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = kLPUART_RxBusy; + } + /* Enable LPUART RX IRQ if previously enabled. */ + LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable); + + /* Call user callback since all data are received. */ + if (0 == bytesToReceive) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); + } + } + } + /* Ring buffer not used. */ + else + { + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = kLPUART_RxBusy; + + /* Enable RX interrupt. */ + LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + } + + /* Return the how many bytes have read. */ + if (receivedBytes) + { + *receivedBytes = bytesCurrentReceived; + } + + status = kStatus_Success; + } + + return status; +} + +void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle) +{ + assert(handle); + + /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ + if (!handle->rxRingBuffer) + { + /* Disable RX interrupt. */ + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + } + + handle->rxDataSize = 0U; + handle->rxState = kLPUART_RxIdle; +} + +status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count) +{ + assert(handle); + assert(count); + + if (kLPUART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->rxDataSizeAll - handle->rxDataSize; + + return kStatus_Success; +} + +void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle) +{ + assert(handle); + + uint8_t count; + uint8_t tempCount; + + /* If RX overrun. */ + if (LPUART_STAT_OR_MASK & base->STAT) + { + /* Clear overrun flag, otherwise the RX does not work. */ + base->STAT = ((base->STAT & 0x3FE00000U) | LPUART_STAT_OR_MASK); + + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxHardwareOverrun, handle->userData); + } + } + + /* Receive data register full */ + if ((LPUART_STAT_RDRF_MASK & base->STAT) && (LPUART_CTRL_RIE_MASK & base->CTRL)) + { +/* Get the size that can be stored into buffer for this interrupt. */ +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)); +#else + count = 1; +#endif + + /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ + while ((count) && (handle->rxDataSize)) + { +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + tempCount = MIN(handle->rxDataSize, count); +#else + tempCount = 1; +#endif + + /* Using non block API to read the data from the registers. */ + LPUART_ReadNonBlocking(base, handle->rxData, tempCount); + handle->rxData += tempCount; + handle->rxDataSize -= tempCount; + count -= tempCount; + + /* If all the data required for upper layer is ready, trigger callback. */ + if (!handle->rxDataSize) + { + handle->rxState = kLPUART_RxIdle; + + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); + } + } + } + + /* If use RX ring buffer, receive data to ring buffer. */ + if (handle->rxRingBuffer) + { + while (count--) + { + /* If RX ring buffer is full, trigger callback to notify over run. */ + if (LPUART_TransferIsRxRingBufferFull(base, handle)) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxRingBufferOverrun, handle->userData); + } + } + + /* If ring buffer is still full after callback function, the oldest data is overrided. */ + if (LPUART_TransferIsRxRingBufferFull(base, handle)) + { + /* Increase handle->rxRingBufferTail to make room for new data. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + +/* Read data. */ +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + if (handle->isSevenDataBits) + { + handle->rxRingBuffer[handle->rxRingBufferHead] = (base->DATA & 0x7F); + } + else + { + handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA; + } +#else + handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA; +#endif + + /* Increase handle->rxRingBufferHead. */ + if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferHead = 0U; + } + else + { + handle->rxRingBufferHead++; + } + } + } + /* If no receive requst pending, stop RX interrupt. */ + else if (!handle->rxDataSize) + { + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + } + else + { + } + } + + /* Send data register empty and the interrupt is enabled. */ + if ((base->STAT & LPUART_STAT_TDRE_MASK) && (base->CTRL & LPUART_CTRL_TIE_MASK)) + { +/* Get the bytes that available at this moment. */ +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + count = FSL_FEATURE_LPUART_FIFO_SIZEn(base) - + ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXCOUNT_SHIFT); +#else + count = 1; +#endif + + while ((count) && (handle->txDataSize)) + { +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + tempCount = MIN(handle->txDataSize, count); +#else + tempCount = 1; +#endif + + /* Using non block API to write the data to the registers. */ + LPUART_WriteNonBlocking(base, handle->txData, tempCount); + handle->txData += tempCount; + handle->txDataSize -= tempCount; + count -= tempCount; + + /* If all the data are written to data register, notify user with the callback, then TX finished. */ + if (!handle->txDataSize) + { + handle->txState = kLPUART_TxIdle; + + /* Disable TX register empty interrupt. */ + base->CTRL = (base->CTRL & ~LPUART_CTRL_TIE_MASK); + + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_TxIdle, handle->userData); + } + } + } + } +} + +void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle) +{ + /* To be implemented by User. */ +} + +#if defined(LPUART0) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART0_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART0, s_lpuartHandle[0]); +} +void LPUART0_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART0, s_lpuartHandle[0]); +} +#else +void LPUART0_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART0, s_lpuartHandle[0]); +} +#endif +#endif + +#if defined(LPUART1) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART1_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART1, s_lpuartHandle[1]); +} +void LPUART1_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART1, s_lpuartHandle[1]); +} +#else +void LPUART1_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART1, s_lpuartHandle[1]); +} +#endif +#endif + +#if defined(LPUART2) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART2_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART2, s_lpuartHandle[2]); +} +void LPUART2_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART2, s_lpuartHandle[2]); +} +#else +void LPUART2_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART2, s_lpuartHandle[2]); +} +#endif +#endif + +#if defined(LPUART3) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART3_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART3, s_lpuartHandle[3]); +} +void LPUART3_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART3, s_lpuartHandle[3]); +} +#else +void LPUART3_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART3, s_lpuartHandle[3]); +} +#endif +#endif + +#if defined(LPUART4) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART4_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART4, s_lpuartHandle[4]); +} +void LPUART4_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART4, s_lpuartHandle[4]); +} +#else +void LPUART4_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART4, s_lpuartHandle[4]); +} +#endif +#endif + +#if defined(LPUART5) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART5_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART5, s_lpuartHandle[5]); +} +void LPUART5_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART5, s_lpuartHandle[5]); +} +#else +void LPUART5_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART5, s_lpuartHandle[5]); +} +#endif +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart.h new file mode 100644 index 00000000000..1db0455f205 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart.h @@ -0,0 +1,814 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_LPUART_H_ +#define _FSL_LPUART_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup lpuart_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief LPUART driver version 2.2.1. */ +#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 2, 3)) +/*@}*/ + +/*! @brief Error codes for the LPUART driver. */ +enum _lpuart_status +{ + kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */ + kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */ + kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */ + kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */ + kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */ + kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */ + kStatus_LPUART_FlagCannotClearManually = MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */ + kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */ + kStatus_LPUART_RxRingBufferOverrun = + MAKE_STATUS(kStatusGroup_LPUART, 8), /*!< LPUART RX software ring buffer overrun. */ + kStatus_LPUART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_LPUART, 9), /*!< LPUART RX receiver overrun. */ + kStatus_LPUART_NoiseError = MAKE_STATUS(kStatusGroup_LPUART, 10), /*!< LPUART noise error. */ + kStatus_LPUART_FramingError = MAKE_STATUS(kStatusGroup_LPUART, 11), /*!< LPUART framing error. */ + kStatus_LPUART_ParityError = MAKE_STATUS(kStatusGroup_LPUART, 12), /*!< LPUART parity error. */ + kStatus_LPUART_BaudrateNotSupport = + MAKE_STATUS(kStatusGroup_LPUART, 13), /*!< Baudrate is not support in current clock source */ +}; + +/*! @brief LPUART parity mode. */ +typedef enum _lpuart_parity_mode +{ + kLPUART_ParityDisabled = 0x0U, /*!< Parity disabled */ + kLPUART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */ + kLPUART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */ +} lpuart_parity_mode_t; + +/*! @brief LPUART data bits count. */ +typedef enum _lpuart_data_bits +{ + kLPUART_EightDataBits = 0x0U, /*!< Eight data bit */ +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + kLPUART_SevenDataBits = 0x1U, /*!< Seven data bit */ +#endif +} lpuart_data_bits_t; + +/*! @brief LPUART stop bit count. */ +typedef enum _lpuart_stop_bit_count +{ + kLPUART_OneStopBit = 0U, /*!< One stop bit */ + kLPUART_TwoStopBit = 1U, /*!< Two stop bits */ +} lpuart_stop_bit_count_t; + +/*! + * @brief LPUART interrupt configuration structure, default settings all disabled. + * + * This structure contains the settings for all LPUART interrupt configurations. + */ +enum _lpuart_interrupt_enable +{ +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + kLPUART_LinBreakInterruptEnable = (LPUART_BAUD_LBKDIE_MASK >> 8), /*!< LIN break detect. */ +#endif + kLPUART_RxActiveEdgeInterruptEnable = (LPUART_BAUD_RXEDGIE_MASK >> 8), /*!< Receive Active Edge. */ + kLPUART_TxDataRegEmptyInterruptEnable = (LPUART_CTRL_TIE_MASK), /*!< Transmit data register empty. */ + kLPUART_TransmissionCompleteInterruptEnable = (LPUART_CTRL_TCIE_MASK), /*!< Transmission complete. */ + kLPUART_RxDataRegFullInterruptEnable = (LPUART_CTRL_RIE_MASK), /*!< Receiver data register full. */ + kLPUART_IdleLineInterruptEnable = (LPUART_CTRL_ILIE_MASK), /*!< Idle line. */ + kLPUART_RxOverrunInterruptEnable = (LPUART_CTRL_ORIE_MASK), /*!< Receiver Overrun. */ + kLPUART_NoiseErrorInterruptEnable = (LPUART_CTRL_NEIE_MASK), /*!< Noise error flag. */ + kLPUART_FramingErrorInterruptEnable = (LPUART_CTRL_FEIE_MASK), /*!< Framing error flag. */ + kLPUART_ParityErrorInterruptEnable = (LPUART_CTRL_PEIE_MASK), /*!< Parity error flag. */ +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + kLPUART_TxFifoOverflowInterruptEnable = (LPUART_FIFO_TXOFE_MASK >> 8), /*!< Transmit FIFO Overflow. */ + kLPUART_RxFifoUnderflowInterruptEnable = (LPUART_FIFO_RXUFE_MASK >> 8), /*!< Receive FIFO Underflow. */ +#endif +}; + +/*! + * @brief LPUART status flags. + * + * This provides constants for the LPUART status flags for use in the LPUART functions. + */ +enum _lpuart_flags +{ + kLPUART_TxDataRegEmptyFlag = + (LPUART_STAT_TDRE_MASK), /*!< Transmit data register empty flag, sets when transmit buffer is empty */ + kLPUART_TransmissionCompleteFlag = + (LPUART_STAT_TC_MASK), /*!< Transmission complete flag, sets when transmission activity complete */ + kLPUART_RxDataRegFullFlag = + (LPUART_STAT_RDRF_MASK), /*!< Receive data register full flag, sets when the receive data buffer is full */ + kLPUART_IdleLineFlag = (LPUART_STAT_IDLE_MASK), /*!< Idle line detect flag, sets when idle line detected */ + kLPUART_RxOverrunFlag = (LPUART_STAT_OR_MASK), /*!< Receive Overrun, sets when new data is received before data is + read from receive register */ + kLPUART_NoiseErrorFlag = (LPUART_STAT_NF_MASK), /*!< Receive takes 3 samples of each received bit. If any of these + samples differ, noise flag sets */ + kLPUART_FramingErrorFlag = + (LPUART_STAT_FE_MASK), /*!< Frame error flag, sets if logic 0 was detected where stop bit expected */ + kLPUART_ParityErrorFlag = (LPUART_STAT_PF_MASK), /*!< If parity enabled, sets upon parity error detection */ +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + kLPUART_LinBreakFlag = (LPUART_STAT_LBKDIF_MASK), /*!< LIN break detect interrupt flag, sets when LIN break char + detected and LIN circuit enabled */ +#endif + kLPUART_RxActiveEdgeFlag = + (LPUART_STAT_RXEDGIF_MASK), /*!< Receive pin active edge interrupt flag, sets when active edge detected */ + kLPUART_RxActiveFlag = + (LPUART_STAT_RAF_MASK), /*!< Receiver Active Flag (RAF), sets at beginning of valid start bit */ +#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING + kLPUART_DataMatch1Flag = LPUART_STAT_MA1F_MASK, /*!< The next character to be read from LPUART_DATA matches MA1*/ + kLPUART_DataMatch2Flag = LPUART_STAT_MA2F_MASK, /*!< The next character to be read from LPUART_DATA matches MA2*/ +#endif +#if defined(FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS + kLPUART_NoiseErrorInRxDataRegFlag = + (LPUART_DATA_NOISY_MASK >> 10), /*!< NOISY bit, sets if noise detected in current data word */ + kLPUART_ParityErrorInRxDataRegFlag = + (LPUART_DATA_PARITYE_MASK >> 10), /*!< PARITYE bit, sets if noise detected in current data word */ +#endif +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + kLPUART_TxFifoEmptyFlag = (LPUART_FIFO_TXEMPT_MASK >> 16), /*!< TXEMPT bit, sets if transmit buffer is empty */ + kLPUART_RxFifoEmptyFlag = (LPUART_FIFO_RXEMPT_MASK >> 16), /*!< RXEMPT bit, sets if receive buffer is empty */ + kLPUART_TxFifoOverflowFlag = + (LPUART_FIFO_TXOF_MASK >> 16), /*!< TXOF bit, sets if transmit buffer overflow occurred */ + kLPUART_RxFifoUnderflowFlag = + (LPUART_FIFO_RXUF_MASK >> 16), /*!< RXUF bit, sets if receive buffer underflow occurred */ +#endif +}; + +/*! @brief LPUART configuration structure. */ +typedef struct _lpuart_config +{ + uint32_t baudRate_Bps; /*!< LPUART baud rate */ + lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */ + lpuart_data_bits_t dataBitsCount; /*!< Data bits count, eight (default), seven */ + bool isMsb; /*!< Data bits order, LSB (default), MSB */ +#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT + lpuart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */ +#endif +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + uint8_t txFifoWatermark; /*!< TX FIFO watermark */ + uint8_t rxFifoWatermark; /*!< RX FIFO watermark */ +#endif + bool enableTx; /*!< Enable TX */ + bool enableRx; /*!< Enable RX */ +} lpuart_config_t; + +/*! @brief LPUART transfer structure. */ +typedef struct _lpuart_transfer +{ + uint8_t *data; /*!< The buffer of data to be transfer.*/ + size_t dataSize; /*!< The byte count to be transfer. */ +} lpuart_transfer_t; + +/* Forward declaration of the handle typedef. */ +typedef struct _lpuart_handle lpuart_handle_t; + +/*! @brief LPUART transfer callback function. */ +typedef void (*lpuart_transfer_callback_t)(LPUART_Type *base, lpuart_handle_t *handle, status_t status, void *userData); + +/*! @brief LPUART handle structure. */ +struct _lpuart_handle +{ + uint8_t *volatile txData; /*!< Address of remaining data to send. */ + volatile size_t txDataSize; /*!< Size of the remaining data to send. */ + size_t txDataSizeAll; /*!< Size of the data to send out. */ + uint8_t *volatile rxData; /*!< Address of remaining data to receive. */ + volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */ + size_t rxDataSizeAll; /*!< Size of the data to receive. */ + + uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */ + size_t rxRingBufferSize; /*!< Size of the ring buffer. */ + volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */ + volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */ + + lpuart_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< LPUART callback function parameter.*/ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state. */ + +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + bool isSevenDataBits; /*!< Seven data bits flag. */ +#endif +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL + +/*! + * @name Software Reset + * @{ + */ + +/*! + * @brief Resets the LPUART using software. + * + * This function resets all internal logic and registers except the Global Register. + * Remains set until cleared by software. + * + * @param base LPUART peripheral base address. + */ +static inline void LPUART_SoftwareReset(LPUART_Type *base) +{ + base->GLOBAL |= LPUART_GLOBAL_RST_MASK; + base->GLOBAL &= ~LPUART_GLOBAL_RST_MASK; +} +/* @} */ +#endif /*FSL_FEATURE_LPUART_HAS_GLOBAL*/ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock. + * + * This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function + * to configure the configuration structure and get the default configuration. + * The example below shows how to use this API to configure the LPUART. + * @code + * lpuart_config_t lpuartConfig; + * lpuartConfig.baudRate_Bps = 115200U; + * lpuartConfig.parityMode = kLPUART_ParityDisabled; + * lpuartConfig.dataBitsCount = kLPUART_EightDataBits; + * lpuartConfig.isMsb = false; + * lpuartConfig.stopBitCount = kLPUART_OneStopBit; + * lpuartConfig.txFifoWatermark = 0; + * lpuartConfig.rxFifoWatermark = 1; + * LPUART_Init(LPUART1, &lpuartConfig, 20000000U); + * @endcode + * + * @param base LPUART peripheral base address. + * @param config Pointer to a user-defined configuration structure. + * @param srcClock_Hz LPUART clock source frequency in HZ. + * @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source. + * @retval kStatus_Success LPUART initialize succeed + */ +status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz); + +/*! + * @brief Deinitializes a LPUART instance. + * + * This function waits for transmit to complete, disables TX and RX, and disables the LPUART clock. + * + * @param base LPUART peripheral base address. + */ +void LPUART_Deinit(LPUART_Type *base); + +/*! + * @brief Gets the default configuration structure. + * + * This function initializes the LPUART configuration structure to a default value. The default + * values are: + * lpuartConfig->baudRate_Bps = 115200U; + * lpuartConfig->parityMode = kLPUART_ParityDisabled; + * lpuartConfig->dataBitsCount = kLPUART_EightDataBits; + * lpuartConfig->isMsb = false; + * lpuartConfig->stopBitCount = kLPUART_OneStopBit; + * lpuartConfig->txFifoWatermark = 0; + * lpuartConfig->rxFifoWatermark = 1; + * lpuartConfig->enableTx = false; + * lpuartConfig->enableRx = false; + * + * @param config Pointer to a configuration structure. + */ +void LPUART_GetDefaultConfig(lpuart_config_t *config); + +/*! + * @brief Sets the LPUART instance baudrate. + * + * This function configures the LPUART module baudrate. This function is used to update + * the LPUART module baudrate after the LPUART module is initialized by the LPUART_Init. + * @code + * LPUART_SetBaudRate(LPUART1, 115200U, 20000000U); + * @endcode + * + * @param base LPUART peripheral base address. + * @param baudRate_Bps LPUART baudrate to be set. + * @param srcClock_Hz LPUART clock source frequency in HZ. + * @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not supported in the current clock source. + * @retval kStatus_Success Set baudrate succeeded. + */ +status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets LPUART status flags. + * + * This function gets all LPUART status flags. The flags are returned as the logical + * OR value of the enumerators @ref _lpuart_flags. To check for a specific status, + * compare the return value with enumerators in the @ref _lpuart_flags. + * For example, to check whether the TX is empty: + * @code + * if (kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1)) + * { + * ... + * } + * @endcode + * + * @param base LPUART peripheral base address. + * @return LPUART status flags which are ORed by the enumerators in the _lpuart_flags. + */ +uint32_t LPUART_GetStatusFlags(LPUART_Type *base); + +/*! + * @brief Clears status flags with a provided mask. + * + * This function clears LPUART status flags with a provided mask. Automatically cleared flags + * can't be cleared by this function. + * Flags that can only cleared or set by hardware are: + * kLPUART_TxDataRegEmptyFlag, kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, + * kLPUART_RxActiveFlag, kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag, + * kLPUART_TxFifoEmptyFlag,kLPUART_RxFifoEmptyFlag + * Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects. + * + * @param base LPUART peripheral base address. + * @param mask the status flags to be cleared. The user can use the enumerators in the + * _lpuart_status_flag_t to do the OR operation and get the mask. + * @return 0 succeed, others failed. + * @retval kStatus_LPUART_FlagCannotClearManually The flag can't be cleared by this function but + * it is cleared automatically by hardware. + * @retval kStatus_Success Status in the mask are cleared. + */ +status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables LPUART interrupts according to a provided mask. + * + * This function enables the LPUART interrupts according to a provided mask. The mask + * is a logical OR of enumeration members. See the @ref _lpuart_interrupt_enable. + * This examples shows how to enable TX empty interrupt and RX full interrupt: + * @code + * LPUART_EnableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); + * @endcode + * + * @param base LPUART peripheral base address. + * @param mask The interrupts to enable. Logical OR of @ref _uart_interrupt_enable. + */ +void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask); + +/*! + * @brief Disables LPUART interrupts according to a provided mask. + * + * This function disables the LPUART interrupts according to a provided mask. The mask + * is a logical OR of enumeration members. See @ref _lpuart_interrupt_enable. + * This example shows how to disable the TX empty interrupt and RX full interrupt: + * @code + * LPUART_DisableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); + * @endcode + * + * @param base LPUART peripheral base address. + * @param mask The interrupts to disable. Logical OR of @ref _lpuart_interrupt_enable. + */ +void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask); + +/*! + * @brief Gets enabled LPUART interrupts. + * + * This function gets the enabled LPUART interrupts. The enabled interrupts are returned + * as the logical OR value of the enumerators @ref _lpuart_interrupt_enable. To check + * a specific interrupt enable status, compare the return value with enumerators + * in @ref _lpuart_interrupt_enable. + * For example, to check whether the TX empty interrupt is enabled: + * @code + * uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(LPUART1); + * + * if (kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts) + * { + * ... + * } + * @endcode + * + * @param base LPUART peripheral base address. + * @return LPUART interrupt flags which are logical OR of the enumerators in @ref _lpuart_interrupt_enable. + */ +uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base); + +#if defined(FSL_FEATURE_LPUART_HAS_DMA_ENABLE) && FSL_FEATURE_LPUART_HAS_DMA_ENABLE +/*! + * @brief Gets the LPUART data register address. + * + * This function returns the LPUART data register address, which is mainly used by the DMA/eDMA. + * + * @param base LPUART peripheral base address. + * @return LPUART data register addresses which are used both by the transmitter and receiver. + */ +static inline uint32_t LPUART_GetDataRegisterAddress(LPUART_Type *base) +{ + return (uint32_t) & (base->DATA); +} + +/*! + * @brief Enables or disables the LPUART transmitter DMA request. + * + * This function enables or disables the transmit data register empty flag, STAT[TDRE], to generate DMA requests. + * + * @param base LPUART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LPUART_EnableTxDMA(LPUART_Type *base, bool enable) +{ + if (enable) + { + base->BAUD |= LPUART_BAUD_TDMAE_MASK; + base->CTRL |= LPUART_CTRL_TIE_MASK; + } + else + { + base->BAUD &= ~LPUART_BAUD_TDMAE_MASK; + base->CTRL &= ~LPUART_CTRL_TIE_MASK; + } +} + +/*! + * @brief Enables or disables the LPUART receiver DMA. + * + * This function enables or disables the receiver data register full flag, STAT[RDRF], to generate DMA requests. + * + * @param base LPUART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LPUART_EnableRxDMA(LPUART_Type *base, bool enable) +{ + if (enable) + { + base->BAUD |= LPUART_BAUD_RDMAE_MASK; + base->CTRL |= LPUART_CTRL_RIE_MASK; + } + else + { + base->BAUD &= ~LPUART_BAUD_RDMAE_MASK; + base->CTRL &= ~LPUART_CTRL_RIE_MASK; + } +} + +/* @} */ +#endif /* FSL_FEATURE_LPUART_HAS_DMA_ENABLE */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Enables or disables the LPUART transmitter. + * + * This function enables or disables the LPUART transmitter. + * + * @param base LPUART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LPUART_EnableTx(LPUART_Type *base, bool enable) +{ + if (enable) + { + base->CTRL |= LPUART_CTRL_TE_MASK; + } + else + { + base->CTRL &= ~LPUART_CTRL_TE_MASK; + } +} + +/*! + * @brief Enables or disables the LPUART receiver. + * + * This function enables or disables the LPUART receiver. + * + * @param base LPUART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LPUART_EnableRx(LPUART_Type *base, bool enable) +{ + if (enable) + { + base->CTRL |= LPUART_CTRL_RE_MASK; + } + else + { + base->CTRL &= ~LPUART_CTRL_RE_MASK; + } +} + +/*! + * @brief Writes to the transmitter register. + * + * This function writes data to the transmitter register directly. The upper layer must + * ensure that the TX register is empty or that the TX FIFO has room before calling this function. + * + * @param base LPUART peripheral base address. + * @param data Data write to the TX register. + */ +static inline void LPUART_WriteByte(LPUART_Type *base, uint8_t data) +{ + base->DATA = data; +} + +/*! + * @brief Reads the receiver register. + * + * This function reads data from the receiver register directly. The upper layer must + * ensure that the receiver register is full or that the RX FIFO has data before calling this function. + * + * @param base LPUART peripheral base address. + * @return Data read from data register. + */ +static inline uint8_t LPUART_ReadByte(LPUART_Type *base) +{ +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + uint32_t ctrl = base->CTRL; + bool isSevenDataBits = + ((ctrl & LPUART_CTRL_M7_MASK) || + ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); + + if (isSevenDataBits) + { + return (base->DATA & 0x7F); + } + else + { + return base->DATA; + } +#else + return base->DATA; +#endif +} + +/*! + * @brief Writes to the transmitter register using a blocking method. + * + * This function polls the transmitter register, waits for the register to be empty or for TX FIFO to have + * room, and writes data to the transmitter buffer. + * + * @note This function does not check whether all data has been sent out to the bus. + * Before disabling the transmitter, check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is + * finished. + * + * @param base LPUART peripheral base address. + * @param data Start address of the data to write. + * @param length Size of the data to write. + */ +void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length); + +/*! +* @brief Reads the receiver data register using a blocking method. + * + * This function polls the receiver register, waits for the receiver register full or receiver FIFO + * has data, and reads data from the TX register. + * + * @param base LPUART peripheral base address. + * @param data Start address of the buffer to store the received data. + * @param length Size of the buffer. + * @retval kStatus_LPUART_RxHardwareOverrun Receiver overrun happened while receiving data. + * @retval kStatus_LPUART_NoiseError Noise error happened while receiving data. + * @retval kStatus_LPUART_FramingError Framing error happened while receiving data. + * @retval kStatus_LPUART_ParityError Parity error happened while receiving data. + * @retval kStatus_Success Successfully received all data. + */ +status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length); + +/* @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the LPUART handle. + * + * This function initializes the LPUART handle, which can be used for other LPUART + * transactional APIs. Usually, for a specified LPUART instance, + * call this API once to get the initialized handle. + * + * The LPUART driver supports the "background" receiving, which means that user can set up + * an RX ring buffer optionally. Data received is stored into the ring buffer even when the + * user doesn't call the LPUART_TransferReceiveNonBlocking() API. If there is already data received + * in the ring buffer, the user can get the received data from the ring buffer directly. + * The ring buffer is disabled if passing NULL as @p ringBuffer. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param callback Callback function. + * @param userData User data. + */ +void LPUART_TransferCreateHandle(LPUART_Type *base, + lpuart_handle_t *handle, + lpuart_transfer_callback_t callback, + void *userData); +/*! + * @brief Transmits a buffer of data using the interrupt method. + * + * This function send data using an interrupt method. This is a non-blocking function, which + * returns directly without waiting for all data written to the transmitter register. When + * all data is written to the TX register in the ISR, the LPUART driver calls the callback + * function and passes the @ref kStatus_LPUART_TxIdle as status parameter. + * + * @note The kStatus_LPUART_TxIdle is passed to the upper layer when all data are written + * to the TX register. However, there is no check to ensure that all the data sent out. Before disabling the TX, + * check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is finished. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param xfer LPUART transfer structure, see #lpuart_transfer_t. + * @retval kStatus_Success Successfully start the data transmission. + * @retval kStatus_LPUART_TxBusy Previous transmission still not finished, data not all written to the TX register. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer); + +/*! + * @brief Sets up the RX ring buffer. + * + * This function sets up the RX ring buffer to a specific UART handle. + * + * When the RX ring buffer is used, data received is stored into the ring buffer even when + * the user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received + * in the ring buffer, the user can get the received data from the ring buffer directly. + * + * @note When using RX ring buffer, one byte is reserved for internal use. In other + * words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer. + * @param ringBufferSize size of the ring buffer. + */ +void LPUART_TransferStartRingBuffer(LPUART_Type *base, + lpuart_handle_t *handle, + uint8_t *ringBuffer, + size_t ringBufferSize); + +/*! + * @brief Aborts the background transfer and uninstalls the ring buffer. + * + * This function aborts the background transfer and uninstalls the ring buffer. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Aborts the interrupt-driven data transmit. + * + * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out + * how many bytes are not sent out. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Gets the number of bytes that have been written to the LPUART transmitter register. + * + * This function gets the number of bytes that have been written to LPUART TX + * register by an interrupt method. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param count Send bytes count. + * @retval kStatus_NoTransferInProgress No send in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count); + +/*! + * @brief Receives a buffer of data using the interrupt method. + * + * This function receives data using an interrupt method. This is a non-blocking function + * which returns without waiting to ensure that all data are received. + * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and + * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer. + * After copying, if the data in the ring buffer is not enough for read, the receive + * request is saved by the LPUART driver. When the new data arrives, the receive request + * is serviced first. When all data is received, the LPUART driver notifies the upper layer + * through a callback function and passes a status parameter @ref kStatus_UART_RxIdle. + * For example, the upper layer needs 10 bytes but there are only 5 bytes in ring buffer. + * The 5 bytes are copied to xfer->data, which returns with the + * parameter @p receivedBytes set to 5. For the remaining 5 bytes, the newly arrived data is + * saved from xfer->data[5]. When 5 bytes are received, the LPUART driver notifies the upper layer. + * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt + * to receive data to xfer->data. When all data is received, the upper layer is notified. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param xfer LPUART transfer structure, see #uart_transfer_t. + * @param receivedBytes Bytes received from the ring buffer directly. + * @retval kStatus_Success Successfully queue the transfer into the transmit queue. + * @retval kStatus_LPUART_RxBusy Previous receive request is not finished. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, + lpuart_handle_t *handle, + lpuart_transfer_t *xfer, + size_t *receivedBytes); + +/*! + * @brief Aborts the interrupt-driven data receiving. + * + * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out + * how many bytes not received yet. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Gets the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_NoTransferInProgress No receive in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count); + +/*! + * @brief LPUART IRQ handle function. + * + * This function handles the LPUART transmit and receive IRQ request. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief LPUART Error IRQ handle function. + * + * This function handles the LPUART error IRQ request. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_LPUART_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart_edma.c new file mode 100644 index 00000000000..5da8d41ed0d --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart_edma.c @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_lpuart_edma.h" +#include "fsl_dmamux.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*base, lpuartPrivateHandle->handle); + + if (lpuartPrivateHandle->handle->callback) + { + lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle, + kStatus_LPUART_TxIdle, lpuartPrivateHandle->handle->userData); + } + } +} + +static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) +{ + assert(param); + + lpuart_edma_private_handle_t *lpuartPrivateHandle = (lpuart_edma_private_handle_t *)param; + + /* Avoid warning for unused parameters. */ + handle = handle; + tcds = tcds; + + if (transferDone) + { + /* Disable transfer. */ + LPUART_TransferAbortReceiveEDMA(lpuartPrivateHandle->base, lpuartPrivateHandle->handle); + + if (lpuartPrivateHandle->handle->callback) + { + lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle, + kStatus_LPUART_RxIdle, lpuartPrivateHandle->handle->userData); + } + } +} + +void LPUART_TransferCreateHandleEDMA(LPUART_Type *base, + lpuart_edma_handle_t *handle, + lpuart_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txEdmaHandle, + edma_handle_t *rxEdmaHandle) +{ + assert(handle); + + uint32_t instance = LPUART_GetInstance(base); + + s_edmaPrivateHandle[instance].base = base; + s_edmaPrivateHandle[instance].handle = handle; + + memset(handle, 0, sizeof(*handle)); + + handle->rxState = kLPUART_RxIdle; + handle->txState = kLPUART_TxIdle; + + handle->rxEdmaHandle = rxEdmaHandle; + handle->txEdmaHandle = txEdmaHandle; + + handle->callback = callback; + handle->userData = userData; + +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + /* Note: + Take care of the RX FIFO, EDMA request only assert when received bytes + equal or more than RX water mark, there is potential issue if RX water + mark larger than 1. + For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and + 5 bytes are received. the last byte will be saved in FIFO but not trigger + EDMA transfer because the water mark is 2. + */ + if (rxEdmaHandle) + { + base->WATER &= (~LPUART_WATER_RXWATER_MASK); + } +#endif + + /* Configure TX. */ + if (txEdmaHandle) + { + EDMA_SetCallback(handle->txEdmaHandle, LPUART_SendEDMACallback, &s_edmaPrivateHandle[instance]); + } + + /* Configure RX. */ + if (rxEdmaHandle) + { + EDMA_SetCallback(handle->rxEdmaHandle, LPUART_ReceiveEDMACallback, &s_edmaPrivateHandle[instance]); + } +} + +status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer) +{ + assert(handle); + assert(handle->txEdmaHandle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); + + edma_transfer_config_t xferConfig; + status_t status; + + /* If previous TX not finished. */ + if (kLPUART_TxBusy == handle->txState) + { + status = kStatus_LPUART_TxBusy; + } + else + { + handle->txState = kLPUART_TxBusy; + handle->txDataSizeAll = xfer->dataSize; + + /* Prepare transfer. */ + EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)LPUART_GetDataRegisterAddress(base), + sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_MemoryToPeripheral); + + /* Store the initially configured eDMA minor byte transfer count into the LPUART handle */ + handle->nbytes = sizeof(uint8_t); + + /* Submit transfer. */ + EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig); + EDMA_StartTransfer(handle->txEdmaHandle); + + /* Enable LPUART TX EDMA. */ + LPUART_EnableTxDMA(base, true); + + status = kStatus_Success; + } + + return status; +} + +status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer) +{ + assert(handle); + assert(handle->rxEdmaHandle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); + + edma_transfer_config_t xferConfig; + status_t status; + + /* If previous RX not finished. */ + if (kLPUART_RxBusy == handle->rxState) + { + status = kStatus_LPUART_RxBusy; + } + else + { + handle->rxState = kLPUART_RxBusy; + handle->rxDataSizeAll = xfer->dataSize; + + /* Prepare transfer. */ + EDMA_PrepareTransfer(&xferConfig, (void *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data, + sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory); + + /* Store the initially configured eDMA minor byte transfer count into the LPUART handle */ + handle->nbytes = sizeof(uint8_t); + + /* Submit transfer. */ + EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig); + EDMA_StartTransfer(handle->rxEdmaHandle); + + /* Enable LPUART RX EDMA. */ + LPUART_EnableRxDMA(base, true); + + status = kStatus_Success; + } + + return status; +} + +void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle) +{ + assert(handle); + assert(handle->txEdmaHandle); + + /* Disable LPUART TX EDMA. */ + LPUART_EnableTxDMA(base, false); + + /* Stop transfer. */ + EDMA_AbortTransfer(handle->txEdmaHandle); + + handle->txState = kLPUART_TxIdle; +} + +void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle) +{ + assert(handle); + assert(handle->rxEdmaHandle); + + /* Disable LPUART RX EDMA. */ + LPUART_EnableRxDMA(base, false); + + /* Stop transfer. */ + EDMA_AbortTransfer(handle->rxEdmaHandle); + + handle->rxState = kLPUART_RxIdle; +} + +status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count) +{ + assert(handle); + assert(handle->rxEdmaHandle); + assert(count); + + if (kLPUART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->rxDataSizeAll - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel); + + return kStatus_Success; +} + +status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count) +{ + assert(handle); + assert(handle->txEdmaHandle); + assert(count); + + if (kLPUART_TxIdle == handle->txState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->txDataSizeAll - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel); + + return kStatus_Success; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart_edma.h new file mode 100644 index 00000000000..8843e958d2d --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_lpuart_edma.h @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_LPUART_EDMA_H_ +#define _FSL_LPUART_EDMA_H_ + +#include "fsl_lpuart.h" +#include "fsl_dmamux.h" +#include "fsl_edma.h" + +/*! + * @addtogroup lpuart_edma_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Forward declaration of the handle typedef. */ +typedef struct _lpuart_edma_handle lpuart_edma_handle_t; + +/*! @brief LPUART transfer callback function. */ +typedef void (*lpuart_edma_transfer_callback_t)(LPUART_Type *base, + lpuart_edma_handle_t *handle, + status_t status, + void *userData); + +/*! +* @brief LPUART eDMA handle +*/ +struct _lpuart_edma_handle +{ + lpuart_edma_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< LPUART callback function parameter.*/ + size_t rxDataSizeAll; /*!< Size of the data to receive. */ + size_t txDataSizeAll; /*!< Size of the data to send out. */ + + edma_handle_t *txEdmaHandle; /*!< The eDMA TX channel used. */ + edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */ + + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name eDMA transactional + * @{ + */ + +/*! + * @brief Initializes the LPUART handle which is used in transactional functions. + * @param base LPUART peripheral base address. + * @param handle Pointer to lpuart_edma_handle_t structure. + * @param callback Callback function. + * @param userData User data. + * @param txEdmaHandle User requested DMA handle for TX DMA transfer. + * @param rxEdmaHandle User requested DMA handle for RX DMA transfer. + */ +void LPUART_TransferCreateHandleEDMA(LPUART_Type *base, + lpuart_edma_handle_t *handle, + lpuart_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txEdmaHandle, + edma_handle_t *rxEdmaHandle); + +/*! + * @brief Sends data using eDMA. + * + * This function sends data using eDMA. This is a non-blocking function, which returns + * right away. When all data is sent, the send callback function is called. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param xfer LPUART eDMA transfer structure. See #lpuart_transfer_t. + * @retval kStatus_Success if succeed, others failed. + * @retval kStatus_LPUART_TxBusy Previous transfer on going. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer); + +/*! + * @brief Receives data using eDMA. + * + * This function receives data using eDMA. This is non-blocking function, which returns + * right away. When all data is received, the receive callback function is called. + * + * @param base LPUART peripheral base address. + * @param handle Pointer to lpuart_edma_handle_t structure. + * @param xfer LPUART eDMA transfer structure, see #lpuart_transfer_t. + * @retval kStatus_Success if succeed, others fail. + * @retval kStatus_LPUART_RxBusy Previous transfer ongoing. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer); + +/*! + * @brief Aborts the sent data using eDMA. + * + * This function aborts the sent data using eDMA. + * + * @param base LPUART peripheral base address. + * @param handle Pointer to lpuart_edma_handle_t structure. + */ +void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle); + +/*! + * @brief Aborts the received data using eDMA. + * + * This function aborts the received data using eDMA. + * + * @param base LPUART peripheral base address. + * @param handle Pointer to lpuart_edma_handle_t structure. + */ +void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle); + +/*! + * @brief Gets the number of bytes written to the LPUART TX register. + * + * This function gets the number of bytes written to the LPUART TX + * register by DMA. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param count Send bytes count. + * @retval kStatus_NoTransferInProgress No send in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count); + +/*! + * @brief Gets the number of received bytes. + * + * This function gets the number of received bytes. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_NoTransferInProgress No receive in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_LPUART_EDMA_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc.c new file mode 100644 index 00000000000..db530c3adc9 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc.c @@ -0,0 +1,4296 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_ltc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! Full word representing the actual bit values for the LTC mode register. */ +typedef uint32_t ltc_mode_t; + +#define LTC_FIFO_SZ_MAX_DOWN_ALGN (0xff0u) +#define LTC_MD_ALG_AES (0x10U) /*!< Bit field value for LTC_MD_ALG: AES */ +#define LTC_MD_ALG_DES (0x20U) /*!< Bit field value for LTC_MD_ALG: DES */ +#define LTC_MD_ALG_TRIPLE_DES (0x21U) /*!< Bit field value for LTC_MD_ALG: 3DES */ +#define LTC_MD_ALG_SHA1 (0x41U) /*!< Bit field value for LTC_MD_ALG: SHA-1 */ +#define LTC_MD_ALG_SHA224 (0x42U) /*!< Bit field value for LTC_MD_ALG: SHA-224 */ +#define LTC_MD_ALG_SHA256 (0x43U) /*!< Bit field value for LTC_MD_ALG: SHA-256 */ +#define LTC_MDPK_ALG_PKHA (0x80U) /*!< Bit field value for LTC_MDPK_ALG: PKHA */ +#define LTC_MD_ENC_DECRYPT (0U) /*!< Bit field value for LTC_MD_ENC: Decrypt. */ +#define LTC_MD_ENC_ENCRYPT (0x1U) /*!< Bit field value for LTC_MD_ENC: Encrypt. */ +#define LTC_MD_AS_UPDATE (0U) /*!< Bit field value for LTC_MD_AS: Update */ +#define LTC_MD_AS_INITIALIZE (0x1U) /*!< Bit field value for LTC_MD_AS: Initialize */ +#define LTC_MD_AS_FINALIZE (0x2U) /*!< Bit field value for LTC_MD_AS: Finalize */ +#define LTC_MD_AS_INIT_FINAL (0x3U) /*!< Bit field value for LTC_MD_AS: Initialize/Finalize */ + +#define LTC_AES_GCM_TYPE_AAD 55 +#define LTC_AES_GCM_TYPE_IV 0 + +#define LTC_CCM_TAG_IDX 8 /*! For CCM encryption, the encrypted final MAC is written to the context word 8-11 */ +#define LTC_GCM_TAG_IDX 0 /*! For GCM encryption, the encrypted final MAC is written to the context word 0-3 */ + +enum _ltc_md_dk_bit_shift +{ + kLTC_ModeRegBitShiftDK = 12U, +}; + +typedef enum _ltc_algorithm +{ +#if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA + kLTC_AlgorithmPKHA = LTC_MDPK_ALG_PKHA << LTC_MD_ALG_SHIFT, +#endif /* FSL_FEATURE_LTC_HAS_PKHA */ + kLTC_AlgorithmAES = LTC_MD_ALG_AES << LTC_MD_ALG_SHIFT, +#if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES + kLTC_AlgorithmDES = LTC_MD_ALG_DES << LTC_MD_ALG_SHIFT, + kLTC_Algorithm3DES = LTC_MD_ALG_TRIPLE_DES << LTC_MD_ALG_SHIFT, +#endif /* FSL_FEATURE_LTC_HAS_DES */ +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + kLTC_AlgorithmSHA1 = LTC_MD_ALG_SHA1 << LTC_MD_ALG_SHIFT, + kLTC_AlgorithmSHA224 = LTC_MD_ALG_SHA224 << LTC_MD_ALG_SHIFT, + kLTC_AlgorithmSHA256 = LTC_MD_ALG_SHA256 << LTC_MD_ALG_SHIFT, +#endif /* FSL_FEATURE_LTC_HAS_SHA */ +} ltc_algorithm_t; + +typedef enum _ltc_mode_symmetric_alg +{ + kLTC_ModeCTR = 0x00U << LTC_MD_AAI_SHIFT, + kLTC_ModeCBC = 0x10U << LTC_MD_AAI_SHIFT, + kLTC_ModeECB = 0x20U << LTC_MD_AAI_SHIFT, + kLTC_ModeCFB = 0x30U << LTC_MD_AAI_SHIFT, + kLTC_ModeOFB = 0x40U << LTC_MD_AAI_SHIFT, + kLTC_ModeCMAC = 0x60U << LTC_MD_AAI_SHIFT, + kLTC_ModeXCBCMAC = 0x70U << LTC_MD_AAI_SHIFT, + kLTC_ModeCCM = 0x80U << LTC_MD_AAI_SHIFT, + kLTC_ModeGCM = 0x90U << LTC_MD_AAI_SHIFT, +} ltc_mode_symmetric_alg_t; + +typedef enum _ltc_mode_encrypt +{ + kLTC_ModeDecrypt = LTC_MD_ENC_DECRYPT << LTC_MD_ENC_SHIFT, + kLTC_ModeEncrypt = LTC_MD_ENC_ENCRYPT << LTC_MD_ENC_SHIFT, +} ltc_mode_encrypt_t; + +typedef enum _ltc_mode_algorithm_state +{ + kLTC_ModeUpdate = LTC_MD_AS_UPDATE << LTC_MD_AS_SHIFT, + kLTC_ModeInit = LTC_MD_AS_INITIALIZE << LTC_MD_AS_SHIFT, + kLTC_ModeFinalize = LTC_MD_AS_FINALIZE << LTC_MD_AS_SHIFT, + kLTC_ModeInitFinal = LTC_MD_AS_INIT_FINAL << LTC_MD_AS_SHIFT +} ltc_mode_algorithm_state_t; + +/*! @brief LTC status flags */ +enum _ltc_status_flag +{ + kLTC_StatusAesBusy = 1U << LTC_STA_AB_SHIFT, +#if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES + kLTC_StatusDesBusy = 1U << LTC_STA_DB_SHIFT, +#endif /* FSL_FEATURE_LTC_HAS_DES */ +#if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA + kLTC_StatusPkhaBusy = 1U << LTC_STA_PB_SHIFT, +#endif /* FSL_FEATURE_LTC_HAS_PKHA */ +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + kLTC_StatusMdhaBusy = 1U << LTC_STA_MB_SHIFT, +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + kLTC_StatusDoneIsr = 1U << LTC_STA_DI_SHIFT, + kLTC_StatusErrorIsr = 1U << LTC_STA_EI_SHIFT, +#if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA + kLTC_StatusPublicKeyPrime = 1U << LTC_STA_PKP_SHIFT, + kLTC_StatusPublicKeyOpOne = 1U << LTC_STA_PKO_SHIFT, + kLTC_StatusPublicKeyOpZero = 1U << LTC_STA_PKZ_SHIFT, +#endif /* FSL_FEATURE_LTC_HAS_PKHA */ + kLTC_StatusAll = LTC_STA_AB_MASK | +#if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES + LTC_STA_DB_MASK | +#endif /* FSL_FEATURE_LTC_HAS_DES */ +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + LTC_STA_MB_MASK | +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + LTC_STA_DI_MASK | LTC_STA_EI_MASK +#if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA + | + LTC_STA_PB_MASK | LTC_STA_PKP_MASK | LTC_STA_PKO_MASK | LTC_STA_PKZ_MASK +#endif /* FSL_FEATURE_LTC_HAS_PKHA */ +}; + +/*! @brief LTC clear register */ +typedef enum _ltc_clear_written +{ + kLTC_ClearMode = 1U << LTC_CW_CM_SHIFT, + kLTC_ClearDataSize = 1U << LTC_CW_CDS_SHIFT, + kLTC_ClearIcvSize = 1U << LTC_CW_CICV_SHIFT, + kLTC_ClearContext = 1U << LTC_CW_CCR_SHIFT, + kLTC_ClearKey = 1U << LTC_CW_CKR_SHIFT, +#if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA + kLTC_ClearPkhaSizeA = 1U << LTC_CW_CPKA_SHIFT, + kLTC_ClearPkhaSizeB = 1U << LTC_CW_CPKB_SHIFT, + kLTC_ClearPkhaSizeN = 1U << LTC_CW_CPKN_SHIFT, + kLTC_ClearPkhaSizeE = 1U << LTC_CW_CPKE_SHIFT, + kLTC_ClearAllSize = (int)kLTC_ClearPkhaSizeA | kLTC_ClearPkhaSizeB | kLTC_ClearPkhaSizeN | kLTC_ClearPkhaSizeE, +#endif /* FSL_FEATURE_LTC_HAS_PKHA */ + kLTC_ClearOutputFifo = 1U << LTC_CW_COF_SHIFT, + kLTC_ClearInputFifo = (int)(1U << LTC_CW_CIF_SHIFT), + kLTC_ClearAll = (int)(LTC_CW_CM_MASK | LTC_CW_CDS_MASK | LTC_CW_CICV_MASK | LTC_CW_CCR_MASK | LTC_CW_CKR_MASK | +#if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA + LTC_CW_CPKA_MASK | LTC_CW_CPKB_MASK | LTC_CW_CPKN_MASK | LTC_CW_CPKE_MASK | +#endif /* FSL_FEATURE_LTC_HAS_PKHA */ + LTC_CW_COF_MASK | LTC_CW_CIF_MASK) +} ltc_clear_written_t; + +enum _ltc_ctrl_swap +{ + kLTC_CtrlSwapAll = + LTC_CTL_IFS_MASK | LTC_CTL_OFS_MASK | LTC_CTL_KIS_MASK | LTC_CTL_KOS_MASK | LTC_CTL_CIS_MASK | LTC_CTL_COS_MASK, +}; + +/*! @brief Type used in GCM and CCM modes. + + Content of a block is established via individual bytes and moved to LTC + IFIFO by moving 32-bit words. +*/ +typedef union _ltc_xcm_block_t +{ + uint32_t w[4]; /*!< LTC context register is 16 bytes written as four 32-bit words */ + uint8_t b[16]; /*!< 16 octets block for CCM B0 and CTR0 and for GCM */ +} ltc_xcm_block_t; + +#if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA + +/*! @brief PKHA functions - arithmetic, copy/clear memory. */ +typedef enum _ltc_pkha_func_t +{ + kLTC_PKHA_ClearMem = 1U, + kLTC_PKHA_ArithModAdd = 2U, /*!< (A + B) mod N */ + kLTC_PKHA_ArithModSub1 = 3U, /*!< (A - B) mod N */ + kLTC_PKHA_ArithModSub2 = 4U, /*!< (B - A) mod N */ + kLTC_PKHA_ArithModMul = 5U, /*!< (A x B) mod N */ + kLTC_PKHA_ArithModExp = 6U, /*!< (A^E) mod N */ + kLTC_PKHA_ArithModRed = 7U, /*!< (A) mod N */ + kLTC_PKHA_ArithModInv = 8U, /*!< (A^-1) mod N */ + kLTC_PKHA_ArithEccAdd = 9U, /*!< (P1 + P2) */ + kLTC_PKHA_ArithEccDouble = 10U, /*!< (P2 + P2) */ + kLTC_PKHA_ArithEccMul = 11U, /*!< (E x P1) */ + kLTC_PKHA_ArithModR2 = 12U, /*!< (R^2 mod N) */ + kLTC_PKHA_ArithGcd = 14U, /*!< GCD (A, N) */ + kLTC_PKHA_ArithPrimalityTest = 15U, /*!< Miller-Rabin */ + kLTC_PKHA_CopyMemSizeN = 16U, + kLTC_PKHA_CopyMemSizeSrc = 17U, +} ltc_pkha_func_t; + +/*! @brief Register areas for PKHA clear memory operations. */ +typedef enum _ltc_pkha_reg_area +{ + kLTC_PKHA_RegA = 8U, + kLTC_PKHA_RegB = 4U, + kLTC_PKHA_RegE = 2U, + kLTC_PKHA_RegN = 1U, + kLTC_PKHA_RegAll = kLTC_PKHA_RegA | kLTC_PKHA_RegB | kLTC_PKHA_RegE | kLTC_PKHA_RegN, +} ltc_pkha_reg_area_t; + +/*! @brief Quadrant areas for 2048-bit registers for PKHA copy memory + * operations. */ +typedef enum _ltc_pkha_quad_area_t +{ + kLTC_PKHA_Quad0 = 0U, + kLTC_PKHA_Quad1 = 1U, + kLTC_PKHA_Quad2 = 2U, + kLTC_PKHA_Quad3 = 3U, +} ltc_pkha_quad_area_t; + +/*! @brief User-supplied (R^2 mod N) input or LTC should calculate. */ +typedef enum _ltc_pkha_r2_t +{ + kLTC_PKHA_CalcR2 = 0U, /*!< Calculate (R^2 mod N) */ + kLTC_PKHA_InputR2 = 1U /*!< (R^2 mod N) supplied as input */ +} ltc_pkha_r2_t; + +/*! @brief LTC PKHA parameters */ +typedef struct _ltc_pkha_mode_params_t +{ + ltc_pkha_func_t func; + ltc_pkha_f2m_t arithType; + ltc_pkha_montgomery_form_t montFormIn; + ltc_pkha_montgomery_form_t montFormOut; + ltc_pkha_reg_area_t srcReg; + ltc_pkha_quad_area_t srcQuad; + ltc_pkha_reg_area_t dstReg; + ltc_pkha_quad_area_t dstQuad; + ltc_pkha_timing_t equalTime; + ltc_pkha_r2_t r2modn; +} ltc_pkha_mode_params_t; + +#endif /* FSL_FEATURE_LTC_HAS_PKHA */ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +#if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA +static status_t ltc_pkha_clear_regabne(LTC_Type *base, bool A, bool B, bool N, bool E); +#endif /* FSL_FEATURE_LTC_HAS_PKHA */ + +/******************************************************************************* + * Code + ******************************************************************************/ + +/******************************************************************************* + * LTC Common code static + ******************************************************************************/ +/*! + * @brief Tests the correct key size. + * + * This function tests the correct key size. + * @param keySize Input key length in bytes. + * @return True if the key length is supported, false if not. + */ +bool ltc_check_key_size(const uint32_t keySize) +{ + return ((keySize == 16u) +#if defined(FSL_FEATURE_LTC_HAS_AES192) && FSL_FEATURE_LTC_HAS_AES192 + || ((keySize == 24u)) +#endif /* FSL_FEATURE_LTC_HAS_AES192 */ +#if defined(FSL_FEATURE_LTC_HAS_AES256) && FSL_FEATURE_LTC_HAS_AES256 + || ((keySize == 32u)) +#endif /* FSL_FEATURE_LTC_HAS_AES256 */ + ); +} + +/*! @brief LTC driver wait mechanism. */ +status_t ltc_wait(LTC_Type *base) +{ + status_t status; + + bool error = false; + bool done = false; + + /* Wait for 'done' or 'error' flag. */ + while ((!error) && (!done)) + { + uint32_t temp32 = base->STA; + error = temp32 & LTC_STA_EI_MASK; + done = temp32 & LTC_STA_DI_MASK; + } + + if (error) + { + base->COM = LTC_COM_ALL_MASK; /* Reset all engine to clear the error flag */ + status = kStatus_Fail; + } + else /* 'done' */ + { + status = kStatus_Success; + + base->CW = kLTC_ClearDataSize; + /* Clear 'done' interrupt status. This also clears the mode register. */ + base->STA = kLTC_StatusDoneIsr; + } + + return status; +} + +/*! + * @brief Clears the LTC module. + * This function can be used to clear all sensitive data from theLTC module, such as private keys. It is called + * internally by the LTC driver in case of an error or operation complete. + * @param base LTC peripheral base address + * @param pkha Include LTC PKHA register clear. If there is no PKHA, the argument is ignored. + */ +void ltc_clear_all(LTC_Type *base, bool addPKHA) +{ + base->CW = (uint32_t)kLTC_ClearAll; +#if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA + if (addPKHA) + { + ltc_pkha_clear_regabne(base, true, true, true, true); + } +#endif /* FSL_FEATURE_LTC_HAS_PKHA */ +} + +void ltc_memcpy(void *dst, const void *src, size_t size) +{ +#if defined(__cplusplus) + register uint8_t *to = (uint8_t *)dst; + register const uint8_t *from = (const uint8_t *)src; +#else + register uint8_t *to = dst; + register const uint8_t *from = src; +#endif + while (size) + { + *to = *from; + size--; + to++; + from++; + } +} + +/*! + * @brief Reads an unaligned word. + * + * This function creates a 32-bit word from an input array of four bytes. + * + * @param src Input array of four bytes. The array can start at any address in memory. + * @return 32-bit unsigned int created from the input byte array. + */ +static inline uint32_t ltc_get_word_from_unaligned(const uint8_t *srcAddr) +{ +#if (!(defined(__CORTEX_M)) || (defined(__CORTEX_M) && (__CORTEX_M == 0))) + register const uint8_t *src = srcAddr; + /* Cortex M0 does not support misaligned loads */ + if ((uint32_t)src & 0x3u) + { + union _align_bytes_t + { + uint32_t word; + uint8_t byte[sizeof(uint32_t)]; + } my_bytes; + + my_bytes.byte[0] = *src; + my_bytes.byte[1] = *(src + 1); + my_bytes.byte[2] = *(src + 2); + my_bytes.byte[3] = *(src + 3); + return my_bytes.word; + } + else + { + /* addr aligned to 0-modulo-4 so it is safe to type cast */ + return *((const uint32_t *)src); + } +#elif defined(__CC_ARM) + /* -O3 optimization in Keil 5.15 and 5.16a uses LDM instruction here (LDM r4!, {r0}) + * which is wrong, because srcAddr might be unaligned. + * LDM on unaligned address causes hard-fault. in contrary, + * LDR supports unaligned address on Cortex M4 */ + register uint32_t retVal; + __asm + { + LDR retVal, [srcAddr] + } + return retVal; +#else + return *((const uint32_t *)srcAddr); +#endif +} + +/*! + * @brief Converts a 32-bit word into a byte array. + * + * This function creates an output array of four bytes from an input 32-bit word. + * + * @param srcWord Input 32-bit unsigned integer. + * @param dst Output array of four bytes. The array can start at any address in memory. + */ +static inline void ltc_set_unaligned_from_word(uint32_t srcWord, uint8_t *dstAddr) +{ +#if (!(defined(__CORTEX_M)) || (defined(__CORTEX_M) && (__CORTEX_M == 0))) + register uint8_t *dst = dstAddr; + /* Cortex M0 does not support misaligned stores */ + if ((uint32_t)dst & 0x3u) + { + *dst++ = (srcWord & 0x000000FFU); + *dst++ = (srcWord & 0x0000FF00U) >> 8; + *dst++ = (srcWord & 0x00FF0000U) >> 16; + *dst++ = (srcWord & 0xFF000000U) >> 24; + } + else + { + *((uint32_t *)dstAddr) = srcWord; /* addr aligned to 0-modulo-4 so it is safe to type cast */ + } +#elif defined(__CC_ARM) + __asm + { + STR srcWord, [dstAddr] + } + return; +#else + *((uint32_t *)dstAddr) = srcWord; +#endif +} + +/*! + * @brief Sets the LTC keys. + * + * This function writes the LTC keys into the key register. The keys should + * be written before the key size. + * + * @param base LTC peripheral base address + * @param key Key + * @param keySize Number of bytes for all keys to be loaded (maximum 32, must be a + * multiple of 4). + * @returns Key set status + */ +static status_t ltc_set_key(LTC_Type *base, const uint8_t *key, uint8_t keySize) +{ + int32_t i; + + for (i = 0; i < (keySize / 4); i++) + { + base->KEY[i] = ltc_get_word_from_unaligned(key + i * sizeof(uint32_t)); + } + + return kStatus_Success; +} + +/*! + * @brief Gets the LTC keys. + * + * This function retrieves the LTC keys from the key register. + * + * @param base LTC peripheral base address + * @param key Array of data to store keys + * @param keySize Number of bytes of keys to retrieve + * @returns Key set status + */ +static status_t ltc_get_key(LTC_Type *base, uint8_t *key, uint8_t keySize) +{ + int32_t i; + + for (i = 0; i < (keySize / 4); i++) + { + ltc_set_unaligned_from_word(base->KEY[i], key + i * sizeof(uint32_t)); + } + + return kStatus_Success; +} + +/*! + * @brief Writes the LTC context register; + * + * The LTC context register is a 512 bit (64 byte) register that holds + * internal context for the crypto engine. The meaning varies based on the + * algorithm and operating state being used. This register is written by the + * driver/application to load state such as IV, counter, and so on. Then, it is + * updated by the internal crypto engine as needed. + * + * @param base LTC peripheral base address + * @param data Data to write + * @param dataSize Size of data to write in bytes + * @param startIndex Starting word (4-byte) index into the 16-word register. + * @return Status of write + */ +status_t ltc_set_context(LTC_Type *base, const uint8_t *data, uint8_t dataSize, uint8_t startIndex) +{ + int32_t i; + int32_t j; + int32_t szLeft; + + /* Context register is 16 words in size (64 bytes). Ensure we are only + * writing a valid amount of data. */ + if (startIndex + (dataSize / 4) >= 16) + { + return kStatus_InvalidArgument; + } + + j = 0; + szLeft = dataSize % 4; + for (i = startIndex; i < (startIndex + dataSize / 4); i++) + { + base->CTX[i] = ltc_get_word_from_unaligned(data + j); + j += sizeof(uint32_t); + } + + if (szLeft) + { + uint32_t context_data = {0}; + ltc_memcpy(&context_data, data + j, szLeft); + base->CTX[i] = context_data; + } + return kStatus_Success; +} + +/*! + * @brief Reads the LTC context register. + * + * The LTC context register is a 512 bit (64 byte) register that holds + * internal context for the crypto engine. The meaning varies based on the + * algorithm and operating state being used. This register is written by the + * driver/application to load state such as IV, counter, and so on. Then, it is + * updated by the internal crypto engine as needed. + * + * @param base LTC peripheral base address + * @param data Destination of read data + * @param dataSize Size of data to read in bytes + * @param startIndex Starting word (4-byte) index into the 16-word register. + * @return Status of read + */ +status_t ltc_get_context(LTC_Type *base, uint8_t *dest, uint8_t dataSize, uint8_t startIndex) +{ + int32_t i; + int32_t j; + int32_t szLeft; + uint32_t rdCtx; + + /* Context register is 16 words in size (64 bytes). Ensure we are only + * writing a valid amount of data. */ + if (startIndex + (dataSize / 4) >= 16) + { + return kStatus_InvalidArgument; + } + + j = 0; + szLeft = dataSize % 4; + for (i = startIndex; i < (startIndex + dataSize / 4); i++) + { + ltc_set_unaligned_from_word(base->CTX[i], dest + j); + j += sizeof(uint32_t); + } + + if (szLeft) + { + rdCtx = 0; + rdCtx = base->CTX[i]; + ltc_memcpy(dest + j, &rdCtx, szLeft); + } + return kStatus_Success; +} + +static status_t ltc_symmetric_alg_state(LTC_Type *base, + const uint8_t *key, + uint8_t keySize, + ltc_algorithm_t alg, + ltc_mode_symmetric_alg_t mode, + ltc_mode_encrypt_t enc, + ltc_mode_algorithm_state_t as) +{ + ltc_mode_t modeReg; + + /* Clear internal register states. */ + base->CW = (uint32_t)kLTC_ClearAll; + + /* Set byte swap on for several registers we will be reading and writing + * user data to/from. */ + base->CTL |= kLTC_CtrlSwapAll; + + /* Write the key in place. */ + ltc_set_key(base, key, keySize); + + /* Write the key size. This must be done after writing the key, and this + * action locks the ability to modify the key registers. */ + base->KS = keySize; + + /* Clear the 'done' interrupt. */ + base->STA = kLTC_StatusDoneIsr; + + /* Set the proper block and algorithm mode. */ + modeReg = (uint32_t)alg | (uint32_t)enc | (uint32_t)as | (uint32_t)mode; + + /* Write the mode register to the hardware. */ + base->MD = modeReg; + + return kStatus_Success; +} + +/*! + * @brief Initializes the LTC for symmetric encrypt/decrypt operation. Mode is set to UPDATE. + * + * @param base LTC peripheral base address + * @param key Input key to use for encryption + * @param keySize Size of the input key, in bytes. Must be 8, 16, 24, or 32. + * @param alg Symmetric algorithm + * @param mode Symmetric block mode + * @param enc Encrypt/decrypt control + * @return Status + */ +status_t ltc_symmetric_update(LTC_Type *base, + const uint8_t *key, + uint8_t keySize, + ltc_algorithm_t alg, + ltc_mode_symmetric_alg_t mode, + ltc_mode_encrypt_t enc) +{ + return ltc_symmetric_alg_state(base, key, keySize, alg, mode, enc, kLTC_ModeUpdate); +} + +#if defined(FSL_FEATURE_LTC_HAS_GCM) && FSL_FEATURE_LTC_HAS_GCM +/*! + * @brief Initializes the LTC for symmetric encrypt/decrypt operation. Mode is set to FINALIZE. + * + * @param base LTC peripheral base address + * @param key Input key to use for encryption + * @param keySize Size of the input key, in bytes. Must be 8, 16, 24, or 32. + * @param alg Symmetric algorithm + * @param mode Symmetric block mode + * @param enc Encrypt/decrypt control + * @return Status + */ +static status_t ltc_symmetric_final(LTC_Type *base, + const uint8_t *key, + uint8_t keySize, + ltc_algorithm_t alg, + ltc_mode_symmetric_alg_t mode, + ltc_mode_encrypt_t enc) +{ + return ltc_symmetric_alg_state(base, key, keySize, alg, mode, enc, kLTC_ModeFinalize); +} +#endif /* FSL_FEATURE_LTC_HAS_GCM */ + +/*! + * @brief Initializes the LTC for symmetric encrypt/decrypt operation. Mode is set to INITIALIZE. + * + * @param base LTC peripheral base address + * @param key Input key to use for encryption + * @param keySize Size of the input key, in bytes. Must be 8, 16, 24, or 32. + * @param alg Symmetric algorithm + * @param mode Symmetric block mode + * @param enc Encrypt/decrypt control + * @return Status + */ +static status_t ltc_symmetric_init(LTC_Type *base, + const uint8_t *key, + uint8_t keySize, + ltc_algorithm_t alg, + ltc_mode_symmetric_alg_t mode, + ltc_mode_encrypt_t enc) +{ + return ltc_symmetric_alg_state(base, key, keySize, alg, mode, enc, kLTC_ModeInit); +} + +/*! + * @brief Initializes the LTC for symmetric encrypt/decrypt operation. Mode is set to INITIALIZE/FINALIZE. + * + * @param base LTC peripheral base address + * @param key Input key to use for encryption + * @param keySize Size of the input key, in bytes. Must be 8, 16, 24, or 32. + * @param alg Symmetric algorithm + * @param mode Symmetric block mode + * @param enc Encrypt/decrypt control + * @return Status + */ +static status_t ltc_symmetric_init_final(LTC_Type *base, + const uint8_t *key, + uint8_t keySize, + ltc_algorithm_t alg, + ltc_mode_symmetric_alg_t mode, + ltc_mode_encrypt_t enc) +{ + return ltc_symmetric_alg_state(base, key, keySize, alg, mode, enc, kLTC_ModeInitFinal); +} + +void ltc_symmetric_process(LTC_Type *base, uint32_t inSize, const uint8_t **inData, uint8_t **outData) +{ + uint32_t outSize; + uint32_t fifoData; + uint32_t fifoStatus; + + register const uint8_t *in = *inData; + register uint8_t *out = *outData; + + outSize = inSize; + while ((outSize > 0) || (inSize > 0)) + { + fifoStatus = base->FIFOSTA; + + /* Check output FIFO level to make sure there is at least an entry + * ready to be read. */ + if (fifoStatus & LTC_FIFOSTA_OFL_MASK) + { + /* Read data from the output FIFO. */ + if (outSize > 0) + { + if (outSize >= sizeof(uint32_t)) + { + ltc_set_unaligned_from_word(base->OFIFO, out); + out += sizeof(uint32_t); + outSize -= sizeof(uint32_t); + } + else /* (outSize > 0) && (outSize < 4) */ + { + fifoData = base->OFIFO; + ltc_memcpy(out, &fifoData, outSize); + out += outSize; + outSize = 0; + } + } + } + + /* Check input FIFO status to see if it is full. We can + * only write more data when both input and output FIFOs are not at a full state. + * At the same time we are sure Output FIFO is not full because we have poped at least one entry + * by the while loop above. + */ + if (!(fifoStatus & LTC_FIFOSTA_IFF_MASK)) + { + /* Copy data to the input FIFO. + * Data can only be copied one word at a time, so pad the data + * appropriately if it is less than this size. */ + if (inSize > 0) + { + if (inSize >= sizeof(uint32_t)) + { + base->IFIFO = ltc_get_word_from_unaligned(in); + inSize -= sizeof(uint32_t); + in += sizeof(uint32_t); + } + else /* (inSize > 0) && (inSize < 4) */ + { + fifoData = 0; + ltc_memcpy(&fifoData, in, inSize); + base->IFIFO = fifoData; + in += inSize; + inSize = 0; + } + } + } + } + *inData = in; + *outData = out; +} + +/*! + * @brief Processes symmetric data through LTC AES and DES engines. + * + * @param base LTC peripheral base address + * @param inData Input data + * @param inSize Size of input data, in bytes + * @param outData Output data + * @return Status from encrypt/decrypt operation + */ +status_t ltc_symmetric_process_data(LTC_Type *base, const uint8_t *inData, uint32_t inSize, uint8_t *outData) +{ + uint32_t lastSize; + + if ((!inData) || (!outData)) + { + return kStatus_InvalidArgument; + } + + /* Write the data size. */ + base->DS = inSize; + + /* Split the inSize into full 16-byte chunks and last incomplete block due to LTC AES OFIFO errata */ + if (inSize <= 16u) + { + lastSize = inSize; + inSize = 0; + } + else + { + /* Process all 16-byte data chunks. */ + lastSize = inSize % 16u; + if (lastSize == 0) + { + lastSize = 16; + inSize -= 16; + } + else + { + inSize -= lastSize; /* inSize will be rounded down to 16 byte boundary. remaining bytes in lastSize */ + } + } + + ltc_symmetric_process(base, inSize, &inData, &outData); + ltc_symmetric_process(base, lastSize, &inData, &outData); + return ltc_wait(base); +} + +/*! + * @brief Splits the LTC job into sessions. Used for CBC, CTR, CFB, OFB cipher block modes. + * + * @param base LTC peripheral base address + * @param inData Input data to process. + * @param inSize Input size of the input buffer. + * @param outData Output data buffer. + */ +static status_t ltc_process_message_in_sessions(LTC_Type *base, + const uint8_t *inData, + uint32_t inSize, + uint8_t *outData) +{ + uint32_t sz; + status_t retval; + ltc_mode_t modeReg; /* read and write LTC mode register */ + + sz = LTC_FIFO_SZ_MAX_DOWN_ALGN; + modeReg = base->MD; + retval = kStatus_Success; + + while (inSize) + { + if (inSize <= sz) + { + retval = ltc_symmetric_process_data(base, inData, inSize, outData); + if (kStatus_Success != retval) + { + return retval; + } + inSize = 0; + } + else + { + retval = ltc_symmetric_process_data(base, inData, sz, outData); + if (kStatus_Success != retval) + { + return retval; + } + inData += sz; + inSize -= sz; + outData += sz; + base->MD = modeReg; + } + } + return retval; +} + +static void ltc_move_block_to_ififo(LTC_Type *base, const ltc_xcm_block_t *blk, uint32_t num_bytes) +{ + uint32_t i = 0; + uint32_t words; + + words = num_bytes / 4u; + if (num_bytes % 4u) + { + words++; + } + + if (words > 4) + { + words = 4; + } + + while (i < words) + { + if (0U == (base->FIFOSTA & LTC_FIFOSTA_IFF_MASK)) + { + /* Copy data to the input FIFO. */ + base->IFIFO = blk->w[i++]; + } + } +} + +static void ltc_move_to_ififo(LTC_Type *base, const uint8_t *data, uint32_t dataSize) +{ + ltc_xcm_block_t blk; + ltc_xcm_block_t blkZero = {{0x0u, 0x0u, 0x0u, 0x0u}}; + + while (dataSize) + { + if (dataSize > 16u) + { + ltc_memcpy(&blk, data, 16u); + dataSize -= 16u; + data += 16u; + } + else + { + ltc_memcpy(&blk, &blkZero, sizeof(ltc_xcm_block_t)); /* memset blk to zeroes */ + ltc_memcpy(&blk, data, dataSize); + dataSize = 0; + } + ltc_move_block_to_ififo(base, &blk, sizeof(ltc_xcm_block_t)); + } +} + +/*! + * @brief Processes symmetric data through LTC AES in multiple sessions. + * + * Specific for AES CCM and GCM modes as they need to update mode register. + * + * @param base LTC peripheral base address + * @param inData Input data + * @param inSize Size of input data, in bytes + * @param outData Output data + * @param lastAs The LTC Algorithm state to be set sup for last block during message processing in multiple sessions. + * For CCM it is kLTC_ModeFinalize. For GCM it is kLTC_ModeInitFinal. + * @return Status from encrypt/decrypt operation + */ +static status_t ltc_symmetric_process_data_multiple(LTC_Type *base, + const uint8_t *inData, + uint32_t inSize, + uint8_t *outData, + ltc_mode_t modeReg, + ltc_mode_algorithm_state_t lastAs) +{ + uint32_t fifoConsumed; + uint32_t lastSize; + uint32_t sz; + uint32_t max_ltc_fifo_size; + ltc_mode_algorithm_state_t fsm; + status_t status; + + if ((!inData) || (!outData)) + { + return kStatus_InvalidArgument; + } + + if (!((kLTC_ModeFinalize == lastAs) || (kLTC_ModeInitFinal == lastAs))) + { + return kStatus_InvalidArgument; + } + + if (0 == inSize) + { + return kStatus_Success; + } + + if (inSize <= 16u) + { + fsm = lastAs; + lastSize = inSize; + } + else + { + fsm = (ltc_mode_algorithm_state_t)( + modeReg & + LTC_MD_AS_MASK); /* this will be either kLTC_ModeInit or kLTC_ModeUpdate, based on prior processing */ + + /* Process all 16-byte data chunks. */ + lastSize = inSize % 16u; + if (lastSize == 0u) + { + lastSize = 16u; + inSize -= 16u; + } + else + { + inSize -= lastSize; /* inSize will be rounded down to 16 byte boundary. remaining bytes in lastSize */ + } + } + + max_ltc_fifo_size = LTC_FIFO_SZ_MAX_DOWN_ALGN; + fifoConsumed = base->DS; + + while (lastSize) + { + switch (fsm) + { + case kLTC_ModeUpdate: + case kLTC_ModeInit: + while (inSize) + { + if (inSize > (max_ltc_fifo_size - fifoConsumed)) + { + sz = (max_ltc_fifo_size - fifoConsumed); + } + else + { + sz = inSize; + } + base->DS = sz; + ltc_symmetric_process(base, sz, &inData, &outData); + inSize -= sz; + fifoConsumed = 0; + + /* after we completed INITIALIZE job, are there still any data left? */ + if (inSize) + { + fsm = kLTC_ModeUpdate; + status = ltc_wait(base); + if (kStatus_Success != status) + { + return status; + } + modeReg &= ~LTC_MD_AS_MASK; + modeReg |= (uint32_t)fsm; + base->MD = modeReg; + } + else + { + fsm = lastAs; + } + } + break; + + case kLTC_ModeFinalize: + case kLTC_ModeInitFinal: + /* process last block in FINALIZE */ + + status = ltc_wait(base); + if (kStatus_Success != status) + { + return status; + } + + modeReg &= ~LTC_MD_AS_MASK; + modeReg |= (uint32_t)lastAs; + base->MD = modeReg; + + base->DS = lastSize; + ltc_symmetric_process(base, lastSize, &inData, &outData); + lastSize = 0; + break; + + default: + break; + } + } + + status = ltc_wait(base); + return status; +} + +/*! + * @brief Receives MAC compare. + * + * This function is a sub-process of CCM and GCM decryption. + * It compares received MAC with the MAC computed during decryption. + * + * @param base LTC peripheral base address + * @param tag Received MAC. + * @param tagSize Number of bytes in the received MAC. + * @param modeReg LTC Mode Register current value. It is modified and written to LTC Mode Register. + */ +static status_t ltc_aes_received_mac_compare(LTC_Type *base, const uint8_t *tag, uint32_t tagSize, ltc_mode_t modeReg) +{ + ltc_xcm_block_t blk = {{0x0u, 0x0u, 0x0u, 0x0u}}; + + base->CW = kLTC_ClearDataSize; + base->STA = kLTC_StatusDoneIsr; + + modeReg &= ~LTC_MD_AS_MASK; + modeReg |= (uint32_t)kLTC_ModeUpdate | LTC_MD_ICV_TEST_MASK; + base->MD = modeReg; + + base->DS = 0u; + base->ICVS = tagSize; + ltc_memcpy(&blk.b[0], &tag[0], tagSize); + + ltc_move_block_to_ififo(base, &blk, tagSize); + return ltc_wait(base); +} + +/*! + * @brief Processes tag during AES GCM and CCM. + * + * This function is a sub-process of CCM and GCM encryption and decryption. + * For encryption, it writes computed MAC to the output tag. + * For decryption, it compares the received MAC with the computed MAC. + * + * @param base LTC peripheral base address + * @param[in,out] tag Output computed MAC during encryption or Input received MAC during decryption. + * @param tagSize Size of MAC buffer in bytes. + * @param modeReg LTC Mode Register current value. It is checked to read Enc/Dec bit. + * It is modified and written to LTC Mode Register during decryption. + * @param ctx Index to LTC context registers with computed MAC for encryption process. + */ +static status_t ltc_aes_process_tag(LTC_Type *base, uint8_t *tag, uint32_t tagSize, ltc_mode_t modeReg, uint32_t ctx) +{ + status_t status = kStatus_Success; + if (tag) + { + /* For decrypt, compare received MAC with the computed MAC. */ + if (kLTC_ModeDecrypt == (modeReg & LTC_MD_ENC_MASK)) + { + status = ltc_aes_received_mac_compare(base, tag, tagSize, modeReg); + } + else /* FSL_AES_GCM_TYPE_ENCRYPT */ + { + /* For encryption, write the computed and encrypted MAC to user buffer */ + ltc_get_context(base, &tag[0], tagSize, ctx); + } + } + return status; +} + +/******************************************************************************* + * LTC Common code public + ******************************************************************************/ +void LTC_Init(LTC_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* ungate clock */ + CLOCK_EnableClock(kCLOCK_Ltc0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void LTC_Deinit(LTC_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* gate clock */ + CLOCK_DisableClock(kCLOCK_Ltc0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +#if defined(FSL_FEATURE_LTC_HAS_DPAMS) && FSL_FEATURE_LTC_HAS_DPAMS +void LTC_SetDpaMaskSeed(LTC_Type *base, uint32_t mask) +{ + base->DPAMS = mask; + /* second write as workaround for DPA mask re-seed errata */ + base->DPAMS = mask; +} +#endif /* FSL_FEATURE_LTC_HAS_DPAMS */ + +/******************************************************************************* + * AES Code static + ******************************************************************************/ +static status_t ltc_aes_decrypt_ecb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t *key, + uint32_t keySize, + ltc_aes_key_t keyType) +{ + status_t retval; + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeECB, kLTC_ModeDecrypt); + + /* set DK bit in the LTC Mode Register AAI field for directly loaded decrypt keys */ + if (keyType == kLTC_DecryptKey) + { + base->MD |= (1U << kLTC_ModeRegBitShiftDK); + } + + /* Process data and return status. */ + retval = ltc_process_message_in_sessions(base, &ciphertext[0], size, &plaintext[0]); + return retval; +} + +/******************************************************************************* + * AES Code public + ******************************************************************************/ +status_t LTC_AES_GenerateDecryptKey(LTC_Type *base, const uint8_t *encryptKey, uint8_t *decryptKey, uint32_t keySize) +{ + uint8_t plaintext[LTC_AES_BLOCK_SIZE]; + uint8_t ciphertext[LTC_AES_BLOCK_SIZE]; + status_t status; + + if (!ltc_check_key_size(keySize)) + { + return kStatus_InvalidArgument; + } + + /* ECB decrypt with encrypt key will convert the key in LTC context into decrypt form of the key */ + status = ltc_aes_decrypt_ecb(base, ciphertext, plaintext, LTC_AES_BLOCK_SIZE, encryptKey, keySize, kLTC_EncryptKey); + /* now there is decrypt form of the key in the LTC context, so take it */ + ltc_get_key(base, decryptKey, keySize); + + ltc_clear_all(base, false); + + return status; +} + +status_t LTC_AES_EncryptEcb( + LTC_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, uint32_t size, const uint8_t *key, uint32_t keySize) +{ + status_t retval; + + if (!ltc_check_key_size(keySize)) + { + return kStatus_InvalidArgument; + } + /* ECB mode, size must be 16-byte multiple */ + if ((size < 16u) || (size % 16u)) + { + return kStatus_InvalidArgument; + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeECB, kLTC_ModeEncrypt); + + /* Process data and return status. */ + retval = ltc_process_message_in_sessions(base, &plaintext[0], size, &ciphertext[0]); + ltc_clear_all(base, false); + return retval; +} + +status_t LTC_AES_DecryptEcb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t *key, + uint32_t keySize, + ltc_aes_key_t keyType) +{ + status_t status; + + if (!ltc_check_key_size(keySize)) + { + return kStatus_InvalidArgument; + } + /* ECB mode, size must be 16-byte multiple */ + if ((size < 16u) || (size % 16u)) + { + return kStatus_InvalidArgument; + } + + status = ltc_aes_decrypt_ecb(base, ciphertext, plaintext, size, key, keySize, keyType); + ltc_clear_all(base, false); + return status; +} + +status_t LTC_AES_EncryptCbc(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_AES_IV_SIZE], + const uint8_t *key, + uint32_t keySize) +{ + status_t retval; + + if (!ltc_check_key_size(keySize)) + { + return kStatus_InvalidArgument; + } + + /* CBC mode, size must be 16-byte multiple */ + if ((size < 16u) || (size % 16u)) + { + return kStatus_InvalidArgument; + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCBC, kLTC_ModeEncrypt); + + /* Write IV data to the context register. */ + ltc_set_context(base, &iv[0], LTC_AES_IV_SIZE, 0); + + /* Process data and return status. */ + retval = ltc_process_message_in_sessions(base, &plaintext[0], size, &ciphertext[0]); + ltc_clear_all(base, false); + return retval; +} + +status_t LTC_AES_DecryptCbc(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_AES_IV_SIZE], + const uint8_t *key, + uint32_t keySize, + ltc_aes_key_t keyType) +{ + status_t retval; + + if (!ltc_check_key_size(keySize)) + { + return kStatus_InvalidArgument; + } + /* CBC mode, size must be 16-byte multiple */ + if ((size < 16u) || (size % 16u)) + { + return kStatus_InvalidArgument; + } + + /* set DK bit in the LTC Mode Register AAI field for directly loaded decrypt keys */ + if (keyType == kLTC_DecryptKey) + { + base->MD |= (1U << kLTC_ModeRegBitShiftDK); + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCBC, kLTC_ModeDecrypt); + + /* Write IV data to the context register. */ + ltc_set_context(base, &iv[0], LTC_AES_IV_SIZE, 0); + + /* Process data and return status. */ + retval = ltc_process_message_in_sessions(base, &ciphertext[0], size, &plaintext[0]); + ltc_clear_all(base, false); + return retval; +} + +status_t LTC_AES_CryptCtr(LTC_Type *base, + const uint8_t *input, + uint8_t *output, + uint32_t size, + uint8_t counter[LTC_AES_BLOCK_SIZE], + const uint8_t *key, + uint32_t keySize, + uint8_t counterlast[LTC_AES_BLOCK_SIZE], + uint32_t *szLeft) +{ + status_t retval; + uint32_t lastSize; + + if (!ltc_check_key_size(keySize)) + { + return kStatus_InvalidArgument; + } + + lastSize = 0U; + if (counterlast != NULL) + { + /* Split the size into full 16-byte chunks and last incomplete block due to LTC AES OFIFO errata */ + if (size <= 16U) + { + lastSize = size; + size = 0U; + } + else + { + /* Process all 16-byte data chunks. */ + lastSize = size % 16U; + if (lastSize == 0U) + { + lastSize = 16U; + size -= 16U; + } + else + { + size -= lastSize; /* size will be rounded down to 16 byte boundary. remaining bytes in lastSize */ + } + } + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCTR, kLTC_ModeEncrypt); + + /* Write initial counter data to the context register. + * NOTE the counter values start at 4-bytes offset into the context. */ + ltc_set_context(base, &counter[0], 16U, 4U); + + /* Process data and return status. */ + retval = ltc_process_message_in_sessions(base, input, size, output); + if (kStatus_Success != retval) + { + return retval; + } + + input += size; + output += size; + + if ((counterlast != NULL) && lastSize) + { + uint8_t zeroes[16] = {0}; + ltc_mode_t modeReg; + + modeReg = (uint32_t)kLTC_AlgorithmAES | (uint32_t)kLTC_ModeCTR | (uint32_t)kLTC_ModeEncrypt; + /* Write the mode register to the hardware. */ + base->MD = modeReg | (uint32_t)kLTC_ModeFinalize; + + /* context is re-used (CTRi) */ + + /* Process data and return status. */ + retval = ltc_symmetric_process_data(base, input, lastSize, output); + if (kStatus_Success != retval) + { + return retval; + } + if (szLeft) + { + *szLeft = 16U - lastSize; + } + + /* Initialize algorithm state. */ + base->MD = modeReg | (uint32_t)kLTC_ModeUpdate; + + /* context is re-used (CTRi) */ + + /* Process data and return status. */ + retval = ltc_symmetric_process_data(base, zeroes, 16U, counterlast); + } + ltc_get_context(base, &counter[0], 16U, 4U); + ltc_clear_all(base, false); + return retval; +} + +#if defined(FSL_FEATURE_LTC_HAS_GCM) && FSL_FEATURE_LTC_HAS_GCM +/******************************************************************************* + * GCM Code static + ******************************************************************************/ +static status_t ltc_aes_gcm_check_input_args(LTC_Type *base, + const uint8_t *src, + const uint8_t *iv, + const uint8_t *aad, + const uint8_t *key, + uint8_t *dst, + uint32_t inputSize, + uint32_t ivSize, + uint32_t aadSize, + uint32_t keySize, + uint32_t tagSize) +{ + if (!base) + { + return kStatus_InvalidArgument; + } + + /* tag can be NULL to skip tag processing */ + if ((!key) || (ivSize && (!iv)) || (aadSize && (!aad)) || (inputSize && ((!src) || (!dst)))) + { + return kStatus_InvalidArgument; + } + + /* octet length of tag (tagSize) must be element of 4,8,12,13,14,15,16 */ + if (((tagSize > 16u) || (tagSize < 12u)) && (tagSize != 4u) && (tagSize != 8u)) + { + return kStatus_InvalidArgument; + } + + /* check if keySize is supported */ + if (!ltc_check_key_size(keySize)) + { + return kStatus_InvalidArgument; + } + + /* no IV AAD DATA makes no sense */ + if (0 == (inputSize + ivSize + aadSize)) + { + return kStatus_InvalidArgument; + } + + return kStatus_Success; +} + +/*! + * @brief Process Wrapper for void (*pfunc)(LTC_Type*, uint32_t, bool). Sets IV Size register. + */ +static void ivsize_next(LTC_Type *base, uint32_t ivSize, bool iv_only) +{ + base->IVSZ = LTC_IVSZ_IL(iv_only) | ((ivSize)<C_DS_DS_MASK); +} + +/*! + * @brief Process Wrapper for void (*pfunc)(LTC_Type*, uint32_t, bool). Sets AAD Size register. + */ +static void aadsize_next(LTC_Type *base, uint32_t aadSize, bool aad_only) +{ + base->AADSZ = LTC_AADSZ_AL(aad_only) | ((aadSize)<C_DS_DS_MASK); +} + +/*! + * @brief Process IV or AAD string in multi-session. + * + * @param base LTC peripheral base address + * @param iv IV or AAD data + * @param ivSize Size in bytes of IV or AAD data + * @param modeReg LTC peripheral Mode register value + * @param iv_only IV only or AAD only flag + * @param type selects between IV or AAD + */ +static status_t ltc_aes_gcm_process_iv_aad( + LTC_Type *base, const uint8_t *iv, uint32_t ivSize, ltc_mode_t modeReg, bool iv_only, int type, ltc_mode_t modeLast) +{ + uint32_t sz; + status_t retval; + void (*next_size_func)(LTC_Type *ltcBase, uint32_t nextSize, bool authOnly); + + if ((NULL == iv) || (ivSize == 0)) + { + return kStatus_InvalidArgument; + } + + sz = LTC_FIFO_SZ_MAX_DOWN_ALGN; + next_size_func = type == LTC_AES_GCM_TYPE_AAD ? aadsize_next : ivsize_next; + + while (ivSize) + { + if (ivSize < sz) + { + modeReg &= ~LTC_MD_AS_MASK; + modeReg |= modeLast; + base->MD = modeReg; + next_size_func(base, ivSize, iv_only); + ltc_move_to_ififo(base, iv, ivSize); + ivSize = 0; + } + else + { + /* set algorithm state to UPDATE */ + modeReg &= ~LTC_MD_AS_MASK; + modeReg |= kLTC_ModeUpdate; + base->MD = modeReg; + + next_size_func(base, (uint16_t)sz, true); + ltc_move_to_ififo(base, iv, sz); + ivSize -= sz; + iv += sz; + } + + retval = ltc_wait(base); + if (kStatus_Success != retval) + { + return retval; + } + } /* end while */ + return kStatus_Success; +} + +static status_t ltc_aes_gcm_process(LTC_Type *base, + ltc_mode_encrypt_t encryptMode, + const uint8_t *src, + uint32_t inputSize, + const uint8_t *iv, + uint32_t ivSize, + const uint8_t *aad, + uint32_t aadSize, + const uint8_t *key, + uint32_t keySize, + uint8_t *dst, + uint8_t *tag, + uint32_t tagSize) +{ + status_t retval; /* return value */ + uint32_t max_ltc_fifo_sz; /* maximum data size that we can put to LTC FIFO in one session. 12-bit limit. */ + ltc_mode_t modeReg; /* read and write LTC mode register */ + + bool single_ses_proc_all; /* iv, aad and src data can be processed in one session */ + bool iv_only; + bool aad_only; + + retval = ltc_aes_gcm_check_input_args(base, src, iv, aad, key, dst, inputSize, ivSize, aadSize, keySize, tagSize); + + /* API input validation */ + if (kStatus_Success != retval) + { + return retval; + } + + max_ltc_fifo_sz = LTC_DS_DS_MASK; /* 12-bit field limit */ + + /* + * Write value to LTC AADSIZE (rounded up to next 16 byte boundary) + * plus the write value to LTC IV (rounded up to next 16 byte boundary) + * plus the inputSize. If the result is less than max_ltc_fifo_sz + * then all can be processed in one session FINALIZE. + * Otherwise, we have to split into multiple session, going through UPDATE(s), INITIALIZE, UPDATE(s) and FINALIZE. + */ + single_ses_proc_all = + (((aadSize + 15u) & 0xfffffff0u) + ((ivSize + 15u) & 0xfffffff0u) + inputSize) <= max_ltc_fifo_sz; + + /* setup key, algorithm and set the alg.state */ + if (single_ses_proc_all) + { + ltc_symmetric_final(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeGCM, encryptMode); + modeReg = base->MD; + + iv_only = (aadSize == 0) && (inputSize == 0); + aad_only = (inputSize == 0); + + /* DS_MASK here is not a bug. IV size field can be written with more than 4-bits, + * as the IVSZ write value, aligned to next 16 bytes boundary, is written also to the Data Size. + * For example, I can write 22 to IVSZ, 32 will be written to Data Size and IVSZ will have value 6, which is 22 + * mod 16. + */ + base->IVSZ = LTC_IVSZ_IL(iv_only) | ((ivSize)<C_DS_DS_MASK); + ltc_move_to_ififo(base, iv, ivSize); + if (iv_only && ivSize) + { + retval = ltc_wait(base); + if (kStatus_Success != retval) + { + return retval; + } + } + base->AADSZ = LTC_AADSZ_AL(aad_only) | ((aadSize)<C_DS_DS_MASK); + ltc_move_to_ififo(base, aad, aadSize); + if (aad_only && aadSize) + { + retval = ltc_wait(base); + if (kStatus_Success != retval) + { + return retval; + } + } + + if (inputSize) + { + /* Workaround for the LTC Data Size register update errata TKT261180 */ + while (16U < base->DS) + { + } + + ltc_symmetric_process_data(base, &src[0], inputSize, &dst[0]); + } + } + else + { + ltc_symmetric_init(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeGCM, encryptMode); + modeReg = base->MD; + + /* process IV */ + if (ivSize) + { + /* last chunk of IV is always INITIALIZE (for GHASH to occur) */ + retval = ltc_aes_gcm_process_iv_aad(base, iv, ivSize, modeReg, true, LTC_AES_GCM_TYPE_IV, kLTC_ModeInit); + if (kStatus_Success != retval) + { + return retval; + } + } + + /* process AAD */ + if (aadSize) + { + /* AS mode to process last chunk of AAD. it differs if we are in GMAC or GCM */ + ltc_mode_t lastModeReg; + if (0 == inputSize) + { + /* if there is no DATA, set mode to compute final MAC. this is GMAC mode */ + lastModeReg = kLTC_ModeInitFinal; + } + else + { + /* there are confidential DATA. so process last chunk of AAD in UPDATE mode */ + lastModeReg = kLTC_ModeUpdate; + } + retval = ltc_aes_gcm_process_iv_aad(base, aad, aadSize, modeReg, true, LTC_AES_GCM_TYPE_AAD, lastModeReg); + if (kStatus_Success != retval) + { + return retval; + } + } + + /* there are DATA. */ + if (inputSize) + { + /* set algorithm state to UPDATE */ + modeReg &= ~LTC_MD_AS_MASK; + modeReg |= kLTC_ModeUpdate; + base->MD = modeReg; + retval = + ltc_symmetric_process_data_multiple(base, &src[0], inputSize, &dst[0], modeReg, kLTC_ModeInitFinal); + } + } + if (kStatus_Success != retval) + { + return retval; + } + retval = ltc_aes_process_tag(base, tag, tagSize, modeReg, LTC_GCM_TAG_IDX); + return retval; +} + +/******************************************************************************* + * GCM Code public + ******************************************************************************/ +status_t LTC_AES_EncryptTagGcm(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t *iv, + uint32_t ivSize, + const uint8_t *aad, + uint32_t aadSize, + const uint8_t *key, + uint32_t keySize, + uint8_t *tag, + uint32_t tagSize) +{ + status_t status; + + status = ltc_aes_gcm_process(base, kLTC_ModeEncrypt, plaintext, size, iv, ivSize, aad, aadSize, key, keySize, + ciphertext, tag, tagSize); + + ltc_clear_all(base, false); + return status; +} + +status_t LTC_AES_DecryptTagGcm(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t *iv, + uint32_t ivSize, + const uint8_t *aad, + uint32_t aadSize, + const uint8_t *key, + uint32_t keySize, + const uint8_t *tag, + uint32_t tagSize) +{ + uint8_t temp_tag[16] = {0}; /* max. octet length of Integrity Check Value ICV (tag) is 16 */ + uint8_t *tag_ptr; + status_t status; + + tag_ptr = NULL; + if (tag) + { + ltc_memcpy(temp_tag, tag, tagSize); + tag_ptr = &temp_tag[0]; + } + status = ltc_aes_gcm_process(base, kLTC_ModeDecrypt, ciphertext, size, iv, ivSize, aad, aadSize, key, keySize, + plaintext, tag_ptr, tagSize); + + ltc_clear_all(base, false); + return status; +} +#endif /* FSL_FEATURE_LTC_HAS_GCM */ + +/******************************************************************************* + * CCM Code static + ******************************************************************************/ +static status_t ltc_aes_ccm_check_input_args(LTC_Type *base, + const uint8_t *src, + const uint8_t *iv, + const uint8_t *key, + uint8_t *dst, + uint32_t ivSize, + uint32_t aadSize, + uint32_t keySize, + uint32_t tagSize) +{ + if (!base) + { + return kStatus_InvalidArgument; + } + + /* tag can be NULL to skip tag processing */ + if ((!src) || (!iv) || (!key) || (!dst)) + { + return kStatus_InvalidArgument; + } + + /* size of Nonce (ivSize) must be element of 7,8,9,10,11,12,13 */ + if ((ivSize < 7u) || (ivSize > 13u)) + { + return kStatus_InvalidArgument; + } + /* octet length of MAC (tagSize) must be element of 4,6,8,10,12,14,16 for tag processing or zero to skip tag + * processing */ + if (((tagSize > 0) && (tagSize < 4u)) || (tagSize > 16u) || (tagSize & 1u)) + { + return kStatus_InvalidArgument; + } + + /* check if keySize is supported */ + if (!ltc_check_key_size(keySize)) + { + return kStatus_InvalidArgument; + } + + /* LTC does not support more AAD than this */ + if (aadSize >= 65280u) + { + return kStatus_InvalidArgument; + } + return kStatus_Success; +} + +static uint32_t swap_bytes(uint32_t in) +{ + return (((in & 0x000000ffu) << 24) | ((in & 0x0000ff00u) << 8) | ((in & 0x00ff0000u) >> 8) | + ((in & 0xff000000u) >> 24)); +} + +static void ltc_aes_ccm_context_init( + LTC_Type *base, uint32_t inputSize, const uint8_t *iv, uint32_t ivSize, uint32_t aadSize, uint32_t tagSize) +{ + ltc_xcm_block_t blk; + ltc_xcm_block_t blkZero = {{0x0u, 0x0u, 0x0u, 0x0u}}; + + int q; /* octet length of binary representation of the octet length of the payload. computed as (15 - n), where n is + length of nonce(=ivSize) */ + uint8_t flags; /* flags field in B0 and CTR0 */ + + /* compute B0 */ + ltc_memcpy(&blk, &blkZero, sizeof(blk)); + /* tagSize - size of output MAC */ + q = 15 - ivSize; + flags = (uint8_t)(8 * ((tagSize - 2) / 2) + q - 1); /* 8*M' + L' */ + if (aadSize) + { + flags |= 0x40; /* Adata */ + } + blk.b[0] = flags; /* flags field */ + blk.w[3] = swap_bytes(inputSize); /* message size, most significant byte first */ + ltc_memcpy(&blk.b[1], iv, ivSize); /* nonce field */ + + /* Write B0 data to the context register. + */ + ltc_set_context(base, &blk.b[0], 16, 0); + + /* Write CTR0 to the context register. + */ + ltc_memcpy(&blk, &blkZero, sizeof(blk)); /* ctr(0) field = zero */ + blk.b[0] = q - 1; /* flags field */ + ltc_memcpy(&blk.b[1], iv, ivSize); /* nonce field */ + ltc_set_context(base, &blk.b[0], 16, 4); +} + +static status_t ltc_aes_ccm_process_aad( + LTC_Type *base, uint32_t inputSize, const uint8_t *aad, uint32_t aadSize, ltc_mode_t *modeReg) +{ + ltc_xcm_block_t blk = {{0x0u, 0x0u, 0x0u, 0x0u}}; + uint32_t swapped; /* holds byte swap of uint32_t */ + status_t retval; + + if (aadSize) + { + bool aad_only; + bool aad_single_session; + + uint32_t sz = 0; + + aad_only = inputSize == 0u; + aad_single_session = (((aadSize + 2u) + 15u) & 0xfffffff0u) <= LTC_FIFO_SZ_MAX_DOWN_ALGN; + + /* limit by CCM spec: 2^16 - 2^8 = 65280 */ + + /* encoding is two octets, msbyte first */ + swapped = swap_bytes(aadSize); + ltc_memcpy(&blk.b[0], ((uint8_t *)&swapped) + sizeof(uint16_t), sizeof(uint16_t)); + + sz = aadSize > 14u ? 14u : aadSize; /* limit aad to the end of 16 bytes blk */ + ltc_memcpy(&blk.b[2], aad, sz); /* fill B1 with aad */ + + if (aad_single_session) + { + base->AADSZ = LTC_AADSZ_AL(aad_only) | ((aadSize + 2U) & LTC_DS_DS_MASK); + /* move first AAD block (16 bytes block B1) to FIFO */ + ltc_move_block_to_ififo(base, &blk, sizeof(blk)); + } + else + { + base->AADSZ = LTC_AADSZ_AL(true) | (16U); + /* move first AAD block (16 bytes block B1) to FIFO */ + ltc_move_block_to_ififo(base, &blk, sizeof(blk)); + } + + /* track consumed AAD. sz bytes have been moved to fifo. */ + aadSize -= sz; + aad += sz; + + if (aad_single_session) + { + /* move remaining AAD to FIFO, then return, to continue with MDATA */ + ltc_move_to_ififo(base, aad, aadSize); + } + else if (aadSize == 0u) + { + retval = ltc_wait(base); + if (kStatus_Success != retval) + { + return retval; + } + } + else + { + while (aadSize) + { + retval = ltc_wait(base); + if (kStatus_Success != retval) + { + return retval; + } + + *modeReg &= ~LTC_MD_AS_MASK; + *modeReg |= (uint32_t)kLTC_ModeUpdate; + base->MD = *modeReg; + + sz = LTC_FIFO_SZ_MAX_DOWN_ALGN; + if (aadSize < sz) + { + base->AADSZ = LTC_AADSZ_AL(aad_only) | (aadSize & LTC_DS_DS_MASK); + ltc_move_to_ififo(base, aad, aadSize); + aadSize = 0; + } + else + { + base->AADSZ = LTC_AADSZ_AL(true) | (sz & LTC_DS_DS_MASK); + ltc_move_to_ififo(base, aad, sz); + aadSize -= sz; + aad += sz; + } + } /* end while */ + } /* end else */ + } /* end if */ + return kStatus_Success; +} + +static status_t ltc_aes_ccm_process(LTC_Type *base, + ltc_mode_encrypt_t encryptMode, + const uint8_t *src, + uint32_t inputSize, + const uint8_t *iv, + uint32_t ivSize, + const uint8_t *aad, + uint32_t aadSize, + const uint8_t *key, + uint32_t keySize, + uint8_t *dst, + uint8_t *tag, + uint32_t tagSize) +{ + status_t retval; /* return value */ + uint32_t max_ltc_fifo_sz; /* maximum data size that we can put to LTC FIFO in one session. 12-bit limit. */ + ltc_mode_t modeReg; /* read and write LTC mode register */ + + bool single_ses_proc_all; /* aad and src data can be processed in one session */ + + retval = ltc_aes_ccm_check_input_args(base, src, iv, key, dst, ivSize, aadSize, keySize, tagSize); + + /* API input validation */ + if (kStatus_Success != retval) + { + return retval; + } + + max_ltc_fifo_sz = LTC_DS_DS_MASK; /* 12-bit field limit */ + + /* Write value to LTC AADSIZE will be (aadSize+2) value. + * The value will be rounded up to next 16 byte boundary and added to Data Size register. + * We then add inputSize to Data Size register. If the resulting Data Size is less than max_ltc_fifo_sz + * then all can be processed in one session INITIALIZE/FINALIZE. + * Otherwise, we have to split into multiple session, going through INITIALIZE, UPDATE (if required) and FINALIZE. + */ + single_ses_proc_all = ((((aadSize + 2) + 15u) & 0xfffffff0u) + inputSize) <= max_ltc_fifo_sz; + + /* setup key, algorithm and set the alg.state to INITIALIZE */ + if (single_ses_proc_all) + { + ltc_symmetric_init_final(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCCM, encryptMode); + } + else + { + ltc_symmetric_init(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCCM, encryptMode); + } + modeReg = base->MD; + + /* Initialize LTC context for AES CCM: block B0 and initial counter CTR0 */ + ltc_aes_ccm_context_init(base, inputSize, iv, ivSize, aadSize, tagSize); + + /* Process additional authentication data, if there are any. + * Need to split the job into individual sessions of up to 4096 bytes, due to LTC IFIFO data size limit. + */ + retval = ltc_aes_ccm_process_aad(base, inputSize, aad, aadSize, &modeReg); + if (kStatus_Success != retval) + { + return retval; + } + + /* Workaround for the LTC Data Size register update errata TKT261180 */ + if (inputSize) + { + while (16u < base->DS) + { + } + } + + /* Process message */ + if (single_ses_proc_all) + { + retval = ltc_symmetric_process_data(base, &src[0], inputSize, &dst[0]); + } + else + { + retval = ltc_symmetric_process_data_multiple(base, &src[0], inputSize, &dst[0], modeReg, kLTC_ModeFinalize); + } + if (kStatus_Success != retval) + { + return retval; + } + retval = ltc_aes_process_tag(base, tag, tagSize, modeReg, LTC_CCM_TAG_IDX); + return retval; +} + +/******************************************************************************* + * CCM Code public + ******************************************************************************/ +status_t LTC_AES_EncryptTagCcm(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t *iv, + uint32_t ivSize, + const uint8_t *aad, + uint32_t aadSize, + const uint8_t *key, + uint32_t keySize, + uint8_t *tag, + uint32_t tagSize) +{ + status_t status; + status = ltc_aes_ccm_process(base, kLTC_ModeEncrypt, plaintext, size, iv, ivSize, aad, aadSize, key, keySize, + ciphertext, tag, tagSize); + + ltc_clear_all(base, false); + return status; +} + +status_t LTC_AES_DecryptTagCcm(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t *iv, + uint32_t ivSize, + const uint8_t *aad, + uint32_t aadSize, + const uint8_t *key, + uint32_t keySize, + const uint8_t *tag, + uint32_t tagSize) +{ + uint8_t temp_tag[16] = {0}; /* max. octet length of MAC (tag) is 16 */ + uint8_t *tag_ptr; + status_t status; + + tag_ptr = NULL; + if (tag) + { + ltc_memcpy(temp_tag, tag, tagSize); + tag_ptr = &temp_tag[0]; + } + + status = ltc_aes_ccm_process(base, kLTC_ModeDecrypt, ciphertext, size, iv, ivSize, aad, aadSize, key, keySize, + plaintext, tag_ptr, tagSize); + + ltc_clear_all(base, false); + return status; +} + +#if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES +/******************************************************************************* + * DES / 3DES Code static + ******************************************************************************/ +static status_t ltc_des_process(LTC_Type *base, + const uint8_t *input, + uint8_t *output, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE], + ltc_mode_symmetric_alg_t modeAs, + ltc_mode_encrypt_t modeEnc) +{ + status_t retval; + + /* all but OFB, size must be 8-byte multiple */ + if ((modeAs != kLTC_ModeOFB) && ((size < 8u) || (size % 8u))) + { + return kStatus_InvalidArgument; + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, &key[0], LTC_DES_KEY_SIZE, kLTC_AlgorithmDES, modeAs, modeEnc); + + if ((modeAs != kLTC_ModeECB)) + { + ltc_set_context(base, iv, LTC_DES_IV_SIZE, 0); + } + + /* Process data and return status. */ + retval = ltc_process_message_in_sessions(base, input, size, output); + ltc_clear_all(base, false); + return retval; +} + +status_t ltc_3des_check_input_args(ltc_mode_symmetric_alg_t modeAs, + uint32_t size, + const uint8_t *key1, + const uint8_t *key2) +{ + /* all but OFB, size must be 8-byte multiple */ + if ((modeAs != kLTC_ModeOFB) && ((size < 8u) || (size % 8u))) + { + return kStatus_InvalidArgument; + } + + if ((key1 == NULL) || (key2 == NULL)) + { + return kStatus_InvalidArgument; + } + return kStatus_Success; +} + +static status_t ltc_3des_process(LTC_Type *base, + const uint8_t *input, + uint8_t *output, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE], + ltc_mode_symmetric_alg_t modeAs, + ltc_mode_encrypt_t modeEnc) +{ + status_t retval; + uint8_t key[LTC_DES_KEY_SIZE * 3]; + uint8_t keySize = LTC_DES_KEY_SIZE * 2; + + retval = ltc_3des_check_input_args(modeAs, size, key1, key2); + if (kStatus_Success != retval) + { + return retval; + } + + ltc_memcpy(&key[0], &key1[0], LTC_DES_KEY_SIZE); + ltc_memcpy(&key[LTC_DES_KEY_SIZE], &key2[0], LTC_DES_KEY_SIZE); + if (key3) + { + ltc_memcpy(&key[LTC_DES_KEY_SIZE * 2], &key3[0], LTC_DES_KEY_SIZE); + keySize = sizeof(key); + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, &key[0], keySize, kLTC_Algorithm3DES, modeAs, modeEnc); + + if ((modeAs != kLTC_ModeECB)) + { + ltc_set_context(base, iv, LTC_DES_IV_SIZE, 0); + } + + /* Process data and return status. */ + retval = ltc_process_message_in_sessions(base, input, size, output); + ltc_clear_all(base, false); + return retval; +} +/******************************************************************************* + * DES / 3DES Code public + ******************************************************************************/ +status_t LTC_DES_EncryptEcb( + LTC_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, uint32_t size, const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process(base, plaintext, ciphertext, size, NULL, key, kLTC_ModeECB, kLTC_ModeEncrypt); +} + +status_t LTC_DES_DecryptEcb( + LTC_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, uint32_t size, const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process(base, ciphertext, plaintext, size, NULL, key, kLTC_ModeECB, kLTC_ModeDecrypt); +} + +status_t LTC_DES_EncryptCbc(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process(base, plaintext, ciphertext, size, iv, key, kLTC_ModeCBC, kLTC_ModeEncrypt); +} + +status_t LTC_DES_DecryptCbc(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process(base, ciphertext, plaintext, size, iv, key, kLTC_ModeCBC, kLTC_ModeDecrypt); +} + +status_t LTC_DES_EncryptCfb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process(base, plaintext, ciphertext, size, iv, key, kLTC_ModeCFB, kLTC_ModeEncrypt); +} + +status_t LTC_DES_DecryptCfb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process(base, ciphertext, plaintext, size, iv, key, kLTC_ModeCFB, kLTC_ModeDecrypt); +} + +status_t LTC_DES_EncryptOfb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process(base, plaintext, ciphertext, size, iv, key, kLTC_ModeOFB, kLTC_ModeEncrypt); +} + +status_t LTC_DES_DecryptOfb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process(base, ciphertext, plaintext, size, iv, key, kLTC_ModeOFB, kLTC_ModeDecrypt); +} + +status_t LTC_DES2_EncryptEcb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, plaintext, ciphertext, size, NULL, key1, key2, NULL, kLTC_ModeECB, kLTC_ModeEncrypt); +} + +status_t LTC_DES3_EncryptEcb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, plaintext, ciphertext, size, NULL, key1, key2, key3, kLTC_ModeECB, kLTC_ModeEncrypt); +} + +status_t LTC_DES2_DecryptEcb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, ciphertext, plaintext, size, NULL, key1, key2, NULL, kLTC_ModeECB, kLTC_ModeDecrypt); +} + +status_t LTC_DES3_DecryptEcb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, ciphertext, plaintext, size, NULL, key1, key2, key3, kLTC_ModeECB, kLTC_ModeDecrypt); +} + +status_t LTC_DES2_EncryptCbc(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, plaintext, ciphertext, size, iv, key1, key2, NULL, kLTC_ModeCBC, kLTC_ModeEncrypt); +} + +status_t LTC_DES3_EncryptCbc(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, plaintext, ciphertext, size, iv, key1, key2, key3, kLTC_ModeCBC, kLTC_ModeEncrypt); +} + +status_t LTC_DES2_DecryptCbc(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, ciphertext, plaintext, size, iv, key1, key2, NULL, kLTC_ModeCBC, kLTC_ModeDecrypt); +} + +status_t LTC_DES3_DecryptCbc(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, ciphertext, plaintext, size, iv, key1, key2, key3, kLTC_ModeCBC, kLTC_ModeDecrypt); +} + +status_t LTC_DES2_EncryptCfb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, plaintext, ciphertext, size, iv, key1, key2, NULL, kLTC_ModeCFB, kLTC_ModeEncrypt); +} + +status_t LTC_DES3_EncryptCfb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, plaintext, ciphertext, size, iv, key1, key2, key3, kLTC_ModeCFB, kLTC_ModeEncrypt); +} + +status_t LTC_DES2_DecryptCfb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, ciphertext, plaintext, size, iv, key1, key2, NULL, kLTC_ModeCFB, kLTC_ModeDecrypt); +} + +status_t LTC_DES3_DecryptCfb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, ciphertext, plaintext, size, iv, key1, key2, key3, kLTC_ModeCFB, kLTC_ModeDecrypt); +} + +status_t LTC_DES2_EncryptOfb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, plaintext, ciphertext, size, iv, key1, key2, NULL, kLTC_ModeOFB, kLTC_ModeEncrypt); +} + +status_t LTC_DES3_EncryptOfb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, plaintext, ciphertext, size, iv, key1, key2, key3, kLTC_ModeOFB, kLTC_ModeEncrypt); +} + +status_t LTC_DES2_DecryptOfb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, ciphertext, plaintext, size, iv, key1, key2, NULL, kLTC_ModeOFB, kLTC_ModeDecrypt); +} + +status_t LTC_DES3_DecryptOfb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process(base, ciphertext, plaintext, size, iv, key1, key2, key3, kLTC_ModeOFB, kLTC_ModeDecrypt); +} +#endif /* FSL_FEATURE_LTC_HAS_DES */ + +/******************************************************************************* + * HASH Definitions + ******************************************************************************/ +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA +#define LTC_SHA_BLOCK_SIZE 64 /*!< SHA-1, SHA-224 & SHA-256 block size */ +#define LTC_HASH_BLOCK_SIZE LTC_SHA_BLOCK_SIZE /*!< LTC hash block size */ + +enum _ltc_sha_digest_len +{ + kLTC_RunLenSha1 = 28u, + kLTC_OutLenSha1 = 20u, + kLTC_RunLenSha224 = 40u, + kLTC_OutLenSha224 = 28u, + kLTC_RunLenSha256 = 40u, + kLTC_OutLenSha256 = 32u, +}; +#else +#define LTC_HASH_BLOCK_SIZE LTC_AES_BLOCK_SIZE /*!< LTC hash block size */ +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + +/*! Internal states of the HASH creation process */ +typedef enum _ltc_hash_algo_state +{ + kLTC_HashInit = 1u, /*!< Key in the HASH context is the input key. */ + kLTC_HashUpdate, /*!< HASH context has algorithm specific context: MAC, K2 and K3 (XCBC-MAC), MAC and L (CMAC), + running digest (MDHA). Key in the HASH context is the derived key. */ +} ltc_hash_algo_state_t; + +/*! 16/64-byte block represented as byte array or 4/16 32-bit words */ +typedef union _ltc_hash_block +{ + uint32_t w[LTC_HASH_BLOCK_SIZE / 4]; /*!< array of 32-bit words */ + uint8_t b[LTC_HASH_BLOCK_SIZE]; /*!< byte array */ +} ltc_hash_block_t; + +/*! Definitions of indexes into hash context array */ +typedef enum _ltc_hash_ctx_indexes +{ + kLTC_HashCtxKeyStartIdx = 12, /*!< context word array index where key is stored */ + kLTC_HashCtxKeySize = 20, /*!< context word array index where key size is stored */ + kLTC_HashCtxNumWords = 21, /*!< number of context array 32-bit words */ +} ltc_hash_ctx_indexes; + +typedef struct _ltc_hash_ctx_internal +{ + ltc_hash_block_t blk; /*!< memory buffer. only full 64/16-byte blocks are written to LTC during hash updates */ + uint32_t blksz; /*!< number of valid bytes in memory buffer */ + LTC_Type *base; /*!< LTC peripheral base address */ + ltc_hash_algo_t algo; /*!< selected algorithm from the set of supported algorithms in ltc_drv_hash_algo */ + ltc_hash_algo_state_t state; /*!< finite machine state of the hash software process */ + uint32_t word[kLTC_HashCtxNumWords]; /*!< LTC module context that needs to be saved/restored between LTC jobs */ +} ltc_hash_ctx_internal_t; + +/******************************************************************************* + * HASH Code static + ******************************************************************************/ +static status_t ltc_hash_check_input_alg(ltc_hash_algo_t algo) +{ + if ((algo != kLTC_XcbcMac) && (algo != kLTC_Cmac) +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + && (algo != kLTC_Sha1) && (algo != kLTC_Sha224) && (algo != kLTC_Sha256) +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + ) + { + return kStatus_InvalidArgument; + } + return kStatus_Success; +} + +static inline bool ltc_hash_alg_is_cmac(ltc_hash_algo_t algo) +{ + return ((algo == kLTC_XcbcMac) || (algo == kLTC_Cmac)); +} + +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA +static inline bool ltc_hash_alg_is_sha(ltc_hash_algo_t algo) +{ + return ((algo == kLTC_Sha1) || (algo == kLTC_Sha224) || (algo == kLTC_Sha256)); +} +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + +static status_t ltc_hash_check_input_args( + LTC_Type *base, ltc_hash_ctx_t *ctx, ltc_hash_algo_t algo, const uint8_t *key, uint32_t keySize) +{ + /* Check validity of input algorithm */ + if (kStatus_Success != ltc_hash_check_input_alg(algo)) + { + return kStatus_InvalidArgument; + } + + if ((NULL == ctx) || (NULL == base)) + { + return kStatus_InvalidArgument; + } + + if (ltc_hash_alg_is_cmac(algo)) + { + if ((NULL == key) || (!ltc_check_key_size(keySize))) + { + return kStatus_InvalidArgument; + } + } + + return kStatus_Success; +} + +static status_t ltc_hash_check_context(ltc_hash_ctx_internal_t *ctxInternal, const uint8_t *data) +{ + if ((NULL == data) || (NULL == ctxInternal) || (NULL == ctxInternal->base) || + (kStatus_Success != ltc_hash_check_input_alg(ctxInternal->algo))) + { + return kStatus_InvalidArgument; + } + return kStatus_Success; +} + +static uint32_t ltc_hash_algo2mode(ltc_hash_algo_t algo, ltc_mode_algorithm_state_t asMode, uint32_t *algOutSize) +{ + uint32_t modeReg = 0u; + uint32_t outSize = 0u; + + /* Set LTC algorithm */ + switch (algo) + { + case kLTC_XcbcMac: + modeReg = (uint32_t)kLTC_AlgorithmAES | (uint32_t)kLTC_ModeXCBCMAC; + outSize = 16u; + break; + case kLTC_Cmac: + modeReg = (uint32_t)kLTC_AlgorithmAES | (uint32_t)kLTC_ModeCMAC; + outSize = 16u; + break; +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + case kLTC_Sha1: + modeReg = (uint32_t)kLTC_AlgorithmSHA1; + outSize = kLTC_OutLenSha1; + break; + case kLTC_Sha224: + modeReg = (uint32_t)kLTC_AlgorithmSHA224; + outSize = kLTC_OutLenSha224; + break; + case kLTC_Sha256: + modeReg = (uint32_t)kLTC_AlgorithmSHA256; + outSize = kLTC_OutLenSha256; + break; +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + default: + break; + } + + modeReg |= (uint32_t)asMode; + if (algOutSize) + { + *algOutSize = outSize; + } + + return modeReg; +} + +static void ltc_hash_engine_init(ltc_hash_ctx_internal_t *ctx) +{ + uint8_t *key; + uint32_t keySize; + LTC_Type *base; + ltc_mode_symmetric_alg_t algo; + + base = ctx->base; +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + if (ltc_hash_alg_is_cmac(ctx->algo)) + { +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + /* + * word[kLtcCmacCtxKeySize] = key_length + * word[1-8] = key + */ + keySize = ctx->word[kLTC_HashCtxKeySize]; + key = (uint8_t *)&ctx->word[kLTC_HashCtxKeyStartIdx]; + + /* set LTC mode register to INITIALIZE */ + algo = (ctx->algo == kLTC_XcbcMac) ? kLTC_ModeXCBCMAC : kLTC_ModeCMAC; + ltc_symmetric_init(base, key, keySize, kLTC_AlgorithmAES, algo, kLTC_ModeEncrypt); +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + } + else if (ltc_hash_alg_is_sha(ctx->algo)) + { + /* Clear internal register states. */ + base->CW = (uint32_t)kLTC_ClearAll; + + /* Set byte swap on for several registers we will be reading and writing + * user data to/from. */ + base->CTL |= kLTC_CtrlSwapAll; + } + else + { + /* do nothing in this case */ + } +#endif /* FSL_FEATURE_LTC_HAS_SHA */ +} + +static void ltc_hash_save_context(ltc_hash_ctx_internal_t *ctx) +{ + uint32_t sz; + LTC_Type *base; + + base = ctx->base; + /* Get context size */ + switch (ctx->algo) + { + case kLTC_XcbcMac: + /* + * word[0-3] = mac + * word[3-7] = k3 + * word[8-11] = k2 + * word[kLtcCmacCtxKeySize] = keySize + */ + sz = 12 * sizeof(uint32_t); + break; + case kLTC_Cmac: + /* + * word[0-3] = mac + * word[3-7] = L */ + sz = 8 * sizeof(uint32_t); + break; +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + case kLTC_Sha1: + sz = (kLTC_RunLenSha1); + break; + case kLTC_Sha224: + sz = (kLTC_RunLenSha224); + break; + case kLTC_Sha256: + sz = (kLTC_RunLenSha256); + break; +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + default: + sz = 0; + break; + } + + ltc_get_context(base, (uint8_t *)&ctx->word[0], sz, 0); + + if (true == ltc_hash_alg_is_cmac(ctx->algo)) + { + /* word[12-19] = key */ + ltc_get_key(base, (uint8_t *)&ctx->word[kLTC_HashCtxKeyStartIdx], ctx->word[kLTC_HashCtxKeySize]); + } +} + +static void ltc_hash_restore_context(ltc_hash_ctx_internal_t *ctx) +{ + uint32_t sz; + uint32_t keySize; + LTC_Type *base; + + base = ctx->base; + /* Get context size */ + switch (ctx->algo) + { + case kLTC_XcbcMac: + /* + * word[0-3] = mac + * word[3-7] = k3 + * word[8-11] = k2 + * word[kLtcCmacCtxKeySize] = keySize + */ + sz = 12 * sizeof(uint32_t); + break; + case kLTC_Cmac: + /* + * word[0-3] = mac + * word[3-7] = L */ + sz = 8 * sizeof(uint32_t); + break; +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + case kLTC_Sha1: + sz = (kLTC_RunLenSha1); + break; + case kLTC_Sha224: + sz = (kLTC_RunLenSha224); + break; + case kLTC_Sha256: + sz = (kLTC_RunLenSha256); + break; +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + default: + sz = 0; + break; + } + + ltc_set_context(base, (const uint8_t *)&ctx->word[0], sz, 0); + + if (ltc_hash_alg_is_cmac(ctx->algo)) + { + /* + * word[12-19] = key + * word[kLtcCmacCtxKeySize] = keySize + */ + base->CW = kLTC_ClearKey; /* clear Key and Key Size registers */ + + keySize = ctx->word[kLTC_HashCtxKeySize]; + /* Write the key in place. */ + ltc_set_key(base, (const uint8_t *)&ctx->word[kLTC_HashCtxKeyStartIdx], keySize); + + /* Write the key size. This must be done after writing the key, and this + * action locks the ability to modify the key registers. */ + base->KS = keySize; + } +} + +static void ltc_hash_prepare_context_switch(LTC_Type *base) +{ + base->CW = (uint32_t)kLTC_ClearDataSize | (uint32_t)kLTC_ClearMode; + base->STA = kLTC_StatusDoneIsr; +} + +static uint32_t ltc_hash_get_block_size(ltc_hash_algo_t algo) +{ + if ((algo == kLTC_XcbcMac) || (algo == kLTC_Cmac)) + { + return (uint32_t)LTC_AES_BLOCK_SIZE; + } +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + else if ((algo == kLTC_Sha1) || (algo == kLTC_Sha224) || (algo == kLTC_Sha256)) + { + return (uint32_t)LTC_SHA_BLOCK_SIZE; + } + else + { + return 0; + } +#else + return 0; +#endif +} + +static void ltc_hash_block_to_ififo(LTC_Type *base, const ltc_hash_block_t *blk, uint32_t numBytes, uint32_t blockSize) +{ + uint32_t i = 0; + uint32_t words; + + words = numBytes / 4u; + if (numBytes % 4u) + { + words++; + } + + if (words > blockSize / 4u) + { + words = blockSize / 4u; + } + + while (i < words) + { + if (0U == (base->FIFOSTA & LTC_FIFOSTA_IFF_MASK)) + { + /* Copy data to the input FIFO. */ + base->IFIFO = blk->w[i++]; + } + } +} + +static void ltc_hash_move_to_ififo(ltc_hash_ctx_internal_t *ctx, + const uint8_t *data, + uint32_t dataSize, + uint32_t blockSize) +{ + ltc_hash_block_t blkZero; + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(blkZero.w); i++) + { + blkZero.w[i] = 0; + } + + while (dataSize) + { + if (dataSize >= blockSize) + { + ltc_memcpy(&ctx->blk, data, blockSize); + ltc_hash_block_to_ififo(ctx->base, &ctx->blk, blockSize, blockSize); + dataSize -= blockSize; + data += blockSize; + } + else + { + /* last incomplete 16/64-bytes block of this message chunk */ + ltc_memcpy(&ctx->blk, &blkZero, sizeof(ctx->blk)); + ltc_memcpy(&ctx->blk, data, dataSize); + ctx->blksz = dataSize; + dataSize = 0; + } + } +} + +static status_t ltc_hash_merge_and_flush_buf(ltc_hash_ctx_internal_t *ctx, + const uint8_t *input, + uint32_t inputSize, + ltc_mode_t modeReg, + uint32_t blockSize, + uint32_t *consumedSize) +{ + uint32_t sz; + LTC_Type *base; + status_t status = kStatus_Success; + + base = ctx->base; + sz = 0; + if (ctx->blksz) + { + sz = blockSize - ctx->blksz; + if (sz > inputSize) + { + sz = inputSize; + } + ltc_memcpy(ctx->blk.b + ctx->blksz, input, sz); + input += sz; + inputSize -= sz; + ctx->blksz += sz; + + if (ctx->blksz == blockSize) + { + base->DS = blockSize; + ltc_hash_block_to_ififo(base, &ctx->blk, blockSize, blockSize); + ctx->blksz = 0; + + status = ltc_wait(base); + if (kStatus_Success != status) + { + return status; + } + + /* if there is still inputSize left, make sure LTC alg.state is set to UPDATE and continue */ + if (inputSize) + { + /* set algorithm state to UPDATE */ + modeReg &= ~LTC_MD_AS_MASK; + modeReg |= kLTC_ModeUpdate; + base->MD = modeReg; + } + } + } + if (consumedSize) + { + *consumedSize = sz; + } + return status; +} + +static status_t ltc_hash_move_rest_to_context( + ltc_hash_ctx_internal_t *ctx, const uint8_t *data, uint32_t dataSize, ltc_mode_t modeReg, uint32_t blockSize) +{ + status_t status = kStatus_Success; + ltc_hash_block_t blkZero; + uint32_t i; + + /* make blkZero clear */ + for (i = 0; i < ARRAY_SIZE(blkZero.w); i++) + { + blkZero.w[i] = 0; + } + + while (dataSize) + { + if (dataSize > blockSize) + { + dataSize -= blockSize; + data += blockSize; + } + else + { + if (dataSize + ctx->blksz > blockSize) + { + uint32_t sz; + status = ltc_hash_merge_and_flush_buf(ctx, data, dataSize, modeReg, blockSize, &sz); + if (kStatus_Success != status) + { + return status; + } + data += sz; + dataSize -= sz; + } + /* last incomplete 16/64-bytes block of this message chunk */ + ltc_memcpy(&ctx->blk, &blkZero, blockSize); + ltc_memcpy(&ctx->blk, data, dataSize); + ctx->blksz = dataSize; + dataSize = 0; + } + } + return status; +} + +static status_t ltc_hash_process_input_data(ltc_hash_ctx_internal_t *ctx, + const uint8_t *input, + uint32_t inputSize, + ltc_mode_t modeReg) +{ + uint32_t sz = 0; + LTC_Type *base; + uint32_t blockSize = 0; + status_t status = kStatus_Success; + + blockSize = ltc_hash_get_block_size(ctx->algo); + base = ctx->base; + + /* fill context struct blk and flush to LTC ififo in case it is full block */ + status = ltc_hash_merge_and_flush_buf(ctx, input, inputSize, modeReg, blockSize, &sz); + if (kStatus_Success != status) + { + return status; + } + input += sz; + inputSize -= sz; + + /* if there is still more than or equal to 64 bytes, move each 64 bytes through LTC */ + sz = LTC_DS_DS_MASK + 1u - LTC_HASH_BLOCK_SIZE; + while (inputSize) + { + if (inputSize < sz) + { + uint32_t lastSize; + + lastSize = inputSize % blockSize; + if (lastSize == 0) + { + lastSize = blockSize; + } + inputSize -= lastSize; + if (inputSize) + { + /* move all complete blocks to ififo. */ + base->DS = inputSize; + ltc_hash_move_to_ififo(ctx, input, inputSize, blockSize); + + status = ltc_wait(base); + if (kStatus_Success != status) + { + return status; + } + + input += inputSize; + } + /* keep last (in)complete 16-bytes block in context struct. */ + /* when 3rd argument of cmac_move_to_ififo() is <= 16 bytes, it only stores the data to context struct */ + status = ltc_hash_move_rest_to_context(ctx, input, lastSize, modeReg, blockSize); + if (kStatus_Success != status) + { + return status; + } + inputSize = 0; + } + else + { + base->DS = sz; + ltc_hash_move_to_ififo(ctx, input, sz, blockSize); + inputSize -= sz; + input += sz; + + status = ltc_wait(base); + if (kStatus_Success != status) + { + return status; + } + + /* set algorithm state to UPDATE */ + modeReg &= ~LTC_MD_AS_MASK; + modeReg |= kLTC_ModeUpdate; + base->MD = modeReg; + } + } /* end while */ + + return status; +} + +/******************************************************************************* + * HASH Code public + ******************************************************************************/ +status_t LTC_HASH_Init(LTC_Type *base, ltc_hash_ctx_t *ctx, ltc_hash_algo_t algo, const uint8_t *key, uint32_t keySize) +{ + status_t ret; + ltc_hash_ctx_internal_t *ctxInternal; + uint32_t i; + + ret = ltc_hash_check_input_args(base, ctx, algo, key, keySize); + if (ret != kStatus_Success) + { + return ret; + } + + /* set algorithm in context struct for later use */ + ctxInternal = (ltc_hash_ctx_internal_t *)ctx; + ctxInternal->algo = algo; + for (i = 0; i < kLTC_HashCtxNumWords; i++) + { + ctxInternal->word[i] = 0u; + } + + /* Steps required only using AES engine */ + if (ltc_hash_alg_is_cmac(algo)) + { + /* store input key and key length in context struct for later use */ + ctxInternal->word[kLTC_HashCtxKeySize] = keySize; + ltc_memcpy(&ctxInternal->word[kLTC_HashCtxKeyStartIdx], key, keySize); + } + ctxInternal->blksz = 0u; + for (i = 0; i < sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]); i++) + { + ctxInternal->blk.w[0] = 0u; + } + ctxInternal->state = kLTC_HashInit; + ctxInternal->base = base; + + return kStatus_Success; +} + +status_t LTC_HASH_Update(ltc_hash_ctx_t *ctx, const uint8_t *input, uint32_t inputSize) +{ + bool isUpdateState; + ltc_mode_t modeReg = 0; /* read and write LTC mode register */ + LTC_Type *base; + status_t status; + ltc_hash_ctx_internal_t *ctxInternal; + uint32_t blockSize; + + ctxInternal = (ltc_hash_ctx_internal_t *)ctx; + status = ltc_hash_check_context(ctxInternal, input); + if (kStatus_Success != status) + { + return status; + } + + base = ctxInternal->base; + blockSize = ltc_hash_get_block_size(ctxInternal->algo); + /* if we are still less than 64 bytes, keep only in context */ + if ((ctxInternal->blksz + inputSize) <= blockSize) + { + ltc_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, input, inputSize); + ctxInternal->blksz += inputSize; + return status; + } + else + { + isUpdateState = ctxInternal->state == kLTC_HashUpdate; + if (ctxInternal->state == kLTC_HashInit) + { + /* set LTC mode register to INITIALIZE job */ + ltc_hash_engine_init(ctxInternal); + +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + if (ltc_hash_alg_is_cmac(ctxInternal->algo)) + { +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + ctxInternal->state = kLTC_HashUpdate; + isUpdateState = true; + base->DS = 0u; + status = ltc_wait(base); +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + } + else + { + /* Set the proper block and algorithm mode. */ + modeReg = ltc_hash_algo2mode(ctxInternal->algo, kLTC_ModeInit, NULL); + base->MD = modeReg; + + ctxInternal->state = kLTC_HashUpdate; + status = ltc_hash_process_input_data(ctxInternal, input, inputSize, modeReg); + ltc_hash_save_context(ctxInternal); + } +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + } + else if (isUpdateState) + { + /* restore LTC context from context struct */ + ltc_hash_restore_context(ctxInternal); + } + else + { + /* nothing special at this place */ + } + } + + if (kStatus_Success != status) + { + return status; + } + + if (isUpdateState) + { + /* set LTC mode register to UPDATE job */ + ltc_hash_prepare_context_switch(base); + base->CW = kLTC_ClearDataSize; + modeReg = ltc_hash_algo2mode(ctxInternal->algo, kLTC_ModeUpdate, NULL); + base->MD = modeReg; + + /* process input data and save LTC context to context structure */ + status = ltc_hash_process_input_data(ctxInternal, input, inputSize, modeReg); + ltc_hash_save_context(ctxInternal); + } + ltc_clear_all(base, false); + return status; +} + +status_t LTC_HASH_Finish(ltc_hash_ctx_t *ctx, uint8_t *output, uint32_t *outputSize) +{ + ltc_mode_t modeReg; /* read and write LTC mode register */ + LTC_Type *base; + uint32_t algOutSize = 0; + status_t status; + ltc_hash_ctx_internal_t *ctxInternal; + uint32_t *ctxW; + uint32_t i; + + ctxInternal = (ltc_hash_ctx_internal_t *)ctx; + status = ltc_hash_check_context(ctxInternal, output); + if (kStatus_Success != status) + { + return status; + } + + base = ctxInternal->base; + ltc_hash_prepare_context_switch(base); + + base->CW = kLTC_ClearDataSize; + if (ctxInternal->state == kLTC_HashInit) + { + ltc_hash_engine_init(ctxInternal); +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + if (ltc_hash_alg_is_cmac(ctxInternal->algo)) + { +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + base->DS = 0u; + status = ltc_wait(base); + if (kStatus_Success != status) + { + return status; + } + modeReg = ltc_hash_algo2mode(ctxInternal->algo, kLTC_ModeFinalize, &algOutSize); +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + } + else + { + modeReg = ltc_hash_algo2mode(ctxInternal->algo, kLTC_ModeInitFinal, &algOutSize); + } +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + base->MD = modeReg; + } + else + { + modeReg = ltc_hash_algo2mode(ctxInternal->algo, kLTC_ModeFinalize, &algOutSize); + base->MD = modeReg; + + /* restore LTC context from context struct */ + ltc_hash_restore_context(ctxInternal); + } + + /* flush message last incomplete block, if there is any, or write zero to data size register. */ + base->DS = ctxInternal->blksz; + ltc_hash_block_to_ififo(base, &ctxInternal->blk, ctxInternal->blksz, ltc_hash_get_block_size(ctxInternal->algo)); + /* Wait for finish of the encryption */ + status = ltc_wait(base); + + if (outputSize) + { + if (algOutSize < *outputSize) + { + *outputSize = algOutSize; + } + else + { + algOutSize = *outputSize; + } + } + + ltc_get_context(base, &output[0], algOutSize, 0u); + + ctxW = (uint32_t *)ctx; + for (i = 0; i < LTC_HASH_CTX_SIZE; i++) + { + ctxW[i] = 0u; + } + + ltc_clear_all(base, false); + return status; +} + +status_t LTC_HASH(LTC_Type *base, + ltc_hash_algo_t algo, + const uint8_t *input, + uint32_t inputSize, + const uint8_t *key, + uint32_t keySize, + uint8_t *output, + uint32_t *outputSize) +{ + status_t status; + ltc_hash_ctx_t ctx; + + status = LTC_HASH_Init(base, &ctx, algo, key, keySize); + if (status != kStatus_Success) + { + return status; + } + status = LTC_HASH_Update(&ctx, input, inputSize); + if (status != kStatus_Success) + { + return status; + } + status = LTC_HASH_Finish(&ctx, output, outputSize); + return status; +} + +/******************************************************************************* + * PKHA Code static + ******************************************************************************/ +#if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA +static status_t ltc_pkha_clear_regabne(LTC_Type *base, bool A, bool B, bool N, bool E) +{ + ltc_mode_t mode; + + /* Set the PKHA algorithm and the appropriate function. */ + mode = (uint32_t)kLTC_AlgorithmPKHA | 1U; + + /* Set ram area to clear. Clear all. */ + if (A) + { + mode |= 1U << 19U; + } + if (B) + { + mode |= 1U << 18U; + } + if (N) + { + mode |= 1U << 16U; + } + if (E) + { + mode |= 1U << 17U; + } + + /* Write the mode register to the hardware. + * NOTE: This will begin the operation. */ + base->MDPK = mode; + + /* Wait for 'done' */ + return ltc_wait(base); +} + +static void ltc_pkha_default_parms(ltc_pkha_mode_params_t *params) +{ + params->func = (ltc_pkha_func_t)0; + params->arithType = kLTC_PKHA_IntegerArith; + params->montFormIn = kLTC_PKHA_NormalValue; + params->montFormOut = kLTC_PKHA_NormalValue; + params->srcReg = kLTC_PKHA_RegAll; + params->srcQuad = kLTC_PKHA_Quad0; + params->dstReg = kLTC_PKHA_RegAll; + params->dstQuad = kLTC_PKHA_Quad0; + params->equalTime = kLTC_PKHA_NoTimingEqualized; + params->r2modn = kLTC_PKHA_CalcR2; +} + +static void ltc_pkha_write_word(LTC_Type *base, ltc_pkha_reg_area_t reg, uint8_t index, uint32_t data) +{ + switch (reg) + { + case kLTC_PKHA_RegA: + base->PKA[index] = data; + break; + + case kLTC_PKHA_RegB: + base->PKB[index] = data; + break; + + case kLTC_PKHA_RegN: + base->PKN[index] = data; + break; + + case kLTC_PKHA_RegE: + base->PKE[index] = data; + break; + + default: + break; + } +} + +static uint32_t ltc_pkha_read_word(LTC_Type *base, ltc_pkha_reg_area_t reg, uint8_t index) +{ + uint32_t retval; + + switch (reg) + { + case kLTC_PKHA_RegA: + retval = base->PKA[index]; + break; + + case kLTC_PKHA_RegB: + retval = base->PKB[index]; + break; + + case kLTC_PKHA_RegN: + retval = base->PKN[index]; + break; + + case kLTC_PKHA_RegE: + retval = base->PKE[index]; + break; + + default: + retval = 0; + break; + } + return retval; +} + +static status_t ltc_pkha_write_reg( + LTC_Type *base, ltc_pkha_reg_area_t reg, uint8_t quad, const uint8_t *data, uint16_t dataSize) +{ + /* Select the word-based start index for each quadrant of 64 bytes. */ + uint8_t startIndex = (quad * 16u); + uint32_t outWord; + + while (dataSize > 0) + { + if (dataSize >= sizeof(uint32_t)) + { + ltc_pkha_write_word(base, reg, startIndex++, ltc_get_word_from_unaligned(data)); + dataSize -= sizeof(uint32_t); + data += sizeof(uint32_t); + } + else /* (dataSize > 0) && (dataSize < 4) */ + { + outWord = 0; + ltc_memcpy(&outWord, data, dataSize); + ltc_pkha_write_word(base, reg, startIndex, outWord); + dataSize = 0; + } + } + + return kStatus_Success; +} + +static void ltc_pkha_read_reg(LTC_Type *base, ltc_pkha_reg_area_t reg, uint8_t quad, uint8_t *data, uint16_t dataSize) +{ + /* Select the word-based start index for each quadrant of 64 bytes. */ + uint8_t startIndex = (quad * 16u); + uint16_t calcSize; + uint32_t word; + + while (dataSize > 0) + { + word = ltc_pkha_read_word(base, reg, startIndex++); + + calcSize = (dataSize >= sizeof(uint32_t)) ? sizeof(uint32_t) : dataSize; + ltc_memcpy(data, &word, calcSize); + + data += calcSize; + dataSize -= calcSize; + } +} + +static void ltc_pkha_init_data(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *B, + uint16_t sizeB, + const uint8_t *N, + uint16_t sizeN, + const uint8_t *E, + uint16_t sizeE) +{ + uint32_t clearMask = kLTC_ClearMode; /* clear Mode Register */ + + /* Clear internal register states. */ + if (sizeA) + { + clearMask |= kLTC_ClearPkhaSizeA; + } + if (sizeB) + { + clearMask |= kLTC_ClearPkhaSizeB; + } + if (sizeN) + { + clearMask |= kLTC_ClearPkhaSizeN; + } + if (sizeE) + { + clearMask |= kLTC_ClearPkhaSizeE; + } + + base->CW = clearMask; + base->STA = kLTC_StatusDoneIsr; + ltc_pkha_clear_regabne(base, A, B, N, E); + + /* Write register sizes. */ + /* Write modulus (N) and A and B register arguments. */ + if (sizeN) + { + base->PKNSZ = sizeN; + if (N) + { + ltc_pkha_write_reg(base, kLTC_PKHA_RegN, 0, N, sizeN); + } + } + + if (sizeA) + { + base->PKASZ = sizeA; + if (A) + { + ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 0, A, sizeA); + } + } + + if (sizeB) + { + base->PKBSZ = sizeB; + if (B) + { + ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 0, B, sizeB); + } + } + + if (sizeE) + { + base->PKESZ = sizeE; + if (E) + { + ltc_pkha_write_reg(base, kLTC_PKHA_RegE, 0, E, sizeE); + } + } +} + +static void ltc_pkha_mode_set_src_reg_copy(ltc_mode_t *outMode, ltc_pkha_reg_area_t reg) +{ + int i = 0; + + do + { + reg = (ltc_pkha_reg_area_t)(((uint32_t)reg) >> 1u); + i++; + } while (reg); + + i = 4 - i; + /* Source register must not be E. */ + if (i != 2) + { + *outMode |= ((uint32_t)i << 17u); + } +} + +static void ltc_pkha_mode_set_dst_reg_copy(ltc_mode_t *outMode, ltc_pkha_reg_area_t reg) +{ + int i = 0; + + do + { + reg = (ltc_pkha_reg_area_t)(((uint32_t)reg) >> 1u); + i++; + } while (reg); + + i = 4 - i; + *outMode |= ((uint32_t)i << 10u); +} + +static void ltc_pkha_mode_set_src_seg_copy(ltc_mode_t *outMode, const ltc_pkha_quad_area_t quad) +{ + *outMode |= ((uint32_t)quad << 8u); +} + +static void ltc_pkha_mode_set_dst_seg_copy(ltc_mode_t *outMode, const ltc_pkha_quad_area_t quad) +{ + *outMode |= ((uint32_t)quad << 6u); +} + +/*! + * @brief Starts the PKHA operation. + * + * This function starts an operation configured by the params parameter. + * + * @param base LTC peripheral base address + * @param params Configuration structure containing all settings required for PKHA operation. + */ +static status_t ltc_pkha_init_mode(LTC_Type *base, const ltc_pkha_mode_params_t *params) +{ + ltc_mode_t modeReg; + status_t retval; + + /* Set the PKHA algorithm and the appropriate function. */ + modeReg = kLTC_AlgorithmPKHA; + modeReg |= (uint32_t)params->func; + + if ((params->func == kLTC_PKHA_CopyMemSizeN) || (params->func == kLTC_PKHA_CopyMemSizeSrc)) + { + /* Set source and destination registers and quads. */ + ltc_pkha_mode_set_src_reg_copy(&modeReg, params->srcReg); + ltc_pkha_mode_set_dst_reg_copy(&modeReg, params->dstReg); + ltc_pkha_mode_set_src_seg_copy(&modeReg, params->srcQuad); + ltc_pkha_mode_set_dst_seg_copy(&modeReg, params->dstQuad); + } + else + { + /* Set the arithmetic type - integer or binary polynomial (F2m). */ + modeReg |= ((uint32_t)params->arithType << 17u); + + /* Set to use Montgomery form of inputs and/or outputs. */ + modeReg |= ((uint32_t)params->montFormIn << 19u); + modeReg |= ((uint32_t)params->montFormOut << 18u); + + /* Set to use pre-computed R2modN */ + modeReg |= ((uint32_t)params->r2modn << 16u); + } + + modeReg |= ((uint32_t)params->equalTime << 10u); + + /* Write the mode register to the hardware. + * NOTE: This will begin the operation. */ + base->MDPK = modeReg; + + retval = ltc_wait(base); + return (retval); +} + +static status_t ltc_pkha_modR2( + LTC_Type *base, const uint8_t *N, uint16_t sizeN, uint8_t *result, uint16_t *resultSize, ltc_pkha_f2m_t arithType) +{ + status_t status; + ltc_pkha_mode_params_t params; + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithModR2; + params.arithType = arithType; + + ltc_pkha_init_data(base, NULL, 0, NULL, 0, N, sizeN, NULL, 0); + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the result and size from register B0. */ + if (resultSize && result) + { + *resultSize = base->PKBSZ; + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize); + } + } + + return status; +} + +static status_t ltc_pkha_modmul(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *B, + uint16_t sizeB, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType, + ltc_pkha_montgomery_form_t montIn, + ltc_pkha_montgomery_form_t montOut, + ltc_pkha_timing_t equalTime) +{ + ltc_pkha_mode_params_t params; + status_t status; + + if (arithType == kLTC_PKHA_IntegerArith) + { + if (LTC_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0) + { + return (kStatus_InvalidArgument); + } + + if (LTC_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0) + { + return (kStatus_InvalidArgument); + } + } + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithModMul; + params.arithType = arithType; + params.montFormIn = montIn; + params.montFormOut = montOut; + params.equalTime = equalTime; + + ltc_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0); + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the result and size from register B0. */ + if (resultSize && result) + { + *resultSize = base->PKBSZ; + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize); + } + } + + return status; +} + +/******************************************************************************* + * PKHA Code public + ******************************************************************************/ +int LTC_PKHA_CompareBigNum(const uint8_t *a, size_t sizeA, const uint8_t *b, size_t sizeB) +{ + int retval; + + /* skip zero msbytes - integer a */ + if (sizeA) + { + while (0u == a[sizeA - 1]) + { + sizeA--; + } + } + + /* skip zero msbytes - integer b */ + if (sizeB) + { + while (0u == b[sizeB - 1]) + { + sizeB--; + } + } + + if (sizeA > sizeB) + { + retval = 1; + } /* int a has more non-zero bytes, thus it is bigger than b */ + else if (sizeA < sizeB) + { + retval = -1; + } /* int b has more non-zero bytes, thus it is bigger than a */ + else if (sizeA == 0) + { + retval = 0; + } /* sizeA = sizeB = 0 */ + else + { + int n; + + n = sizeA - 1; + /* skip all equal bytes */ + while ((n >= 0) && (a[n] == b[n])) + { + n--; + } + if (n < 0) + { + retval = 0; + } + else + { + retval = (a[n] > b[n]) ? 1 : -1; + } + } + return (retval); +} + +status_t LTC_PKHA_NormalToMontgomery(LTC_Type *base, + const uint8_t *N, + uint16_t sizeN, + uint8_t *A, + uint16_t *sizeA, + uint8_t *B, + uint16_t *sizeB, + uint8_t *R2, + uint16_t *sizeR2, + ltc_pkha_timing_t equalTime, + ltc_pkha_f2m_t arithType) +{ + status_t status; + + /* need to convert our Integer inputs into Montgomery format */ + if (N && sizeN && R2 && sizeR2) + { + /* 1. R2 = MOD_R2(N) */ + status = ltc_pkha_modR2(base, N, sizeN, R2, sizeR2, arithType); + if (status != kStatus_Success) + { + return status; + } + + /* 2. A(Montgomery) = MOD_MUL_IM_OM(A, R2, N) */ + if (A && sizeA) + { + status = ltc_pkha_modmul(base, A, *sizeA, R2, *sizeR2, N, sizeN, A, sizeA, arithType, + kLTC_PKHA_MontgomeryFormat, kLTC_PKHA_MontgomeryFormat, equalTime); + if (status != kStatus_Success) + { + return status; + } + } + + /* 2. B(Montgomery) = MOD_MUL_IM_OM(B, R2, N) */ + if (B && sizeB) + { + status = ltc_pkha_modmul(base, B, *sizeB, R2, *sizeR2, N, sizeN, B, sizeB, arithType, + kLTC_PKHA_MontgomeryFormat, kLTC_PKHA_MontgomeryFormat, equalTime); + if (status != kStatus_Success) + { + return status; + } + } + + ltc_clear_all(base, true); + } + else + { + status = kStatus_InvalidArgument; + } + + return status; +} + +status_t LTC_PKHA_MontgomeryToNormal(LTC_Type *base, + const uint8_t *N, + uint16_t sizeN, + uint8_t *A, + uint16_t *sizeA, + uint8_t *B, + uint16_t *sizeB, + ltc_pkha_timing_t equalTime, + ltc_pkha_f2m_t arithType) +{ + uint8_t one = 1; + status_t status = kStatus_InvalidArgument; + + /* A = MOD_MUL_IM_OM(A(Montgomery), 1, N) */ + if (A && sizeA) + { + status = ltc_pkha_modmul(base, A, *sizeA, &one, sizeof(one), N, sizeN, A, sizeA, arithType, + kLTC_PKHA_MontgomeryFormat, kLTC_PKHA_MontgomeryFormat, equalTime); + if (kStatus_Success != status) + { + return status; + } + } + + /* B = MOD_MUL_IM_OM(B(Montgomery), 1, N) */ + if (B && sizeB) + { + status = ltc_pkha_modmul(base, B, *sizeB, &one, sizeof(one), N, sizeN, B, sizeB, arithType, + kLTC_PKHA_MontgomeryFormat, kLTC_PKHA_MontgomeryFormat, equalTime); + if (kStatus_Success != status) + { + return status; + } + } + + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_ModAdd(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *B, + uint16_t sizeB, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType) +{ + ltc_pkha_mode_params_t params; + status_t status; + + if (arithType == kLTC_PKHA_IntegerArith) + { + if (LTC_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0) + { + return (kStatus_InvalidArgument); + } + + if (LTC_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0) + { + return (kStatus_InvalidArgument); + } + } + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithModAdd; + params.arithType = arithType; + + ltc_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0); + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the result and size from register B0. */ + if (resultSize && result) + { + *resultSize = base->PKBSZ; + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize); + } + } + + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_ModSub1(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *B, + uint16_t sizeB, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize) +{ + ltc_pkha_mode_params_t params; + status_t status; + + if (LTC_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0) + { + return (kStatus_InvalidArgument); + } + + if (LTC_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0) + { + return (kStatus_InvalidArgument); + } + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithModSub1; + ltc_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0); + + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the result and size from register B0. */ + if (resultSize && result) + { + *resultSize = base->PKBSZ; + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize); + } + } + + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_ModSub2(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *B, + uint16_t sizeB, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize) +{ + ltc_pkha_mode_params_t params; + status_t status; + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithModSub2; + + ltc_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0); + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the result and size from register B0. */ + if (resultSize && result) + { + *resultSize = base->PKBSZ; + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize); + } + } + + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_ModMul(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *B, + uint16_t sizeB, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType, + ltc_pkha_montgomery_form_t montIn, + ltc_pkha_montgomery_form_t montOut, + ltc_pkha_timing_t equalTime) +{ + status_t status; + + status = + ltc_pkha_modmul(base, A, sizeA, B, sizeB, N, sizeN, result, resultSize, arithType, montIn, montOut, equalTime); + + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_ModExp(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *N, + uint16_t sizeN, + const uint8_t *E, + uint16_t sizeE, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType, + ltc_pkha_montgomery_form_t montIn, + ltc_pkha_timing_t equalTime) +{ + ltc_pkha_mode_params_t params; + status_t status; + + if (arithType == kLTC_PKHA_IntegerArith) + { + if (LTC_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0) + { + return (kStatus_InvalidArgument); + } + } + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithModExp; + params.arithType = arithType; + params.montFormIn = montIn; + params.equalTime = equalTime; + + ltc_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, E, sizeE); + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the result and size from register B0. */ + if (resultSize && result) + { + *resultSize = base->PKBSZ; + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize); + } + } + + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_ModRed(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType) +{ + ltc_pkha_mode_params_t params; + status_t status; + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithModRed; + params.arithType = arithType; + + ltc_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0); + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the result and size from register B0. */ + if (resultSize && result) + { + *resultSize = base->PKBSZ; + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize); + } + } + + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_ModInv(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType) +{ + ltc_pkha_mode_params_t params; + status_t status; + + /* A must be less than N -> LTC_PKHA_CompareBigNum() must return -1 */ + if (arithType == kLTC_PKHA_IntegerArith) + { + if (LTC_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0) + { + return (kStatus_InvalidArgument); + } + } + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithModInv; + params.arithType = arithType; + + ltc_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0); + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the result and size from register B0. */ + if (resultSize && result) + { + *resultSize = base->PKBSZ; + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize); + } + } + + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_ModR2( + LTC_Type *base, const uint8_t *N, uint16_t sizeN, uint8_t *result, uint16_t *resultSize, ltc_pkha_f2m_t arithType) +{ + status_t status; + status = ltc_pkha_modR2(base, N, sizeN, result, resultSize, arithType); + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_GCD(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType) +{ + ltc_pkha_mode_params_t params; + status_t status; + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithGcd; + params.arithType = arithType; + + ltc_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0); + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the result and size from register B0. */ + if (resultSize && result) + { + *resultSize = base->PKBSZ; + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize); + } + } + + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_PrimalityTest(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *B, + uint16_t sizeB, + const uint8_t *N, + uint16_t sizeN, + bool *res) +{ + uint8_t result; + ltc_pkha_mode_params_t params; + status_t status; + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithPrimalityTest; + ltc_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0); + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, &result, 1); + + *res = (bool)result; + } + + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_ECC_PointAdd(LTC_Type *base, + const ltc_pkha_ecc_point_t *A, + const ltc_pkha_ecc_point_t *B, + const uint8_t *N, + const uint8_t *R2modN, + const uint8_t *aCurveParam, + const uint8_t *bCurveParam, + uint8_t size, + ltc_pkha_f2m_t arithType, + ltc_pkha_ecc_point_t *result) +{ + ltc_pkha_mode_params_t params; + uint32_t clearMask; + status_t status; + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithEccAdd; + params.arithType = arithType; + params.r2modn = R2modN ? kLTC_PKHA_InputR2 : kLTC_PKHA_CalcR2; + + clearMask = kLTC_ClearMode; + + /* Clear internal register states. */ + clearMask |= kLTC_ClearPkhaSizeA; + clearMask |= kLTC_ClearPkhaSizeB; + clearMask |= kLTC_ClearPkhaSizeN; + clearMask |= kLTC_ClearPkhaSizeE; + + base->CW = clearMask; + base->STA = kLTC_StatusDoneIsr; + ltc_pkha_clear_regabne(base, true, true, true, false); + + /* sizeN should be less than 64 bytes. */ + base->PKNSZ = size; + ltc_pkha_write_reg(base, kLTC_PKHA_RegN, 0, N, size); + + base->PKASZ = size; + ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 0, A->X, size); + ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 1, A->Y, size); + ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 3, aCurveParam, size); + + base->PKBSZ = size; + ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 0, bCurveParam, size); + ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 1, B->X, size); + ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 2, B->Y, size); + if (R2modN) + { + ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 3, R2modN, size); + } + + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 1, result->X, size); + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 2, result->Y, size); + } + + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_ECC_PointDouble(LTC_Type *base, + const ltc_pkha_ecc_point_t *B, + const uint8_t *N, + const uint8_t *aCurveParam, + const uint8_t *bCurveParam, + uint8_t size, + ltc_pkha_f2m_t arithType, + ltc_pkha_ecc_point_t *result) +{ + ltc_pkha_mode_params_t params; + uint32_t clearMask; + status_t status; + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithEccDouble; + params.arithType = arithType; + + clearMask = kLTC_ClearMode; + + /* Clear internal register states. */ + clearMask |= kLTC_ClearPkhaSizeA; + clearMask |= kLTC_ClearPkhaSizeB; + clearMask |= kLTC_ClearPkhaSizeN; + clearMask |= kLTC_ClearPkhaSizeE; + + base->CW = clearMask; + base->STA = kLTC_StatusDoneIsr; + ltc_pkha_clear_regabne(base, true, true, true, false); + + /* sizeN should be less than 64 bytes. */ + base->PKNSZ = size; + ltc_pkha_write_reg(base, kLTC_PKHA_RegN, 0, N, size); + + base->PKASZ = size; + ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 3, aCurveParam, size); + + base->PKBSZ = size; + ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 0, bCurveParam, size); + ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 1, B->X, size); + ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 2, B->Y, size); + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 1, result->X, size); + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 2, result->Y, size); + } + + ltc_clear_all(base, true); + return status; +} + +status_t LTC_PKHA_ECC_PointMul(LTC_Type *base, + const ltc_pkha_ecc_point_t *A, + const uint8_t *E, + uint8_t sizeE, + const uint8_t *N, + const uint8_t *R2modN, + const uint8_t *aCurveParam, + const uint8_t *bCurveParam, + uint8_t size, + ltc_pkha_timing_t equalTime, + ltc_pkha_f2m_t arithType, + ltc_pkha_ecc_point_t *result, + bool *infinity) +{ + ltc_pkha_mode_params_t params; + uint32_t clearMask; + status_t status; + + ltc_pkha_default_parms(¶ms); + params.func = kLTC_PKHA_ArithEccMul; + params.equalTime = equalTime; + params.arithType = arithType; + params.r2modn = R2modN ? kLTC_PKHA_InputR2 : kLTC_PKHA_CalcR2; + + clearMask = kLTC_ClearMode; + + /* Clear internal register states. */ + clearMask |= kLTC_ClearPkhaSizeA; + clearMask |= kLTC_ClearPkhaSizeB; + clearMask |= kLTC_ClearPkhaSizeN; + clearMask |= kLTC_ClearPkhaSizeE; + + base->CW = clearMask; + base->STA = kLTC_StatusDoneIsr; + ltc_pkha_clear_regabne(base, true, true, true, true); + + /* sizeN should be less than 64 bytes. */ + base->PKNSZ = size; + ltc_pkha_write_reg(base, kLTC_PKHA_RegN, 0, N, size); + + base->PKESZ = sizeE; + ltc_pkha_write_reg(base, kLTC_PKHA_RegE, 0, E, sizeE); + + base->PKASZ = size; + ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 0, A->X, size); + ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 1, A->Y, size); + ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 3, aCurveParam, size); + + base->PKBSZ = size; + ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 0, bCurveParam, size); + if (R2modN) + { + ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 1, R2modN, size); + } + + status = ltc_pkha_init_mode(base, ¶ms); + + if (status == kStatus_Success) + { + /* Read the data from the result register into place. */ + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 1, result->X, size); + ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 2, result->Y, size); + + if (infinity) + { + *infinity = (bool)(base->STA & kLTC_StatusPublicKeyOpZero); + } + } + + ltc_clear_all(base, true); + return status; +} + +#endif /* FSL_FEATURE_LTC_HAS_PKHA */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc.h new file mode 100644 index 00000000000..3019b510488 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc.h @@ -0,0 +1,1578 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_LTC_H_ +#define _FSL_LTC_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! + * @addtogroup ltc + * @{ + */ +/*! @name Driver version */ +/*@{*/ +/*! @brief LTC driver version. Version 2.0.2. + * + * Current version: 2.0.2 + * + * Change log: + * - Version 2.0.1 + * - fixed warning during g++ compilation + * + * - Version 2.0.2 + * - fixed [KPSDK-10932][LTC][SHA] LTC_HASH() blocks indefinitely when message size exceeds 4080 bytes + */ +#define FSL_LTC_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) +/*@}*/ +/*! @} */ + +/******************************************************************************* + * AES Definitions + *******************************************************************************/ +/*! + * @addtogroup ltc_driver_aes + * @{ + */ +/*! AES block size in bytes */ +#define LTC_AES_BLOCK_SIZE 16 +/*! AES Input Vector size in bytes */ +#define LTC_AES_IV_SIZE 16 + +/*! @brief Type of AES key for ECB and CBC decrypt operations. */ +typedef enum _ltc_aes_key_t +{ + kLTC_EncryptKey = 0U, /*!< Input key is an encrypt key */ + kLTC_DecryptKey = 1U, /*!< Input key is a decrypt key */ +} ltc_aes_key_t; + +/*! + *@} + */ + +/******************************************************************************* + * DES Definitions + *******************************************************************************/ +/*! + * @addtogroup ltc_driver_des + * @{ + */ + +/*! @brief LTC DES key size - 64 bits. */ +#define LTC_DES_KEY_SIZE 8 + +/*! @brief LTC DES IV size - 8 bytes */ +#define LTC_DES_IV_SIZE 8 + +/*! + *@} + */ + +/******************************************************************************* + * HASH Definitions + ******************************************************************************/ +/*! + * @addtogroup ltc_driver_hash + * @{ + */ +/*! Supported cryptographic block cipher functions for HASH creation */ +typedef enum _ltc_hash_algo_t +{ + kLTC_XcbcMac = 0, /*!< XCBC-MAC (AES engine) */ + kLTC_Cmac, /*!< CMAC (AES engine) */ +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + kLTC_Sha1, /*!< SHA_1 (MDHA engine) */ + kLTC_Sha224, /*!< SHA_224 (MDHA engine) */ + kLTC_Sha256, /*!< SHA_256 (MDHA engine) */ +#endif /* FSL_FEATURE_LTC_HAS_SHA */ +} ltc_hash_algo_t; + +/*! @brief LTC HASH Context size. */ +#if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA +#define LTC_HASH_CTX_SIZE 41 +#else +#define LTC_HASH_CTX_SIZE 29 +#endif /* FSL_FEATURE_LTC_HAS_SHA */ + +/*! @brief Storage type used to save hash context. */ +typedef uint32_t ltc_hash_ctx_t[LTC_HASH_CTX_SIZE]; + +/*! + *@} + */ +/******************************************************************************* + * PKHA Definitions + ******************************************************************************/ +/*! + * @addtogroup ltc_driver_pkha + * @{ + */ +/*! PKHA ECC point structure */ +typedef struct _ltc_pkha_ecc_point_t +{ + uint8_t *X; /*!< X coordinate (affine) */ + uint8_t *Y; /*!< Y coordinate (affine) */ +} ltc_pkha_ecc_point_t; + +/*! @brief Use of timing equalized version of a PKHA function. */ +typedef enum _ltc_pkha_timing_t +{ + kLTC_PKHA_NoTimingEqualized = 0U, /*!< Normal version of a PKHA operation */ + kLTC_PKHA_TimingEqualized = 1U /*!< Timing-equalized version of a PKHA operation */ +} ltc_pkha_timing_t; + +/*! @brief Integer vs binary polynomial arithmetic selection. */ +typedef enum _ltc_pkha_f2m_t +{ + kLTC_PKHA_IntegerArith = 0U, /*!< Use integer arithmetic */ + kLTC_PKHA_F2mArith = 1U /*!< Use binary polynomial arithmetic */ +} ltc_pkha_f2m_t; + +/*! @brief Montgomery or normal PKHA input format. */ +typedef enum _ltc_pkha_montgomery_form_t +{ + kLTC_PKHA_NormalValue = 0U, /*!< PKHA number is normal integer */ + kLTC_PKHA_MontgomeryFormat = 1U /*!< PKHA number is in montgomery format */ +} ltc_pkha_montgomery_form_t; + +/*! + *@} + */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @addtogroup ltc + * @{ + */ + +/*! + * @brief Initializes the LTC driver. + * This function initializes the LTC driver. + * @param base LTC peripheral base address + */ +void LTC_Init(LTC_Type *base); + +/*! + * @brief Deinitializes the LTC driver. + * This function deinitializes the LTC driver. + * @param base LTC peripheral base address + */ +void LTC_Deinit(LTC_Type *base); + +#if defined(FSL_FEATURE_LTC_HAS_DPAMS) && FSL_FEATURE_LTC_HAS_DPAMS +/*! + * @brief Sets the DPA Mask Seed register. + * + * The DPA Mask Seed register reseeds the mask that provides resistance against DPA (differential power analysis) + * attacks on AES or DES keys. + * + * Differential Power Analysis Mask (DPA) resistance uses a randomly changing mask that introduces + * "noise" into the power consumed by the AES or DES. This reduces the signal-to-noise ratio that differential + * power analysis attacks use to "guess" bits of the key. This randomly changing mask should be + * seeded at POR, and continues to provide DPA resistance from that point on. However, to provide even more + * DPA protection it is recommended that the DPA mask be reseeded after every 50,000 blocks have + * been processed. At that time, software can opt to write a new seed (preferably obtained from an RNG) + * into the DPA Mask Seed register (DPAMS), or software can opt to provide the new seed earlier or + * later, or not at all. DPA resistance continues even if the DPA mask is never reseeded. + * + * @param base LTC peripheral base address + * @param mask The DPA mask seed. + */ +void LTC_SetDpaMaskSeed(LTC_Type *base, uint32_t mask); +#endif /* FSL_FEATURE_LTC_HAS_DPAMS */ + +/*! + *@} + */ + +/******************************************************************************* + * AES API + ******************************************************************************/ + +/*! + * @addtogroup ltc_driver_aes + * @{ + */ + +/*! + * @brief Transforms an AES encrypt key (forward AES) into the decrypt key (inverse AES). + * + * Transforms the AES encrypt key (forward AES) into the decrypt key (inverse AES). + * The key derived by this function can be used as a direct load decrypt key + * for AES ECB and CBC decryption operations (keyType argument). + * + * @param base LTC peripheral base address + * @param encryptKey Input key for decrypt key transformation + * @param[out] decryptKey Output key, the decrypt form of the AES key. + * @param keySize Size of the input key and output key in bytes. Must be 16, 24, or 32. + * @return Status from key generation operation + */ +status_t LTC_AES_GenerateDecryptKey(LTC_Type *base, const uint8_t *encryptKey, uint8_t *decryptKey, uint32_t keySize); + +/*! + * @brief Encrypts AES using the ECB block mode. + * + * Encrypts AES using the ECB block mode. + * + * @param base LTC peripheral base address + * @param plaintext Input plain text to encrypt + * @param[out] ciphertext Output cipher text + * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. + * @param key Input key to use for encryption + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @return Status from encrypt operation + */ +status_t LTC_AES_EncryptEcb( + LTC_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, uint32_t size, const uint8_t *key, uint32_t keySize); + +/*! + * @brief Decrypts AES using ECB block mode. + * + * Decrypts AES using ECB block mode. + * + * @param base LTC peripheral base address + * @param ciphertext Input cipher text to decrypt + * @param[out] plaintext Output plain text + * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. + * @param key Input key. + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @param keyType Input type of the key (allows to directly load decrypt key for AES ECB decrypt operation.) + * @return Status from decrypt operation + */ +status_t LTC_AES_DecryptEcb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t *key, + uint32_t keySize, + ltc_aes_key_t keyType); + +/*! + * @brief Encrypts AES using CBC block mode. + * + * @param base LTC peripheral base address + * @param plaintext Input plain text to encrypt + * @param[out] ciphertext Output cipher text + * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. + * @param iv Input initial vector to combine with the first input block. + * @param key Input key to use for encryption + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @return Status from encrypt operation + */ +status_t LTC_AES_EncryptCbc(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_AES_IV_SIZE], + const uint8_t *key, + uint32_t keySize); + +/*! + * @brief Decrypts AES using CBC block mode. + * + * @param base LTC peripheral base address + * @param ciphertext Input cipher text to decrypt + * @param[out] plaintext Output plain text + * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. + * @param iv Input initial vector to combine with the first input block. + * @param key Input key to use for decryption + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @param keyType Input type of the key (allows to directly load decrypt key for AES CBC decrypt operation.) + * @return Status from decrypt operation + */ +status_t LTC_AES_DecryptCbc(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_AES_IV_SIZE], + const uint8_t *key, + uint32_t keySize, + ltc_aes_key_t keyType); + +/*! + * @brief Encrypts or decrypts AES using CTR block mode. + * + * Encrypts or decrypts AES using CTR block mode. + * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption. + * The only difference between encryption and decryption is that, for encryption, the input argument + * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text + * and the output argument is plain text. + * + * @param base LTC peripheral base address + * @param input Input data for CTR block mode + * @param[out] output Output data for CTR block mode + * @param size Size of input and output data in bytes + * @param[in,out] counter Input counter (updates on return) + * @param key Input key to use for forward AES cipher + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @param[out] counterlast Output cipher of last counter, for chained CTR calls. NULL can be passed if chained calls are + * not used. + * @param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls + * are not used. + * @return Status from encrypt operation + */ +status_t LTC_AES_CryptCtr(LTC_Type *base, + const uint8_t *input, + uint8_t *output, + uint32_t size, + uint8_t counter[LTC_AES_BLOCK_SIZE], + const uint8_t *key, + uint32_t keySize, + uint8_t counterlast[LTC_AES_BLOCK_SIZE], + uint32_t *szLeft); + +/*! AES CTR decrypt is mapped to the AES CTR generic operation */ +#define LTC_AES_DecryptCtr(base, input, output, size, counter, key, keySize, counterlast, szLeft) \ + LTC_AES_CryptCtr(base, input, output, size, counter, key, keySize, counterlast, szLeft) + +/*! AES CTR encrypt is mapped to the AES CTR generic operation */ +#define LTC_AES_EncryptCtr(base, input, output, size, counter, key, keySize, counterlast, szLeft) \ + LTC_AES_CryptCtr(base, input, output, size, counter, key, keySize, counterlast, szLeft) + +#if defined(FSL_FEATURE_LTC_HAS_GCM) && FSL_FEATURE_LTC_HAS_GCM +/*! + * @brief Encrypts AES and tags using GCM block mode. + * + * Encrypts AES and optionally tags using GCM block mode. If plaintext is NULL, only the GHASH is calculated and output + * in the 'tag' field. + * + * @param base LTC peripheral base address + * @param plaintext Input plain text to encrypt + * @param[out] ciphertext Output cipher text. + * @param size Size of input and output data in bytes + * @param iv Input initial vector + * @param ivSize Size of the IV + * @param aad Input additional authentication data + * @param aadSize Input size in bytes of AAD + * @param key Input key to use for encryption + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @param[out] tag Output hash tag. Set to NULL to skip tag processing. + * @param tagSize Input size of the tag to generate, in bytes. Must be 4,8,12,13,14,15 or 16. + * @return Status from encrypt operation + */ +status_t LTC_AES_EncryptTagGcm(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t *iv, + uint32_t ivSize, + const uint8_t *aad, + uint32_t aadSize, + const uint8_t *key, + uint32_t keySize, + uint8_t *tag, + uint32_t tagSize); + +/*! + * @brief Decrypts AES and authenticates using GCM block mode. + * + * Decrypts AES and optionally authenticates using GCM block mode. If ciphertext is NULL, only the GHASH is calculated + * and compared with the received GHASH in 'tag' field. + * + * @param base LTC peripheral base address + * @param ciphertext Input cipher text to decrypt + * @param[out] plaintext Output plain text. + * @param size Size of input and output data in bytes + * @param iv Input initial vector + * @param ivSize Size of the IV + * @param aad Input additional authentication data + * @param aadSize Input size in bytes of AAD + * @param key Input key to use for encryption + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @param tag Input hash tag to compare. Set to NULL to skip tag processing. + * @param tagSize Input size of the tag, in bytes. Must be 4, 8, 12, 13, 14, 15, or 16. + * @return Status from decrypt operation + */ +status_t LTC_AES_DecryptTagGcm(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t *iv, + uint32_t ivSize, + const uint8_t *aad, + uint32_t aadSize, + const uint8_t *key, + uint32_t keySize, + const uint8_t *tag, + uint32_t tagSize); +#endif /* FSL_FEATURE_LTC_HAS_GCM */ + +/*! + * @brief Encrypts AES and tags using CCM block mode. + * + * Encrypts AES and optionally tags using CCM block mode. + * + * @param base LTC peripheral base address + * @param plaintext Input plain text to encrypt + * @param[out] ciphertext Output cipher text. + * @param size Size of input and output data in bytes. Zero means authentication only. + * @param iv Nonce + * @param ivSize Length of the Nonce in bytes. Must be 7, 8, 9, 10, 11, 12, or 13. + * @param aad Input additional authentication data. Can be NULL if aadSize is zero. + * @param aadSize Input size in bytes of AAD. Zero means data mode only (authentication skipped). + * @param key Input key to use for encryption + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @param[out] tag Generated output tag. Set to NULL to skip tag processing. + * @param tagSize Input size of the tag to generate, in bytes. Must be 4, 6, 8, 10, 12, 14, or 16. + * @return Status from encrypt operation + */ +status_t LTC_AES_EncryptTagCcm(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t *iv, + uint32_t ivSize, + const uint8_t *aad, + uint32_t aadSize, + const uint8_t *key, + uint32_t keySize, + uint8_t *tag, + uint32_t tagSize); + +/*! + * @brief Decrypts AES and authenticates using CCM block mode. + * + * Decrypts AES and optionally authenticates using CCM block mode. + * + * @param base LTC peripheral base address + * @param ciphertext Input cipher text to decrypt + * @param[out] plaintext Output plain text. + * @param size Size of input and output data in bytes. Zero means authentication only. + * @param iv Nonce + * @param ivSize Length of the Nonce in bytes. Must be 7, 8, 9, 10, 11, 12, or 13. + * @param aad Input additional authentication data. Can be NULL if aadSize is zero. + * @param aadSize Input size in bytes of AAD. Zero means data mode only (authentication skipped). + * @param key Input key to use for decryption + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @param tag Received tag. Set to NULL to skip tag processing. + * @param tagSize Input size of the received tag to compare with the computed tag, in bytes. Must be 4, 6, 8, 10, 12, + * 14, or 16. + * @return Status from decrypt operation + */ +status_t LTC_AES_DecryptTagCcm(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t *iv, + uint32_t ivSize, + const uint8_t *aad, + uint32_t aadSize, + const uint8_t *key, + uint32_t keySize, + const uint8_t *tag, + uint32_t tagSize); + +/*! + *@} + */ + +/******************************************************************************* + * DES API + ******************************************************************************/ +/*! + * @addtogroup ltc_driver_des + * @{ + */ +/*! + * @brief Encrypts DES using ECB block mode. + * + * Encrypts DES using ECB block mode. + * + * @param base LTC peripheral base address + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param key Input key to use for encryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_EncryptEcb( + LTC_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, uint32_t size, const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts DES using ECB block mode. + * + * Decrypts DES using ECB block mode. + * + * @param base LTC peripheral base address + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param key Input key to use for decryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_DecryptEcb( + LTC_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, uint32_t size, const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts DES using CBC block mode. + * + * Encrypts DES using CBC block mode. + * + * @param base LTC peripheral base address + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Ouput ciphertext + * @param size Size of input and output data in bytes + * @param iv Input initial vector to combine with the first plaintext block. + * The iv does not need to be secret, but it must be unpredictable. + * @param key Input key to use for encryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_EncryptCbc(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts DES using CBC block mode. + * + * Decrypts DES using CBC block mode. + * + * @param base LTC peripheral base address + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input data in bytes + * @param iv Input initial vector to combine with the first plaintext block. + * The iv does not need to be secret, but it must be unpredictable. + * @param key Input key to use for decryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_DecryptCbc(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts DES using CFB block mode. + * + * Encrypts DES using CFB block mode. + * + * @param base LTC peripheral base address + * @param plaintext Input plaintext to encrypt + * @param size Size of input data in bytes + * @param iv Input initial block. + * @param key Input key to use for encryption + * @param[out] ciphertext Output ciphertext + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_EncryptCfb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts DES using CFB block mode. + * + * Decrypts DES using CFB block mode. + * + * @param base LTC peripheral base address + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes + * @param iv Input initial block. + * @param key Input key to use for decryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_DecryptCfb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts DES using OFB block mode. + * + * Encrypts DES using OFB block mode. + * + * @param base LTC peripheral base address + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes + * @param iv Input unique input vector. The OFB mode requires that the IV be unique + * for each execution of the mode under the given key. + * @param key Input key to use for encryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_EncryptOfb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts DES using OFB block mode. + * + * Decrypts DES using OFB block mode. + * + * @param base LTC peripheral base address + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param iv Input unique input vector. The OFB mode requires that the IV be unique + * for each execution of the mode under the given key. + * @param key Input key to use for decryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_DecryptOfb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using ECB block mode with two keys. + * + * Encrypts triple DES using ECB block mode with two keys. + * + * @param base LTC peripheral base address + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_EncryptEcb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using ECB block mode with two keys. + * + * Decrypts triple DES using ECB block mode with two keys. + * + * @param base LTC peripheral base address + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_DecryptEcb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using CBC block mode with two keys. + * + * Encrypts triple DES using CBC block mode with two keys. + * + * @param base LTC peripheral base address + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes + * @param iv Input initial vector to combine with the first plaintext block. + * The iv does not need to be secret, but it must be unpredictable. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_EncryptCbc(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using CBC block mode with two keys. + * + * Decrypts triple DES using CBC block mode with two keys. + * + * @param base LTC peripheral base address + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes + * @param iv Input initial vector to combine with the first plaintext block. + * The iv does not need to be secret, but it must be unpredictable. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_DecryptCbc(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using CFB block mode with two keys. + * + * Encrypts triple DES using CFB block mode with two keys. + * + * @param base LTC peripheral base address + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes + * @param iv Input initial block. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_EncryptCfb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using CFB block mode with two keys. + * + * Decrypts triple DES using CFB block mode with two keys. + * + * @param base LTC peripheral base address + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes + * @param iv Input initial block. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_DecryptCfb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using OFB block mode with two keys. + * + * Encrypts triple DES using OFB block mode with two keys. + * + * @param base LTC peripheral base address + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes + * @param iv Input unique input vector. The OFB mode requires that the IV be unique + * for each execution of the mode under the given key. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_EncryptOfb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using OFB block mode with two keys. + * + * Decrypts triple DES using OFB block mode with two keys. + * + * @param base LTC peripheral base address + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes + * @param iv Input unique input vector. The OFB mode requires that the IV be unique + * for each execution of the mode under the given key. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_DecryptOfb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using ECB block mode with three keys. + * + * Encrypts triple DES using ECB block mode with three keys. + * + * @param base LTC peripheral base address + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_EncryptEcb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using ECB block mode with three keys. + * + * Decrypts triple DES using ECB block mode with three keys. + * + * @param base LTC peripheral base address + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_DecryptEcb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using CBC block mode with three keys. + * + * Encrypts triple DES using CBC block mode with three keys. + * + * @param base LTC peripheral base address + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input data in bytes + * @param iv Input initial vector to combine with the first plaintext block. + * The iv does not need to be secret, but it must be unpredictable. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_EncryptCbc(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using CBC block mode with three keys. + * + * Decrypts triple DES using CBC block mode with three keys. + * + * @param base LTC peripheral base address + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes + * @param iv Input initial vector to combine with the first plaintext block. + * The iv does not need to be secret, but it must be unpredictable. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_DecryptCbc(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using CFB block mode with three keys. + * + * Encrypts triple DES using CFB block mode with three keys. + * + * @param base LTC peripheral base address + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and ouput data in bytes + * @param iv Input initial block. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_EncryptCfb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using CFB block mode with three keys. + * + * Decrypts triple DES using CFB block mode with three keys. + * + * @param base LTC peripheral base address + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input data in bytes + * @param iv Input initial block. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_DecryptCfb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using OFB block mode with three keys. + * + * Encrypts triple DES using OFB block mode with three keys. + * + * @param base LTC peripheral base address + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes + * @param iv Input unique input vector. The OFB mode requires that the IV be unique + * for each execution of the mode under the given key. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_EncryptOfb(LTC_Type *base, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using OFB block mode with three keys. + * + * Decrypts triple DES using OFB block mode with three keys. + * + * @param base LTC peripheral base address + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes + * @param iv Input unique input vector. The OFB mode requires that the IV be unique + * for each execution of the mode under the given key. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_DecryptOfb(LTC_Type *base, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + *@} + */ + +/******************************************************************************* + * HASH API + ******************************************************************************/ + +/*! + * @addtogroup ltc_driver_hash + * @{ + */ +/*! + * @brief Initialize HASH context + * + * This function initialize the HASH. + * Key shall be supplied if the underlaying algoritm is AES XCBC-MAC or CMAC. + * Key shall be NULL if the underlaying algoritm is SHA. + * + * For XCBC-MAC, the key length must be 16. For CMAC, the key length can be + * the AES key lengths supported by AES engine. For MDHA the key length argument + * is ignored. + * + * @param base LTC peripheral base address + * @param[out] ctx Output hash context + * @param algo Underlaying algorithm to use for hash computation. + * @param key Input key (NULL if underlaying algorithm is SHA) + * @param keySize Size of input key in bytes + * @return Status of initialization + */ +status_t LTC_HASH_Init(LTC_Type *base, ltc_hash_ctx_t *ctx, ltc_hash_algo_t algo, const uint8_t *key, uint32_t keySize); + +/*! + * @brief Add data to current HASH + * + * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be + * hashed. + * + * @param[in,out] ctx HASH context + * @param input Input data + * @param inputSize Size of input data in bytes + * @return Status of the hash update operation + */ +status_t LTC_HASH_Update(ltc_hash_ctx_t *ctx, const uint8_t *input, uint32_t inputSize); + +/*! + * @brief Finalize hashing + * + * Outputs the final hash and erases the context. + * + * @param[in,out] ctx Input hash context + * @param[out] output Output hash data + * @param[out] outputSize Output parameter storing the size of the output hash in bytes + * @return Status of the hash finish operation + */ +status_t LTC_HASH_Finish(ltc_hash_ctx_t *ctx, uint8_t *output, uint32_t *outputSize); + +/*! + * @brief Create HASH on given data + * + * Perform the full keyed HASH in one function call. + * + * @param base LTC peripheral base address + * @param algo Block cipher algorithm to use for CMAC creation + * @param input Input data + * @param inputSize Size of input data in bytes + * @param key Input key + * @param keySize Size of input key in bytes + * @param[out] output Output hash data + * @param[out] outputSize Output parameter storing the size of the output hash in bytes + * @return Status of the one call hash operation. + */ +status_t LTC_HASH(LTC_Type *base, + ltc_hash_algo_t algo, + const uint8_t *input, + uint32_t inputSize, + const uint8_t *key, + uint32_t keySize, + uint8_t *output, + uint32_t *outputSize); +/*! + *@} + */ + +/******************************************************************************* + * PKHA API + ******************************************************************************/ +/*! + * @addtogroup ltc_driver_pkha + * @{ + */ + +/*! + * @brief Compare two PKHA big numbers. + * + * Compare two PKHA big numbers. Return 1 for a > b, -1 for a < b and 0 if they are same. + * PKHA big number is lsbyte first. Thus the comparison starts at msbyte which is the last member of tested arrays. + * + * @param a First integer represented as an array of bytes, lsbyte first. + * @param sizeA Size in bytes of the first integer. + * @param b Second integer represented as an array of bytes, lsbyte first. + * @param sizeB Size in bytes of the second integer. + * @return 1 if a > b. + * @return -1 if a < b. + * @return 0 if a = b. + */ +int LTC_PKHA_CompareBigNum(const uint8_t *a, size_t sizeA, const uint8_t *b, size_t sizeB); + +/*! + * @brief Converts from integer to Montgomery format. + * + * This function computes R2 mod N and optionally converts A or B into Montgomery format of A or B. + * + * @param base LTC peripheral base address + * @param N modulus + * @param sizeN size of N in bytes + * @param[in,out] A The first input in non-Montgomery format. Output Montgomery format of the first input. + * @param[in,out] sizeA pointer to size variable. On input it holds size of input A in bytes. On output it holds size of + * Montgomery format of A in bytes. + * @param[in,out] B Second input in non-Montgomery format. Output Montgomery format of the second input. + * @param[in,out] sizeB pointer to size variable. On input it holds size of input B in bytes. On output it holds size of + * Montgomery format of B in bytes. + * @param[out] R2 Output Montgomery factor R2 mod N. + * @param[out] sizeR2 pointer to size variable. On output it holds size of Montgomery factor R2 mod N in bytes. + * @param equalTime Run the function time equalized or no timing equalization. + * @param arithType Type of arithmetic to perform (integer or F2m) + * @return Operation status. + */ +status_t LTC_PKHA_NormalToMontgomery(LTC_Type *base, + const uint8_t *N, + uint16_t sizeN, + uint8_t *A, + uint16_t *sizeA, + uint8_t *B, + uint16_t *sizeB, + uint8_t *R2, + uint16_t *sizeR2, + ltc_pkha_timing_t equalTime, + ltc_pkha_f2m_t arithType); + +/*! + * @brief Converts from Montgomery format to int. + * + * This function converts Montgomery format of A or B into int A or B. + * + * @param base LTC peripheral base address + * @param N modulus. + * @param sizeN size of N modulus in bytes. + * @param[in,out] A Input first number in Montgomery format. Output is non-Montgomery format. + * @param[in,out] sizeA pointer to size variable. On input it holds size of the input A in bytes. On output it holds + * size of non-Montgomery A in bytes. + * @param[in,out] B Input first number in Montgomery format. Output is non-Montgomery format. + * @param[in,out] sizeB pointer to size variable. On input it holds size of the input B in bytes. On output it holds + * size of non-Montgomery B in bytes. + * @param equalTime Run the function time equalized or no timing equalization. + * @param arithType Type of arithmetic to perform (integer or F2m) + * @return Operation status. + */ +status_t LTC_PKHA_MontgomeryToNormal(LTC_Type *base, + const uint8_t *N, + uint16_t sizeN, + uint8_t *A, + uint16_t *sizeA, + uint8_t *B, + uint16_t *sizeB, + ltc_pkha_timing_t equalTime, + ltc_pkha_f2m_t arithType); + +/*! + * @brief Performs modular addition - (A + B) mod N. + * + * This function performs modular addition of (A + B) mod N, with either + * integer or binary polynomial (F2m) inputs. In the F2m form, this function is + * equivalent to a bitwise XOR and it is functionally the same as subtraction. + * + * @param base LTC peripheral base address + * @param A first addend (integer or binary polynomial) + * @param sizeA Size of A in bytes + * @param B second addend (integer or binary polynomial) + * @param sizeB Size of B in bytes + * @param N modulus. For F2m operation this can be NULL, as N is ignored during F2m polynomial addition. + * @param sizeN Size of N in bytes. This must be given for both integer and F2m polynomial additions. + * @param[out] result Output array to store result of operation + * @param[out] resultSize Output size of operation in bytes + * @param arithType Type of arithmetic to perform (integer or F2m) + * @return Operation status. + */ +status_t LTC_PKHA_ModAdd(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *B, + uint16_t sizeB, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType); + +/*! + * @brief Performs modular subtraction - (A - B) mod N. + * + * This function performs modular subtraction of (A - B) mod N with + * integer inputs. + * + * @param base LTC peripheral base address + * @param A first addend (integer or binary polynomial) + * @param sizeA Size of A in bytes + * @param B second addend (integer or binary polynomial) + * @param sizeB Size of B in bytes + * @param N modulus + * @param sizeN Size of N in bytes + * @param[out] result Output array to store result of operation + * @param[out] resultSize Output size of operation in bytes + * @return Operation status. + */ +status_t LTC_PKHA_ModSub1(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *B, + uint16_t sizeB, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize); + +/*! + * @brief Performs modular subtraction - (B - A) mod N. + * + * This function performs modular subtraction of (B - A) mod N, + * with integer inputs. + * + * @param base LTC peripheral base address + * @param A first addend (integer or binary polynomial) + * @param sizeA Size of A in bytes + * @param B second addend (integer or binary polynomial) + * @param sizeB Size of B in bytes + * @param N modulus + * @param sizeN Size of N in bytes + * @param[out] result Output array to store result of operation + * @param[out] resultSize Output size of operation in bytes + * @return Operation status. + */ +status_t LTC_PKHA_ModSub2(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *B, + uint16_t sizeB, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize); + +/*! + * @brief Performs modular multiplication - (A x B) mod N. + * + * This function performs modular multiplication with either integer or + * binary polynomial (F2m) inputs. It can optionally specify whether inputs + * and/or outputs will be in Montgomery form or not. + * + * @param base LTC peripheral base address + * @param A first addend (integer or binary polynomial) + * @param sizeA Size of A in bytes + * @param B second addend (integer or binary polynomial) + * @param sizeB Size of B in bytes + * @param N modulus. + * @param sizeN Size of N in bytes + * @param[out] result Output array to store result of operation + * @param[out] resultSize Output size of operation in bytes + * @param arithType Type of arithmetic to perform (integer or F2m) + * @param montIn Format of inputs + * @param montOut Format of output + * @param equalTime Run the function time equalized or no timing equalization. This argument is ignored for F2m modular + * multiplication. + * @return Operation status. + */ +status_t LTC_PKHA_ModMul(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *B, + uint16_t sizeB, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType, + ltc_pkha_montgomery_form_t montIn, + ltc_pkha_montgomery_form_t montOut, + ltc_pkha_timing_t equalTime); + +/*! + * @brief Performs modular exponentiation - (A^E) mod N. + * + * This function performs modular exponentiation with either integer or + * binary polynomial (F2m) inputs. + * + * @param base LTC peripheral base address + * @param A first addend (integer or binary polynomial) + * @param sizeA Size of A in bytes + * @param N modulus + * @param sizeN Size of N in bytes + * @param E exponent + * @param sizeE Size of E in bytes + * @param[out] result Output array to store result of operation + * @param[out] resultSize Output size of operation in bytes + * @param montIn Format of A input (normal or Montgomery) + * @param arithType Type of arithmetic to perform (integer or F2m) + * @param equalTime Run the function time equalized or no timing equalization. + * @return Operation status. + */ +status_t LTC_PKHA_ModExp(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *N, + uint16_t sizeN, + const uint8_t *E, + uint16_t sizeE, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType, + ltc_pkha_montgomery_form_t montIn, + ltc_pkha_timing_t equalTime); + +/*! + * @brief Performs modular reduction - (A) mod N. + * + * This function performs modular reduction with either integer or + * binary polynomial (F2m) inputs. + * + * @param base LTC peripheral base address + * @param A first addend (integer or binary polynomial) + * @param sizeA Size of A in bytes + * @param N modulus + * @param sizeN Size of N in bytes + * @param[out] result Output array to store result of operation + * @param[out] resultSize Output size of operation in bytes + * @param arithType Type of arithmetic to perform (integer or F2m) + * @return Operation status. + */ +status_t LTC_PKHA_ModRed(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType); + +/*! + * @brief Performs modular inversion - (A^-1) mod N. + * + * This function performs modular inversion with either integer or + * binary polynomial (F2m) inputs. + * + * @param base LTC peripheral base address + * @param A first addend (integer or binary polynomial) + * @param sizeA Size of A in bytes + * @param N modulus + * @param sizeN Size of N in bytes + * @param[out] result Output array to store result of operation + * @param[out] resultSize Output size of operation in bytes + * @param arithType Type of arithmetic to perform (integer or F2m) + * @return Operation status. + */ +status_t LTC_PKHA_ModInv(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType); + +/*! + * @brief Computes integer Montgomery factor R^2 mod N. + * + * This function computes a constant to assist in converting operands + * into the Montgomery residue system representation. + * + * @param base LTC peripheral base address + * @param N modulus + * @param sizeN Size of N in bytes + * @param[out] result Output array to store result of operation + * @param[out] resultSize Output size of operation in bytes + * @param arithType Type of arithmetic to perform (integer or F2m) + * @return Operation status. + */ +status_t LTC_PKHA_ModR2( + LTC_Type *base, const uint8_t *N, uint16_t sizeN, uint8_t *result, uint16_t *resultSize, ltc_pkha_f2m_t arithType); + +/*! + * @brief Calculates the greatest common divisor - GCD (A, N). + * + * This function calculates the greatest common divisor of two inputs with + * either integer or binary polynomial (F2m) inputs. + * + * @param base LTC peripheral base address + * @param A first value (must be smaller than or equal to N) + * @param sizeA Size of A in bytes + * @param N second value (must be non-zero) + * @param sizeN Size of N in bytes + * @param[out] result Output array to store result of operation + * @param[out] resultSize Output size of operation in bytes + * @param arithType Type of arithmetic to perform (integer or F2m) + * @return Operation status. + */ +status_t LTC_PKHA_GCD(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *N, + uint16_t sizeN, + uint8_t *result, + uint16_t *resultSize, + ltc_pkha_f2m_t arithType); + +/*! + * @brief Executes Miller-Rabin primality test. + * + * This function calculates whether or not a candidate prime number is likely + * to be a prime. + * + * @param base LTC peripheral base address + * @param A initial random seed + * @param sizeA Size of A in bytes + * @param B number of trial runs + * @param sizeB Size of B in bytes + * @param N candidate prime integer + * @param sizeN Size of N in bytes + * @param[out] res True if the value is likely prime or false otherwise + * @return Operation status. + */ +status_t LTC_PKHA_PrimalityTest(LTC_Type *base, + const uint8_t *A, + uint16_t sizeA, + const uint8_t *B, + uint16_t sizeB, + const uint8_t *N, + uint16_t sizeN, + bool *res); + +/*! + * @brief Adds elliptic curve points - A + B. + * + * This function performs ECC point addition over a prime field (Fp) or binary field (F2m) using + * affine coordinates. + * + * @param base LTC peripheral base address + * @param A Left-hand point + * @param B Right-hand point + * @param N Prime modulus of the field + * @param R2modN NULL (the function computes R2modN internally) or pointer to pre-computed R2modN (obtained from + * LTC_PKHA_ModR2() function). + * @param aCurveParam A parameter from curve equation + * @param bCurveParam B parameter from curve equation (constant) + * @param size Size in bytes of curve points and parameters + * @param arithType Type of arithmetic to perform (integer or F2m) + * @param[out] result Result point + * @return Operation status. + */ +status_t LTC_PKHA_ECC_PointAdd(LTC_Type *base, + const ltc_pkha_ecc_point_t *A, + const ltc_pkha_ecc_point_t *B, + const uint8_t *N, + const uint8_t *R2modN, + const uint8_t *aCurveParam, + const uint8_t *bCurveParam, + uint8_t size, + ltc_pkha_f2m_t arithType, + ltc_pkha_ecc_point_t *result); + +/*! + * @brief Doubles elliptic curve points - B + B. + * + * This function performs ECC point doubling over a prime field (Fp) or binary field (F2m) using + * affine coordinates. + * + * @param base LTC peripheral base address + * @param B Point to double + * @param N Prime modulus of the field + * @param aCurveParam A parameter from curve equation + * @param bCurveParam B parameter from curve equation (constant) + * @param size Size in bytes of curve points and parameters + * @param arithType Type of arithmetic to perform (integer or F2m) + * @param[out] result Result point + * @return Operation status. + */ +status_t LTC_PKHA_ECC_PointDouble(LTC_Type *base, + const ltc_pkha_ecc_point_t *B, + const uint8_t *N, + const uint8_t *aCurveParam, + const uint8_t *bCurveParam, + uint8_t size, + ltc_pkha_f2m_t arithType, + ltc_pkha_ecc_point_t *result); + +/*! + * @brief Multiplies an elliptic curve point by a scalar - E x (A0, A1). + * + * This function performs ECC point multiplication to multiply an ECC point by + * a scalar integer multiplier over a prime field (Fp) or a binary field (F2m). + * + * @param base LTC peripheral base address + * @param A Point as multiplicand + * @param E Scalar multiple + * @param sizeE The size of E, in bytes + * @param N Modulus, a prime number for the Fp field or Irreducible polynomial for F2m field. + * @param R2modN NULL (the function computes R2modN internally) or pointer to pre-computed R2modN (obtained from + * LTC_PKHA_ModR2() function). + * @param aCurveParam A parameter from curve equation + * @param bCurveParam B parameter from curve equation (C parameter for operation over F2m). + * @param size Size in bytes of curve points and parameters + * @param equalTime Run the function time equalized or no timing equalization. + * @param arithType Type of arithmetic to perform (integer or F2m) + * @param[out] result Result point + * @param[out] infinity Output true if the result is point of infinity, and false otherwise. Writing of this output will + * be ignored if the argument is NULL. + * @return Operation status. + */ +status_t LTC_PKHA_ECC_PointMul(LTC_Type *base, + const ltc_pkha_ecc_point_t *A, + const uint8_t *E, + uint8_t sizeE, + const uint8_t *N, + const uint8_t *R2modN, + const uint8_t *aCurveParam, + const uint8_t *bCurveParam, + uint8_t size, + ltc_pkha_timing_t equalTime, + ltc_pkha_f2m_t arithType, + ltc_pkha_ecc_point_t *result, + bool *infinity); + +/*! + *@} + */ + +#if defined(__cplusplus) +} +#endif + +/*! + *@} + */ + +#endif /* _FSL_LTC_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc_edma.c new file mode 100644 index 00000000000..93e969b6a2e --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc_edma.c @@ -0,0 +1,1247 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_ltc_edma.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*modeReg = base->MD; + retval = kStatus_Success; + + if ((!handle->inData) || (!handle->outData)) + { + handle->state = LTC_SM_STATE_FINISH; /* END */ + retval = kStatus_InvalidArgument; + } + + while (exit_sm == false) + { + switch (handle->state) + { + case LTC_SM_STATE_START: + if (handle->size) + { + uint32_t sz; + + if (handle->size <= LTC_FIFO_SZ_MAX_DOWN_ALGN) + { + sz = handle->size; + } + else + { + sz = LTC_FIFO_SZ_MAX_DOWN_ALGN; + } + + /* retval = ltc_symmetric_process_data_EDMA(base, handle->inData, sz, handle->outData); */ + { + uint32_t lastSize; + uint32_t inSize = sz; + + /* Write the data size. */ + base->DS = inSize; + + /* Split the inSize into full 16-byte chunks and last incomplete block due to LTC AES OFIFO + * errata */ + if (inSize <= 16u) + { + lastSize = inSize; + inSize = 0; + } + else + { + /* Process all 16-byte data chunks. */ + lastSize = inSize % 16u; + if (lastSize == 0) + { + lastSize = 16; + inSize -= 16; + } + else + { + inSize -= + lastSize; /* inSize will be rounded down to 16 byte boundary. remaining bytes in + lastSize */ + } + } + + if (inSize) + { + handle->size -= inSize; + ltc_symmetric_process_EDMA(base, inSize, &handle->inData, &handle->outData); + exit_sm = true; + } + else if (lastSize) + { + ltc_symmetric_process(base, lastSize, &handle->inData, &handle->outData); + retval = ltc_wait(base); + handle->size -= lastSize; + } + else + { + } + } + } + else + { + handle->state = LTC_SM_STATE_FINISH; + } + break; + case LTC_SM_STATE_FINISH: + default: + base->MD = handle->modeReg; + + ltc_clear_all(base, false); + + if (handle->callback) + { + handle->callback(base, handle, retval, handle->userData); + } + exit_sm = true; + break; + } + } + + return retval; +} + +/*! + * @brief Splits the LTC job into sessions. Used for CBC, CTR, CFB, OFB cipher block modes. + * + * @param base LTC peripheral base address + * @param inData Input data to process. + * @param inSize Input size of the input buffer. + * @param outData Output data buffer. + */ +static status_t ltc_process_message_in_sessions_ctr_EDMA(LTC_Type *base, ltc_edma_handle_t *handle) +{ + status_t retval; + bool exit_sm = false; + + handle->modeReg = base->MD; + retval = kStatus_Success; + + if ((!handle->inData) || (!handle->outData)) + { + handle->state = LTC_SM_STATE_FINISH; + retval = kStatus_InvalidArgument; + } + + while (exit_sm == false) + { + switch (handle->state) + { + case LTC_SM_STATE_START: + if (handle->size) + { + uint32_t sz; + + if (handle->size <= LTC_FIFO_SZ_MAX_DOWN_ALGN) + { + sz = handle->size; + } + else + { + sz = LTC_FIFO_SZ_MAX_DOWN_ALGN; + } + + /* retval = ltc_symmetric_process_data_EDMA(base, handle->inData, sz, handle->outData); */ + { + uint32_t lastSize; + uint32_t inSize = sz; + + /* Write the data size. */ + base->DS = inSize; + + /* Split the inSize into full 16-byte chunks and last incomplete block due to LTC AES OFIFO + * errata */ + if (inSize <= 16u) + { + lastSize = inSize; + inSize = 0; + } + else + { + /* Process all 16-byte data chunks. */ + lastSize = inSize % 16u; + if (lastSize == 0) + { + lastSize = 16; + inSize -= 16; + } + else + { + inSize -= + lastSize; /* inSize will be rounded down to 16 byte boundary. remaining bytes in + lastSize */ + } + } + + if (inSize) + { + handle->size -= inSize; + ltc_symmetric_process_EDMA(base, inSize, &handle->inData, &handle->outData); + exit_sm = true; + } + else if (lastSize) + { + ltc_symmetric_process(base, lastSize, &handle->inData, &handle->outData); + retval = ltc_wait(base); + handle->size -= lastSize; + } + else + { + } + } + } + else + { + handle->state = LTC_SM_STATE_FINISH; + } + break; + case LTC_SM_STATE_FINISH: + default: + base->MD = handle->modeReg; + + /* CTR final phase.*/ + if (kStatus_Success == retval) + { + const uint8_t *input = handle->inData; + uint8_t *output = handle->outData; + + if ((handle->counterlast != NULL) && (handle->lastSize)) + { + uint8_t zeroes[16] = {0}; + ltc_mode_t modeReg; + + modeReg = (uint32_t)kLTC_AlgorithmAES | (uint32_t)kLTC_ModeCTR | (uint32_t)kLTC_ModeEncrypt; + /* Write the mode register to the hardware. */ + base->MD = modeReg | (uint32_t)kLTC_ModeFinalize; + + /* context is re-used (CTRi) */ + + /* Process data and return status. */ + retval = ltc_symmetric_process_data(base, input, handle->lastSize, output); + if (kStatus_Success == retval) + { + if (handle->szLeft) + { + *handle->szLeft = 16U - handle->lastSize; + } + + /* Initialize algorithm state. */ + base->MD = modeReg | (uint32_t)kLTC_ModeUpdate; + + /* context is re-used (CTRi) */ + + /* Process data and return status. */ + retval = ltc_symmetric_process_data(base, zeroes, 16U, handle->counterlast); + } + } + if (kStatus_Success == retval) + { + ltc_get_context(base, &handle->counter[0], 16U, 4U); + + ltc_clear_all(base, false); + } + } + + if (handle->callback) + { + handle->callback(base, handle, retval, handle->userData); + } + + exit_sm = true; + break; + } + } + + return retval; +} + +/******************************************************************************* + * AES Code public + ******************************************************************************/ + +status_t LTC_AES_EncryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t *key, + uint32_t keySize) +{ + status_t retval; + + if ((ltc_check_key_size(keySize) == 0) || (size < 16u) || + (size % 16u)) /* ECB mode, size must be 16-byte multiple */ + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); + } + + return kStatus_InvalidArgument; + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeECB, kLTC_ModeEncrypt); + + /* Process data and return status. */ + handle->inData = &plaintext[0]; + handle->outData = &ciphertext[0]; + handle->size = size; + handle->state = LTC_SM_STATE_START; + handle->state_machine = ltc_process_message_in_sessions_EDMA; + retval = handle->state_machine(base, handle); + return retval; +} + +status_t LTC_AES_DecryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t *key, + uint32_t keySize, + ltc_aes_key_t keyType) +{ + status_t status; + + if ((ltc_check_key_size(keySize) == 0) || (size < 16u) || + (size % 16u)) /* ECB mode, size must be 16-byte multiple */ + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); + } + + return kStatus_InvalidArgument; + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeECB, kLTC_ModeDecrypt); + + /* set DK bit in the LTC Mode Register AAI field for directly loaded decrypt keys */ + if (keyType == kLTC_DecryptKey) + { + base->MD |= (1U << kLTC_ModeRegBitShiftDK); + } + + /* Process data and return status. */ + handle->inData = &ciphertext[0]; + handle->outData = &plaintext[0]; + handle->size = size; + handle->state = LTC_SM_STATE_START; + handle->state_machine = ltc_process_message_in_sessions_EDMA; + status = handle->state_machine(base, handle); + + return status; +} + +status_t LTC_AES_EncryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_AES_IV_SIZE], + const uint8_t *key, + uint32_t keySize) +{ + status_t retval; + + if ((ltc_check_key_size(keySize) == 0) || (size < 16u) || + (size % 16u)) /* CBC mode, size must be 16-byte multiple */ + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); + } + + return kStatus_InvalidArgument; + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCBC, kLTC_ModeEncrypt); + + /* Write IV data to the context register. */ + ltc_set_context(base, &iv[0], LTC_AES_IV_SIZE, 0); + + /* Process data and return status. */ + handle->inData = &plaintext[0]; + handle->outData = &ciphertext[0]; + handle->size = size; + handle->state = LTC_SM_STATE_START; + handle->state_machine = ltc_process_message_in_sessions_EDMA; + retval = handle->state_machine(base, handle); + return retval; +} + +status_t LTC_AES_DecryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_AES_IV_SIZE], + const uint8_t *key, + uint32_t keySize, + ltc_aes_key_t keyType) +{ + status_t retval; + + if ((ltc_check_key_size(keySize) == 0) || (size < 16u) || + (size % 16u)) /* CBC mode, size must be 16-byte multiple */ + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); + } + + return kStatus_InvalidArgument; + } + + /* set DK bit in the LTC Mode Register AAI field for directly loaded decrypt keys */ + if (keyType == kLTC_DecryptKey) + { + base->MD |= (1U << kLTC_ModeRegBitShiftDK); + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCBC, kLTC_ModeDecrypt); + + /* Write IV data to the context register. */ + ltc_set_context(base, &iv[0], LTC_AES_IV_SIZE, 0); + + /* Process data and return status. */ + handle->inData = &ciphertext[0]; + handle->outData = &plaintext[0]; + handle->size = size; + handle->state = LTC_SM_STATE_START; + handle->state_machine = ltc_process_message_in_sessions_EDMA; + retval = handle->state_machine(base, handle); + return retval; +} + +status_t LTC_AES_CryptCtrEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *input, + uint8_t *output, + uint32_t size, + uint8_t counter[LTC_AES_BLOCK_SIZE], + const uint8_t *key, + uint32_t keySize, + uint8_t counterlast[LTC_AES_BLOCK_SIZE], + uint32_t *szLeft) +{ + status_t retval; + uint32_t lastSize; + + if (!ltc_check_key_size(keySize)) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); + } + return kStatus_InvalidArgument; + } + + lastSize = 0U; + if (counterlast != NULL) + { + /* Split the size into full 16-byte chunks and last incomplete block due to LTC AES OFIFO errata */ + if (size <= 16U) + { + lastSize = size; + size = 0U; + } + else + { + /* Process all 16-byte data chunks. */ + lastSize = size % 16U; + if (lastSize == 0U) + { + lastSize = 16U; + size -= 16U; + } + else + { + size -= lastSize; /* size will be rounded down to 16 byte boundary. remaining bytes in lastSize */ + } + } + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCTR, kLTC_ModeEncrypt); + + /* Write initial counter data to the context register. + * NOTE the counter values start at 4-bytes offset into the context. */ + ltc_set_context(base, &counter[0], 16U, 4U); + + /* Process data and return status. */ + handle->inData = &input[0]; + handle->outData = &output[0]; + handle->size = size; + handle->state = LTC_SM_STATE_START; + handle->state_machine = ltc_process_message_in_sessions_ctr_EDMA; + + handle->counter = counter; + handle->key = key; + handle->keySize = keySize; + handle->counterlast = counterlast; + handle->szLeft = szLeft; + handle->lastSize = lastSize; + retval = handle->state_machine(base, handle); + + return retval; +} + +#if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES +/******************************************************************************* + * DES / 3DES Code static + ******************************************************************************/ +static status_t ltc_des_process_EDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *input, + uint8_t *output, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE], + ltc_mode_symmetric_alg_t modeAs, + ltc_mode_encrypt_t modeEnc) +{ + status_t retval; + + /* all but OFB, size must be 8-byte multiple */ + if ((modeAs != kLTC_ModeOFB) && ((size < 8u) || (size % 8u))) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); + } + return kStatus_InvalidArgument; + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, &key[0], LTC_DES_KEY_SIZE, kLTC_AlgorithmDES, modeAs, modeEnc); + + if ((modeAs != kLTC_ModeECB)) + { + ltc_set_context(base, iv, LTC_DES_IV_SIZE, 0); + } + + /* Process data and return status. */ + handle->inData = input; + handle->outData = output; + handle->size = size; + handle->state = LTC_SM_STATE_START; + handle->state_machine = ltc_process_message_in_sessions_EDMA; + retval = handle->state_machine(base, handle); + + return retval; +} + +static status_t ltc_3des_process_EDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *input, + uint8_t *output, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE], + ltc_mode_symmetric_alg_t modeAs, + ltc_mode_encrypt_t modeEnc) +{ + status_t retval; + uint8_t key[LTC_DES_KEY_SIZE * 3]; + uint8_t keySize = LTC_DES_KEY_SIZE * 2; + + retval = ltc_3des_check_input_args(modeAs, size, key1, key2); + if (kStatus_Success != retval) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); + } + return retval; + } + + ltc_memcpy(&key[0], &key1[0], LTC_DES_KEY_SIZE); + ltc_memcpy(&key[LTC_DES_KEY_SIZE], &key2[0], LTC_DES_KEY_SIZE); + if (key3) + { + ltc_memcpy(&key[LTC_DES_KEY_SIZE * 2], &key3[0], LTC_DES_KEY_SIZE); + keySize = sizeof(key); + } + + /* Initialize algorithm state. */ + ltc_symmetric_update(base, &key[0], keySize, kLTC_Algorithm3DES, modeAs, modeEnc); + + if ((modeAs != kLTC_ModeECB)) + { + ltc_set_context(base, iv, LTC_DES_IV_SIZE, 0); + } + + /* Process data and return status. */ + handle->inData = input; + handle->outData = output; + handle->size = size; + handle->state = LTC_SM_STATE_START; + handle->state_machine = ltc_process_message_in_sessions_EDMA; + retval = handle->state_machine(base, handle); + + return retval; +} +/******************************************************************************* + * DES / 3DES Code public + ******************************************************************************/ +status_t LTC_DES_EncryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process_EDMA(base, handle, plaintext, ciphertext, size, NULL, key, kLTC_ModeECB, kLTC_ModeEncrypt); +} + +status_t LTC_DES_DecryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process_EDMA(base, handle, ciphertext, plaintext, size, NULL, key, kLTC_ModeECB, kLTC_ModeDecrypt); +} + +status_t LTC_DES_EncryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key, kLTC_ModeCBC, kLTC_ModeEncrypt); +} + +status_t LTC_DES_DecryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key, kLTC_ModeCBC, kLTC_ModeDecrypt); +} + +status_t LTC_DES_EncryptCfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key, kLTC_ModeCFB, kLTC_ModeEncrypt); +} + +status_t LTC_DES_DecryptCfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key, kLTC_ModeCFB, kLTC_ModeDecrypt); +} + +status_t LTC_DES_EncryptOfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key, kLTC_ModeOFB, kLTC_ModeEncrypt); +} + +status_t LTC_DES_DecryptOfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]) +{ + return ltc_des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key, kLTC_ModeOFB, kLTC_ModeDecrypt); +} + +status_t LTC_DES2_EncryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, NULL, key1, key2, NULL, kLTC_ModeECB, + kLTC_ModeEncrypt); +} + +status_t LTC_DES3_EncryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, NULL, key1, key2, key3, kLTC_ModeECB, + kLTC_ModeEncrypt); +} + +status_t LTC_DES2_DecryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, NULL, key1, key2, NULL, kLTC_ModeECB, + kLTC_ModeDecrypt); +} + +status_t LTC_DES3_DecryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, NULL, key1, key2, key3, kLTC_ModeECB, + kLTC_ModeDecrypt); +} + +status_t LTC_DES2_EncryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key1, key2, NULL, kLTC_ModeCBC, + kLTC_ModeEncrypt); +} + +status_t LTC_DES3_EncryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key1, key2, key3, kLTC_ModeCBC, + kLTC_ModeEncrypt); +} + +status_t LTC_DES2_DecryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key1, key2, NULL, kLTC_ModeCBC, + kLTC_ModeDecrypt); +} + +status_t LTC_DES3_DecryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key1, key2, key3, kLTC_ModeCBC, + kLTC_ModeDecrypt); +} + +status_t LTC_DES2_EncryptCfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key1, key2, NULL, kLTC_ModeCFB, + kLTC_ModeEncrypt); +} + +status_t LTC_DES3_EncryptCfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key1, key2, key3, kLTC_ModeCFB, + kLTC_ModeEncrypt); +} + +status_t LTC_DES2_DecryptCfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key1, key2, NULL, kLTC_ModeCFB, + kLTC_ModeDecrypt); +} + +status_t LTC_DES3_DecryptCfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key1, key2, key3, kLTC_ModeCFB, + kLTC_ModeDecrypt); +} + +status_t LTC_DES2_EncryptOfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key1, key2, NULL, kLTC_ModeOFB, + kLTC_ModeEncrypt); +} + +status_t LTC_DES3_EncryptOfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key1, key2, key3, kLTC_ModeOFB, + kLTC_ModeEncrypt); +} + +status_t LTC_DES2_DecryptOfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key1, key2, NULL, kLTC_ModeOFB, + kLTC_ModeDecrypt); +} + +status_t LTC_DES3_DecryptOfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]) +{ + return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key1, key2, key3, kLTC_ModeOFB, + kLTC_ModeDecrypt); +} +#endif /* FSL_FEATURE_LTC_HAS_DES */ + +/*********************** LTC EDMA tools ***************************************/ + +static uint32_t LTC_GetInstance(LTC_Type *base) +{ + uint32_t instance = 0; + uint32_t i; + + for (i = 0; i < FSL_FEATURE_SOC_LTC_COUNT; i++) + { + if (s_ltcBase[instance] == base) + { + instance = i; + break; + } + } + return instance; +} + +/*! + * @brief Enable or disable LTC Input FIFO DMA request. + * + * This function enables or disables DMA request and done signals for Input FIFO. + * + * @param base LTC peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LTC_EnableInputFifoDMA(LTC_Type *base, bool enable) +{ + if (enable) + { + base->CTL |= LTC_CTL_IFE_MASK; + } + else + { + base->CTL &= ~LTC_CTL_IFE_MASK; + } +} + +/*! + * @brief Enable or disable LTC Output FIFO DMA request. + * + * This function enables or disables DMA request and done signals for Output FIFO. + * + * @param base LTC peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LTC_EnableOutputFifoDMA(LTC_Type *base, bool enable) +{ + if (enable) + { + base->CTL |= LTC_CTL_OFE_MASK; + } + else + { + base->CTL &= ~LTC_CTL_OFE_MASK; + } +} + +static void LTC_InputFifoEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) +{ + ltc_edma_private_handle_t *ltcPrivateHandle = (ltc_edma_private_handle_t *)param; + + /* Avoid the warning for unused variables. */ + handle = handle; + tcds = tcds; + + if (transferDone) + { + /* Stop DMA channel. */ + EDMA_StopTransfer(ltcPrivateHandle->handle->inputFifoEdmaHandle); + + /* Disable Input Fifo DMA */ + LTC_EnableInputFifoDMA(ltcPrivateHandle->base, false); + } +} + +static void LTC_OutputFifoEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) +{ + ltc_edma_private_handle_t *ltcPrivateHandle = (ltc_edma_private_handle_t *)param; + + /* Avoid the warning for unused variables. */ + handle = handle; + tcds = tcds; + + if (transferDone) + { + /* Stop DMA channel. */ + EDMA_StopTransfer(ltcPrivateHandle->handle->outputFifoEdmaHandle); + + /* Disable Output Fifo DMA */ + LTC_EnableOutputFifoDMA(ltcPrivateHandle->base, false); + + if (ltcPrivateHandle->handle->state_machine) + { + ltcPrivateHandle->handle->state_machine(ltcPrivateHandle->base, ltcPrivateHandle->handle); + } + } +} + +/* @brief Copy data to Input FIFO and reading from Ouput FIFO using eDMA. */ +static void ltc_symmetric_process_EDMA(LTC_Type *base, uint32_t inSize, const uint8_t **inData, uint8_t **outData) +{ + const uint8_t *in = *inData; + uint8_t *out = *outData; + uint32_t instance = LTC_GetInstance(base); + uint32_t entry_number = inSize / sizeof(uint32_t); + const uint8_t *inputBuffer = *inData; + uint8_t *outputBuffer = *outData; + edma_transfer_config_t config; + + if (entry_number) + { + /* =========== Init Input FIFO DMA ======================*/ + memset(&config, 0, sizeof(config)); + + /* Prepare transfer. */ + EDMA_PrepareTransfer(&config, (void *)inputBuffer, 1, (void *)(&((base)->IFIFO)), 4U, 4U, entry_number * 4, + kEDMA_MemoryToPeripheral); + /* Submit transfer. */ + EDMA_SubmitTransfer(s_edmaPrivateHandle[instance].handle->inputFifoEdmaHandle, &config); + + /* Set request size.*/ + base->CTL &= ~LTC_CTL_IFR_MASK; /* 1 entry */ + /* Enable Input Fifo DMA */ + LTC_EnableInputFifoDMA(base, true); + + /* Start the DMA channel */ + EDMA_StartTransfer(s_edmaPrivateHandle[instance].handle->inputFifoEdmaHandle); + + /* =========== Init Output FIFO DMA ======================*/ + memset(&config, 0, sizeof(config)); + + /* Prepare transfer. */ + EDMA_PrepareTransfer(&config, (void *)(&((base)->OFIFO)), 4U, (void *)outputBuffer, 1U, 4U, entry_number * 4, + kEDMA_PeripheralToMemory); + /* Submit transfer. */ + EDMA_SubmitTransfer(s_edmaPrivateHandle[instance].handle->outputFifoEdmaHandle, &config); + + /* Set request size.*/ + base->CTL &= ~LTC_CTL_OFR_MASK; /* 1 entry */ + + /* Enable Output Fifo DMA */ + LTC_EnableOutputFifoDMA(base, true); + + /* Start the DMA channel */ + EDMA_StartTransfer(s_edmaPrivateHandle[instance].handle->outputFifoEdmaHandle); + + { /* Dummy read of LTC register. Do not delete.*/ + volatile uint32_t status_reg; + + status_reg = (base)->STA; + + (void)status_reg; + } + + out += entry_number * sizeof(uint32_t); + in += entry_number * sizeof(uint32_t); + + *inData = in; + *outData = out; + } +} + +void LTC_CreateHandleEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + ltc_edma_callback_t callback, + void *userData, + edma_handle_t *inputFifoEdmaHandle, + edma_handle_t *outputFifoEdmaHandle) +{ + assert(handle); + assert(inputFifoEdmaHandle); + assert(outputFifoEdmaHandle); + + uint32_t instance = LTC_GetInstance(base); + + s_edmaPrivateHandle[instance].base = base; + s_edmaPrivateHandle[instance].handle = handle; + + memset(handle, 0, sizeof(*handle)); + + handle->inputFifoEdmaHandle = inputFifoEdmaHandle; + handle->outputFifoEdmaHandle = outputFifoEdmaHandle; + + handle->callback = callback; + handle->userData = userData; + + /* Register DMA callback functions */ + EDMA_SetCallback(handle->inputFifoEdmaHandle, LTC_InputFifoEDMACallback, &s_edmaPrivateHandle[instance]); + EDMA_SetCallback(handle->outputFifoEdmaHandle, LTC_OutputFifoEDMACallback, &s_edmaPrivateHandle[instance]); + + /* Set request size. DMA request size is 1 entry.*/ + base->CTL &= ~LTC_CTL_IFR_MASK; + base->CTL &= ~LTC_CTL_OFR_MASK; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc_edma.h new file mode 100644 index 00000000000..5456fb443b6 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_ltc_edma.h @@ -0,0 +1,850 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_LTC_EDMA_H_ +#define _FSL_LTC_EDMA_H_ + +#include "fsl_common.h" + +#include "fsl_ltc.h" +#include "fsl_dmamux.h" +#include "fsl_edma.h" + +/*! + * @addtogroup ltc_edma_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* @brief The LTC eDMA handle type. */ +typedef struct _ltc_edma_handle ltc_edma_handle_t; + +/*! @brief LTC eDMA callback function. */ +typedef void (*ltc_edma_callback_t)(LTC_Type *base, ltc_edma_handle_t *handle, status_t status, void *userData); + +/*! @brief LTC eDMA state machine function. It is defined only for private usage inside LTC eDMA driver. */ +typedef status_t (*ltc_edma_state_machine_t)(LTC_Type *base, ltc_edma_handle_t *handle); + +/*! +* @brief LTC eDMA handle. It is defined only for private usage inside LTC eDMA driver. +*/ +struct _ltc_edma_handle +{ + ltc_edma_callback_t callback; /*!< Callback function. */ + void *userData; /*!< LTC callback function parameter.*/ + + edma_handle_t *inputFifoEdmaHandle; /*!< The eDMA TX channel used. */ + edma_handle_t *outputFifoEdmaHandle; /*!< The eDMA RX channel used. */ + + ltc_edma_state_machine_t state_machine; /*!< State machine. */ + uint32_t state; /*!< Internal state. */ + const uint8_t *inData; /*!< Input data. */ + uint8_t *outData; /*!< Output data. */ + uint32_t size; /*!< Size of input and output data in bytes.*/ + uint32_t modeReg; /*!< LTC mode register.*/ + /* Used by AES CTR*/ + uint8_t *counter; /*!< Input counter (updates on return)*/ + const uint8_t *key; /*!< Input key to use for forward AES cipher*/ + uint32_t keySize; /*!< Size of the input key, in bytes. Must be 16, 24, or 32.*/ + uint8_t + *counterlast; /*!< Output cipher of last counter, for chained CTR calls. NULL can be passed if chained calls are + not used.*/ + uint32_t *szLeft; /*!< Output number of bytes in left unused in counterlast block. NULL can be passed if chained + calls are not used.*/ + uint32_t lastSize; /*!< Last size.*/ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Init the LTC eDMA handle which is used in transcational functions + * @param base LTC module base address + * @param handle Pointer to ltc_edma_handle_t structure + * @param callback Callback function, NULL means no callback. + * @param userData Callback function parameter. + * @param inputFifoEdmaHandle User requested eDMA handle for Input FIFO eDMA. + * @param outputFifoEdmaHandle User requested eDMA handle for Output FIFO eDMA. + */ +void LTC_CreateHandleEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + ltc_edma_callback_t callback, + void *userData, + edma_handle_t *inputFifoEdmaHandle, + edma_handle_t *outputFifoEdmaHandle); + +/*! @}*/ + +/******************************************************************************* + * AES API + ******************************************************************************/ + +/*! + * @addtogroup ltc_edma_driver_aes + * @{ + */ + +/*! + * @brief Encrypts AES using the ECB block mode. + * + * Encrypts AES using the ECB block mode. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plain text to encrypt + * @param[out] ciphertext Output cipher text + * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. + * @param key Input key to use for encryption + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @return Status from encrypt operation + */ +status_t LTC_AES_EncryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t *key, + uint32_t keySize); + +/*! + * @brief Decrypts AES using ECB block mode. + * + * Decrypts AES using ECB block mode. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input cipher text to decrypt + * @param[out] plaintext Output plain text + * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. + * @param key Input key. + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @param keyType Input type of the key (allows to directly load decrypt key for AES ECB decrypt operation.) + * @return Status from decrypt operation + */ +status_t LTC_AES_DecryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t *key, + uint32_t keySize, + ltc_aes_key_t keyType); + +/*! + * @brief Encrypts AES using CBC block mode. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plain text to encrypt + * @param[out] ciphertext Output cipher text + * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. + * @param iv Input initial vector to combine with the first input block. + * @param key Input key to use for encryption + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @return Status from encrypt operation + */ +status_t LTC_AES_EncryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_AES_IV_SIZE], + const uint8_t *key, + uint32_t keySize); + +/*! + * @brief Decrypts AES using CBC block mode. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input cipher text to decrypt + * @param[out] plaintext Output plain text + * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. + * @param iv Input initial vector to combine with the first input block. + * @param key Input key to use for decryption + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @param keyType Input type of the key (allows to directly load decrypt key for AES CBC decrypt operation.) + * @return Status from decrypt operation + */ +status_t LTC_AES_DecryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_AES_IV_SIZE], + const uint8_t *key, + uint32_t keySize, + ltc_aes_key_t keyType); + +/*! + * @brief Encrypts or decrypts AES using CTR block mode. + * + * Encrypts or decrypts AES using CTR block mode. + * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption. + * The only difference between encryption and decryption is that, for encryption, the input argument + * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text + * and the output argument is plain text. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param input Input data for CTR block mode + * @param[out] output Output data for CTR block mode + * @param size Size of input and output data in bytes + * @param[in,out] counter Input counter (updates on return) + * @param key Input key to use for forward AES cipher + * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32. + * @param[out] counterlast Output cipher of last counter, for chained CTR calls. NULL can be passed if chained calls are + * not used. + * @param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls + * are not used. + * @return Status from encrypt operation + */ +status_t LTC_AES_CryptCtrEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *input, + uint8_t *output, + uint32_t size, + uint8_t counter[LTC_AES_BLOCK_SIZE], + const uint8_t *key, + uint32_t keySize, + uint8_t counterlast[LTC_AES_BLOCK_SIZE], + uint32_t *szLeft); + +/*! AES CTR decrypt is mapped to the AES CTR generic operation */ +#define LTC_AES_DecryptCtrEDMA(base, handle, input, output, size, counter, key, keySize, counterlast, szLeft) \ + LTC_AES_CryptCtrEDMA(base, handle, input, output, size, counter, key, keySize, counterlast, szLeft) + +/*! AES CTR encrypt is mapped to the AES CTR generic operation */ +#define LTC_AES_EncryptCtrEDMA(base, handle, input, output, size, counter, key, keySize, counterlast, szLeft) \ + LTC_AES_CryptCtrEDMA(base, handle, input, output, size, counter, key, keySize, counterlast, szLeft) + +/*! + *@} + */ + +/******************************************************************************* + * DES API + ******************************************************************************/ +/*! + * @addtogroup ltc_edma_driver_des + * @{ + */ +/*! + * @brief Encrypts DES using ECB block mode. + * + * Encrypts DES using ECB block mode. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param key Input key to use for encryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_EncryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts DES using ECB block mode. + * + * Decrypts DES using ECB block mode. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param key Input key to use for decryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_DecryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts DES using CBC block mode. + * + * Encrypts DES using CBC block mode. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Ouput ciphertext + * @param size Size of input and output data in bytes + * @param iv Input initial vector to combine with the first plaintext block. + * The iv does not need to be secret, but it must be unpredictable. + * @param key Input key to use for encryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_EncryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts DES using CBC block mode. + * + * Decrypts DES using CBC block mode. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input data in bytes + * @param iv Input initial vector to combine with the first plaintext block. + * The iv does not need to be secret, but it must be unpredictable. + * @param key Input key to use for decryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_DecryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts DES using CFB block mode. + * + * Encrypts DES using CFB block mode. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plaintext to encrypt + * @param size Size of input data in bytes + * @param iv Input initial block. + * @param key Input key to use for encryption + * @param[out] ciphertext Output ciphertext + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_EncryptCfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts DES using CFB block mode. + * + * Decrypts DES using CFB block mode. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes + * @param iv Input initial block. + * @param key Input key to use for decryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_DecryptCfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts DES using OFB block mode. + * + * Encrypts DES using OFB block mode. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes + * @param iv Input unique input vector. The OFB mode requires that the IV be unique + * for each execution of the mode under the given key. + * @param key Input key to use for encryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_EncryptOfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts DES using OFB block mode. + * + * Decrypts DES using OFB block mode. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param iv Input unique input vector. The OFB mode requires that the IV be unique + * for each execution of the mode under the given key. + * @param key Input key to use for decryption + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES_DecryptOfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using ECB block mode with two keys. + * + * Encrypts triple DES using ECB block mode with two keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_EncryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using ECB block mode with two keys. + * + * Decrypts triple DES using ECB block mode with two keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_DecryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using CBC block mode with two keys. + * + * Encrypts triple DES using CBC block mode with two keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes + * @param iv Input initial vector to combine with the first plaintext block. + * The iv does not need to be secret, but it must be unpredictable. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_EncryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using CBC block mode with two keys. + * + * Decrypts triple DES using CBC block mode with two keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes + * @param iv Input initial vector to combine with the first plaintext block. + * The iv does not need to be secret, but it must be unpredictable. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_DecryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using CFB block mode with two keys. + * + * Encrypts triple DES using CFB block mode with two keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes + * @param iv Input initial block. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_EncryptCfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using CFB block mode with two keys. + * + * Decrypts triple DES using CFB block mode with two keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes + * @param iv Input initial block. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_DecryptCfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using OFB block mode with two keys. + * + * Encrypts triple DES using OFB block mode with two keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes + * @param iv Input unique input vector. The OFB mode requires that the IV be unique + * for each execution of the mode under the given key. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_EncryptOfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using OFB block mode with two keys. + * + * Decrypts triple DES using OFB block mode with two keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes + * @param iv Input unique input vector. The OFB mode requires that the IV be unique + * for each execution of the mode under the given key. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES2_DecryptOfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using ECB block mode with three keys. + * + * Encrypts triple DES using ECB block mode with three keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_EncryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using ECB block mode with three keys. + * + * Decrypts triple DES using ECB block mode with three keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes. Must be multiple of 8 bytes. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_DecryptEcbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using CBC block mode with three keys. + * + * Encrypts triple DES using CBC block mode with three keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input data in bytes + * @param iv Input initial vector to combine with the first plaintext block. + * The iv does not need to be secret, but it must be unpredictable. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_EncryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using CBC block mode with three keys. + * + * Decrypts triple DES using CBC block mode with three keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes + * @param iv Input initial vector to combine with the first plaintext block. + * The iv does not need to be secret, but it must be unpredictable. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_DecryptCbcEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using CFB block mode with three keys. + * + * Encrypts triple DES using CFB block mode with three keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and ouput data in bytes + * @param iv Input initial block. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_EncryptCfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using CFB block mode with three keys. + * + * Decrypts triple DES using CFB block mode with three keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input data in bytes + * @param iv Input initial block. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_DecryptCfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Encrypts triple DES using OFB block mode with three keys. + * + * Encrypts triple DES using OFB block mode with three keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param plaintext Input plaintext to encrypt + * @param[out] ciphertext Output ciphertext + * @param size Size of input and output data in bytes + * @param iv Input unique input vector. The OFB mode requires that the IV be unique + * for each execution of the mode under the given key. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_EncryptOfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *plaintext, + uint8_t *ciphertext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + * @brief Decrypts triple DES using OFB block mode with three keys. + * + * Decrypts triple DES using OFB block mode with three keys. + * + * @param base LTC peripheral base address + * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state. + * @param ciphertext Input ciphertext to decrypt + * @param[out] plaintext Output plaintext + * @param size Size of input and output data in bytes + * @param iv Input unique input vector. The OFB mode requires that the IV be unique + * for each execution of the mode under the given key. + * @param key1 First input key for key bundle + * @param key2 Second input key for key bundle + * @param key3 Third input key for key bundle + * @return Status from encrypt/decrypt operation + */ +status_t LTC_DES3_DecryptOfbEDMA(LTC_Type *base, + ltc_edma_handle_t *handle, + const uint8_t *ciphertext, + uint8_t *plaintext, + uint32_t size, + const uint8_t iv[LTC_DES_IV_SIZE], + const uint8_t key1[LTC_DES_KEY_SIZE], + const uint8_t key2[LTC_DES_KEY_SIZE], + const uint8_t key3[LTC_DES_KEY_SIZE]); + +/*! + *@} + */ + +#if defined(__cplusplus) +} +#endif + +#endif /* _FSL_LTC_EDMA_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_mpu.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_mpu.c new file mode 100644 index 00000000000..ee4be1259c7 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_mpu.c @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_mpu.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +const clock_ip_name_t g_mpuClock[FSL_FEATURE_SOC_MPU_COUNT] = MPU_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Codes + ******************************************************************************/ + +void MPU_Init(MPU_Type *base, const mpu_config_t *config) +{ + assert(config); + uint8_t count; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Un-gate MPU clock */ + CLOCK_EnableClock(g_mpuClock[0]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Initializes the regions. */ + for (count = 1; count < FSL_FEATURE_MPU_DESCRIPTOR_COUNT; count++) + { + base->WORD[count][3] = 0; /* VLD/VID+PID. */ + base->WORD[count][0] = 0; /* Start address. */ + base->WORD[count][1] = 0; /* End address. */ + base->WORD[count][2] = 0; /* Access rights. */ + base->RGDAAC[count] = 0; /* Alternate access rights. */ + } + + /* MPU configure. */ + while (config) + { + MPU_SetRegionConfig(base, &(config->regionConfig)); + config = config->next; + } + /* Enable MPU. */ + MPU_Enable(base, true); +} + +void MPU_Deinit(MPU_Type *base) +{ + /* Disable MPU. */ + MPU_Enable(base, false); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate the clock. */ + CLOCK_DisableClock(g_mpuClock[0]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void MPU_GetHardwareInfo(MPU_Type *base, mpu_hardware_info_t *hardwareInform) +{ + assert(hardwareInform); + + uint32_t cesReg = base->CESR; + + hardwareInform->hardwareRevisionLevel = (cesReg & MPU_CESR_HRL_MASK) >> MPU_CESR_HRL_SHIFT; + hardwareInform->slavePortsNumbers = (cesReg & MPU_CESR_NSP_MASK) >> MPU_CESR_NSP_SHIFT; + hardwareInform->regionsNumbers = (mpu_region_total_num_t)((cesReg & MPU_CESR_NRGD_MASK) >> MPU_CESR_NRGD_SHIFT); +} + +void MPU_SetRegionConfig(MPU_Type *base, const mpu_region_config_t *regionConfig) +{ + assert(regionConfig); + assert(regionConfig->regionNum < FSL_FEATURE_MPU_DESCRIPTOR_COUNT); + + uint32_t wordReg = 0; + uint8_t msPortNum; + uint8_t regNumber = regionConfig->regionNum; + + /* The start and end address of the region descriptor. */ + base->WORD[regNumber][0] = regionConfig->startAddress; + base->WORD[regNumber][1] = regionConfig->endAddress; + + /* Set the privilege rights for master 0 ~ master 3. */ + for (msPortNum = 0; msPortNum <= MPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX; msPortNum++) + { + wordReg |= MPU_REGION_RWXRIGHTS_MASTER( + msPortNum, (((uint32_t)regionConfig->accessRights1[msPortNum].superAccessRights << 3U) | + (uint32_t)regionConfig->accessRights1[msPortNum].userAccessRights)); + +#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER + wordReg |= + MPU_REGION_RWXRIGHTS_MASTER_PE(msPortNum, regionConfig->accessRights1[msPortNum].processIdentifierEnable); +#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ + } + + /* Set the normal read write rights for master 4 ~ master 7. */ + for (msPortNum = FSL_FEATURE_MPU_PRIVILEGED_RIGHTS_MASTER_COUNT; msPortNum < FSL_FEATURE_MPU_MASTER_COUNT; + msPortNum++) + { + wordReg |= MPU_REGION_RWRIGHTS_MASTER(msPortNum, + ((uint32_t)regionConfig->accessRights2[msPortNum - FSL_FEATURE_MPU_PRIVILEGED_RIGHTS_MASTER_COUNT].readEnable << 1U | + (uint32_t)regionConfig->accessRights2[msPortNum - FSL_FEATURE_MPU_PRIVILEGED_RIGHTS_MASTER_COUNT].writeEnable)); + } + + /* Set region descriptor access rights. */ + base->WORD[regNumber][2] = wordReg; + + wordReg = MPU_WORD_VLD(1); +#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER + wordReg |= MPU_WORD_PID(regionConfig->processIdentifier) | MPU_WORD_PIDMASK(regionConfig->processIdMask); +#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ + + base->WORD[regNumber][3] = wordReg; +} + +void MPU_SetRegionAddr(MPU_Type *base, uint32_t regionNum, uint32_t startAddr, uint32_t endAddr) +{ + assert(regionNum < FSL_FEATURE_MPU_DESCRIPTOR_COUNT); + + base->WORD[regionNum][0] = startAddr; + base->WORD[regionNum][1] = endAddr; +} + +void MPU_SetRegionRwxMasterAccessRights(MPU_Type *base, + uint32_t regionNum, + uint32_t masterNum, + const mpu_rwxrights_master_access_control_t *accessRights) +{ + assert(accessRights); + assert(regionNum < FSL_FEATURE_MPU_DESCRIPTOR_COUNT); + assert(masterNum <= MPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX); + + uint32_t mask = MPU_REGION_RWXRIGHTS_MASTER_MASK(masterNum); + uint32_t right = base->RGDAAC[regionNum]; + +#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER + mask |= MPU_REGION_RWXRIGHTS_MASTER_PE_MASK(masterNum); +#endif + + /* Build rights control value. */ + right &= ~mask; + right |= MPU_REGION_RWXRIGHTS_MASTER( + masterNum, ((uint32_t)(accessRights->superAccessRights << 3U) | accessRights->userAccessRights)); +#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER + right |= MPU_REGION_RWXRIGHTS_MASTER_PE(masterNum, accessRights->processIdentifierEnable); +#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ + + /* Set low master region access rights. */ + base->RGDAAC[regionNum] = right; +} + +#if FSL_FEATURE_MPU_HAS_MASTER_4_7 +void MPU_SetRegionRwMasterAccessRights(MPU_Type *base, + uint32_t regionNum, + uint32_t masterNum, + const mpu_rwrights_master_access_control_t *accessRights) +{ + assert(accessRights); + assert(regionNum < FSL_FEATURE_MPU_DESCRIPTOR_COUNT); + assert(masterNum > MPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX); + assert(masterNum <= FSL_FEATURE_MPU_MASTER_MAX_INDEX); + + uint32_t mask = MPU_REGION_RWRIGHTS_MASTER_MASK(masterNum); + uint32_t right = base->RGDAAC[regionNum]; + + /* Build rights control value. */ + right &= ~mask; + right |= + MPU_REGION_RWRIGHTS_MASTER(masterNum, (((uint32_t)accessRights->readEnable << 1U) | accessRights->writeEnable)); + /* Set low master region access rights. */ + base->RGDAAC[regionNum] = right; +} +#endif /* FSL_FEATURE_MPU_HAS_MASTER_4_7 */ + +bool MPU_GetSlavePortErrorStatus(MPU_Type *base, mpu_slave_t slaveNum) +{ + uint8_t sperr; + + sperr = ((base->CESR & MPU_CESR_SPERR_MASK) >> MPU_CESR_SPERR_SHIFT) & (0x1U << (MPU_SLAVE_PORT_NUM - slaveNum)); + + return (sperr != 0) ? true : false; +} + +void MPU_GetDetailErrorAccessInfo(MPU_Type *base, mpu_slave_t slaveNum, mpu_access_err_info_t *errInform) +{ + assert(errInform); + + uint16_t value; + uint32_t cesReg; + + /* Error address. */ + errInform->address = base->SP[slaveNum].EAR; + + /* Error detail information. */ + value = (base->SP[slaveNum].EDR & MPU_EDR_EACD_MASK) >> MPU_EDR_EACD_SHIFT; + if (!value) + { + errInform->accessControl = kMPU_NoRegionHit; + } + else if (!(value & (uint16_t)(value - 1))) + { + errInform->accessControl = kMPU_NoneOverlappRegion; + } + else + { + errInform->accessControl = kMPU_OverlappRegion; + } + + value = base->SP[slaveNum].EDR; + errInform->master = (uint32_t)((value & MPU_EDR_EMN_MASK) >> MPU_EDR_EMN_SHIFT); + errInform->attributes = (mpu_err_attributes_t)((value & MPU_EDR_EATTR_MASK) >> MPU_EDR_EATTR_SHIFT); + errInform->accessType = (mpu_err_access_type_t)((value & MPU_EDR_ERW_MASK) >> MPU_EDR_ERW_SHIFT); +#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER + errInform->processorIdentification = (uint8_t)((value & MPU_EDR_EPID_MASK) >> MPU_EDR_EPID_SHIFT); +#endif + + /* Clears error slave port bit. */ + cesReg = (base->CESR & ~MPU_CESR_SPERR_MASK) | ((0x1U << slaveNum) << MPU_CESR_SPERR_SHIFT); + base->CESR = cesReg; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_mpu.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_mpu.h new file mode 100644 index 00000000000..e6968612e0f --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_mpu.h @@ -0,0 +1,427 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_MPU_H_ +#define _FSL_MPU_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup mpu + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief MPU driver version 2.1.0. */ +#define FSL_MPU_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) +/*@}*/ + +/*! @brief MPU the bit shift for masters with privilege rights: read write and execute. */ +#define MPU_REGION_RWXRIGHTS_MASTER_SHIFT(n) (n * 6) + +/*! @brief MPU masters with read, write and execute rights bit mask. */ +#define MPU_REGION_RWXRIGHTS_MASTER_MASK(n) (0x1Fu << MPU_REGION_RWXRIGHTS_MASTER_SHIFT(n)) + +/*! @brief MPU masters with read, write and execute rights bit width. */ +#define MPU_REGION_RWXRIGHTS_MASTER_WIDTH 5 + +/*! @brief MPU masters with read, write and execute rights priority setting. */ +#define MPU_REGION_RWXRIGHTS_MASTER(n, x) \ + (((uint32_t)(((uint32_t)(x)) << MPU_REGION_RWXRIGHTS_MASTER_SHIFT(n))) & MPU_REGION_RWXRIGHTS_MASTER_MASK(n)) + +/*! @brief MPU masters with read, write and execute rights process enable bit shift. */ +#define MPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n) (n * 6 + MPU_REGION_RWXRIGHTS_MASTER_WIDTH) + +/*! @brief MPU masters with read, write and execute rights process enable bit mask. */ +#define MPU_REGION_RWXRIGHTS_MASTER_PE_MASK(n) (0x1u << MPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n)) + +/*! @brief MPU masters with read, write and execute rights process enable setting. */ +#define MPU_REGION_RWXRIGHTS_MASTER_PE(n, x) \ + (((uint32_t)(((uint32_t)(x)) << MPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n))) & MPU_REGION_RWXRIGHTS_MASTER_PE_MASK(n)) + +/*! @brief MPU masters with normal read write permission bit shift. */ +#define MPU_REGION_RWRIGHTS_MASTER_SHIFT(n) ((n - FSL_FEATURE_MPU_PRIVILEGED_RIGHTS_MASTER_COUNT) * 2 + 24) + +/*! @brief MPU masters with normal read write rights bit mask. */ +#define MPU_REGION_RWRIGHTS_MASTER_MASK(n) (0x3u << MPU_REGION_RWRIGHTS_MASTER_SHIFT(n)) + +/*! @brief MPU masters with normal read write rights priority setting. */ +#define MPU_REGION_RWRIGHTS_MASTER(n, x) \ + (((uint32_t)(((uint32_t)(x)) << MPU_REGION_RWRIGHTS_MASTER_SHIFT(n))) & MPU_REGION_RWRIGHTS_MASTER_MASK(n)) + +/*! @brief the Slave port numbers. */ +#define MPU_SLAVE_PORT_NUM (4u) +/*! @brief define the maximum index of master with privileged rights. */ +#define MPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX (3) + +/*! @brief Describes the number of MPU regions. */ +typedef enum _mpu_region_total_num +{ + kMPU_8Regions = 0x0U, /*!< MPU supports 8 regions. */ + kMPU_12Regions = 0x1U, /*!< MPU supports 12 regions. */ + kMPU_16Regions = 0x2U /*!< MPU supports 16 regions. */ +} mpu_region_total_num_t; + +/*! @brief MPU slave port number. */ +typedef enum _mpu_slave +{ + kMPU_Slave0 = 0U, /*!< MPU slave port 0. */ + kMPU_Slave1 = 1U, /*!< MPU slave port 1. */ + kMPU_Slave2 = 2U, /*!< MPU slave port 2. */ + kMPU_Slave3 = 3U, /*!< MPU slave port 3. */ + kMPU_Slave4 = 4U /*!< MPU slave port 4. */ +} mpu_slave_t; + +/*! @brief MPU error access control detail. */ +typedef enum _mpu_err_access_control +{ + kMPU_NoRegionHit = 0U, /*!< No region hit error. */ + kMPU_NoneOverlappRegion = 1U, /*!< Access single region error. */ + kMPU_OverlappRegion = 2U /*!< Access overlapping region error. */ +} mpu_err_access_control_t; + +/*! @brief MPU error access type. */ +typedef enum _mpu_err_access_type +{ + kMPU_ErrTypeRead = 0U, /*!< MPU error access type --- read. */ + kMPU_ErrTypeWrite = 1U /*!< MPU error access type --- write. */ +} mpu_err_access_type_t; + +/*! @brief MPU access error attributes.*/ +typedef enum _mpu_err_attributes +{ + kMPU_InstructionAccessInUserMode = 0U, /*!< Access instruction error in user mode. */ + kMPU_DataAccessInUserMode = 1U, /*!< Access data error in user mode. */ + kMPU_InstructionAccessInSupervisorMode = 2U, /*!< Access instruction error in supervisor mode. */ + kMPU_DataAccessInSupervisorMode = 3U /*!< Access data error in supervisor mode. */ +} mpu_err_attributes_t; + +/*! @brief MPU access rights in supervisor mode for bus master 0 ~ 3. */ +typedef enum _mpu_supervisor_access_rights +{ + kMPU_SupervisorReadWriteExecute = 0U, /*!< Read write and execute operations are allowed in supervisor mode. */ + kMPU_SupervisorReadExecute = 1U, /*!< Read and execute operations are allowed in supervisor mode. */ + kMPU_SupervisorReadWrite = 2U, /*!< Read write operations are allowed in supervisor mode. */ + kMPU_SupervisorEqualToUsermode = 3U /*!< Access permission equal to user mode. */ +} mpu_supervisor_access_rights_t; + +/*! @brief MPU access rights in user mode for bus master 0 ~ 3. */ +typedef enum _mpu_user_access_rights +{ + kMPU_UserNoAccessRights = 0U, /*!< No access allowed in user mode. */ + kMPU_UserExecute = 1U, /*!< Execute operation is allowed in user mode. */ + kMPU_UserWrite = 2U, /*!< Write operation is allowed in user mode. */ + kMPU_UserWriteExecute = 3U, /*!< Write and execute operations are allowed in user mode. */ + kMPU_UserRead = 4U, /*!< Read is allowed in user mode. */ + kMPU_UserReadExecute = 5U, /*!< Read and execute operations are allowed in user mode. */ + kMPU_UserReadWrite = 6U, /*!< Read and write operations are allowed in user mode. */ + kMPU_UserReadWriteExecute = 7U /*!< Read write and execute operations are allowed in user mode. */ +} mpu_user_access_rights_t; + +/*! @brief MPU hardware basic information. */ +typedef struct _mpu_hardware_info +{ + uint8_t hardwareRevisionLevel; /*!< Specifies the MPU's hardware and definition reversion level. */ + uint8_t slavePortsNumbers; /*!< Specifies the number of slave ports connected to MPU. */ + mpu_region_total_num_t regionsNumbers; /*!< Indicates the number of region descriptors implemented. */ +} mpu_hardware_info_t; + +/*! @brief MPU detail error access information. */ +typedef struct _mpu_access_err_info +{ + uint32_t master; /*!< Access error master. */ + mpu_err_attributes_t attributes; /*!< Access error attributes. */ + mpu_err_access_type_t accessType; /*!< Access error type. */ + mpu_err_access_control_t accessControl; /*!< Access error control. */ + uint32_t address; /*!< Access error address. */ +#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER + uint8_t processorIdentification; /*!< Access error processor identification. */ +#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ +} mpu_access_err_info_t; + +/*! @brief MPU read/write/execute rights control for bus master 0 ~ 3. */ +typedef struct _mpu_rwxrights_master_access_control +{ + mpu_supervisor_access_rights_t superAccessRights; /*!< Master access rights in supervisor mode. */ + mpu_user_access_rights_t userAccessRights; /*!< Master access rights in user mode. */ +#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER + bool processIdentifierEnable; /*!< Enables or disables process identifier. */ +#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ +} mpu_rwxrights_master_access_control_t; + +/*! @brief MPU read/write access control for bus master 4 ~ 7. */ +typedef struct _mpu_rwrights_master_access_control +{ + bool writeEnable; /*!< Enables or disables write permission. */ + bool readEnable; /*!< Enables or disables read permission. */ +} mpu_rwrights_master_access_control_t; + +/*! + * @brief MPU region configuration structure. + * + * This structure is used to configure the regionNum region. + * The accessRights1[0] ~ accessRights1[3] are used to configure the bus master + * 0 ~ 3 with the privilege rights setting. The accessRights2[0] ~ accessRights2[3] + * are used to configure the high master 4 ~ 7 with the normal read write permission. + * The master port assignment is the chip configuration. Normally, the core is the + * master 0, debugger is the master 1. + * Note that the MPU assigns a priority scheme where the debugger is treated as the highest + * priority master followed by the core and then all the remaining masters. + * MPU protection does not allow writes from the core to affect the "regionNum 0" start + * and end address nor the permissions associated with the debugger. It can only write + * the permission fields associated with the other masters. This protection guarantees that + * the debugger always has access to the entire address space and those rights can't + * be changed by the core or any other bus master. Prepare + * the region configuration when regionNum is 0. + */ +typedef struct _mpu_region_config +{ + uint32_t regionNum; /*!< MPU region number, range form 0 ~ FSL_FEATURE_MPU_DESCRIPTOR_COUNT - 1. */ + uint32_t startAddress; /*!< Memory region start address. Note: bit0 ~ bit4 always be marked as 0 by MPU. The actual + start address is 0-modulo-32 byte address. */ + uint32_t endAddress; /*!< Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by MPU. The actual end + address is 31-modulo-32 byte address. */ + mpu_rwxrights_master_access_control_t accessRights1[4]; /*!< Masters with read, write and execute rights setting. */ + mpu_rwrights_master_access_control_t accessRights2[4]; /*!< Masters with normal read write rights setting. */ +#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER + uint8_t processIdentifier; /*!< Process identifier used when "processIdentifierEnable" set with true. */ + uint8_t + processIdMask; /*!< Process identifier mask. The setting bit will ignore the same bit in process identifier. */ +#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ +} mpu_region_config_t; + +/*! + * @brief The configuration structure for the MPU initialization. + * + * This structure is used when calling the MPU_Init function. + */ +typedef struct _mpu_config +{ + mpu_region_config_t regionConfig; /*!< Region access permission. */ + struct _mpu_config *next; /*!< Pointer to the next structure. */ +} mpu_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes the MPU with the user configuration structure. + * + * This function configures the MPU module with the user-defined configuration. + * + * @param base MPU peripheral base address. + * @param config The pointer to the configuration structure. + */ +void MPU_Init(MPU_Type *base, const mpu_config_t *config); + +/*! + * @brief Deinitializes the MPU regions. + * + * @param base MPU peripheral base address. + */ +void MPU_Deinit(MPU_Type *base); + +/* @}*/ + +/*! + * @name Basic Control Operations + * @{ + */ + +/*! + * @brief Enables/disables the MPU globally. + * + * Call this API to enable or disable the MPU module. + * + * @param base MPU peripheral base address. + * @param enable True enable MPU, false disable MPU. + */ +static inline void MPU_Enable(MPU_Type *base, bool enable) +{ + if (enable) + { + /* Enable the MPU globally. */ + base->CESR |= MPU_CESR_VLD_MASK; + } + else + { /* Disable the MPU globally. */ + base->CESR &= ~MPU_CESR_VLD_MASK; + } +} + +/*! + * @brief Enables/disables the MPU for a special region. + * + * When MPU is enabled, call this API to disable an unused region + * of an enabled MPU. Call this API to minimize the power dissipation. + * + * @param base MPU peripheral base address. + * @param number MPU region number. + * @param enable True enable the special region MPU, false disable the special region MPU. + */ +static inline void MPU_RegionEnable(MPU_Type *base, uint32_t number, bool enable) +{ + if (enable) + { + /* Enable the #number region MPU. */ + base->WORD[number][3] |= MPU_WORD_VLD_MASK; + } + else + { /* Disable the #number region MPU. */ + base->WORD[number][3] &= ~MPU_WORD_VLD_MASK; + } +} + +/*! + * @brief Gets the MPU basic hardware information. + * + * @param base MPU peripheral base address. + * @param hardwareInform The pointer to the MPU hardware information structure. See "mpu_hardware_info_t". + */ +void MPU_GetHardwareInfo(MPU_Type *base, mpu_hardware_info_t *hardwareInform); + +/*! + * @brief Sets the MPU region. + * + * Note: Due to the MPU protection, the region number 0 does not allow writes from + * core to affect the start and end address nor the permissions associated with + * the debugger. It can only write the permission fields associated + * with the other masters. + * + * @param base MPU peripheral base address. + * @param regionConfig The pointer to the MPU user configuration structure. See "mpu_region_config_t". + */ +void MPU_SetRegionConfig(MPU_Type *base, const mpu_region_config_t *regionConfig); + +/*! + * @brief Sets the region start and end address. + * + * Memory region start address. Note: bit0 ~ bit4 is always marked as 0 by MPU. + * The actual start address by MPU is 0-modulo-32 byte address. + * Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by MPU. + * The end address used by the MPU is 31-modulo-32 byte address. + * Note: Due to the MPU protection, the startAddr and endAddr can't be + * changed by the core when regionNum is 0. + * + * @param base MPU peripheral base address. + * @param regionNum MPU region number. The range is from 0 to + * FSL_FEATURE_MPU_DESCRIPTOR_COUNT - 1. + * @param startAddr Region start address. + * @param endAddr Region end address. + */ +void MPU_SetRegionAddr(MPU_Type *base, uint32_t regionNum, uint32_t startAddr, uint32_t endAddr); + +/*! + * @brief Sets the MPU region access rights for masters with read, write, and execute rights. + * The MPU access rights depend on two board classifications of bus masters. + * The privilege rights masters and the normal rights masters. + * The privilege rights masters have the read, write, and execute access rights. + * Except the normal read and write rights, the execute rights are also + * allowed for these masters. The privilege rights masters normally range from + * bus masters 0 - 3. However, the maximum master number is device-specific. + * See the "MPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX". + * The normal rights masters access rights control see + * "MPU_SetRegionRwMasterAccessRights()". + * + * @param base MPU peripheral base address. + * @param regionNum MPU region number. Should range from 0 to + * FSL_FEATURE_MPU_DESCRIPTOR_COUNT - 1. + * @param masterNum MPU bus master number. Should range from 0 to + * MPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX. + * @param accessRights The pointer to the MPU access rights configuration. See "mpu_rwxrights_master_access_control_t". + */ +void MPU_SetRegionRwxMasterAccessRights(MPU_Type *base, + uint32_t regionNum, + uint32_t masterNum, + const mpu_rwxrights_master_access_control_t *accessRights); +#if FSL_FEATURE_MPU_HAS_MASTER_4_7 +/*! + * @brief Sets the MPU region access rights for masters with read and write rights. + * The MPU access rights depend on two board classifications of bus masters. + * The privilege rights masters and the normal rights masters. + * The normal rights masters only have the read and write access permissions. + * The privilege rights access control see "MPU_SetRegionRwxMasterAccessRights". + * + * @param base MPU peripheral base address. + * @param regionNum MPU region number. The range is from 0 to + * FSL_FEATURE_MPU_DESCRIPTOR_COUNT - 1. + * @param masterNum MPU bus master number. Should range from FSL_FEATURE_MPU_PRIVILEGED_RIGHTS_MASTER_COUNT + * to ~ FSL_FEATURE_MPU_MASTER_MAX_INDEX. + * @param accessRights The pointer to the MPU access rights configuration. See "mpu_rwrights_master_access_control_t". + */ +void MPU_SetRegionRwMasterAccessRights(MPU_Type *base, + uint32_t regionNum, + uint32_t masterNum, + const mpu_rwrights_master_access_control_t *accessRights); +#endif /* FSL_FEATURE_MPU_HAS_MASTER_4_7 */ +/*! + * @brief Gets the numbers of slave ports where errors occur. + * + * @param base MPU peripheral base address. + * @param slaveNum MPU slave port number. + * @return The slave ports error status. + * true - error happens in this slave port. + * false - error didn't happen in this slave port. + */ +bool MPU_GetSlavePortErrorStatus(MPU_Type *base, mpu_slave_t slaveNum); + +/*! + * @brief Gets the MPU detailed error access information. + * + * @param base MPU peripheral base address. + * @param slaveNum MPU slave port number. + * @param errInform The pointer to the MPU access error information. See "mpu_access_err_info_t". + */ +void MPU_GetDetailErrorAccessInfo(MPU_Type *base, mpu_slave_t slaveNum, mpu_access_err_info_t *errInform); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_MPU_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pdb.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pdb.c new file mode 100644 index 00000000000..c3b8c6ebc70 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pdb.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_pdb.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get instance number for PDB module. + * + * @param base PDB peripheral base address + */ +static uint32_t PDB_GetInstance(PDB_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to PDB bases for each instance. */ +static PDB_Type *const s_pdbBases[] = PDB_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to PDB clocks for each instance. */ +static const clock_ip_name_t s_pdbClocks[] = PDB_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Codes + ******************************************************************************/ +static uint32_t PDB_GetInstance(PDB_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_PDB_COUNT; instance++) + { + if (s_pdbBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_PDB_COUNT); + + return instance; +} + +void PDB_Init(PDB_Type *base, const pdb_config_t *config) +{ + assert(NULL != config); + + uint32_t tmp32; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the clock. */ + CLOCK_EnableClock(s_pdbClocks[PDB_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Configure. */ + /* PDBx_SC. */ + tmp32 = base->SC & + ~(PDB_SC_LDMOD_MASK | PDB_SC_PRESCALER_MASK | PDB_SC_TRGSEL_MASK | PDB_SC_MULT_MASK | PDB_SC_CONT_MASK); + + tmp32 |= PDB_SC_LDMOD(config->loadValueMode) | PDB_SC_PRESCALER(config->prescalerDivider) | + PDB_SC_TRGSEL(config->triggerInputSource) | PDB_SC_MULT(config->dividerMultiplicationFactor); + if (config->enableContinuousMode) + { + tmp32 |= PDB_SC_CONT_MASK; + } + base->SC = tmp32; + + PDB_Enable(base, true); /* Enable the PDB module. */ +} + +void PDB_Deinit(PDB_Type *base) +{ + PDB_Enable(base, false); /* Disable the PDB module. */ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable the clock. */ + CLOCK_DisableClock(s_pdbClocks[PDB_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void PDB_GetDefaultConfig(pdb_config_t *config) +{ + assert(NULL != config); + + config->loadValueMode = kPDB_LoadValueImmediately; + config->prescalerDivider = kPDB_PrescalerDivider1; + config->dividerMultiplicationFactor = kPDB_DividerMultiplicationFactor1; + config->triggerInputSource = kPDB_TriggerSoftware; + config->enableContinuousMode = false; +} + +#if defined(FSL_FEATURE_PDB_HAS_DAC) && FSL_FEATURE_PDB_HAS_DAC +void PDB_SetDACTriggerConfig(PDB_Type *base, uint32_t channel, pdb_dac_trigger_config_t *config) +{ + assert(channel < PDB_INTC_COUNT); + assert(NULL != config); + + uint32_t tmp32 = 0U; + + /* PDBx_DACINTC. */ + if (config->enableExternalTriggerInput) + { + tmp32 |= PDB_INTC_EXT_MASK; + } + if (config->enableIntervalTrigger) + { + tmp32 |= PDB_INTC_TOE_MASK; + } + base->DAC[channel].INTC = tmp32; +} +#endif /* FSL_FEATURE_PDB_HAS_DAC */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pdb.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pdb.h new file mode 100644 index 00000000000..126bdc339c5 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pdb.h @@ -0,0 +1,576 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_PDB_H_ +#define _FSL_PDB_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup pdb + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief PDB driver version 2.0.1. */ +#define FSL_PDB_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! + * @brief PDB flags. + */ +enum _pdb_status_flags +{ + kPDB_LoadOKFlag = PDB_SC_LDOK_MASK, /*!< This flag is automatically cleared when the values in buffers are + loaded into the internal registers after the LDOK bit is set or the + PDBEN is cleared. */ + kPDB_DelayEventFlag = PDB_SC_PDBIF_MASK, /*!< PDB timer delay event flag. */ +}; + +/*! + * @brief PDB ADC PreTrigger channel flags. + */ +enum _pdb_adc_pretrigger_flags +{ + /* PDB PreTrigger channel match flags. */ + kPDB_ADCPreTriggerChannel0Flag = PDB_S_CF(1U << 0), /*!< Pre-trigger 0 flag. */ + kPDB_ADCPreTriggerChannel1Flag = PDB_S_CF(1U << 1), /*!< Pre-trigger 1 flag. */ +#if (PDB_DLY_COUNT2 > 2) + kPDB_ADCPreTriggerChannel2Flag = PDB_S_CF(1U << 2), /*!< Pre-trigger 2 flag. */ + kPDB_ADCPreTriggerChannel3Flag = PDB_S_CF(1U << 3), /*!< Pre-trigger 3 flag. */ +#endif /* PDB_DLY_COUNT2 > 2 */ +#if (PDB_DLY_COUNT2 > 4) + kPDB_ADCPreTriggerChannel4Flag = PDB_S_CF(1U << 4), /*!< Pre-trigger 4 flag. */ + kPDB_ADCPreTriggerChannel5Flag = PDB_S_CF(1U << 5), /*!< Pre-trigger 5 flag. */ + kPDB_ADCPreTriggerChannel6Flag = PDB_S_CF(1U << 6), /*!< Pre-trigger 6 flag. */ + kPDB_ADCPreTriggerChannel7Flag = PDB_S_CF(1U << 7), /*!< Pre-trigger 7 flag. */ +#endif /* PDB_DLY_COUNT2 > 4 */ + + /* PDB PreTrigger channel error flags. */ + kPDB_ADCPreTriggerChannel0ErrorFlag = PDB_S_ERR(1U << 0), /*!< Pre-trigger 0 Error. */ + kPDB_ADCPreTriggerChannel1ErrorFlag = PDB_S_ERR(1U << 1), /*!< Pre-trigger 1 Error. */ +#if (PDB_DLY_COUNT2 > 2) + kPDB_ADCPreTriggerChannel2ErrorFlag = PDB_S_ERR(1U << 2), /*!< Pre-trigger 2 Error. */ + kPDB_ADCPreTriggerChannel3ErrorFlag = PDB_S_ERR(1U << 3), /*!< Pre-trigger 3 Error. */ +#endif /* PDB_DLY_COUNT2 > 2 */ +#if (PDB_DLY_COUNT2 > 4) + kPDB_ADCPreTriggerChannel4ErrorFlag = PDB_S_ERR(1U << 4), /*!< Pre-trigger 4 Error. */ + kPDB_ADCPreTriggerChannel5ErrorFlag = PDB_S_ERR(1U << 5), /*!< Pre-trigger 5 Error. */ + kPDB_ADCPreTriggerChannel6ErrorFlag = PDB_S_ERR(1U << 6), /*!< Pre-trigger 6 Error. */ + kPDB_ADCPreTriggerChannel7ErrorFlag = PDB_S_ERR(1U << 7), /*!< Pre-trigger 7 Error. */ +#endif /* PDB_DLY_COUNT2 > 4 */ +}; + +/*! + * @brief PDB buffer interrupts. + */ +enum _pdb_interrupt_enable +{ + kPDB_SequenceErrorInterruptEnable = PDB_SC_PDBEIE_MASK, /*!< PDB sequence error interrupt enable. */ + kPDB_DelayInterruptEnable = PDB_SC_PDBIE_MASK, /*!< PDB delay interrupt enable. */ +}; + +/*! + * @brief PDB load value mode. + * + * Selects the mode to load the internal values after doing the load operation (write 1 to PDBx_SC[LDOK]). + * These values are for the following operations. + * - PDB counter (PDBx_MOD, PDBx_IDLY) + * - ADC trigger (PDBx_CHnDLYm) + * - DAC trigger (PDBx_DACINTx) + * - CMP trigger (PDBx_POyDLY) + */ +typedef enum _pdb_load_value_mode +{ + kPDB_LoadValueImmediately = 0U, /*!< Load immediately after 1 is written to LDOK. */ + kPDB_LoadValueOnCounterOverflow = 1U, /*!< Load when the PDB counter overflows (reaches the MOD + register value). */ + kPDB_LoadValueOnTriggerInput = 2U, /*!< Load a trigger input event is detected. */ + kPDB_LoadValueOnCounterOverflowOrTriggerInput = 3U, /*!< Load either when the PDB counter overflows or a trigger + input is detected. */ +} pdb_load_value_mode_t; + +/*! + * @brief Prescaler divider. + * + * Counting uses the peripheral clock divided by multiplication factor selected by times of MULT. + */ +typedef enum _pdb_prescaler_divider +{ + kPDB_PrescalerDivider1 = 0U, /*!< Divider x1. */ + kPDB_PrescalerDivider2 = 1U, /*!< Divider x2. */ + kPDB_PrescalerDivider4 = 2U, /*!< Divider x4. */ + kPDB_PrescalerDivider8 = 3U, /*!< Divider x8. */ + kPDB_PrescalerDivider16 = 4U, /*!< Divider x16. */ + kPDB_PrescalerDivider32 = 5U, /*!< Divider x32. */ + kPDB_PrescalerDivider64 = 6U, /*!< Divider x64. */ + kPDB_PrescalerDivider128 = 7U, /*!< Divider x128. */ +} pdb_prescaler_divider_t; + +/*! + * @brief Multiplication factor select for prescaler. + * + * Selects the multiplication factor of the prescaler divider for the counter clock. + */ +typedef enum _pdb_divider_multiplication_factor +{ + kPDB_DividerMultiplicationFactor1 = 0U, /*!< Multiplication factor is 1. */ + kPDB_DividerMultiplicationFactor10 = 1U, /*!< Multiplication factor is 10. */ + kPDB_DividerMultiplicationFactor20 = 2U, /*!< Multiplication factor is 20. */ + kPDB_DividerMultiplicationFactor40 = 3U, /*!< Multiplication factor is 40. */ +} pdb_divider_multiplication_factor_t; + +/*! + * @brief Trigger input source + * + * Selects the trigger input source for the PDB. The trigger input source can be internal or external (EXTRG pin), or + * the software trigger. See chip configuration details for the actual PDB input trigger connections. + */ +typedef enum _pdb_trigger_input_source +{ + kPDB_TriggerInput0 = 0U, /*!< Trigger-In 0. */ + kPDB_TriggerInput1 = 1U, /*!< Trigger-In 1. */ + kPDB_TriggerInput2 = 2U, /*!< Trigger-In 2. */ + kPDB_TriggerInput3 = 3U, /*!< Trigger-In 3. */ + kPDB_TriggerInput4 = 4U, /*!< Trigger-In 4. */ + kPDB_TriggerInput5 = 5U, /*!< Trigger-In 5. */ + kPDB_TriggerInput6 = 6U, /*!< Trigger-In 6. */ + kPDB_TriggerInput7 = 7U, /*!< Trigger-In 7. */ + kPDB_TriggerInput8 = 8U, /*!< Trigger-In 8. */ + kPDB_TriggerInput9 = 9U, /*!< Trigger-In 9. */ + kPDB_TriggerInput10 = 10U, /*!< Trigger-In 10. */ + kPDB_TriggerInput11 = 11U, /*!< Trigger-In 11. */ + kPDB_TriggerInput12 = 12U, /*!< Trigger-In 12. */ + kPDB_TriggerInput13 = 13U, /*!< Trigger-In 13. */ + kPDB_TriggerInput14 = 14U, /*!< Trigger-In 14. */ + kPDB_TriggerSoftware = 15U, /*!< Trigger-In 15, software trigger. */ +} pdb_trigger_input_source_t; + +/*! + * @brief PDB module configuration. + */ +typedef struct _pdb_config +{ + pdb_load_value_mode_t loadValueMode; /*!< Select the load value mode. */ + pdb_prescaler_divider_t prescalerDivider; /*!< Select the prescaler divider. */ + pdb_divider_multiplication_factor_t dividerMultiplicationFactor; /*!< Multiplication factor select for prescaler. */ + pdb_trigger_input_source_t triggerInputSource; /*!< Select the trigger input source. */ + bool enableContinuousMode; /*!< Enable the PDB operation in Continuous mode.*/ +} pdb_config_t; + +/*! + * @brief PDB ADC Pre-trigger configuration. + */ +typedef struct _pdb_adc_pretrigger_config +{ + uint32_t enablePreTriggerMask; /*!< PDB Channel Pre-trigger Enable. */ + uint32_t enableOutputMask; /*!< PDB Channel Pre-trigger Output Select. + PDB channel's corresponding pre-trigger asserts when the counter + reaches the channel delay register. */ + uint32_t enableBackToBackOperationMask; /*!< PDB Channel pre-trigger Back-to-Back Operation Enable. + Back-to-back operation enables the ADC conversions complete to trigger + the next PDB channel pre-trigger and trigger output, so that the ADC + conversions can be triggered on next set of configuration and results + registers.*/ +} pdb_adc_pretrigger_config_t; + +/*! + * @brief PDB DAC trigger configuration. + */ +typedef struct _pdb_dac_trigger_config +{ + bool enableExternalTriggerInput; /*!< Enables the external trigger for DAC interval counter. */ + bool enableIntervalTrigger; /*!< Enables the DAC interval trigger. */ +} pdb_dac_trigger_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization + * @{ + */ + +/*! + * @brief Initializes the PDB module. + * + * This function initializes the PDB module. The operations included are as follows. + * - Enable the clock for PDB instance. + * - Configure the PDB module. + * - Enable the PDB module. + * + * @param base PDB peripheral base address. + * @param config Pointer to the configuration structure. See "pdb_config_t". + */ +void PDB_Init(PDB_Type *base, const pdb_config_t *config); + +/*! + * @brief De-initializes the PDB module. + * + * @param base PDB peripheral base address. + */ +void PDB_Deinit(PDB_Type *base); + +/*! + * @brief Initializes the PDB user configuration structure. + * + * This function initializes the user configuration structure to a default value. The default values are as follows. + * @code + * config->loadValueMode = kPDB_LoadValueImmediately; + * config->prescalerDivider = kPDB_PrescalerDivider1; + * config->dividerMultiplicationFactor = kPDB_DividerMultiplicationFactor1; + * config->triggerInputSource = kPDB_TriggerSoftware; + * config->enableContinuousMode = false; + * @endcode + * @param config Pointer to configuration structure. See "pdb_config_t". + */ +void PDB_GetDefaultConfig(pdb_config_t *config); + +/*! + * @brief Enables the PDB module. + * + * @param base PDB peripheral base address. + * @param enable Enable the module or not. + */ +static inline void PDB_Enable(PDB_Type *base, bool enable) +{ + if (enable) + { + base->SC |= PDB_SC_PDBEN_MASK; + } + else + { + base->SC &= ~PDB_SC_PDBEN_MASK; + } +} + +/* @} */ + +/*! + * @name Basic Counter + * @{ + */ + +/*! + * @brief Triggers the PDB counter by software. + * + * @param base PDB peripheral base address. + */ +static inline void PDB_DoSoftwareTrigger(PDB_Type *base) +{ + base->SC |= PDB_SC_SWTRIG_MASK; +} + +/*! + * @brief Loads the counter values. + * + * This function loads the counter values from the internal buffer. + * See "pdb_load_value_mode_t" about PDB's load mode. + * + * @param base PDB peripheral base address. + */ +static inline void PDB_DoLoadValues(PDB_Type *base) +{ + base->SC |= PDB_SC_LDOK_MASK; +} + +/*! + * @brief Enables the DMA for the PDB module. + * + * @param base PDB peripheral base address. + * @param enable Enable the feature or not. + */ +static inline void PDB_EnableDMA(PDB_Type *base, bool enable) +{ + if (enable) + { + base->SC |= PDB_SC_DMAEN_MASK; + } + else + { + base->SC &= ~PDB_SC_DMAEN_MASK; + } +} + +/*! + * @brief Enables the interrupts for the PDB module. + * + * @param base PDB peripheral base address. + * @param mask Mask value for interrupts. See "_pdb_interrupt_enable". + */ +static inline void PDB_EnableInterrupts(PDB_Type *base, uint32_t mask) +{ + assert(0U == (mask & ~(PDB_SC_PDBEIE_MASK | PDB_SC_PDBIE_MASK))); + + base->SC |= mask; +} + +/*! + * @brief Disables the interrupts for the PDB module. + * + * @param base PDB peripheral base address. + * @param mask Mask value for interrupts. See "_pdb_interrupt_enable". + */ +static inline void PDB_DisableInterrupts(PDB_Type *base, uint32_t mask) +{ + assert(0U == (mask & ~(PDB_SC_PDBEIE_MASK | PDB_SC_PDBIE_MASK))); + + base->SC &= ~mask; +} + +/*! + * @brief Gets the status flags of the PDB module. + * + * @param base PDB peripheral base address. + * + * @return Mask value for asserted flags. See "_pdb_status_flags". + */ +static inline uint32_t PDB_GetStatusFlags(PDB_Type *base) +{ + return base->SC & (PDB_SC_PDBIF_MASK | PDB_SC_LDOK_MASK); +} + +/*! + * @brief Clears the status flags of the PDB module. + * + * @param base PDB peripheral base address. + * @param mask Mask value of flags. See "_pdb_status_flags". + */ +static inline void PDB_ClearStatusFlags(PDB_Type *base, uint32_t mask) +{ + assert(0U == (mask & ~PDB_SC_PDBIF_MASK)); + + base->SC &= ~mask; +} + +/*! + * @brief Specifies the counter period. + * + * @param base PDB peripheral base address. + * @param value Setting value for the modulus. 16-bit is available. + */ +static inline void PDB_SetModulusValue(PDB_Type *base, uint32_t value) +{ + base->MOD = PDB_MOD_MOD(value); +} + +/*! + * @brief Gets the PDB counter's current value. + * + * @param base PDB peripheral base address. + * + * @return PDB counter's current value. + */ +static inline uint32_t PDB_GetCounterValue(PDB_Type *base) +{ + return base->CNT; +} + +/*! + * @brief Sets the value for the PDB counter delay event. + * + * @param base PDB peripheral base address. + * @param value Setting value for PDB counter delay event. 16-bit is available. + */ +static inline void PDB_SetCounterDelayValue(PDB_Type *base, uint32_t value) +{ + base->IDLY = PDB_IDLY_IDLY(value); +} +/* @} */ + +/*! + * @name ADC Pre-trigger + * @{ + */ + +/*! + * @brief Configures the ADC pre-trigger in the PDB module. + * + * @param base PDB peripheral base address. + * @param channel Channel index for ADC instance. + * @param config Pointer to the configuration structure. See "pdb_adc_pretrigger_config_t". + */ +static inline void PDB_SetADCPreTriggerConfig(PDB_Type *base, uint32_t channel, pdb_adc_pretrigger_config_t *config) +{ + assert(channel < PDB_C1_COUNT); + assert(NULL != config); + + base->CH[channel].C1 = PDB_C1_BB(config->enableBackToBackOperationMask) | PDB_C1_TOS(config->enableOutputMask) | + PDB_C1_EN(config->enablePreTriggerMask); +} + +/*! + * @brief Sets the value for the ADC pre-trigger delay event. + * + * This function sets the value for ADC pre-trigger delay event. It specifies the delay value for the channel's + * corresponding pre-trigger. The pre-trigger asserts when the PDB counter is equal to the set value. + * + * @param base PDB peripheral base address. + * @param channel Channel index for ADC instance. + * @param preChannel Channel group index for ADC instance. + * @param value Setting value for ADC pre-trigger delay event. 16-bit is available. + */ +static inline void PDB_SetADCPreTriggerDelayValue(PDB_Type *base, uint32_t channel, uint32_t preChannel, uint32_t value) +{ + assert(channel < PDB_C1_COUNT); + assert(preChannel < PDB_DLY_COUNT2); + /* xx_COUNT2 is actually the count for pre-triggers in header file. xx_COUNT is used for the count of channels. */ + + base->CH[channel].DLY[preChannel] = PDB_DLY_DLY(value); +} + +/*! + * @brief Gets the ADC pre-trigger's status flags. + * + * @param base PDB peripheral base address. + * @param channel Channel index for ADC instance. + * + * @return Mask value for asserted flags. See "_pdb_adc_pretrigger_flags". + */ +static inline uint32_t PDB_GetADCPreTriggerStatusFlags(PDB_Type *base, uint32_t channel) +{ + assert(channel < PDB_C1_COUNT); + + return base->CH[channel].S; +} + +/*! + * @brief Clears the ADC pre-trigger status flags. + * + * @param base PDB peripheral base address. + * @param channel Channel index for ADC instance. + * @param mask Mask value for flags. See "_pdb_adc_pretrigger_flags". + */ +static inline void PDB_ClearADCPreTriggerStatusFlags(PDB_Type *base, uint32_t channel, uint32_t mask) +{ + assert(channel < PDB_C1_COUNT); + + base->CH[channel].S &= ~mask; +} + +/* @} */ + +#if defined(FSL_FEATURE_PDB_HAS_DAC) && FSL_FEATURE_PDB_HAS_DAC +/*! + * @name DAC Interval Trigger + * @{ + */ + +/*! + * @brief Configures the DAC trigger in the PDB module. + * + * @param base PDB peripheral base address. + * @param channel Channel index for DAC instance. + * @param config Pointer to the configuration structure. See "pdb_dac_trigger_config_t". + */ +void PDB_SetDACTriggerConfig(PDB_Type *base, uint32_t channel, pdb_dac_trigger_config_t *config); + +/*! + * @brief Sets the value for the DAC interval event. + * + * This fucntion sets the value for DAC interval event. DAC interval trigger triggers the DAC module to update + * the buffer when the DAC interval counter is equal to the set value. + * + * @param base PDB peripheral base address. + * @param channel Channel index for DAC instance. + * @param value Setting value for the DAC interval event. + */ +static inline void PDB_SetDACTriggerIntervalValue(PDB_Type *base, uint32_t channel, uint32_t value) +{ + assert(channel < PDB_INT_COUNT); + + base->DAC[channel].INT = PDB_INT_INT(value); +} + +/* @} */ +#endif /* FSL_FEATURE_PDB_HAS_DAC */ + +/*! + * @name Pulse-Out Trigger + * @{ + */ + +/*! + * @brief Enables the pulse out trigger channels. + * + * @param base PDB peripheral base address. + * @param channelMask Channel mask value for multiple pulse out trigger channel. + * @param enable Whether the feature is enabled or not. + */ +static inline void PDB_EnablePulseOutTrigger(PDB_Type *base, uint32_t channelMask, bool enable) +{ + if (enable) + { + base->POEN |= PDB_POEN_POEN(channelMask); + } + else + { + base->POEN &= ~(PDB_POEN_POEN(channelMask)); + } +} + +/*! + * @brief Sets event values for the pulse out trigger. + * + * This function is used to set event values for the pulse output trigger. + * These pulse output trigger delay values specify the delay for the PDB Pulse-out. Pulse-out goes high when the PDB + * counter is equal to the pulse output high value (value1). Pulse-out goes low when the PDB counter is equal to the + * pulse output low value (value2). + * + * @param base PDB peripheral base address. + * @param channel Channel index for pulse out trigger channel. + * @param value1 Setting value for pulse out high. + * @param value2 Setting value for pulse out low. + */ +static inline void PDB_SetPulseOutTriggerDelayValue(PDB_Type *base, uint32_t channel, uint32_t value1, uint32_t value2) +{ + assert(channel < PDB_PODLY_COUNT); + + base->PODLY[channel] = PDB_PODLY_DLY1(value1) | PDB_PODLY_DLY2(value2); +} + +/* @} */ +#if defined(__cplusplus) +} +#endif +/*! + * @} + */ +#endif /* _FSL_PDB_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pit.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pit.c new file mode 100644 index 00000000000..81c844f7fbf --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pit.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_pit.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address to be used to gate or ungate the module clock + * + * @param base PIT peripheral base address + * + * @return The PIT instance + */ +static uint32_t PIT_GetInstance(PIT_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to PIT bases for each instance. */ +static PIT_Type *const s_pitBases[] = PIT_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to PIT clocks for each instance. */ +static const clock_ip_name_t s_pitClocks[] = PIT_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t PIT_GetInstance(PIT_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_PIT_COUNT; instance++) + { + if (s_pitBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_PIT_COUNT); + + return instance; +} + +void PIT_Init(PIT_Type *base, const pit_config_t *config) +{ + assert(config); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate the PIT clock*/ + CLOCK_EnableClock(s_pitClocks[PIT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Enable PIT timers */ + base->MCR &= ~PIT_MCR_MDIS_MASK; + + /* Config timer operation when in debug mode */ + if (config->enableRunInDebug) + { + base->MCR &= ~PIT_MCR_FRZ_MASK; + } + else + { + base->MCR |= PIT_MCR_FRZ_MASK; + } +} + +void PIT_Deinit(PIT_Type *base) +{ + /* Disable PIT timers */ + base->MCR |= PIT_MCR_MDIS_MASK; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate the PIT clock*/ + CLOCK_DisableClock(s_pitClocks[PIT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +#if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && FSL_FEATURE_PIT_HAS_LIFETIME_TIMER + +uint64_t PIT_GetLifetimeTimerCount(PIT_Type *base) +{ + uint32_t valueH = 0U; + uint32_t valueL = 0U; + + /* LTMR64H should be read before LTMR64L */ + valueH = base->LTMR64H; + valueL = base->LTMR64L; + + return (((uint64_t)valueH << 32U) + (uint64_t)(valueL)); +} + +#endif /* FSL_FEATURE_PIT_HAS_LIFETIME_TIMER */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pit.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pit.h new file mode 100644 index 00000000000..edc4e76fbf2 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pit.h @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_PIT_H_ +#define _FSL_PIT_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup pit + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_PIT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +/*@}*/ + +/*! + * @brief List of PIT channels + * @note Actual number of available channels is SoC dependent + */ +typedef enum _pit_chnl +{ + kPIT_Chnl_0 = 0U, /*!< PIT channel number 0*/ + kPIT_Chnl_1, /*!< PIT channel number 1 */ + kPIT_Chnl_2, /*!< PIT channel number 2 */ + kPIT_Chnl_3, /*!< PIT channel number 3 */ +} pit_chnl_t; + +/*! @brief List of PIT interrupts */ +typedef enum _pit_interrupt_enable +{ + kPIT_TimerInterruptEnable = PIT_TCTRL_TIE_MASK, /*!< Timer interrupt enable*/ +} pit_interrupt_enable_t; + +/*! @brief List of PIT status flags */ +typedef enum _pit_status_flags +{ + kPIT_TimerFlag = PIT_TFLG_TIF_MASK, /*!< Timer flag */ +} pit_status_flags_t; + +/*! + * @brief PIT configuration structure + * + * This structure holds the configuration settings for the PIT peripheral. To initialize this + * structure to reasonable defaults, call the PIT_GetDefaultConfig() function and pass a + * pointer to your config structure instance. + * + * The configuration structure can be made constant so it resides in flash. + */ +typedef struct _pit_config +{ + bool enableRunInDebug; /*!< true: Timers run in debug mode; false: Timers stop in debug mode */ +} pit_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the PIT clock, enables the PIT module, and configures the peripheral for basic operations. + * + * @note This API should be called at the beginning of the application using the PIT driver. + * + * @param base PIT peripheral base address + * @param config Pointer to the user's PIT config structure + */ +void PIT_Init(PIT_Type *base, const pit_config_t *config); + +/*! + * @brief Gates the PIT clock and disables the PIT module. + * + * @param base PIT peripheral base address + */ +void PIT_Deinit(PIT_Type *base); + +/*! + * @brief Fills in the PIT configuration structure with the default settings. + * + * The default values are as follows. + * @code + * config->enableRunInDebug = false; + * @endcode + * @param config Pointer to the onfiguration structure. + */ +static inline void PIT_GetDefaultConfig(pit_config_t *config) +{ + assert(config); + + /* Timers are stopped in Debug mode */ + config->enableRunInDebug = false; +} + +#if defined(FSL_FEATURE_PIT_HAS_CHAIN_MODE) && FSL_FEATURE_PIT_HAS_CHAIN_MODE + +/*! + * @brief Enables or disables chaining a timer with the previous timer. + * + * When a timer has a chain mode enabled, it only counts after the previous + * timer has expired. If the timer n-1 has counted down to 0, counter n + * decrements the value by one. Each timer is 32-bits, which allows the developers + * to chain timers together and form a longer timer (64-bits and larger). The first timer + * (timer 0) can't be chained to any other timer. + * + * @param base PIT peripheral base address + * @param channel Timer channel number which is chained with the previous timer + * @param enable Enable or disable chain. + * true: Current timer is chained with the previous timer. + * false: Timer doesn't chain with other timers. + */ +static inline void PIT_SetTimerChainMode(PIT_Type *base, pit_chnl_t channel, bool enable) +{ + if (enable) + { + base->CHANNEL[channel].TCTRL |= PIT_TCTRL_CHN_MASK; + } + else + { + base->CHANNEL[channel].TCTRL &= ~PIT_TCTRL_CHN_MASK; + } +} + +#endif /* FSL_FEATURE_PIT_HAS_CHAIN_MODE */ + +/*! @}*/ + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected PIT interrupts. + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::pit_interrupt_enable_t + */ +static inline void PIT_EnableInterrupts(PIT_Type *base, pit_chnl_t channel, uint32_t mask) +{ + base->CHANNEL[channel].TCTRL |= mask; +} + +/*! + * @brief Disables the selected PIT interrupts. + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * @param mask The interrupts to disable. This is a logical OR of members of the + * enumeration ::pit_interrupt_enable_t + */ +static inline void PIT_DisableInterrupts(PIT_Type *base, pit_chnl_t channel, uint32_t mask) +{ + base->CHANNEL[channel].TCTRL &= ~mask; +} + +/*! + * @brief Gets the enabled PIT interrupts. + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::pit_interrupt_enable_t + */ +static inline uint32_t PIT_GetEnabledInterrupts(PIT_Type *base, pit_chnl_t channel) +{ + return (base->CHANNEL[channel].TCTRL & PIT_TCTRL_TIE_MASK); +} + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the PIT status flags. + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::pit_status_flags_t + */ +static inline uint32_t PIT_GetStatusFlags(PIT_Type *base, pit_chnl_t channel) +{ + return (base->CHANNEL[channel].TFLG & PIT_TFLG_TIF_MASK); +} + +/*! + * @brief Clears the PIT status flags. + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::pit_status_flags_t + */ +static inline void PIT_ClearStatusFlags(PIT_Type *base, pit_chnl_t channel, uint32_t mask) +{ + base->CHANNEL[channel].TFLG = mask; +} + +/*! @}*/ + +/*! + * @name Read and Write the timer period + * @{ + */ + +/*! + * @brief Sets the timer period in units of count. + * + * Timers begin counting from the value set by this function until it reaches 0, + * then it generates an interrupt and load this register value again. + * Writing a new value to this register does not restart the timer. Instead, the value + * is loaded after the timer expires. + * + * @note Users can call the utility macros provided in fsl_common.h to convert to ticks. + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * @param count Timer period in units of ticks + */ +static inline void PIT_SetTimerPeriod(PIT_Type *base, pit_chnl_t channel, uint32_t count) +{ + base->CHANNEL[channel].LDVAL = count; +} + +/*! + * @brief Reads the current timer counting value. + * + * This function returns the real-time timer counting value, in a range from 0 to a + * timer period. + * + * @note Users can call the utility macros provided in fsl_common.h to convert ticks to usec or msec. + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * + * @return Current timer counting value in ticks + */ +static inline uint32_t PIT_GetCurrentTimerCount(PIT_Type *base, pit_chnl_t channel) +{ + return base->CHANNEL[channel].CVAL; +} + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ + +/*! + * @brief Starts the timer counting. + * + * After calling this function, timers load period value, count down to 0 and + * then load the respective start value again. Each time a timer reaches 0, + * it generates a trigger pulse and sets the timeout interrupt flag. + * + * @param base PIT peripheral base address + * @param channel Timer channel number. + */ +static inline void PIT_StartTimer(PIT_Type *base, pit_chnl_t channel) +{ + base->CHANNEL[channel].TCTRL |= PIT_TCTRL_TEN_MASK; +} + +/*! + * @brief Stops the timer counting. + * + * This function stops every timer counting. Timers reload their periods + * respectively after the next time they call the PIT_DRV_StartTimer. + * + * @param base PIT peripheral base address + * @param channel Timer channel number. + */ +static inline void PIT_StopTimer(PIT_Type *base, pit_chnl_t channel) +{ + base->CHANNEL[channel].TCTRL &= ~PIT_TCTRL_TEN_MASK; +} + +/*! @}*/ + +#if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && FSL_FEATURE_PIT_HAS_LIFETIME_TIMER + +/*! + * @brief Reads the current lifetime counter value. + * + * The lifetime timer is a 64-bit timer which chains timer 0 and timer 1 together. + * Timer 0 and 1 are chained by calling the PIT_SetTimerChainMode before using this timer. + * The period of lifetime timer is equal to the "period of timer 0 * period of timer 1". + * For the 64-bit value, the higher 32-bit has the value of timer 1, and the lower 32-bit + * has the value of timer 0. + * + * @param base PIT peripheral base address + * + * @return Current lifetime timer value + */ +uint64_t PIT_GetLifetimeTimerCount(PIT_Type *base); + +#endif /* FSL_FEATURE_PIT_HAS_LIFETIME_TIMER */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_PIT_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pmc.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pmc.c new file mode 100644 index 00000000000..82d7b7ace13 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pmc.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_pmc.h" + +#if (defined(FSL_FEATURE_PMC_HAS_PARAM) && FSL_FEATURE_PMC_HAS_PARAM) +void PMC_GetParam(PMC_Type *base, pmc_param_t *param) +{ + uint32_t reg = base->PARAM; + ; + param->vlpoEnable = (bool)(reg & PMC_PARAM_VLPOE_MASK); + param->hvdEnable = (bool)(reg & PMC_PARAM_HVDE_MASK); +} +#endif /* FSL_FEATURE_PMC_HAS_PARAM */ + +void PMC_ConfigureLowVoltDetect(PMC_Type *base, const pmc_low_volt_detect_config_t *config) +{ + base->LVDSC1 = (0U | +#if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV) + ((uint32_t)config->voltSelect << PMC_LVDSC1_LVDV_SHIFT) | +#endif + ((uint32_t)config->enableInt << PMC_LVDSC1_LVDIE_SHIFT) | + ((uint32_t)config->enableReset << PMC_LVDSC1_LVDRE_SHIFT) + /* Clear the Low Voltage Detect Flag with previouse power detect setting */ + | PMC_LVDSC1_LVDACK_MASK); +} + +void PMC_ConfigureLowVoltWarning(PMC_Type *base, const pmc_low_volt_warning_config_t *config) +{ + base->LVDSC2 = (0U | +#if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV) + ((uint32_t)config->voltSelect << PMC_LVDSC2_LVWV_SHIFT) | +#endif + ((uint32_t)config->enableInt << PMC_LVDSC2_LVWIE_SHIFT) + /* Clear the Low Voltage Warning Flag with previouse power detect setting */ + | PMC_LVDSC2_LVWACK_MASK); +} + +#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) +void PMC_ConfigureHighVoltDetect(PMC_Type *base, const pmc_high_volt_detect_config_t *config) +{ + base->HVDSC1 = (((uint32_t)config->voltSelect << PMC_HVDSC1_HVDV_SHIFT) | + ((uint32_t)config->enableInt << PMC_HVDSC1_HVDIE_SHIFT) | + ((uint32_t)config->enableReset << PMC_HVDSC1_HVDRE_SHIFT) + /* Clear the High Voltage Detect Flag with previouse power detect setting */ + | PMC_HVDSC1_HVDACK_MASK); +} +#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */ + +#if ((defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) || \ + (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) || \ + (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS)) +void PMC_ConfigureBandgapBuffer(PMC_Type *base, const pmc_bandgap_buffer_config_t *config) +{ + base->REGSC = (0U +#if (defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) + | ((uint32_t)config->enable << PMC_REGSC_BGBE_SHIFT) +#endif /* FSL_FEATURE_PMC_HAS_BGBE */ +#if (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) + | (((uint32_t)config->enableInLowPowerMode << PMC_REGSC_BGEN_SHIFT)) +#endif /* FSL_FEATURE_PMC_HAS_BGEN */ +#if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS) + | ((uint32_t)config->drive << PMC_REGSC_BGBDS_SHIFT) +#endif /* FSL_FEATURE_PMC_HAS_BGBDS */ + ); +} +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pmc.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pmc.h new file mode 100644 index 00000000000..eb3a648ecd4 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_pmc.h @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_PMC_H_ +#define _FSL_PMC_H_ + +#include "fsl_common.h" + +/*! @addtogroup pmc */ +/*! @{ */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief PMC driver version */ +#define FSL_PMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ +/*@}*/ + +#if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV) +/*! + * @brief Low-voltage Detect Voltage Select + */ +typedef enum _pmc_low_volt_detect_volt_select +{ + kPMC_LowVoltDetectLowTrip = 0U, /*!< Low-trip point selected (VLVD = VLVDL )*/ + kPMC_LowVoltDetectHighTrip = 1U /*!< High-trip point selected (VLVD = VLVDH )*/ +} pmc_low_volt_detect_volt_select_t; +#endif + +#if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV) +/*! + * @brief Low-voltage Warning Voltage Select + */ +typedef enum _pmc_low_volt_warning_volt_select +{ + kPMC_LowVoltWarningLowTrip = 0U, /*!< Low-trip point selected (VLVW = VLVW1)*/ + kPMC_LowVoltWarningMid1Trip = 1U, /*!< Mid 1 trip point selected (VLVW = VLVW2)*/ + kPMC_LowVoltWarningMid2Trip = 2U, /*!< Mid 2 trip point selected (VLVW = VLVW3)*/ + kPMC_LowVoltWarningHighTrip = 3U /*!< High-trip point selected (VLVW = VLVW4)*/ +} pmc_low_volt_warning_volt_select_t; +#endif + +#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) +/*! + * @brief High-voltage Detect Voltage Select + */ +typedef enum _pmc_high_volt_detect_volt_select +{ + kPMC_HighVoltDetectLowTrip = 0U, /*!< Low-trip point selected (VHVD = VHVDL )*/ + kPMC_HighVoltDetectHighTrip = 1U /*!< High-trip point selected (VHVD = VHVDH )*/ +} pmc_high_volt_detect_volt_select_t; +#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */ + +#if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS) +/*! + * @brief Bandgap Buffer Drive Select. + */ +typedef enum _pmc_bandgap_buffer_drive_select +{ + kPMC_BandgapBufferDriveLow = 0U, /*!< Low-drive. */ + kPMC_BandgapBufferDriveHigh = 1U /*!< High-drive. */ +} pmc_bandgap_buffer_drive_select_t; +#endif /* FSL_FEATURE_PMC_HAS_BGBDS */ + +#if (defined(FSL_FEATURE_PMC_HAS_VLPO) && FSL_FEATURE_PMC_HAS_VLPO) +/*! + * @brief VLPx Option + */ +typedef enum _pmc_vlp_freq_option +{ + kPMC_FreqRestrict = 0U, /*!< Frequency is restricted in VLPx mode. */ + kPMC_FreqUnrestrict = 1U /*!< Frequency is unrestricted in VLPx mode. */ +} pmc_vlp_freq_mode_t; +#endif /* FSL_FEATURE_PMC_HAS_VLPO */ + +#if (defined(FSL_FEATURE_PMC_HAS_VERID) && FSL_FEATURE_PMC_HAS_VERID) +/*! + @brief IP version ID definition. + */ +typedef struct _pmc_version_id +{ + uint16_t feature; /*!< Feature Specification Number. */ + uint8_t minor; /*!< Minor version number. */ + uint8_t major; /*!< Major version number. */ +} pmc_version_id_t; +#endif /* FSL_FEATURE_PMC_HAS_VERID */ + +#if (defined(FSL_FEATURE_PMC_HAS_PARAM) && FSL_FEATURE_PMC_HAS_PARAM) +/*! @brief IP parameter definition. */ +typedef struct _pmc_param +{ + bool vlpoEnable; /*!< VLPO enable. */ + bool hvdEnable; /*!< HVD enable. */ +} pmc_param_t; +#endif /* FSL_FEATURE_PMC_HAS_PARAM */ + +/*! + * @brief Low-voltage Detect Configuration Structure + */ +typedef struct _pmc_low_volt_detect_config +{ + bool enableInt; /*!< Enable interrupt when Low-voltage detect*/ + bool enableReset; /*!< Enable system reset when Low-voltage detect*/ +#if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV) + pmc_low_volt_detect_volt_select_t voltSelect; /*!< Low-voltage detect trip point voltage selection*/ +#endif +} pmc_low_volt_detect_config_t; + +/*! + * @brief Low-voltage Warning Configuration Structure + */ +typedef struct _pmc_low_volt_warning_config +{ + bool enableInt; /*!< Enable interrupt when low-voltage warning*/ +#if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV) + pmc_low_volt_warning_volt_select_t voltSelect; /*!< Low-voltage warning trip point voltage selection*/ +#endif +} pmc_low_volt_warning_config_t; + +#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) +/*! + * @brief High-voltage Detect Configuration Structure + */ +typedef struct _pmc_high_volt_detect_config +{ + bool enableInt; /*!< Enable interrupt when high-voltage detect*/ + bool enableReset; /*!< Enable system reset when high-voltage detect*/ + pmc_high_volt_detect_volt_select_t voltSelect; /*!< High-voltage detect trip point voltage selection*/ +} pmc_high_volt_detect_config_t; +#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */ + +#if ((defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) || \ + (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) || \ + (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS)) +/*! + * @brief Bandgap Buffer configuration. + */ +typedef struct _pmc_bandgap_buffer_config +{ +#if (defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) + bool enable; /*!< Enable bandgap buffer. */ +#endif +#if (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) + bool enableInLowPowerMode; /*!< Enable bandgap buffer in low-power mode. */ +#endif /* FSL_FEATURE_PMC_HAS_BGEN */ +#if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS) + pmc_bandgap_buffer_drive_select_t drive; /*!< Bandgap buffer drive select. */ +#endif /* FSL_FEATURE_PMC_HAS_BGBDS */ +} pmc_bandgap_buffer_config_t; +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! @name Power Management Controller Control APIs*/ +/*@{*/ + +#if (defined(FSL_FEATURE_PMC_HAS_VERID) && FSL_FEATURE_PMC_HAS_VERID) +/*! + * @brief Gets the PMC version ID. + * + * This function gets the PMC version ID, including major version number, + * minor version number, and a feature specification number. + * + * @param base PMC peripheral base address. + * @param versionId Pointer to version ID structure. + */ +static inline void PMC_GetVersionId(PMC_Type *base, pmc_version_id_t *versionId) +{ + *((uint32_t *)versionId) = base->VERID; +} +#endif /* FSL_FEATURE_PMC_HAS_VERID */ + +#if (defined(FSL_FEATURE_PMC_HAS_PARAM) && FSL_FEATURE_PMC_HAS_PARAM) +/*! + * @brief Gets the PMC parameter. + * + * This function gets the PMC parameter including the VLPO enable and the HVD enable. + * + * @param base PMC peripheral base address. + * @param param Pointer to PMC param structure. + */ +void PMC_GetParam(PMC_Type *base, pmc_param_t *param); +#endif + +/*! + * @brief Configures the low-voltage detect setting. + * + * This function configures the low-voltage detect setting, including the trip + * point voltage setting, enables or disables the interrupt, enables or disables the system reset. + * + * @param base PMC peripheral base address. + * @param config Low-voltage detect configuration structure. + */ +void PMC_ConfigureLowVoltDetect(PMC_Type *base, const pmc_low_volt_detect_config_t *config); + +/*! + * @brief Gets the Low-voltage Detect Flag status. + * + * This function reads the current LVDF status. If it returns 1, a low-voltage event is detected. + * + * @param base PMC peripheral base address. + * @return Current low-voltage detect flag + * - true: Low-voltage detected + * - false: Low-voltage not detected + */ +static inline bool PMC_GetLowVoltDetectFlag(PMC_Type *base) +{ + return (bool)(base->LVDSC1 & PMC_LVDSC1_LVDF_MASK); +} + +/*! + * @brief Acknowledges clearing the Low-voltage Detect flag. + * + * This function acknowledges the low-voltage detection errors (write 1 to + * clear LVDF). + * + * @param base PMC peripheral base address. + */ +static inline void PMC_ClearLowVoltDetectFlag(PMC_Type *base) +{ + base->LVDSC1 |= PMC_LVDSC1_LVDACK_MASK; +} + +/*! + * @brief Configures the low-voltage warning setting. + * + * This function configures the low-voltage warning setting, including the trip + * point voltage setting and enabling or disabling the interrupt. + * + * @param base PMC peripheral base address. + * @param config Low-voltage warning configuration structure. + */ +void PMC_ConfigureLowVoltWarning(PMC_Type *base, const pmc_low_volt_warning_config_t *config); + +/*! + * @brief Gets the Low-voltage Warning Flag status. + * + * This function polls the current LVWF status. When 1 is returned, it + * indicates a low-voltage warning event. LVWF is set when V Supply transitions + * below the trip point or after reset and V Supply is already below the V LVW. + * + * @param base PMC peripheral base address. + * @return Current LVWF status + * - true: Low-voltage Warning Flag is set. + * - false: the Low-voltage Warning does not happen. + */ +static inline bool PMC_GetLowVoltWarningFlag(PMC_Type *base) +{ + return (bool)(base->LVDSC2 & PMC_LVDSC2_LVWF_MASK); +} + +/*! + * @brief Acknowledges the Low-voltage Warning flag. + * + * This function acknowledges the low voltage warning errors (write 1 to + * clear LVWF). + * + * @param base PMC peripheral base address. + */ +static inline void PMC_ClearLowVoltWarningFlag(PMC_Type *base) +{ + base->LVDSC2 |= PMC_LVDSC2_LVWACK_MASK; +} + +#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) +/*! + * @brief Configures the high-voltage detect setting. + * + * This function configures the high-voltage detect setting, including the trip + * point voltage setting, enabling or disabling the interrupt, enabling or disabling the system reset. + * + * @param base PMC peripheral base address. + * @param config High-voltage detect configuration structure. + */ +void PMC_ConfigureHighVoltDetect(PMC_Type *base, const pmc_high_volt_detect_config_t *config); + +/*! + * @brief Gets the High-voltage Detect Flag status. + * + * This function reads the current HVDF status. If it returns 1, a low + * voltage event is detected. + * + * @param base PMC peripheral base address. + * @return Current high-voltage detect flag + * - true: High-voltage detected + * - false: High-voltage not detected + */ +static inline bool PMC_GetHighVoltDetectFlag(PMC_Type *base) +{ + return (bool)(base->HVDSC1 & PMC_HVDSC1_HVDF_MASK); +} + +/*! + * @brief Acknowledges clearing the High-voltage Detect flag. + * + * This function acknowledges the high-voltage detection errors (write 1 to + * clear HVDF). + * + * @param base PMC peripheral base address. + */ +static inline void PMC_ClearHighVoltDetectFlag(PMC_Type *base) +{ + base->HVDSC1 |= PMC_HVDSC1_HVDACK_MASK; +} +#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */ + +#if ((defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) || \ + (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) || \ + (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS)) +/*! + * @brief Configures the PMC bandgap. + * + * This function configures the PMC bandgap, including the drive select and + * behavior in low-power mode. + * + * @param base PMC peripheral base address. + * @param config Pointer to the configuration structure + */ +void PMC_ConfigureBandgapBuffer(PMC_Type *base, const pmc_bandgap_buffer_config_t *config); +#endif + +#if (defined(FSL_FEATURE_PMC_HAS_ACKISO) && FSL_FEATURE_PMC_HAS_ACKISO) +/*! + * @brief Gets the acknowledge Peripherals and I/O pads isolation flag. + * + * This function reads the Acknowledge Isolation setting that indicates + * whether certain peripherals and the I/O pads are in a latched state as + * a result of having been in the VLLS mode. + * + * @param base PMC peripheral base address. + * @param base Base address for current PMC instance. + * @return ACK isolation + * 0 - Peripherals and I/O pads are in a normal run state. + * 1 - Certain peripherals and I/O pads are in an isolated and + * latched state. + */ +static inline bool PMC_GetPeriphIOIsolationFlag(PMC_Type *base) +{ + return (bool)(base->REGSC & PMC_REGSC_ACKISO_MASK); +} + +/*! + * @brief Acknowledges the isolation flag to Peripherals and I/O pads. + * + * This function clears the ACK Isolation flag. Writing one to this setting + * when it is set releases the I/O pads and certain peripherals to their normal + * run mode state. + * + * @param base PMC peripheral base address. + */ +static inline void PMC_ClearPeriphIOIsolationFlag(PMC_Type *base) +{ + base->REGSC |= PMC_REGSC_ACKISO_MASK; +} +#endif /* FSL_FEATURE_PMC_HAS_ACKISO */ + +#if (defined(FSL_FEATURE_PMC_HAS_REGONS) && FSL_FEATURE_PMC_HAS_REGONS) +/*! + * @brief Gets the regulator regulation status. + * + * This function returns the regulator to run a regulation status. It provides + * the current status of the internal voltage regulator. + * + * @param base PMC peripheral base address. + * @param base Base address for current PMC instance. + * @return Regulation status + * 0 - Regulator is in a stop regulation or in transition to/from the regulation. + * 1 - Regulator is in a run regulation. + * + */ +static inline bool PMC_IsRegulatorInRunRegulation(PMC_Type *base) +{ + return (bool)(base->REGSC & PMC_REGSC_REGONS_MASK); +} +#endif /* FSL_FEATURE_PMC_HAS_REGONS */ + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/*! @}*/ + +#endif /* _FSL_PMC_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_port.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_port.h new file mode 100644 index 00000000000..74aea8346d2 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_port.h @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SDRVL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_PORT_H_ +#define _FSL_PORT_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup port + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! Version 2.0.2. */ +#define FSL_PORT_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) +/*@}*/ + +#if defined(FSL_FEATURE_PORT_HAS_PULL_ENABLE) && FSL_FEATURE_PORT_HAS_PULL_ENABLE +/*! @brief Internal resistor pull feature selection */ +enum _port_pull +{ + kPORT_PullDisable = 0U, /*!< Internal pull-up/down resistor is disabled. */ + kPORT_PullDown = 2U, /*!< Internal pull-down resistor is enabled. */ + kPORT_PullUp = 3U, /*!< Internal pull-up resistor is enabled. */ +}; +#endif /* FSL_FEATURE_PORT_HAS_PULL_ENABLE */ + +#if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE +/*! @brief Slew rate selection */ +enum _port_slew_rate +{ + kPORT_FastSlewRate = 0U, /*!< Fast slew rate is configured. */ + kPORT_SlowSlewRate = 1U, /*!< Slow slew rate is configured. */ +}; +#endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */ + +#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN +/*! @brief Open Drain feature enable/disable */ +enum _port_open_drain_enable +{ + kPORT_OpenDrainDisable = 0U, /*!< Open drain output is disabled. */ + kPORT_OpenDrainEnable = 1U, /*!< Open drain output is enabled. */ +}; +#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */ + +#if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER +/*! @brief Passive filter feature enable/disable */ +enum _port_passive_filter_enable +{ + kPORT_PassiveFilterDisable = 0U, /*!< Passive input filter is disabled. */ + kPORT_PassiveFilterEnable = 1U, /*!< Passive input filter is enabled. */ +}; +#endif + +#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH +/*! @brief Configures the drive strength. */ +enum _port_drive_strength +{ + kPORT_LowDriveStrength = 0U, /*!< Low-drive strength is configured. */ + kPORT_HighDriveStrength = 1U, /*!< High-drive strength is configured. */ +}; +#endif /* FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH */ + +#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK +/*! @brief Unlock/lock the pin control register field[15:0] */ +enum _port_lock_register +{ + kPORT_UnlockRegister = 0U, /*!< Pin Control Register fields [15:0] are not locked. */ + kPORT_LockRegister = 1U, /*!< Pin Control Register fields [15:0] are locked. */ +}; +#endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */ + +#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH +/*! @brief Pin mux selection */ +typedef enum _port_mux +{ + kPORT_PinDisabledOrAnalog = 0U, /*!< Corresponding pin is disabled, but is used as an analog pin. */ + kPORT_MuxAsGpio = 1U, /*!< Corresponding pin is configured as GPIO. */ + kPORT_MuxAlt2 = 2U, /*!< Chip-specific */ + kPORT_MuxAlt3 = 3U, /*!< Chip-specific */ + kPORT_MuxAlt4 = 4U, /*!< Chip-specific */ + kPORT_MuxAlt5 = 5U, /*!< Chip-specific */ + kPORT_MuxAlt6 = 6U, /*!< Chip-specific */ + kPORT_MuxAlt7 = 7U, /*!< Chip-specific */ + kPORT_MuxAlt8 = 8U, /*!< Chip-specific */ + kPORT_MuxAlt9 = 9U, /*!< Chip-specific */ + kPORT_MuxAlt10 = 10U, /*!< Chip-specific */ + kPORT_MuxAlt11 = 11U, /*!< Chip-specific */ + kPORT_MuxAlt12 = 12U, /*!< Chip-specific */ + kPORT_MuxAlt13 = 13U, /*!< Chip-specific */ + kPORT_MuxAlt14 = 14U, /*!< Chip-specific */ + kPORT_MuxAlt15 = 15U, /*!< Chip-specific */ +} port_mux_t; +#endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */ + +/*! @brief Configures the interrupt generation condition. */ +typedef enum _port_interrupt +{ + kPORT_InterruptOrDMADisabled = 0x0U, /*!< Interrupt/DMA request is disabled. */ +#if defined(FSL_FEATURE_PORT_HAS_DMA_REQUEST) && FSL_FEATURE_PORT_HAS_DMA_REQUEST + kPORT_DMARisingEdge = 0x1U, /*!< DMA request on rising edge. */ + kPORT_DMAFallingEdge = 0x2U, /*!< DMA request on falling edge. */ + kPORT_DMAEitherEdge = 0x3U, /*!< DMA request on either edge. */ +#endif +#if defined(FSL_FEATURE_PORT_HAS_IRQC_FLAG) && FSL_FEATURE_PORT_HAS_IRQC_FLAG + kPORT_FlagRisingEdge = 0x05U, /*!< Flag sets on rising edge. */ + kPORT_FlagFallingEdge = 0x06U, /*!< Flag sets on falling edge. */ + kPORT_FlagEitherEdge = 0x07U, /*!< Flag sets on either edge. */ +#endif + kPORT_InterruptLogicZero = 0x8U, /*!< Interrupt when logic zero. */ + kPORT_InterruptRisingEdge = 0x9U, /*!< Interrupt on rising edge. */ + kPORT_InterruptFallingEdge = 0xAU, /*!< Interrupt on falling edge. */ + kPORT_InterruptEitherEdge = 0xBU, /*!< Interrupt on either edge. */ + kPORT_InterruptLogicOne = 0xCU, /*!< Interrupt when logic one. */ +#if defined(FSL_FEATURE_PORT_HAS_IRQC_TRIGGER) && FSL_FEATURE_PORT_HAS_IRQC_TRIGGER + kPORT_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high-trigger output. */ + kPORT_ActiveLowTriggerOutputEnable = 0xEU, /*!< Enable active low-trigger output. */ +#endif +} port_interrupt_t; + +#if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER +/*! @brief Digital filter clock source selection */ +typedef enum _port_digital_filter_clock_source +{ + kPORT_BusClock = 0U, /*!< Digital filters are clocked by the bus clock. */ + kPORT_LpoClock = 1U, /*!< Digital filters are clocked by the 1 kHz LPO clock. */ +} port_digital_filter_clock_source_t; + +/*! @brief PORT digital filter feature configuration definition */ +typedef struct _port_digital_filter_config +{ + uint32_t digitalFilterWidth; /*!< Set digital filter width */ + port_digital_filter_clock_source_t clockSource; /*!< Set digital filter clockSource */ +} port_digital_filter_config_t; +#endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */ + +#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH +/*! @brief PORT pin configuration structure */ +typedef struct _port_pin_config +{ +#if defined(FSL_FEATURE_PORT_HAS_PULL_ENABLE) && FSL_FEATURE_PORT_HAS_PULL_ENABLE + uint16_t pullSelect : 2; /*!< No-pull/pull-down/pull-up select */ +#else + uint16_t : 2; +#endif /* FSL_FEATURE_PORT_HAS_PULL_ENABLE */ + +#if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE + uint16_t slewRate : 1; /*!< Fast/slow slew rate Configure */ +#else + uint16_t : 1; +#endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */ + + uint16_t : 1; + +#if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER + uint16_t passiveFilterEnable : 1; /*!< Passive filter enable/disable */ +#else + uint16_t : 1; +#endif /* FSL_FEATURE_PORT_HAS_PASSIVE_FILTER */ + +#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN + uint16_t openDrainEnable : 1; /*!< Open drain enable/disable */ +#else + uint16_t : 1; +#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */ + +#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH + uint16_t driveStrength : 1; /*!< Fast/slow drive strength configure */ +#else + uint16_t : 1; +#endif + + uint16_t : 1; + +#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH + uint16_t mux : 3; /*!< Pin mux Configure */ +#else + uint16_t : 3; +#endif + + uint16_t : 4; + +#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK + uint16_t lockRegister : 1; /*!< Lock/unlock the PCR field[15:0] */ +#else + uint16_t : 1; +#endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */ +} port_pin_config_t; +#endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */ + +/******************************************************************************* +* API +******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH +/*! @name Configuration */ +/*@{*/ + +/*! + * @brief Sets the port PCR register. + * + * This is an example to define an input pin or output pin PCR configuration. + * @code + * // Define a digital input pin PCR configuration + * port_pin_config_t config = { + * kPORT_PullUp, + * kPORT_FastSlewRate, + * kPORT_PassiveFilterDisable, + * kPORT_OpenDrainDisable, + * kPORT_LowDriveStrength, + * kPORT_MuxAsGpio, + * kPORT_UnLockRegister, + * }; + * @endcode + * + * @param base PORT peripheral base pointer. + * @param pin PORT pin number. + * @param config PORT PCR register configuration structure. + */ +static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_pin_config_t *config) +{ + assert(config); + uint32_t addr = (uint32_t)&base->PCR[pin]; + *(volatile uint16_t *)(addr) = *((const uint16_t *)config); +} + +/*! + * @brief Sets the port PCR register for multiple pins. + * + * This is an example to define input pins or output pins PCR configuration. + * @code + * // Define a digital input pin PCR configuration + * port_pin_config_t config = { + * kPORT_PullUp , + * kPORT_PullEnable, + * kPORT_FastSlewRate, + * kPORT_PassiveFilterDisable, + * kPORT_OpenDrainDisable, + * kPORT_LowDriveStrength, + * kPORT_MuxAsGpio, + * kPORT_UnlockRegister, + * }; + * @endcode + * + * @param base PORT peripheral base pointer. + * @param mask PORT pin number macro. + * @param config PORT PCR register configuration structure. + */ +static inline void PORT_SetMultiplePinsConfig(PORT_Type *base, uint32_t mask, const port_pin_config_t *config) +{ + assert(config); + + uint16_t pcrl = *((const uint16_t *)config); + + if (mask & 0xffffU) + { + base->GPCLR = ((mask & 0xffffU) << 16) | pcrl; + } + if (mask >> 16) + { + base->GPCHR = (mask & 0xffff0000U) | pcrl; + } +} + +/*! + * @brief Configures the pin muxing. + * + * @param base PORT peripheral base pointer. + * @param pin PORT pin number. + * @param mux pin muxing slot selection. + * - #kPORT_PinDisabledOrAnalog: Pin disabled or work in analog function. + * - #kPORT_MuxAsGpio : Set as GPIO. + * - #kPORT_MuxAlt2 : chip-specific. + * - #kPORT_MuxAlt3 : chip-specific. + * - #kPORT_MuxAlt4 : chip-specific. + * - #kPORT_MuxAlt5 : chip-specific. + * - #kPORT_MuxAlt6 : chip-specific. + * - #kPORT_MuxAlt7 : chip-specific. + * @Note : This function is NOT recommended to use together with the PORT_SetPinsConfig, because + * the PORT_SetPinsConfig need to configure the pin mux anyway (Otherwise the pin mux is + * reset to zero : kPORT_PinDisabledOrAnalog). + * This function is recommended to use to reset the pin mux + * + */ +static inline void PORT_SetPinMux(PORT_Type *base, uint32_t pin, port_mux_t mux) +{ + base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(mux); +} +#endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */ + +#if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER + +/*! + * @brief Enables the digital filter in one port, each bit of the 32-bit register represents one pin. + * + * @param base PORT peripheral base pointer. + * @param mask PORT pin number macro. + */ +static inline void PORT_EnablePinsDigitalFilter(PORT_Type *base, uint32_t mask, bool enable) +{ + if (enable == true) + { + base->DFER |= mask; + } + else + { + base->DFER &= ~mask; + } +} + +/*! + * @brief Sets the digital filter in one port, each bit of the 32-bit register represents one pin. + * + * @param base PORT peripheral base pointer. + * @param config PORT digital filter configuration structure. + */ +static inline void PORT_SetDigitalFilterConfig(PORT_Type *base, const port_digital_filter_config_t *config) +{ + assert(config); + + base->DFCR = PORT_DFCR_CS(config->clockSource); + base->DFWR = PORT_DFWR_FILT(config->digitalFilterWidth); +} + +#endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */ + +/*@}*/ + +/*! @name Interrupt */ +/*@{*/ + +/*! + * @brief Configures the port pin interrupt/DMA request. + * + * @param base PORT peripheral base pointer. + * @param pin PORT pin number. + * @param config PORT pin interrupt configuration. + * - #kPORT_InterruptOrDMADisabled: Interrupt/DMA request disabled. + * - #kPORT_DMARisingEdge : DMA request on rising edge(if the DMA requests exit). + * - #kPORT_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit). + * - #kPORT_DMAEitherEdge : DMA request on either edge(if the DMA requests exit). + * - #kPORT_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit). + * - #kPORT_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit). + * - #kPORT_FlagEitherEdge : Flag sets on either edge(if the Flag states exit). + * - #kPORT_InterruptLogicZero : Interrupt when logic zero. + * - #kPORT_InterruptRisingEdge : Interrupt on rising edge. + * - #kPORT_InterruptFallingEdge: Interrupt on falling edge. + * - #kPORT_InterruptEitherEdge : Interrupt on either edge. + * - #kPORT_InterruptLogicOne : Interrupt when logic one. + * - #kPORT_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit). + * - #kPORT_ActiveLowTriggerOutputEnable : Enable active low-trigger output (if the trigger states exit). + */ +static inline void PORT_SetPinInterruptConfig(PORT_Type *base, uint32_t pin, port_interrupt_t config) +{ + base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_IRQC_MASK) | PORT_PCR_IRQC(config); +} + +/*! + * @brief Reads the whole port status flag. + * + * If a pin is configured to generate the DMA request, the corresponding flag + * is cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic one is written to that flag. + * If configured for a level sensitive interrupt that remains asserted, the flag + * is set again immediately. + * + * @param base PORT peripheral base pointer. + * @return Current port interrupt status flags, for example, 0x00010001 means the + * pin 0 and 16 have the interrupt. + */ +static inline uint32_t PORT_GetPinsInterruptFlags(PORT_Type *base) +{ + return base->ISFR; +} + +/*! + * @brief Clears the multiple pin interrupt status flag. + * + * @param base PORT peripheral base pointer. + * @param mask PORT pin number macro. + */ +static inline void PORT_ClearPinsInterruptFlags(PORT_Type *base, uint32_t mask) +{ + base->ISFR = mask; +} + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_PORT_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi.c new file mode 100644 index 00000000000..748a1e7167e --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi.c @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_qspi.h" + +/******************************************************************************* + * Definitations + ******************************************************************************/ +enum _qspi_transfer_state +{ + kQSPI_TxBusy = 0x0U, /*!< QSPI is busy */ + kQSPI_TxIdle, /*!< Transfer is done. */ + kQSPI_TxError /*!< Transfer error occured. */ +}; + +#define QSPI_AHB_BUFFER_REG(base, index) (*((uint32_t *)&(base->BUF0CR) + index)) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! +* @brief Get the instance number for QSPI. +* +* @param base QSPI base pointer. +*/ +uint32_t QSPI_GetInstance(QuadSPI_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Base pointer array */ +static QuadSPI_Type *const s_qspiBases[] = QuadSPI_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/* Clock name array */ +static const clock_ip_name_t s_qspiClock[] = QSPI_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ +uint32_t QSPI_GetInstance(QuadSPI_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_QuadSPI_COUNT; instance++) + { + if (s_qspiBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_QuadSPI_COUNT); + + return instance; +} + +void QSPI_Init(QuadSPI_Type *base, qspi_config_t *config, uint32_t srcClock_Hz) +{ + uint32_t i = 0; + uint32_t val = 0; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable QSPI clock */ + CLOCK_EnableClock(s_qspiClock[QSPI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Do software reset to QSPI module */ + QSPI_SoftwareReset(base); + + /* Clear the FIFO region */ + QSPI_ClearFifo(base, kQSPI_AllFifo); + + /* Configure QSPI */ + QSPI_Enable(base, false); + + /* Set qspi clock source */ + base->SOCCR = config->clockSource; + + /* Set the divider of QSPI clock */ + base->MCR &= ~QuadSPI_MCR_SCLKCFG_MASK; + base->MCR |= QuadSPI_MCR_SCLKCFG(srcClock_Hz / config->baudRate - 1U); + + /* Set AHB buffer size and buffer master */ + for (i = 0; i < FSL_FEATURE_QSPI_AHB_BUFFER_COUNT; i++) + { + val = QuadSPI_BUF0CR_MSTRID(config->AHBbufferMaster[i]) | QuadSPI_BUF0CR_ADATSZ(config->AHBbufferSize[i] / 8U); + QSPI_AHB_BUFFER_REG(base, i) = val; + } + if (config->enableAHBbuffer3AllMaster) + { + base->BUF3CR |= QuadSPI_BUF3CR_ALLMST_MASK; + } + else + { + base->BUF3CR &= ~QuadSPI_BUF3CR_ALLMST_MASK; + } + + /* Set watermark */ + base->RBCT &= ~QuadSPI_RBCT_WMRK_MASK; + base->RBCT |= QuadSPI_RBCT_WMRK(config->rxWatermark - 1); + base->TBCT &= ~QuadSPI_TBCT_WMRK_MASK; + base->TBCT |= QuadSPI_TBCT_WMRK(config->txWatermark - 1); + + /* Enable QSPI module */ + if (config->enableQspi) + { + QSPI_Enable(base, true); + } +} + +void QSPI_GetDefaultQspiConfig(qspi_config_t *config) +{ + config->clockSource = 2U; + config->baudRate = 24000000U; + config->AHBbufferMaster[0] = 0xE; + config->AHBbufferMaster[1] = 0xE; + config->AHBbufferMaster[2] = 0xE; + config->enableAHBbuffer3AllMaster = true; + config->txWatermark = 8; + config->rxWatermark = 8; + config->enableQspi = true; +} + +void QSPI_Deinit(QuadSPI_Type *base) +{ + QSPI_Enable(base, false); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(s_qspiClock[QSPI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void QSPI_SetFlashConfig(QuadSPI_Type *base, qspi_flash_config_t *config) +{ + uint32_t address = FSL_FEATURE_QSPI_AMBA_BASE + config->flashA1Size; + uint32_t val = 0; + uint32_t i = 0; + + /* Disable module */ + QSPI_Enable(base, false); + + /* Config the serial flash size */ + base->SFA1AD = address; + address += config->flashA2Size; + base->SFA2AD = address; +#if defined(FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE) && (FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE) + address += config->flashB1Size; + base->SFB1AD = address; + address += config->flashB2Size; + base->SFB2AD = address; +#endif /* FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE */ + + /* Set Word Addressable feature */ + val = QuadSPI_SFACR_WA(config->enableWordAddress) | QuadSPI_SFACR_CAS(config->cloumnspace); + base->SFACR = val; + + /* Config look up table */ + base->LUTKEY = 0x5AF05AF0U; + base->LCKCR = 0x2U; + for (i = 0; i < FSL_FEATURE_QSPI_LUT_DEPTH; i++) + { + base->LUT[i] = config->lookuptable[i]; + } + base->LUTKEY = 0x5AF05AF0U; + base->LCKCR = 0x1U; + + /* Config flash timing */ + val = QuadSPI_FLSHCR_TCSS(config->CSHoldTime) | QuadSPI_FLSHCR_TDH(config->dataHoldTime) | + QuadSPI_FLSHCR_TCSH(config->CSSetupTime); + base->FLSHCR = val; + + /* Set flash endianness */ + base->MCR &= ~QuadSPI_MCR_END_CFG_MASK; + base->MCR |= QuadSPI_MCR_END_CFG(config->endian); + + /* Enable QSPI again */ + QSPI_Enable(base, true); +} + +void QSPI_SoftwareReset(QuadSPI_Type *base) +{ + volatile uint32_t i = 0; + + /* Reset AHB domain and buffer domian */ + base->MCR |= (QuadSPI_MCR_SWRSTHD_MASK | QuadSPI_MCR_SWRSTSD_MASK); + + /* Wait several time for the reset to finish, this method came from IC team */ + for (i = 0; i < 100; i++) + { + __ASM("nop"); + } + + /* Disable QSPI module */ + QSPI_Enable(base, false); + + /* Clear the reset flags */ + base->MCR &= ~(QuadSPI_MCR_SWRSTHD_MASK | QuadSPI_MCR_SWRSTSD_MASK); + + /* Enable QSPI module */ + QSPI_Enable(base, true); +} + +uint32_t QSPI_GetRxDataRegisterAddress(QuadSPI_Type *base) +{ + /* From RDBR */ + if (base->RBCT & QuadSPI_RBCT_RXBRD_MASK) + { + return (uint32_t)(&(base->RBDR[0])); + } + else + { + /* From ARDB */ + return FSL_FEATURE_QSPI_ARDB_BASE; + } +} + +void QSPI_ExecuteIPCommand(QuadSPI_Type *base, uint32_t index) +{ + while (QSPI_GetStatusFlags(base) & (kQSPI_Busy | kQSPI_IPAccess)) + { + } + QSPI_ClearCommandSequence(base, kQSPI_IPSeq); + + /* Write the seqid bit */ + base->IPCR = ((base->IPCR & (~QuadSPI_IPCR_SEQID_MASK)) | QuadSPI_IPCR_SEQID(index / 4U)); +} + +void QSPI_ExecuteAHBCommand(QuadSPI_Type *base, uint32_t index) +{ + while (QSPI_GetStatusFlags(base) & (kQSPI_Busy | kQSPI_AHBAccess)) + { + } + QSPI_ClearCommandSequence(base, kQSPI_BufferSeq); + base->BFGENCR = ((base->BFGENCR & (~QuadSPI_BFGENCR_SEQID_MASK)) | QuadSPI_BFGENCR_SEQID(index / 4U)); +} + +void QSPI_UpdateLUT(QuadSPI_Type *base, uint32_t index, uint32_t *cmd) +{ + uint8_t i = 0; + + /* Unlock the LUT */ + base->LUTKEY = 0x5AF05AF0U; + base->LCKCR = 0x2U; + + /* Write data into LUT */ + for (i = 0; i < 4; i++) + { + base->LUT[index + i] = *cmd; + cmd++; + } + + /* Lcok LUT again */ + base->LUTKEY = 0x5AF05AF0U; + base->LCKCR = 0x1U; +} + +void QSPI_SetReadDataArea(QuadSPI_Type *base, qspi_read_area_t area) +{ + base->RBCT &= ~QuadSPI_RBCT_RXBRD_MASK; + base->RBCT |= QuadSPI_RBCT_RXBRD(area); +} + +uint32_t QSPI_ReadData(QuadSPI_Type *base) +{ + if (base->RBCT & QuadSPI_RBCT_RXBRD_MASK) + { + return base->RBDR[0]; + } + else + { + /* Data from ARDB. */ + return *((uint32_t *)FSL_FEATURE_QSPI_ARDB_BASE); + } +} + +void QSPI_WriteBlocking(QuadSPI_Type *base, uint32_t *buffer, size_t size) +{ + assert(size >= 16U); + + uint32_t i = 0; + + for (i = 0; i < size / 4U; i++) + { + /* Check if the buffer is full */ + while (QSPI_GetStatusFlags(base) & kQSPI_TxBufferFull) + { + } + QSPI_WriteData(base, *buffer); + buffer++; + } +} + +void QSPI_ReadBlocking(QuadSPI_Type *base, uint32_t *buffer, size_t size) +{ + uint32_t i = 0; + uint32_t j = 0; + uint32_t temp = 0; + uint32_t level = (base->RBCT & QuadSPI_RBCT_WMRK_MASK) + 1U; + + while (i < size / 4) + { + /* Check if there is data */ + if ((size / 4 - i) < level) + { + do + { + temp = (base->RBSR & QuadSPI_RBSR_RDBFL_MASK) >> QuadSPI_RBSR_RDBFL_SHIFT; + } while (!temp); + } + else + { + while ((QSPI_GetStatusFlags(base) & kQSPI_RxWatermark) == 0U) + { + } + } + + level = (level < (size / 4 - i)) ? level : (size / 4 - i); + + /* Data from RBDR */ + if (base->RBCT & QuadSPI_RBCT_RXBRD_MASK) + { + for (j = 0; j < level; j++) + { + buffer[i + j] = base->RBDR[j]; + } + } + else + { + /* Data from ARDB. */ + for (j = 0; j < level; j++) + { + buffer[i + j] = ((uint32_t *)FSL_FEATURE_QSPI_ARDB_BASE)[j]; + } + } + i += level; + + /* Clear the Buffer */ + QSPI_ClearErrorFlag(base, kQSPI_RxBufferDrain); + } +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi.h new file mode 100644 index 00000000000..40f5ee413c4 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi.h @@ -0,0 +1,636 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_QSPI_H_ +#define _FSL_QSPI_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup qspi + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief I2C driver version 2.0.1. */ +#define FSL_QSPI_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! @brief Status structure of QSPI.*/ +enum _status_t +{ + kStatus_QSPI_Idle = MAKE_STATUS(kStatusGroup_QSPI, 0), /*!< QSPI is in idle state */ + kStatus_QSPI_Busy = MAKE_STATUS(kStatusGroup_QSPI, 1), /*!< QSPI is busy */ + kStatus_QSPI_Error = MAKE_STATUS(kStatusGroup_QSPI, 2), /*!< Error occurred during QSPI transfer */ +}; + +/*! @brief QSPI read data area, from IP FIFO or AHB buffer.*/ +typedef enum _qspi_read_area +{ + kQSPI_ReadAHB = 0x0U, /*!< QSPI read from AHB buffer. */ + kQSPI_ReadIP /*!< QSPI read from IP FIFO. */ +} qspi_read_area_t; + +/*! @brief QSPI command sequence type */ +typedef enum _qspi_command_seq +{ + kQSPI_IPSeq = QuadSPI_SPTRCLR_IPPTRC_MASK, /*!< IP command sequence */ + kQSPI_BufferSeq = QuadSPI_SPTRCLR_BFPTRC_MASK, /*!< Buffer command sequence */ + kQSPI_AllSeq = QuadSPI_SPTRCLR_IPPTRC_MASK | QuadSPI_SPTRCLR_BFPTRC_MASK /* All command sequence */ +} qspi_command_seq_t; + +/*! @brief QSPI buffer type */ +typedef enum _qspi_fifo +{ + kQSPI_TxFifo = QuadSPI_MCR_CLR_TXF_MASK, /*!< QSPI Tx FIFO */ + kQSPI_RxFifo = QuadSPI_MCR_CLR_RXF_MASK, /*!< QSPI Rx FIFO */ + kQSPI_AllFifo = QuadSPI_MCR_CLR_TXF_MASK | QuadSPI_MCR_CLR_RXF_MASK /*!< QSPI all FIFO, including Tx and Rx */ +} qspi_fifo_t; + +/*! @brief QSPI transfer endianess*/ +typedef enum _qspi_endianness +{ + kQSPI_64BigEndian = 0x0U, /*!< 64 bits big endian */ + kQSPI_32LittleEndian, /*!< 32 bit little endian */ + kQSPI_32BigEndian, /*!< 32 bit big endian */ + kQSPI_64LittleEndian /*!< 64 bit little endian */ +} qspi_endianness_t; + +/*! @brief QSPI error flags */ +enum _qspi_error_flags +{ + kQSPI_DataLearningFail = QuadSPI_FR_DLPFF_MASK, /*!< Data learning pattern failure flag */ + kQSPI_TxBufferFill = QuadSPI_FR_TBFF_MASK, /*!< Tx buffer fill flag */ + kQSPI_TxBufferUnderrun = QuadSPI_FR_TBUF_MASK, /*!< Tx buffer underrun flag */ + kQSPI_IllegalInstruction = QuadSPI_FR_ILLINE_MASK, /*!< Illegal instruction error flag */ + kQSPI_RxBufferOverflow = QuadSPI_FR_RBOF_MASK, /*!< Rx buffer overflow flag */ + kQSPI_RxBufferDrain = QuadSPI_FR_RBDF_MASK, /*!< Rx buffer drain flag */ + kQSPI_AHBSequenceError = QuadSPI_FR_ABSEF_MASK, /*!< AHB sequence error flag */ + kQSPI_AHBIllegalTransaction = QuadSPI_FR_AITEF_MASK, /*!< AHB illegal transaction error flag */ + kQSPI_AHBIllegalBurstSize = QuadSPI_FR_AIBSEF_MASK, /*!< AHB illegal burst error flag */ + kQSPI_AHBBufferOverflow = QuadSPI_FR_ABOF_MASK, /*!< AHB buffer overflow flag */ +#if defined(FSL_FEATURE_QSPI_HAS_IP_COMMAND_USAGE_ERROR) && (FSL_FEATURE_QSPI_HAS_IP_COMMAND_USAGE_ERROR) + kQSPI_IPCommandUsageError = QuadSPI_FR_IUEF_MASK, /*!< IP command usage error flag */ +#endif /* FSL_FEATURE_QSPI_HAS_IP_COMMAND_USAGE_ERROR */ + kQSPI_IPCommandTriggerDuringAHBAccess = QuadSPI_FR_IPAEF_MASK, /*!< IP command trigger during AHB access error */ + kQSPI_IPCommandTriggerDuringIPAccess = QuadSPI_FR_IPIEF_MASK, /*!< IP command trigger cannot be executed */ + kQSPI_IPCommandTriggerDuringAHBGrant = QuadSPI_FR_IPGEF_MASK, /*!< IP command trigger during AHB grant error */ + kQSPI_IPCommandTransactionFinished = QuadSPI_FR_TFF_MASK, /*!< IP command transaction finished flag */ + kQSPI_FlagAll = 0x8C83F8D1U /*!< All error flag */ +}; + +/*! @brief QSPI state bit */ +enum _qspi_flags +{ + kQSPI_DataLearningSamplePoint = QuadSPI_SR_DLPSMP_MASK, /*!< Data learning sample point */ + kQSPI_TxBufferFull = QuadSPI_SR_TXFULL_MASK, /*!< Tx buffer full flag */ + kQSPI_TxDMA = QuadSPI_SR_TXDMA_MASK, /*!< Tx DMA is requested or running */ + kQSPI_TxWatermark = QuadSPI_SR_TXWA_MASK, /*!< Tx buffer watermark available */ + kQSPI_TxBufferEnoughData = QuadSPI_SR_TXEDA_MASK, /*!< Tx buffer enough data available */ + kQSPI_RxDMA = QuadSPI_SR_RXDMA_MASK, /*!< Rx DMA is requesting or running */ + kQSPI_RxBufferFull = QuadSPI_SR_RXFULL_MASK, /*!< Rx buffer full */ + kQSPI_RxWatermark = QuadSPI_SR_RXWE_MASK, /*!< Rx buffer watermark exceeded */ + kQSPI_AHB3BufferFull = QuadSPI_SR_AHB3FUL_MASK, /*!< AHB buffer 3 full*/ + kQSPI_AHB2BufferFull = QuadSPI_SR_AHB2FUL_MASK, /*!< AHB buffer 2 full */ + kQSPI_AHB1BufferFull = QuadSPI_SR_AHB1FUL_MASK, /*!< AHB buffer 1 full */ + kQSPI_AHB0BufferFull = QuadSPI_SR_AHB0FUL_MASK, /*!< AHB buffer 0 full */ + kQSPI_AHB3BufferNotEmpty = QuadSPI_SR_AHB3NE_MASK, /*!< AHB buffer 3 not empty */ + kQSPI_AHB2BufferNotEmpty = QuadSPI_SR_AHB2NE_MASK, /*!< AHB buffer 2 not empty */ + kQSPI_AHB1BufferNotEmpty = QuadSPI_SR_AHB1NE_MASK, /*!< AHB buffer 1 not empty */ + kQSPI_AHB0BufferNotEmpty = QuadSPI_SR_AHB0NE_MASK, /*!< AHB buffer 0 not empty */ + kQSPI_AHBTransactionPending = QuadSPI_SR_AHBTRN_MASK, /*!< AHB access transaction pending */ + kQSPI_AHBCommandPriorityGranted = QuadSPI_SR_AHBGNT_MASK, /*!< AHB command priority granted */ + kQSPI_AHBAccess = QuadSPI_SR_AHB_ACC_MASK, /*!< AHB access */ + kQSPI_IPAccess = QuadSPI_SR_IP_ACC_MASK, /*!< IP access */ + kQSPI_Busy = QuadSPI_SR_BUSY_MASK, /*!< Module busy */ + kQSPI_StateAll = 0xEF897FE7U /*!< All flags */ +}; + +/*! @brief QSPI interrupt enable */ +enum _qspi_interrupt_enable +{ + kQSPI_DataLearningFailInterruptEnable = + QuadSPI_RSER_DLPFIE_MASK, /*!< Data learning pattern failure interrupt enable */ + kQSPI_TxBufferFillInterruptEnable = QuadSPI_RSER_TBFIE_MASK, /*!< Tx buffer fill interrupt enable */ + kQSPI_TxBufferUnderrunInterruptEnable = QuadSPI_RSER_TBUIE_MASK, /*!< Tx buffer underrun interrupt enable */ + kQSPI_IllegalInstructionInterruptEnable = + QuadSPI_RSER_ILLINIE_MASK, /*!< Illegal instruction error interrupt enable */ + kQSPI_RxBufferOverflowInterruptEnable = QuadSPI_RSER_RBOIE_MASK, /*!< Rx buffer overflow interrupt enable */ + kQSPI_RxBufferDrainInterruptEnable = QuadSPI_RSER_RBDIE_MASK, /*!< Rx buffer drain interrupt enable */ + kQSPI_AHBSequenceErrorInterruptEnable = QuadSPI_RSER_ABSEIE_MASK, /*!< AHB sequence error interrupt enable */ + kQSPI_AHBIllegalTransactionInterruptEnable = + QuadSPI_RSER_AITIE_MASK, /*!< AHB illegal transaction error interrupt enable */ + kQSPI_AHBIllegalBurstSizeInterruptEnable = + QuadSPI_RSER_AIBSIE_MASK, /*!< AHB illegal burst error interrupt enable */ + kQSPI_AHBBufferOverflowInterruptEnable = QuadSPI_RSER_ABOIE_MASK, /*!< AHB buffer overflow interrupt enable */ +#if defined(FSL_FEATURE_QSPI_HAS_IP_COMMAND_USAGE_ERROR) && (FSL_FEATURE_QSPI_HAS_IP_COMMAND_USAGE_ERROR) + kQSPI_IPCommandUsageErrorInterruptEnable = QuadSPI_RSER_IUEIE_MASK, /*!< IP command usage error interrupt enable */ +#endif /* FSL_FEATURE_QSPI_HAS_IP_COMMAND_USAGE_ERROR */ + kQSPI_IPCommandTriggerDuringAHBAccessInterruptEnable = + QuadSPI_RSER_IPAEIE_MASK, /*!< IP command trigger during AHB access error */ + kQSPI_IPCommandTriggerDuringIPAccessInterruptEnable = + QuadSPI_RSER_IPIEIE_MASK, /*!< IP command trigger cannot be executed */ + kQSPI_IPCommandTriggerDuringAHBGrantInterruptEnable = + QuadSPI_RSER_IPGEIE_MASK, /*!< IP command trigger during AHB grant error */ + kQSPI_IPCommandTransactionFinishedInterruptEnable = + QuadSPI_RSER_TFIE_MASK, /*!< IP command transaction finished interrupt enable */ + kQSPI_AllInterruptEnable = 0x8C83F8D1U /*!< All error interrupt enable */ +}; + +/*! @brief QSPI DMA request flag */ +enum _qspi_dma_enable +{ + kQSPI_TxBufferFillDMAEnable = QuadSPI_RSER_TBFDE_MASK, /*!< Tx buffer fill DMA */ + kQSPI_RxBufferDrainDMAEnable = QuadSPI_RSER_RBDDE_MASK, /*!< Rx buffer drain DMA */ + kQSPI_AllDDMAEnable = QuadSPI_RSER_TBFDE_MASK | QuadSPI_RSER_RBDDE_MASK /*!< All DMA source */ +}; + +/*! @brief Phrase shift number for DQS mode. */ +typedef enum _qspi_dqs_phrase_shift +{ + kQSPI_DQSNoPhraseShift = 0x0U, /*!< No phase shift */ + kQSPI_DQSPhraseShift45Degree, /*!< Select 45 degree phase shift*/ + kQSPI_DQSPhraseShift90Degree, /*!< Select 90 degree phase shift */ + kQSPI_DQSPhraseShift135Degree /*!< Select 135 degree phase shift */ +} qspi_dqs_phrase_shift_t; + +/*! @brief DQS configure features*/ +typedef struct QspiDQSConfig +{ + uint32_t portADelayTapNum; /*!< Delay chain tap number selection for QSPI port A DQS */ + uint32_t portBDelayTapNum; /*!< Delay chain tap number selection for QSPI port B DQS*/ + qspi_dqs_phrase_shift_t shift; /*!< Phase shift for internal DQS generation */ + bool enableDQSClkInverse; /*!< Enable inverse clock for internal DQS generation */ + bool enableDQSPadLoopback; /*!< Enable DQS loop back from DQS pad */ + bool enableDQSLoopback; /*!< Enable DQS loop back */ +} qspi_dqs_config_t; + +/*! @brief Flash timing configuration. */ +typedef struct QspiFlashTiming +{ + uint32_t dataHoldTime; /*!< Serial flash data in hold time */ + uint32_t CSHoldTime; /*!< Serial flash CS hold time in terms of serial flash clock cycles */ + uint32_t CSSetupTime; /*!< Serial flash CS setup time in terms of serial flash clock cycles */ +} qspi_flash_timing_t; + +/*! @brief QSPI configuration structure*/ +typedef struct QspiConfig +{ + uint32_t clockSource; /*!< Clock source for QSPI module */ + uint32_t baudRate; /*!< Serial flash clock baud rate */ + uint8_t txWatermark; /*!< QSPI transmit watermark value */ + uint8_t rxWatermark; /*!< QSPI receive watermark value. */ + uint32_t AHBbufferSize[FSL_FEATURE_QSPI_AHB_BUFFER_COUNT]; /*!< AHB buffer size. */ + uint8_t AHBbufferMaster[FSL_FEATURE_QSPI_AHB_BUFFER_COUNT]; /*!< AHB buffer master. */ + bool enableAHBbuffer3AllMaster; /*!< Is AHB buffer3 for all master.*/ + qspi_read_area_t area; /*!< Which area Rx data readout */ + bool enableQspi; /*!< Enable QSPI after initialization */ +} qspi_config_t; + +/*! @brief External flash configuration items*/ +typedef struct _qspi_flash_config +{ + uint32_t flashA1Size; /*!< Flash A1 size */ + uint32_t flashA2Size; /*!< Flash A2 size */ +#if defined(FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE) && (FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE) + uint32_t flashB1Size; /*!< Flash B1 size */ + uint32_t flashB2Size; /*!< Flash B2 size */ +#endif /* FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE */ + uint32_t lookuptable[FSL_FEATURE_QSPI_LUT_DEPTH]; /*!< Flash command in LUT */ + uint32_t dataHoldTime; /*!< Data line hold time. */ + uint32_t CSHoldTime; /*!< CS line hold time */ + uint32_t CSSetupTime; /*!< CS line setup time*/ + uint32_t cloumnspace; /*!< Column space size */ + uint32_t dataLearnValue; /*!< Data Learn value if enable data learn */ + qspi_endianness_t endian; /*!< Flash data endianess. */ + bool enableWordAddress; /*!< If enable word address.*/ +} qspi_flash_config_t; + +/*! @brief Transfer structure for QSPI */ +typedef struct _qspi_transfer +{ + uint32_t *data; /*!< Pointer to data to transmit */ + size_t dataSize; /*!< Bytes to be transmit */ +} qspi_transfer_t; + +/****************************************************************************** + * API + *****************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes the QSPI module and internal state. + * + * This function enables the clock for QSPI and also configures the QSPI with the + * input configure parameters. Users should call this function before any QSPI operations. + * + * @param base Pointer to QuadSPI Type. + * @param config QSPI configure structure. + * @param srcClock_Hz QSPI source clock frequency in Hz. + */ +void QSPI_Init(QuadSPI_Type *base, qspi_config_t *config, uint32_t srcClock_Hz); + +/*! + * @brief Gets default settings for QSPI. + * + * @param config QSPI configuration structure. + */ +void QSPI_GetDefaultQspiConfig(qspi_config_t *config); + +/*! + * @brief Deinitializes the QSPI module. + * + * Clears the QSPI state and QSPI module registers. + * @param base Pointer to QuadSPI Type. + */ +void QSPI_Deinit(QuadSPI_Type *base); + +/*! + * @brief Configures the serial flash parameter. + * + * This function configures the serial flash relevant parameters, such as the size, command, and so on. + * The flash configuration value cannot have a default value. The user needs to configure it according to the + * QSPI features. + * + * @param base Pointer to QuadSPI Type. + * @param config Flash configuration parameters. + */ +void QSPI_SetFlashConfig(QuadSPI_Type *base, qspi_flash_config_t *config); + +/*! + * @brief Software reset for the QSPI logic. + * + * This function sets the software reset flags for both AHB and buffer domain and + * resets both AHB buffer and also IP FIFOs. + * + * @param base Pointer to QuadSPI Type. + */ +void QSPI_SoftwareReset(QuadSPI_Type *base); + +/*! + * @brief Enables or disables the QSPI module. + * + * @param base Pointer to QuadSPI Type. + * @param enable True means enable QSPI, false means disable. + */ +static inline void QSPI_Enable(QuadSPI_Type *base, bool enable) +{ + if (enable) + { + base->MCR &= ~QuadSPI_MCR_MDIS_MASK; + } + else + { + base->MCR |= QuadSPI_MCR_MDIS_MASK; + } +} + +/*! @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the state value of QSPI. + * + * @param base Pointer to QuadSPI Type. + * @return status flag, use status flag to AND #_qspi_flags could get the related status. + */ +static inline uint32_t QSPI_GetStatusFlags(QuadSPI_Type *base) +{ + return base->SR; +} + +/*! + * @brief Gets QSPI error status flags. + * + * @param base Pointer to QuadSPI Type. + * @return status flag, use status flag to AND #_qspi_error_flags could get the related status. + */ +static inline uint32_t QSPI_GetErrorStatusFlags(QuadSPI_Type *base) +{ + return base->FR; +} + +/*! @brief Clears the QSPI error flags. + * + * @param base Pointer to QuadSPI Type. + * @param mask Which kind of QSPI flags to be cleared, a combination of _qspi_error_flags. + */ +static inline void QSPI_ClearErrorFlag(QuadSPI_Type *base, uint32_t mask) +{ + base->FR = mask; +} + +/*! @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the QSPI interrupts. + * + * @param base Pointer to QuadSPI Type. + * @param mask QSPI interrupt source. + */ +static inline void QSPI_EnableInterrupts(QuadSPI_Type *base, uint32_t mask) +{ + base->RSER |= mask; +} + +/*! + * @brief Disables the QSPI interrupts. + * + * @param base Pointer to QuadSPI Type. + * @param mask QSPI interrupt source. + */ +static inline void QSPI_DisableInterrupts(QuadSPI_Type *base, uint32_t mask) +{ + base->RSER &= ~mask; +} + +/*! @} */ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Enables the QSPI DMA source. + * + * @param base Pointer to QuadSPI Type. + * @param mask QSPI DMA source. + * @param enable True means enable DMA, false means disable. + */ +static inline void QSPI_EnableDMA(QuadSPI_Type *base, uint32_t mask, bool enable) +{ + if (enable) + { + base->RSER |= mask; + } + else + { + base->RSER &= ~mask; + } +} + +/*! + * @brief Gets the Tx data register address. It is used for DMA operation. + * + * @param base Pointer to QuadSPI Type. + * @return QSPI Tx data register address. + */ +static inline uint32_t QSPI_GetTxDataRegisterAddress(QuadSPI_Type *base) +{ + return (uint32_t)(&base->TBDR); +} + +/*! + * @brief Gets the Rx data register address used for DMA operation. + * + * This function returns the Rx data register address or Rx buffer address + * according to the Rx read area settings. + * + * @param base Pointer to QuadSPI Type. + * @return QSPI Rx data register address. + */ +uint32_t QSPI_GetRxDataRegisterAddress(QuadSPI_Type *base); + +/* @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! @brief Sets the IP command address. + * + * @param base Pointer to QuadSPI Type. + * @param addr IP command address. + */ +static inline void QSPI_SetIPCommandAddress(QuadSPI_Type *base, uint32_t addr) +{ + base->SFAR = addr; +} + +/*! @brief Sets the IP command size. + * + * @param base Pointer to QuadSPI Type. + * @param size IP command size. + */ +static inline void QSPI_SetIPCommandSize(QuadSPI_Type *base, uint32_t size) +{ + base->IPCR = ((base->IPCR & (~QuadSPI_IPCR_IDATSZ_MASK)) | QuadSPI_IPCR_IDATSZ(size)); +} + +/*! @brief Executes IP commands located in LUT table. + * + * @param base Pointer to QuadSPI Type. + * @param index IP command located in which LUT table index. + */ +void QSPI_ExecuteIPCommand(QuadSPI_Type *base, uint32_t index); + +/*! @brief Executes AHB commands located in LUT table. + * + * @param base Pointer to QuadSPI Type. + * @param index AHB command located in which LUT table index. + */ +void QSPI_ExecuteAHBCommand(QuadSPI_Type *base, uint32_t index); + +#if defined(FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE) && (FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE) +/*! @brief Enables/disables the QSPI IP command parallel mode. + * + * @param base Pointer to QuadSPI Type. + * @param enable True means enable parallel mode, false means disable parallel mode. + */ +static inline void QSPI_EnableIPParallelMode(QuadSPI_Type *base, bool enable) +{ + if (enable) + { + base->IPCR |= QuadSPI_IPCR_PAR_EN_MASK; + } + else + { + base->IPCR &= ~QuadSPI_IPCR_PAR_EN_MASK; + } +} + +/*! @brief Enables/disables the QSPI AHB command parallel mode. + * + * @param base Pointer to QuadSPI Type. + * @param enable True means enable parallel mode, false means disable parallel mode. + */ +static inline void QSPI_EnableAHBParallelMode(QuadSPI_Type *base, bool enable) +{ + if (enable) + { + base->BFGENCR |= QuadSPI_BFGENCR_PAR_EN_MASK; + } + else + { + base->BFGENCR &= ~QuadSPI_BFGENCR_PAR_EN_MASK; + } +} +#endif /* FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE */ + +/*! @brief Updates the LUT table. +* +* @param base Pointer to QuadSPI Type. +* @param index Which LUT index needs to be located. It should be an integer divided by 4. +* @param cmd Command sequence array. +*/ +void QSPI_UpdateLUT(QuadSPI_Type *base, uint32_t index, uint32_t *cmd); + +/*! @brief Clears the QSPI FIFO logic. + * + * @param base Pointer to QuadSPI Type. + * @param mask Which kind of QSPI FIFO to be cleared. + */ +static inline void QSPI_ClearFifo(QuadSPI_Type *base, uint32_t mask) +{ + base->MCR |= mask; +} + +/*!@ brief Clears the command sequence for the IP/buffer command. + * + * This function can reset the command sequence. + * @param base QSPI base address. + * @param seq Which command sequence need to reset, IP command, buffer command or both. + */ +static inline void QSPI_ClearCommandSequence(QuadSPI_Type *base, qspi_command_seq_t seq) +{ + base->SPTRCLR = seq; +} + +/*!@ brief Set the RX buffer readout area. + * + * This function can set the RX buffer readout, from AHB bus or IP Bus. + * @param base QSPI base address. + * @param area QSPI Rx buffer readout area. AHB bus buffer or IP bus buffer. + */ +void QSPI_SetReadDataArea(QuadSPI_Type *base, qspi_read_area_t area); + +/*! + * @brief Sends a buffer of data bytes using a blocking method. + * @note This function blocks via polling until all bytes have been sent. + * @param base QSPI base pointer + * @param buffer The data bytes to send + * @param size The number of data bytes to send + */ +void QSPI_WriteBlocking(QuadSPI_Type *base, uint32_t *buffer, size_t size); + +/*! + * @brief Writes data into FIFO. + * + * @param base QSPI base pointer + * @param data The data bytes to send + */ +static inline void QSPI_WriteData(QuadSPI_Type *base, uint32_t data) +{ + base->TBDR = data; +} + +/*! + * @brief Receives a buffer of data bytes using a blocking method. + * @note This function blocks via polling until all bytes have been sent. + * @param base QSPI base pointer + * @param buffer The data bytes to send + * @param size The number of data bytes to receive + */ +void QSPI_ReadBlocking(QuadSPI_Type *base, uint32_t *buffer, size_t size); + +/*! + * @brief Receives data from data FIFO. + * + * @param base QSPI base pointer + * @return The data in the FIFO. + */ +uint32_t QSPI_ReadData(QuadSPI_Type *base); + +/*! @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Writes data to the QSPI transmit buffer. + * + * This function writes a continuous data to the QSPI transmit FIFO. This function is a block function + * and can return only when finished. This function uses polling methods. + * + * @param base Pointer to QuadSPI Type. + * @param xfer QSPI transfer structure. + */ +static inline void QSPI_TransferSendBlocking(QuadSPI_Type *base, qspi_transfer_t *xfer) +{ + QSPI_WriteBlocking(base, xfer->data, xfer->dataSize); +} + +/*! + * @brief Reads data from the QSPI receive buffer in polling way. + * + * This function reads continuous data from the QSPI receive buffer/FIFO. This function is a blocking + * function and can return only when finished. This function uses polling methods. + * @param base Pointer to QuadSPI Type. + * @param xfer QSPI transfer structure. + */ +static inline void QSPI_TransferReceiveBlocking(QuadSPI_Type *base, qspi_transfer_t *xfer) +{ + QSPI_ReadBlocking(base, xfer->data, xfer->dataSize); +} + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/* @}*/ + +#endif /* _FSL_QSPI_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi_edma.c new file mode 100644 index 00000000000..e008da004a8 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi_edma.c @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_qspi_edma.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*base, qspiPrivateHandle->handle); + + if (qspiPrivateHandle->handle->callback) + { + qspiPrivateHandle->handle->callback(qspiPrivateHandle->base, qspiPrivateHandle->handle, kStatus_QSPI_Idle, + qspiPrivateHandle->handle->userData); + } + } +} + +static void QSPI_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) +{ + qspi_edma_private_handle_t *qspiPrivateHandle = (qspi_edma_private_handle_t *)param; + + /* Avoid warning for unused parameters. */ + handle = handle; + tcds = tcds; + + if (transferDone) + { + /* Disable transfer. */ + QSPI_TransferAbortReceiveEDMA(qspiPrivateHandle->base, qspiPrivateHandle->handle); + + if (qspiPrivateHandle->handle->callback) + { + qspiPrivateHandle->handle->callback(qspiPrivateHandle->base, qspiPrivateHandle->handle, kStatus_QSPI_Idle, + qspiPrivateHandle->handle->userData); + } + } +} + +void QSPI_TransferTxCreateHandleEDMA(QuadSPI_Type *base, + qspi_edma_handle_t *handle, + qspi_edma_callback_t callback, + void *userData, + edma_handle_t *dmaHandle) +{ + assert(handle); + + uint32_t instance = QSPI_GetInstance(base); + + s_edmaPrivateHandle[instance][0].base = base; + s_edmaPrivateHandle[instance][0].handle = handle; + + memset(handle, 0, sizeof(*handle)); + + handle->state = kQSPI_Idle; + handle->dmaHandle = dmaHandle; + + handle->callback = callback; + handle->userData = userData; + + /* Get the watermark value */ + handle->count = base->TBCT + 1; + + /* Configure TX edma callback */ + EDMA_SetCallback(handle->dmaHandle, QSPI_SendEDMACallback, &s_edmaPrivateHandle[instance][0]); +} + +void QSPI_TransferRxCreateHandleEDMA(QuadSPI_Type *base, + qspi_edma_handle_t *handle, + qspi_edma_callback_t callback, + void *userData, + edma_handle_t *dmaHandle) +{ + assert(handle); + + uint32_t instance = QSPI_GetInstance(base); + + s_edmaPrivateHandle[instance][1].base = base; + s_edmaPrivateHandle[instance][1].handle = handle; + + memset(handle, 0, sizeof(*handle)); + + handle->state = kQSPI_Idle; + handle->dmaHandle = dmaHandle; + + handle->callback = callback; + handle->userData = userData; + + /* Get the watermark value */ + handle->count = (base->RBCT & QuadSPI_RBCT_WMRK_MASK) + 1; + + /* Configure RX edma callback */ + EDMA_SetCallback(handle->dmaHandle, QSPI_ReceiveEDMACallback, &s_edmaPrivateHandle[instance][1]); +} + +status_t QSPI_TransferSendEDMA(QuadSPI_Type *base, qspi_edma_handle_t *handle, qspi_transfer_t *xfer) +{ + assert(handle && (handle->dmaHandle)); + + edma_transfer_config_t xferConfig; + status_t status; + + /* If previous TX not finished. */ + if (kQSPI_BusBusy == handle->state) + { + status = kStatus_QSPI_Busy; + } + else + { + handle->state = kQSPI_BusBusy; + + /* Prepare transfer. */ + EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint32_t), (void *)QSPI_GetTxDataRegisterAddress(base), + sizeof(uint32_t), (sizeof(uint32_t) * handle->count), xfer->dataSize, + kEDMA_MemoryToPeripheral); + + /* Store the initially configured eDMA minor byte transfer count into the QSPI handle */ + handle->nbytes = (sizeof(uint32_t) * handle->count); + + /* Submit transfer. */ + EDMA_SubmitTransfer(handle->dmaHandle, &xferConfig); + EDMA_StartTransfer(handle->dmaHandle); + + /* Enable QSPI TX EDMA. */ + QSPI_EnableDMA(base, kQSPI_TxBufferFillDMAEnable, true); + + status = kStatus_Success; + } + + return status; +} + +status_t QSPI_TransferReceiveEDMA(QuadSPI_Type *base, qspi_edma_handle_t *handle, qspi_transfer_t *xfer) +{ + assert(handle && (handle->dmaHandle)); + + edma_transfer_config_t xferConfig; + status_t status; + + /* If previous TX not finished. */ + if (kQSPI_BusBusy == handle->state) + { + status = kStatus_QSPI_Busy; + } + else + { + handle->state = kQSPI_BusBusy; + + /* Prepare transfer. */ + EDMA_PrepareTransfer(&xferConfig, (void *)QSPI_GetRxDataRegisterAddress(base), sizeof(uint32_t), xfer->data, + sizeof(uint32_t), (sizeof(uint32_t) * handle->count), xfer->dataSize, + kEDMA_MemoryToMemory); + + /* Store the initially configured eDMA minor byte transfer count into the QSPI handle */ + handle->nbytes = (sizeof(uint32_t) * handle->count); + /* Submit transfer. */ + EDMA_SubmitTransfer(handle->dmaHandle, &xferConfig); + handle->dmaHandle->base->TCD[handle->dmaHandle->channel].ATTR |= DMA_ATTR_SMOD(0x5U); + EDMA_StartTransfer(handle->dmaHandle); + + /* Enable QSPI TX EDMA. */ + QSPI_EnableDMA(base, kQSPI_RxBufferDrainDMAEnable, true); + + status = kStatus_Success; + } + + return status; +} + +void QSPI_TransferAbortSendEDMA(QuadSPI_Type *base, qspi_edma_handle_t *handle) +{ + assert(handle && (handle->dmaHandle)); + + /* Disable QSPI TX EDMA. */ + QSPI_EnableDMA(base, kQSPI_TxBufferFillDMAEnable, false); + + /* Stop transfer. */ + EDMA_AbortTransfer(handle->dmaHandle); + + handle->state = kQSPI_Idle; +} + +void QSPI_TransferAbortReceiveEDMA(QuadSPI_Type *base, qspi_edma_handle_t *handle) +{ + assert(handle && (handle->dmaHandle)); + + /* Disable QSPI RX EDMA. */ + QSPI_EnableDMA(base, kQSPI_RxBufferDrainDMAEnable, false); + + /* Stop transfer. */ + EDMA_AbortTransfer(handle->dmaHandle); + + handle->state = kQSPI_Idle; +} + +status_t QSPI_TransferGetSendCountEDMA(QuadSPI_Type *base, qspi_edma_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kQSPI_BusBusy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = (handle->transferSize - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel)); + } + + return status; +} + +status_t QSPI_TransferGetReceiveCountEDMA(QuadSPI_Type *base, qspi_edma_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kQSPI_BusBusy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = (handle->transferSize - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel)); + } + + return status; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi_edma.h new file mode 100644 index 00000000000..0fa0fa2de0a --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_qspi_edma.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_QSPI_EDMA_H_ +#define _FSL_QSPI_EDMA_H_ + +#include "fsl_qspi.h" +#include "fsl_edma.h" + +/*! + * @addtogroup qspi_edma + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +typedef struct _qspi_edma_handle qspi_edma_handle_t; + +/*! @brief QSPI eDMA transfer callback function for finish and error */ +typedef void (*qspi_edma_callback_t)(QuadSPI_Type *base, qspi_edma_handle_t *handle, status_t status, void *userData); + +/*! @brief QSPI DMA transfer handle, users should not touch the content of the handle.*/ +struct _qspi_edma_handle +{ + edma_handle_t *dmaHandle; /*!< eDMA handler for QSPI send */ + size_t transferSize; /*!< Bytes need to transfer. */ + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + uint8_t count; /*!< The transfer data count in a DMA request */ + uint32_t state; /*!< Internal state for QSPI eDMA transfer */ + qspi_edma_callback_t callback; /*!< Callback for users while transfer finish or error occurred */ + void *userData; /*!< User callback parameter */ +}; + +/******************************************************************************* + * APIs + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name eDMA Transactional + * @{ + */ + +/*! + * @brief Initializes the QSPI handle for send which is used in transactional functions and set the callback. + * + * @param base QSPI peripheral base address + * @param handle Pointer to qspi_edma_handle_t structure + * @param callback QSPI callback, NULL means no callback. + * @param userData User callback function data. + * @param rxDmaHandle User requested eDMA handle for eDMA transfer + */ +void QSPI_TransferTxCreateHandleEDMA(QuadSPI_Type *base, + qspi_edma_handle_t *handle, + qspi_edma_callback_t callback, + void *userData, + edma_handle_t *dmaHandle); + +/*! + * @brief Initializes the QSPI handle for receive which is used in transactional functions and set the callback. + * + * @param base QSPI peripheral base address + * @param handle Pointer to qspi_edma_handle_t structure + * @param callback QSPI callback, NULL means no callback. + * @param userData User callback function data. + * @param rxDmaHandle User requested eDMA handle for eDMA transfer + */ +void QSPI_TransferRxCreateHandleEDMA(QuadSPI_Type *base, + qspi_edma_handle_t *handle, + qspi_edma_callback_t callback, + void *userData, + edma_handle_t *dmaHandle); + +/*! + * @brief Transfers QSPI data using an eDMA non-blocking method. + * + * This function writes data to the QSPI transmit FIFO. This function is non-blocking. + * @param base Pointer to QuadSPI Type. + * @param handle Pointer to qspi_edma_handle_t structure + * @param xfer QSPI transfer structure. + */ +status_t QSPI_TransferSendEDMA(QuadSPI_Type *base, qspi_edma_handle_t *handle, qspi_transfer_t *xfer); + +/*! + * @brief Receives data using an eDMA non-blocking method. + * + * This function receive data from the QSPI receive buffer/FIFO. This function is non-blocking. + * @param base Pointer to QuadSPI Type. + * @param handle Pointer to qspi_edma_handle_t structure + * @param xfer QSPI transfer structure. + */ +status_t QSPI_TransferReceiveEDMA(QuadSPI_Type *base, qspi_edma_handle_t *handle, qspi_transfer_t *xfer); + +/*! + * @brief Aborts the sent data using eDMA. + * + * This function aborts the sent data using eDMA. + * + * @param base QSPI peripheral base address. + * @param handle Pointer to qspi_edma_handle_t structure + */ +void QSPI_TransferAbortSendEDMA(QuadSPI_Type *base, qspi_edma_handle_t *handle); + +/*! + * @brief Aborts the receive data using eDMA. + * + * This function abort receive data which using eDMA. + * + * @param base QSPI peripheral base address. + * @param handle Pointer to qspi_edma_handle_t structure + */ +void QSPI_TransferAbortReceiveEDMA(QuadSPI_Type *base, qspi_edma_handle_t *handle); + +/*! + * @brief Gets the transferred counts of send. + * + * @param base Pointer to QuadSPI Type. + * @param handle Pointer to qspi_edma_handle_t structure. + * @param count Bytes sent. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t QSPI_TransferGetSendCountEDMA(QuadSPI_Type *base, qspi_edma_handle_t *handle, size_t *count); + +/*! + * @brief Gets the status of the receive transfer. + * + * @param base Pointer to QuadSPI Type. + * @param handle Pointer to qspi_edma_handle_t structure + * @param count Bytes received. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t QSPI_TransferGetReceiveCountEDMA(QuadSPI_Type *base, qspi_edma_handle_t *handle, size_t *count); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/* @} */ + +#endif /* _FSL_QSPI_EDMA_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rcm.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rcm.c new file mode 100644 index 00000000000..9cf7479d337 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rcm.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_rcm.h" + +void RCM_ConfigureResetPinFilter(RCM_Type *base, const rcm_reset_pin_filter_config_t *config) +{ + assert(config); + +#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32)) + uint32_t reg; + + reg = (((uint32_t)config->enableFilterInStop << RCM_RPC_RSTFLTSS_SHIFT) | (uint32_t)config->filterInRunWait); + if (config->filterInRunWait == kRCM_FilterBusClock) + { + reg |= ((uint32_t)config->busClockFilterCount << RCM_RPC_RSTFLTSEL_SHIFT); + } + base->RPC = reg; +#else + base->RPFC = ((uint8_t)(config->enableFilterInStop << RCM_RPFC_RSTFLTSS_SHIFT) | (uint8_t)config->filterInRunWait); + if (config->filterInRunWait == kRCM_FilterBusClock) + { + base->RPFW = config->busClockFilterCount; + } +#endif /* FSL_FEATURE_RCM_REG_WIDTH */ +} + +#if (defined(FSL_FEATURE_RCM_HAS_BOOTROM) && FSL_FEATURE_RCM_HAS_BOOTROM) +void RCM_SetForceBootRomSource(RCM_Type *base, rcm_boot_rom_config_t config) +{ + uint32_t reg; + + reg = base->FM; + reg &= ~RCM_FM_FORCEROM_MASK; + reg |= ((uint32_t)config << RCM_FM_FORCEROM_SHIFT); + base->FM = reg; +} +#endif /* #if FSL_FEATURE_RCM_HAS_BOOTROM */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rcm.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rcm.h new file mode 100644 index 00000000000..d329e57e4b8 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rcm.h @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_RCM_H_ +#define _FSL_RCM_H_ + +#include "fsl_common.h" + +/*! @addtogroup rcm */ +/*! @{*/ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief RCM driver version 2.0.1. */ +#define FSL_RCM_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! + * @brief System Reset Source Name definitions + */ +typedef enum _rcm_reset_source +{ +#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32)) +/* RCM register bit width is 32. */ +#if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP) + kRCM_SourceWakeup = RCM_SRS_WAKEUP_MASK, /*!< Low-leakage wakeup reset */ +#endif + kRCM_SourceLvd = RCM_SRS_LVD_MASK, /*!< Low-voltage detect reset */ +#if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC) + kRCM_SourceLoc = RCM_SRS_LOC_MASK, /*!< Loss of clock reset */ +#endif /* FSL_FEATURE_RCM_HAS_LOC */ +#if (defined(FSL_FEATURE_RCM_HAS_LOL) && FSL_FEATURE_RCM_HAS_LOL) + kRCM_SourceLol = RCM_SRS_LOL_MASK, /*!< Loss of lock reset */ +#endif /* FSL_FEATURE_RCM_HAS_LOL */ + kRCM_SourceWdog = RCM_SRS_WDOG_MASK, /*!< Watchdog reset */ + kRCM_SourcePin = RCM_SRS_PIN_MASK, /*!< External pin reset */ + kRCM_SourcePor = RCM_SRS_POR_MASK, /*!< Power on reset */ +#if (defined(FSL_FEATURE_RCM_HAS_JTAG) && FSL_FEATURE_RCM_HAS_JTAG) + kRCM_SourceJtag = RCM_SRS_JTAG_MASK, /*!< JTAG generated reset */ +#endif /* FSL_FEATURE_RCM_HAS_JTAG */ + kRCM_SourceLockup = RCM_SRS_LOCKUP_MASK, /*!< Core lock up reset */ + kRCM_SourceSw = RCM_SRS_SW_MASK, /*!< Software reset */ +#if (defined(FSL_FEATURE_RCM_HAS_MDM_AP) && FSL_FEATURE_RCM_HAS_MDM_AP) + kRCM_SourceMdmap = RCM_SRS_MDM_AP_MASK, /*!< MDM-AP system reset */ +#endif /* FSL_FEATURE_RCM_HAS_MDM_AP */ +#if (defined(FSL_FEATURE_RCM_HAS_EZPORT) && FSL_FEATURE_RCM_HAS_EZPORT) + kRCM_SourceEzpt = RCM_SRS_EZPT_MASK, /*!< EzPort reset */ +#endif /* FSL_FEATURE_RCM_HAS_EZPORT */ + kRCM_SourceSackerr = RCM_SRS_SACKERR_MASK, /*!< Parameter could get all reset flags */ + +#else /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */ +/* RCM register bit width is 8. */ +#if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP) + kRCM_SourceWakeup = RCM_SRS0_WAKEUP_MASK, /*!< Low-leakage wakeup reset */ +#endif + kRCM_SourceLvd = RCM_SRS0_LVD_MASK, /*!< Low-voltage detect reset */ +#if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC) + kRCM_SourceLoc = RCM_SRS0_LOC_MASK, /*!< Loss of clock reset */ +#endif /* FSL_FEATURE_RCM_HAS_LOC */ +#if (defined(FSL_FEATURE_RCM_HAS_LOL) && FSL_FEATURE_RCM_HAS_LOL) + kRCM_SourceLol = RCM_SRS0_LOL_MASK, /*!< Loss of lock reset */ +#endif /* FSL_FEATURE_RCM_HAS_LOL */ + kRCM_SourceWdog = RCM_SRS0_WDOG_MASK, /*!< Watchdog reset */ + kRCM_SourcePin = RCM_SRS0_PIN_MASK, /*!< External pin reset */ + kRCM_SourcePor = RCM_SRS0_POR_MASK, /*!< Power on reset */ +#if (defined(FSL_FEATURE_RCM_HAS_JTAG) && FSL_FEATURE_RCM_HAS_JTAG) + kRCM_SourceJtag = RCM_SRS1_JTAG_MASK << 8U, /*!< JTAG generated reset */ +#endif /* FSL_FEATURE_RCM_HAS_JTAG */ + kRCM_SourceLockup = RCM_SRS1_LOCKUP_MASK << 8U, /*!< Core lock up reset */ + kRCM_SourceSw = RCM_SRS1_SW_MASK << 8U, /*!< Software reset */ +#if (defined(FSL_FEATURE_RCM_HAS_MDM_AP) && FSL_FEATURE_RCM_HAS_MDM_AP) + kRCM_SourceMdmap = RCM_SRS1_MDM_AP_MASK << 8U, /*!< MDM-AP system reset */ +#endif /* FSL_FEATURE_RCM_HAS_MDM_AP */ +#if (defined(FSL_FEATURE_RCM_HAS_EZPORT) && FSL_FEATURE_RCM_HAS_EZPORT) + kRCM_SourceEzpt = RCM_SRS1_EZPT_MASK << 8U, /*!< EzPort reset */ +#endif /* FSL_FEATURE_RCM_HAS_EZPORT */ + kRCM_SourceSackerr = RCM_SRS1_SACKERR_MASK << 8U, /*!< Parameter could get all reset flags */ +#endif /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */ + kRCM_SourceAll = 0xffffffffU, +} rcm_reset_source_t; + +/*! + * @brief Reset pin filter select in Run and Wait modes. + */ +typedef enum _rcm_run_wait_filter_mode +{ + kRCM_FilterDisable = 0U, /*!< All filtering disabled */ + kRCM_FilterBusClock = 1U, /*!< Bus clock filter enabled */ + kRCM_FilterLpoClock = 2U /*!< LPO clock filter enabled */ +} rcm_run_wait_filter_mode_t; + +#if (defined(FSL_FEATURE_RCM_HAS_BOOTROM) && FSL_FEATURE_RCM_HAS_BOOTROM) +/*! + * @brief Boot from ROM configuration. + */ +typedef enum _rcm_boot_rom_config +{ + kRCM_BootFlash = 0U, /*!< Boot from flash */ + kRCM_BootRomCfg0 = 1U, /*!< Boot from boot ROM due to BOOTCFG0 */ + kRCM_BootRomFopt = 2U, /*!< Boot from boot ROM due to FOPT[7] */ + kRCM_BootRomBoth = 3U /*!< Boot from boot ROM due to both BOOTCFG0 and FOPT[7] */ +} rcm_boot_rom_config_t; +#endif /* FSL_FEATURE_RCM_HAS_BOOTROM */ + +#if (defined(FSL_FEATURE_RCM_HAS_SRIE) && FSL_FEATURE_RCM_HAS_SRIE) +/*! + * @brief Maximum delay time from interrupt asserts to system reset. + */ +typedef enum _rcm_reset_delay +{ + kRCM_ResetDelay8Lpo = 0U, /*!< Delay 8 LPO cycles. */ + kRCM_ResetDelay32Lpo = 1U, /*!< Delay 32 LPO cycles. */ + kRCM_ResetDelay128Lpo = 2U, /*!< Delay 128 LPO cycles. */ + kRCM_ResetDelay512Lpo = 3U /*!< Delay 512 LPO cycles. */ +} rcm_reset_delay_t; + +/*! + * @brief System reset interrupt enable bit definitions. + */ +typedef enum _rcm_interrupt_enable +{ + kRCM_IntNone = 0U, /*!< No interrupt enabled. */ + kRCM_IntLossOfClk = RCM_SRIE_LOC_MASK, /*!< Loss of clock interrupt. */ + kRCM_IntLossOfLock = RCM_SRIE_LOL_MASK, /*!< Loss of lock interrupt. */ + kRCM_IntWatchDog = RCM_SRIE_WDOG_MASK, /*!< Watch dog interrupt. */ + kRCM_IntExternalPin = RCM_SRIE_PIN_MASK, /*!< External pin interrupt. */ + kRCM_IntGlobal = RCM_SRIE_GIE_MASK, /*!< Global interrupts. */ + kRCM_IntCoreLockup = RCM_SRIE_LOCKUP_MASK, /*!< Core lock up interrupt */ + kRCM_IntSoftware = RCM_SRIE_SW_MASK, /*!< software interrupt */ + kRCM_IntStopModeAckErr = RCM_SRIE_SACKERR_MASK, /*!< Stop mode ACK error interrupt. */ +#if (defined(FSL_FEATURE_RCM_HAS_CORE1) && FSL_FEATURE_RCM_HAS_CORE1) + kRCM_IntCore1 = RCM_SRIE_CORE1_MASK, /*!< Core 1 interrupt. */ +#endif + kRCM_IntAll = RCM_SRIE_LOC_MASK /*!< Enable all interrupts. */ + | + RCM_SRIE_LOL_MASK | RCM_SRIE_WDOG_MASK | RCM_SRIE_PIN_MASK | RCM_SRIE_GIE_MASK | + RCM_SRIE_LOCKUP_MASK | RCM_SRIE_SW_MASK | RCM_SRIE_SACKERR_MASK +#if (defined(FSL_FEATURE_RCM_HAS_CORE1) && FSL_FEATURE_RCM_HAS_CORE1) + | + RCM_SRIE_CORE1_MASK +#endif +} rcm_interrupt_enable_t; +#endif /* FSL_FEATURE_RCM_HAS_SRIE */ + +#if (defined(FSL_FEATURE_RCM_HAS_VERID) && FSL_FEATURE_RCM_HAS_VERID) +/*! + * @brief IP version ID definition. + */ +typedef struct _rcm_version_id +{ + uint16_t feature; /*!< Feature Specification Number. */ + uint8_t minor; /*!< Minor version number. */ + uint8_t major; /*!< Major version number. */ +} rcm_version_id_t; +#endif + +/*! + * @brief Reset pin filter configuration. + */ +typedef struct _rcm_reset_pin_filter_config +{ + bool enableFilterInStop; /*!< Reset pin filter select in stop mode. */ + rcm_run_wait_filter_mode_t filterInRunWait; /*!< Reset pin filter in run/wait mode. */ + uint8_t busClockFilterCount; /*!< Reset pin bus clock filter width. */ +} rcm_reset_pin_filter_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! @name Reset Control Module APIs*/ +/*@{*/ + +#if (defined(FSL_FEATURE_RCM_HAS_VERID) && FSL_FEATURE_RCM_HAS_VERID) +/*! + * @brief Gets the RCM version ID. + * + * This function gets the RCM version ID including the major version number, + * the minor version number, and the feature specification number. + * + * @param base RCM peripheral base address. + * @param versionId Pointer to the version ID structure. + */ +static inline void RCM_GetVersionId(RCM_Type *base, rcm_version_id_t *versionId) +{ + *((uint32_t *)versionId) = base->VERID; +} +#endif + +#if (defined(FSL_FEATURE_RCM_HAS_PARAM) && FSL_FEATURE_RCM_HAS_PARAM) +/*! + * @brief Gets the reset source implemented status. + * + * This function gets the RCM parameter that indicates whether the corresponding reset source is implemented. + * Use source masks defined in the rcm_reset_source_t to get the desired source status. + * + * This is an example. + @code + uint32_t status; + + // To test whether the MCU is reset using Watchdog. + status = RCM_GetResetSourceImplementedStatus(RCM) & (kRCM_SourceWdog | kRCM_SourcePin); + @endcode + * + * @param base RCM peripheral base address. + * @return All reset source implemented status bit map. + */ +static inline uint32_t RCM_GetResetSourceImplementedStatus(RCM_Type *base) +{ + return base->PARAM; +} +#endif /* FSL_FEATURE_RCM_HAS_PARAM */ + +/*! + * @brief Gets the reset source status which caused a previous reset. + * + * This function gets the current reset source status. Use source masks + * defined in the rcm_reset_source_t to get the desired source status. + * + * This is an example. + @code + uint32_t resetStatus; + + // To get all reset source statuses. + resetStatus = RCM_GetPreviousResetSources(RCM) & kRCM_SourceAll; + + // To test whether the MCU is reset using Watchdog. + resetStatus = RCM_GetPreviousResetSources(RCM) & kRCM_SourceWdog; + + // To test multiple reset sources. + resetStatus = RCM_GetPreviousResetSources(RCM) & (kRCM_SourceWdog | kRCM_SourcePin); + @endcode + * + * @param base RCM peripheral base address. + * @return All reset source status bit map. + */ +static inline uint32_t RCM_GetPreviousResetSources(RCM_Type *base) +{ +#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32)) + return base->SRS; +#else + return (uint32_t)((uint32_t)base->SRS0 | ((uint32_t)base->SRS1 << 8U)); +#endif /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */ +} + +#if (defined(FSL_FEATURE_RCM_HAS_SSRS) && FSL_FEATURE_RCM_HAS_SSRS) +/*! + * @brief Gets the sticky reset source status. + * + * This function gets the current reset source status that has not been cleared + * by software for a specific source. + * + * This is an example. + @code + uint32_t resetStatus; + + // To get all reset source statuses. + resetStatus = RCM_GetStickyResetSources(RCM) & kRCM_SourceAll; + + // To test whether the MCU is reset using Watchdog. + resetStatus = RCM_GetStickyResetSources(RCM) & kRCM_SourceWdog; + + // To test multiple reset sources. + resetStatus = RCM_GetStickyResetSources(RCM) & (kRCM_SourceWdog | kRCM_SourcePin); + @endcode + * + * @param base RCM peripheral base address. + * @return All reset source status bit map. + */ +static inline uint32_t RCM_GetStickyResetSources(RCM_Type *base) +{ +#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32)) + return base->SSRS; +#else + return (base->SSRS0 | ((uint32_t)base->SSRS1 << 8U)); +#endif /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */ +} + +/*! + * @brief Clears the sticky reset source status. + * + * This function clears the sticky system reset flags indicated by source masks. + * + * This is an example. + @code + // Clears multiple reset sources. + RCM_ClearStickyResetSources(kRCM_SourceWdog | kRCM_SourcePin); + @endcode + * + * @param base RCM peripheral base address. + * @param sourceMasks reset source status bit map + */ +static inline void RCM_ClearStickyResetSources(RCM_Type *base, uint32_t sourceMasks) +{ +#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32)) + base->SSRS = sourceMasks; +#else + base->SSRS0 = (sourceMasks & 0xffU); + base->SSRS1 = ((sourceMasks >> 8U) & 0xffU); +#endif /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */ +} +#endif /* FSL_FEATURE_RCM_HAS_SSRS */ + +/*! + * @brief Configures the reset pin filter. + * + * This function sets the reset pin filter including the filter source, filter + * width, and so on. + * + * @param base RCM peripheral base address. + * @param config Pointer to the configuration structure. + */ +void RCM_ConfigureResetPinFilter(RCM_Type *base, const rcm_reset_pin_filter_config_t *config); + +#if (defined(FSL_FEATURE_RCM_HAS_EZPMS) && FSL_FEATURE_RCM_HAS_EZPMS) +/*! + * @brief Gets the EZP_MS_B pin assert status. + * + * This function gets the easy port mode status (EZP_MS_B) pin assert status. + * + * @param base RCM peripheral base address. + * @return status true - asserted, false - reasserted + */ +static inline bool RCM_GetEasyPortModePinStatus(RCM_Type *base) +{ + return (bool)(base->MR & RCM_MR_EZP_MS_MASK); +} +#endif /* FSL_FEATURE_RCM_HAS_EZPMS */ + +#if (defined(FSL_FEATURE_RCM_HAS_BOOTROM) && FSL_FEATURE_RCM_HAS_BOOTROM) +/*! + * @brief Gets the ROM boot source. + * + * This function gets the ROM boot source during the last chip reset. + * + * @param base RCM peripheral base address. + * @return The ROM boot source. + */ +static inline rcm_boot_rom_config_t RCM_GetBootRomSource(RCM_Type *base) +{ + return (rcm_boot_rom_config_t)((base->MR & RCM_MR_BOOTROM_MASK) >> RCM_MR_BOOTROM_SHIFT); +} + +/*! + * @brief Clears the ROM boot source flag. + * + * This function clears the ROM boot source flag. + * + * @param base Register base address of RCM + */ +static inline void RCM_ClearBootRomSource(RCM_Type *base) +{ + base->MR |= RCM_MR_BOOTROM_MASK; +} + +/*! + * @brief Forces the boot from ROM. + * + * This function forces booting from ROM during all subsequent system resets. + * + * @param base RCM peripheral base address. + * @param config Boot configuration. + */ +void RCM_SetForceBootRomSource(RCM_Type *base, rcm_boot_rom_config_t config); +#endif /* FSL_FEATURE_RCM_HAS_BOOTROM */ + +#if (defined(FSL_FEATURE_RCM_HAS_SRIE) && FSL_FEATURE_RCM_HAS_SRIE) +/*! + * @brief Sets the system reset interrupt configuration. + * + * For a graceful shut down, the RCM supports delaying the assertion of the system + * reset for a period of time when the reset interrupt is generated. This function + * can be used to enable the interrupt and the delay period. The interrupts + * are passed in as bit mask. See rcm_int_t for details. For example, to + * delay a reset for 512 LPO cycles after the WDOG timeout or loss-of-clock occurs, + * configure as follows: + * RCM_SetSystemResetInterruptConfig(kRCM_IntWatchDog | kRCM_IntLossOfClk, kRCM_ResetDelay512Lpo); + * + * @param base RCM peripheral base address. + * @param intMask Bit mask of the system reset interrupts to enable. See + * rcm_interrupt_enable_t for details. + * @param Delay Bit mask of the system reset interrupts to enable. + */ +static inline void RCM_SetSystemResetInterruptConfig(RCM_Type *base, uint32_t intMask, rcm_reset_delay_t delay) +{ + base->SRIE = (intMask | delay); +} +#endif /* FSL_FEATURE_RCM_HAS_SRIE */ +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/*! @}*/ + +#endif /* _FSL_RCM_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rtc.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rtc.c new file mode 100644 index 00000000000..5f8a1079eb3 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rtc.c @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_rtc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define SECONDS_IN_A_DAY (86400U) +#define SECONDS_IN_A_HOUR (3600U) +#define SECONDS_IN_A_MINUTE (60U) +#define DAYS_IN_A_YEAR (365U) +#define YEAR_RANGE_START (1970U) +#define YEAR_RANGE_END (2099U) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Checks whether the date and time passed in is valid + * + * @param datetime Pointer to structure where the date and time details are stored + * + * @return Returns false if the date & time details are out of range; true if in range + */ +static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime); + +/*! + * @brief Converts time data from datetime to seconds + * + * @param datetime Pointer to datetime structure where the date and time details are stored + * + * @return The result of the conversion in seconds + */ +static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime); + +/*! + * @brief Converts time data from seconds to a datetime structure + * + * @param seconds Seconds value that needs to be converted to datetime format + * @param datetime Pointer to the datetime structure where the result of the conversion is stored + */ +static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime); + +/******************************************************************************* + * Code + ******************************************************************************/ +static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime) +{ + assert(datetime); + + /* Table of days in a month for a non leap year. First entry in the table is not used, + * valid months start from 1 + */ + uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; + + /* Check year, month, hour, minute, seconds */ + if ((datetime->year < YEAR_RANGE_START) || (datetime->year > YEAR_RANGE_END) || (datetime->month > 12U) || + (datetime->month < 1U) || (datetime->hour >= 24U) || (datetime->minute >= 60U) || (datetime->second >= 60U)) + { + /* If not correct then error*/ + return false; + } + + /* Adjust the days in February for a leap year */ + if ((((datetime->year & 3U) == 0) && (datetime->year % 100 != 0)) || (datetime->year % 400 == 0)) + { + daysPerMonth[2] = 29U; + } + + /* Check the validity of the day */ + if ((datetime->day > daysPerMonth[datetime->month]) || (datetime->day < 1U)) + { + return false; + } + + return true; +} + +static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime) +{ + assert(datetime); + + /* Number of days from begin of the non Leap-year*/ + /* Number of days from begin of the non Leap-year*/ + uint16_t monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U}; + uint32_t seconds; + + /* Compute number of days from 1970 till given year*/ + seconds = (datetime->year - 1970U) * DAYS_IN_A_YEAR; + /* Add leap year days */ + seconds += ((datetime->year / 4) - (1970U / 4)); + /* Add number of days till given month*/ + seconds += monthDays[datetime->month]; + /* Add days in given month. We subtract the current day as it is + * represented in the hours, minutes and seconds field*/ + seconds += (datetime->day - 1); + /* For leap year if month less than or equal to Febraury, decrement day counter*/ + if ((!(datetime->year & 3U)) && (datetime->month <= 2U)) + { + seconds--; + } + + seconds = (seconds * SECONDS_IN_A_DAY) + (datetime->hour * SECONDS_IN_A_HOUR) + + (datetime->minute * SECONDS_IN_A_MINUTE) + datetime->second; + + return seconds; +} + +static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime) +{ + assert(datetime); + + uint32_t x; + uint32_t secondsRemaining, days; + uint16_t daysInYear; + /* Table of days in a month for a non leap year. First entry in the table is not used, + * valid months start from 1 + */ + uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; + + /* Start with the seconds value that is passed in to be converted to date time format */ + secondsRemaining = seconds; + + /* Calcuate the number of days, we add 1 for the current day which is represented in the + * hours and seconds field + */ + days = secondsRemaining / SECONDS_IN_A_DAY + 1; + + /* Update seconds left*/ + secondsRemaining = secondsRemaining % SECONDS_IN_A_DAY; + + /* Calculate the datetime hour, minute and second fields */ + datetime->hour = secondsRemaining / SECONDS_IN_A_HOUR; + secondsRemaining = secondsRemaining % SECONDS_IN_A_HOUR; + datetime->minute = secondsRemaining / 60U; + datetime->second = secondsRemaining % SECONDS_IN_A_MINUTE; + + /* Calculate year */ + daysInYear = DAYS_IN_A_YEAR; + datetime->year = YEAR_RANGE_START; + while (days > daysInYear) + { + /* Decrease day count by a year and increment year by 1 */ + days -= daysInYear; + datetime->year++; + + /* Adjust the number of days for a leap year */ + if (datetime->year & 3U) + { + daysInYear = DAYS_IN_A_YEAR; + } + else + { + daysInYear = DAYS_IN_A_YEAR + 1; + } + } + + /* Adjust the days in February for a leap year */ + if (!(datetime->year & 3U)) + { + daysPerMonth[2] = 29U; + } + + for (x = 1U; x <= 12U; x++) + { + if (days <= daysPerMonth[x]) + { + datetime->month = x; + break; + } + else + { + days -= daysPerMonth[x]; + } + } + + datetime->day = days; +} + +void RTC_Init(RTC_Type *base, const rtc_config_t *config) +{ + assert(config); + + uint32_t reg; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(kCLOCK_Rtc0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Issue a software reset if timer is invalid */ + if (RTC_GetStatusFlags(RTC) & kRTC_TimeInvalidFlag) + { + RTC_Reset(RTC); + } + + reg = base->CR; + /* Setup the update mode and supervisor access mode */ + reg &= ~(RTC_CR_UM_MASK | RTC_CR_SUP_MASK); + reg |= RTC_CR_UM(config->updateMode) | RTC_CR_SUP(config->supervisorAccess); +#if defined(FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION) && FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION + /* Setup the wakeup pin select */ + reg &= ~(RTC_CR_WPS_MASK); + reg |= RTC_CR_WPS(config->wakeupSelect); +#endif /* FSL_FEATURE_RTC_HAS_WAKEUP_PIN */ + base->CR = reg; + + /* Configure the RTC time compensation register */ + base->TCR = (RTC_TCR_CIR(config->compensationInterval) | RTC_TCR_TCR(config->compensationTime)); +} + +void RTC_GetDefaultConfig(rtc_config_t *config) +{ + assert(config); + + /* Wakeup pin will assert if the RTC interrupt asserts or if the wakeup pin is turned on */ + config->wakeupSelect = false; + /* Registers cannot be written when locked */ + config->updateMode = false; + /* Non-supervisor mode write accesses are not supported and will generate a bus error */ + config->supervisorAccess = false; + /* Compensation interval used by the crystal compensation logic */ + config->compensationInterval = 0; + /* Compensation time used by the crystal compensation logic */ + config->compensationTime = 0; +} + +status_t RTC_SetDatetime(RTC_Type *base, const rtc_datetime_t *datetime) +{ + assert(datetime); + + /* Return error if the time provided is not valid */ + if (!(RTC_CheckDatetimeFormat(datetime))) + { + return kStatus_InvalidArgument; + } + + /* Set time in seconds */ + base->TSR = RTC_ConvertDatetimeToSeconds(datetime); + + return kStatus_Success; +} + +void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime) +{ + assert(datetime); + + uint32_t seconds = 0; + + seconds = base->TSR; + RTC_ConvertSecondsToDatetime(seconds, datetime); +} + +status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime) +{ + assert(alarmTime); + + uint32_t alarmSeconds = 0; + uint32_t currSeconds = 0; + + /* Return error if the alarm time provided is not valid */ + if (!(RTC_CheckDatetimeFormat(alarmTime))) + { + return kStatus_InvalidArgument; + } + + alarmSeconds = RTC_ConvertDatetimeToSeconds(alarmTime); + + /* Get the current time */ + currSeconds = base->TSR; + + /* Return error if the alarm time has passed */ + if (alarmSeconds < currSeconds) + { + return kStatus_Fail; + } + + /* Set alarm in seconds*/ + base->TAR = alarmSeconds; + + return kStatus_Success; +} + +void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime) +{ + assert(datetime); + + uint32_t alarmSeconds = 0; + + /* Get alarm in seconds */ + alarmSeconds = base->TAR; + + RTC_ConvertSecondsToDatetime(alarmSeconds, datetime); +} + +void RTC_ClearStatusFlags(RTC_Type *base, uint32_t mask) +{ + /* The alarm flag is cleared by writing to the TAR register */ + if (mask & kRTC_AlarmFlag) + { + base->TAR = 0U; + } + + /* The timer overflow flag is cleared by initializing the TSR register. + * The time counter should be disabled for this write to be successful + */ + if (mask & kRTC_TimeOverflowFlag) + { + base->TSR = 1U; + } + + /* The timer overflow flag is cleared by initializing the TSR register. + * The time counter should be disabled for this write to be successful + */ + if (mask & kRTC_TimeInvalidFlag) + { + base->TSR = 1U; + } +} + +#if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC) + +void RTC_GetMonotonicCounter(RTC_Type *base, uint64_t *counter) +{ + assert(counter); + + *counter = (((uint64_t)base->MCHR << 32) | ((uint64_t)base->MCLR)); +} + +void RTC_SetMonotonicCounter(RTC_Type *base, uint64_t counter) +{ + /* Prepare to initialize the register with the new value written */ + base->MER &= ~RTC_MER_MCE_MASK; + + base->MCHR = (uint32_t)((counter) >> 32); + base->MCLR = (uint32_t)(counter); +} + +status_t RTC_IncrementMonotonicCounter(RTC_Type *base) +{ + if (base->SR & (RTC_SR_MOF_MASK | RTC_SR_TIF_MASK)) + { + return kStatus_Fail; + } + + /* Prepare to switch to increment mode */ + base->MER |= RTC_MER_MCE_MASK; + /* Write anything so the counter increments*/ + base->MCLR = 1U; + + return kStatus_Success; +} + +#endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rtc.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rtc.h new file mode 100644 index 00000000000..e4d8f160296 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_rtc.h @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_RTC_H_ +#define _FSL_RTC_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup rtc + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_RTC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +/*@}*/ + +/*! @brief List of RTC interrupts */ +typedef enum _rtc_interrupt_enable +{ + kRTC_TimeInvalidInterruptEnable = RTC_IER_TIIE_MASK, /*!< Time invalid interrupt.*/ + kRTC_TimeOverflowInterruptEnable = RTC_IER_TOIE_MASK, /*!< Time overflow interrupt.*/ + kRTC_AlarmInterruptEnable = RTC_IER_TAIE_MASK, /*!< Alarm interrupt.*/ + kRTC_SecondsInterruptEnable = RTC_IER_TSIE_MASK /*!< Seconds interrupt.*/ +} rtc_interrupt_enable_t; + +/*! @brief List of RTC flags */ +typedef enum _rtc_status_flags +{ + kRTC_TimeInvalidFlag = RTC_SR_TIF_MASK, /*!< Time invalid flag */ + kRTC_TimeOverflowFlag = RTC_SR_TOF_MASK, /*!< Time overflow flag */ + kRTC_AlarmFlag = RTC_SR_TAF_MASK /*!< Alarm flag*/ +} rtc_status_flags_t; + +#if (defined(FSL_FEATURE_RTC_HAS_OSC_SCXP) && FSL_FEATURE_RTC_HAS_OSC_SCXP) + +/*! @brief List of RTC Oscillator capacitor load settings */ +typedef enum _rtc_osc_cap_load +{ + kRTC_Capacitor_2p = RTC_CR_SC2P_MASK, /*!< 2 pF capacitor load */ + kRTC_Capacitor_4p = RTC_CR_SC4P_MASK, /*!< 4 pF capacitor load */ + kRTC_Capacitor_8p = RTC_CR_SC8P_MASK, /*!< 8 pF capacitor load */ + kRTC_Capacitor_16p = RTC_CR_SC16P_MASK /*!< 16 pF capacitor load */ +} rtc_osc_cap_load_t; + +#endif /* FSL_FEATURE_SCG_HAS_OSC_SCXP */ + +/*! @brief Structure is used to hold the date and time */ +typedef struct _rtc_datetime +{ + uint16_t year; /*!< Range from 1970 to 2099.*/ + uint8_t month; /*!< Range from 1 to 12.*/ + uint8_t day; /*!< Range from 1 to 31 (depending on month).*/ + uint8_t hour; /*!< Range from 0 to 23.*/ + uint8_t minute; /*!< Range from 0 to 59.*/ + uint8_t second; /*!< Range from 0 to 59.*/ +} rtc_datetime_t; + +/*! + * @brief RTC config structure + * + * This structure holds the configuration settings for the RTC peripheral. To initialize this + * structure to reasonable defaults, call the RTC_GetDefaultConfig() function and pass a + * pointer to your config structure instance. + * + * The config struct can be made const so it resides in flash + */ +typedef struct _rtc_config +{ + bool wakeupSelect; /*!< true: Wakeup pin outputs the 32 KHz clock; + false:Wakeup pin used to wakeup the chip */ + bool updateMode; /*!< true: Registers can be written even when locked under certain + conditions, false: No writes allowed when registers are locked */ + bool supervisorAccess; /*!< true: Non-supervisor accesses are allowed; + false: Non-supervisor accesses are not supported */ + uint32_t compensationInterval; /*!< Compensation interval that is written to the CIR field in RTC TCR Register */ + uint32_t compensationTime; /*!< Compensation time that is written to the TCR field in RTC TCR Register */ +} rtc_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the RTC clock and configures the peripheral for basic operation. + * + * This function issues a software reset if the timer invalid flag is set. + * + * @note This API should be called at the beginning of the application using the RTC driver. + * + * @param base RTC peripheral base address + * @param config Pointer to the user's RTC configuration structure. + */ +void RTC_Init(RTC_Type *base, const rtc_config_t *config); + +/*! + * @brief Stops the timer and gate the RTC clock. + * + * @param base RTC peripheral base address + */ +static inline void RTC_Deinit(RTC_Type *base) +{ + /* Stop the RTC timer */ + base->SR &= ~RTC_SR_TCE_MASK; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate the module clock */ + CLOCK_DisableClock(kCLOCK_Rtc0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * @brief Fills in the RTC config struct with the default settings. + * + * The default values are as follows. + * @code + * config->wakeupSelect = false; + * config->updateMode = false; + * config->supervisorAccess = false; + * config->compensationInterval = 0; + * config->compensationTime = 0; + * @endcode + * @param config Pointer to the user's RTC configuration structure. + */ +void RTC_GetDefaultConfig(rtc_config_t *config); + +/*! @}*/ + +/*! + * @name Current Time & Alarm + * @{ + */ + +/*! + * @brief Sets the RTC date and time according to the given time structure. + * + * The RTC counter must be stopped prior to calling this function because writes to the RTC + * seconds register fail if the RTC counter is running. + * + * @param base RTC peripheral base address + * @param datetime Pointer to the structure where the date and time details are stored. + * + * @return kStatus_Success: Success in setting the time and starting the RTC + * kStatus_InvalidArgument: Error because the datetime format is incorrect + */ +status_t RTC_SetDatetime(RTC_Type *base, const rtc_datetime_t *datetime); + +/*! + * @brief Gets the RTC time and stores it in the given time structure. + * + * @param base RTC peripheral base address + * @param datetime Pointer to the structure where the date and time details are stored. + */ +void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime); + +/*! + * @brief Sets the RTC alarm time. + * + * The function checks whether the specified alarm time is greater than the present + * time. If not, the function does not set the alarm and returns an error. + * + * @param base RTC peripheral base address + * @param alarmTime Pointer to the structure where the alarm time is stored. + * + * @return kStatus_Success: success in setting the RTC alarm + * kStatus_InvalidArgument: Error because the alarm datetime format is incorrect + * kStatus_Fail: Error because the alarm time has already passed + */ +status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime); + +/*! + * @brief Returns the RTC alarm time. + * + * @param base RTC peripheral base address + * @param datetime Pointer to the structure where the alarm date and time details are stored. + */ +void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime); + +/*! @}*/ + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected RTC interrupts. + * + * @param base RTC peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::rtc_interrupt_enable_t + */ +static inline void RTC_EnableInterrupts(RTC_Type *base, uint32_t mask) +{ + base->IER |= mask; +} + +/*! + * @brief Disables the selected RTC interrupts. + * + * @param base RTC peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::rtc_interrupt_enable_t + */ +static inline void RTC_DisableInterrupts(RTC_Type *base, uint32_t mask) +{ + base->IER &= ~mask; +} + +/*! + * @brief Gets the enabled RTC interrupts. + * + * @param base RTC peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::rtc_interrupt_enable_t + */ +static inline uint32_t RTC_GetEnabledInterrupts(RTC_Type *base) +{ + return (base->IER & (RTC_IER_TIIE_MASK | RTC_IER_TOIE_MASK | RTC_IER_TAIE_MASK | RTC_IER_TSIE_MASK)); +} + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the RTC status flags. + * + * @param base RTC peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::rtc_status_flags_t + */ +static inline uint32_t RTC_GetStatusFlags(RTC_Type *base) +{ + return (base->SR & (RTC_SR_TIF_MASK | RTC_SR_TOF_MASK | RTC_SR_TAF_MASK)); +} + +/*! + * @brief Clears the RTC status flags. + * + * @param base RTC peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::rtc_status_flags_t + */ +void RTC_ClearStatusFlags(RTC_Type *base, uint32_t mask); + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ + +/*! + * @brief Starts the RTC time counter. + * + * After calling this function, the timer counter increments once a second provided SR[TOF] or + * SR[TIF] are not set. + * + * @param base RTC peripheral base address + */ +static inline void RTC_StartTimer(RTC_Type *base) +{ + base->SR |= RTC_SR_TCE_MASK; +} + +/*! + * @brief Stops the RTC time counter. + * + * RTC's seconds register can be written to only when the timer is stopped. + * + * @param base RTC peripheral base address + */ +static inline void RTC_StopTimer(RTC_Type *base) +{ + base->SR &= ~RTC_SR_TCE_MASK; +} + +/*! @}*/ + +#if (defined(FSL_FEATURE_RTC_HAS_OSC_SCXP) && FSL_FEATURE_RTC_HAS_OSC_SCXP) + +/*! + * @brief This function sets the specified capacitor configuration for the RTC oscillator. + * + * @param base RTC peripheral base address + * @param capLoad Oscillator loads to enable. This is a logical OR of members of the + * enumeration ::rtc_osc_cap_load_t + */ +static inline void RTC_SetOscCapLoad(RTC_Type *base, uint32_t capLoad) +{ + uint32_t reg = base->CR; + + reg &= ~(RTC_CR_SC2P_MASK | RTC_CR_SC4P_MASK | RTC_CR_SC8P_MASK | RTC_CR_SC16P_MASK); + reg |= capLoad; + + base->CR = reg; +} + +#endif /* FSL_FEATURE_SCG_HAS_OSC_SCXP */ + +/*! + * @brief Performs a software reset on the RTC module. + * + * This resets all RTC registers except for the SWR bit and the RTC_WAR and RTC_RAR + * registers. The SWR bit is cleared by software explicitly clearing it. + * + * @param base RTC peripheral base address + */ +static inline void RTC_Reset(RTC_Type *base) +{ + base->CR |= RTC_CR_SWR_MASK; + base->CR &= ~RTC_CR_SWR_MASK; + + /* Set TSR register to 0x1 to avoid the timer invalid (TIF) bit being set in the SR register */ + base->TSR = 1U; +} + +#if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC) + +/*! + * @name Monotonic counter functions + * @{ + */ + +/*! + * @brief Reads the values of the Monotonic Counter High and Monotonic Counter Low and returns + * them as a single value. + * + * @param base RTC peripheral base address + * @param counter Pointer to variable where the value is stored. + */ +void RTC_GetMonotonicCounter(RTC_Type *base, uint64_t *counter); + +/*! + * @brief Writes values Monotonic Counter High and Monotonic Counter Low by decomposing + * the given single value. + * + * @param base RTC peripheral base address + * @param counter Counter value + */ +void RTC_SetMonotonicCounter(RTC_Type *base, uint64_t counter); + +/*! + * @brief Increments the Monotonic Counter by one. + * + * Increments the Monotonic Counter (registers RTC_MCLR and RTC_MCHR accordingly) by setting + * the monotonic counter enable (MER[MCE]) and then writing to the RTC_MCLR register. A write to the + * monotonic counter low that causes it to overflow also increments the monotonic counter high. + * + * @param base RTC peripheral base address + * + * @return kStatus_Success: success + * kStatus_Fail: error occurred, either time invalid or monotonic overflow flag was found + */ +status_t RTC_IncrementMonotonicCounter(RTC_Type *base); + +/*! @}*/ + +#endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_RTC_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai.c new file mode 100644 index 00000000000..0d19d09e7a3 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai.c @@ -0,0 +1,1074 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_sai.h" + +/******************************************************************************* + * Definitations + ******************************************************************************/ +enum _sai_transfer_state +{ + kSAI_Busy = 0x0U, /*!< SAI is busy */ + kSAI_Idle, /*!< Transfer is done. */ + kSAI_Error /*!< Transfer error occured. */ +}; + +/*! @brief Typedef for sai tx interrupt handler. */ +typedef void (*sai_tx_isr_t)(I2S_Type *base, sai_handle_t *saiHandle); + +/*! @brief Typedef for sai rx interrupt handler. */ +typedef void (*sai_rx_isr_t)(I2S_Type *base, sai_handle_t *saiHandle); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) + +/*! + * @brief Set the master clock divider. + * + * This API will compute the master clock divider according to master clock frequency and master + * clock source clock source frequency. + * + * @param base SAI base pointer. + * @param mclk_Hz Mater clock frequency in Hz. + * @param mclkSrcClock_Hz Master clock source frequency in Hz. + */ +static void SAI_SetMasterClockDivider(I2S_Type *base, uint32_t mclk_Hz, uint32_t mclkSrcClock_Hz); +#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ + +/*! + * @brief Get the instance number for SAI. + * + * @param base SAI base pointer. + */ +uint32_t SAI_GetInstance(I2S_Type *base); + +/*! + * @brief sends a piece of data in non-blocking way. + * + * @param base SAI base pointer + * @param channel Data channel used. + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param buffer Pointer to the data to be written. + * @param size Bytes to be written. + */ +static void SAI_WriteNonBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size); + +/*! + * @brief Receive a piece of data in non-blocking way. + * + * @param base SAI base pointer + * @param channel Data channel used. + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param buffer Pointer to the data to be read. + * @param size Bytes to be read. + */ +static void SAI_ReadNonBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size); +/******************************************************************************* + * Variables + ******************************************************************************/ +/*!@brief SAI handle pointer */ +sai_handle_t *s_saiHandle[FSL_FEATURE_SOC_I2S_COUNT][2]; +/* Base pointer array */ +static I2S_Type *const s_saiBases[] = I2S_BASE_PTRS; +/* IRQ number array */ +static const IRQn_Type s_saiTxIRQ[] = I2S_TX_IRQS; +static const IRQn_Type s_saiRxIRQ[] = I2S_RX_IRQS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/* Clock name array */ +static const clock_ip_name_t s_saiClock[] = SAI_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +/*! @brief Pointer to tx IRQ handler for each instance. */ +static sai_tx_isr_t s_saiTxIsr; +/*! @brief Pointer to tx IRQ handler for each instance. */ +static sai_rx_isr_t s_saiRxIsr; + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) +static void SAI_SetMasterClockDivider(I2S_Type *base, uint32_t mclk_Hz, uint32_t mclkSrcClock_Hz) +{ + uint32_t freq = mclkSrcClock_Hz; + uint16_t fract, divide; + uint32_t remaind = 0; + uint32_t current_remainder = 0xFFFFFFFFU; + uint16_t current_fract = 0; + uint16_t current_divide = 0; + uint32_t mul_freq = 0; + uint32_t max_fract = 256; + + /*In order to prevent overflow */ + freq /= 100; + mclk_Hz /= 100; + + /* Compute the max fract number */ + max_fract = mclk_Hz * 4096 / freq + 1; + if (max_fract > 256) + { + max_fract = 256; + } + + /* Looking for the closet frequency */ + for (fract = 1; fract < max_fract; fract++) + { + mul_freq = freq * fract; + remaind = mul_freq % mclk_Hz; + divide = mul_freq / mclk_Hz; + + /* Find the exactly frequency */ + if (remaind == 0) + { + current_fract = fract; + current_divide = mul_freq / mclk_Hz; + break; + } + + /* Closer to next one, set the closest to next data */ + if (remaind > mclk_Hz / 2) + { + remaind = mclk_Hz - remaind; + divide += 1; + } + + /* Update the closest div and fract */ + if (remaind < current_remainder) + { + current_fract = fract; + current_divide = divide; + current_remainder = remaind; + } + } + + /* Fill the computed fract and divider to registers */ + base->MDR = I2S_MDR_DIVIDE(current_divide - 1) | I2S_MDR_FRACT(current_fract - 1); + + /* Waiting for the divider updated */ + while (base->MCR & I2S_MCR_DUF_MASK) + { + } +} +#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ + +uint32_t SAI_GetInstance(I2S_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_I2S_COUNT; instance++) + { + if (s_saiBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_I2S_COUNT); + + return instance; +} + +static void SAI_WriteNonBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size) +{ + uint32_t i = 0; + uint8_t j = 0; + uint8_t bytesPerWord = bitWidth / 8U; + uint32_t data = 0; + uint32_t temp = 0; + + for (i = 0; i < size / bytesPerWord; i++) + { + for (j = 0; j < bytesPerWord; j++) + { + temp = (uint32_t)(*buffer); + data |= (temp << (8U * j)); + buffer++; + } + base->TDR[channel] = data; + data = 0; + } +} + +static void SAI_ReadNonBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size) +{ + uint32_t i = 0; + uint8_t j = 0; + uint8_t bytesPerWord = bitWidth / 8U; + uint32_t data = 0; + + for (i = 0; i < size / bytesPerWord; i++) + { + data = base->RDR[channel]; + for (j = 0; j < bytesPerWord; j++) + { + *buffer = (data >> (8U * j)) & 0xFF; + buffer++; + } + } +} + +void SAI_TxInit(I2S_Type *base, const sai_config_t *config) +{ + uint32_t val = 0; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the SAI clock */ + CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) + /* Master clock source setting */ + val = (base->MCR & ~I2S_MCR_MICS_MASK); + base->MCR = (val | I2S_MCR_MICS(config->mclkSource)); + + /* Configure Master clock output enable */ + val = (base->MCR & ~I2S_MCR_MOE_MASK); + base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable)); +#endif /* FSL_FEATURE_SAI_HAS_MCR */ + + /* Configure audio protocol */ + switch (config->protocol) + { + case kSAI_BusLeftJustified: + base->TCR2 |= I2S_TCR2_BCP_MASK; + base->TCR3 &= ~I2S_TCR3_WDFL_MASK; + base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U); + break; + + case kSAI_BusRightJustified: + base->TCR2 |= I2S_TCR2_BCP_MASK; + base->TCR3 &= ~I2S_TCR3_WDFL_MASK; + base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U); + break; + + case kSAI_BusI2S: + base->TCR2 |= I2S_TCR2_BCP_MASK; + base->TCR3 &= ~I2S_TCR3_WDFL_MASK; + base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(1U) | I2S_TCR4_FSP(1U) | I2S_TCR4_FRSZ(1U); + break; + + case kSAI_BusPCMA: + base->TCR2 &= ~I2S_TCR2_BCP_MASK; + base->TCR3 &= ~I2S_TCR3_WDFL_MASK; + base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(0U) | I2S_TCR4_FSE(1U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U); + break; + + case kSAI_BusPCMB: + base->TCR2 &= ~I2S_TCR2_BCP_MASK; + base->TCR3 &= ~I2S_TCR3_WDFL_MASK; + base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(0U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U); + break; + + default: + break; + } + + /* Set master or slave */ + if (config->masterSlave == kSAI_Master) + { + base->TCR2 |= I2S_TCR2_BCD_MASK; + base->TCR4 |= I2S_TCR4_FSD_MASK; + + /* Bit clock source setting */ + val = base->TCR2 & (~I2S_TCR2_MSEL_MASK); + base->TCR2 = (val | I2S_TCR2_MSEL(config->bclkSource)); + } + else + { + base->TCR2 &= ~I2S_TCR2_BCD_MASK; + base->TCR4 &= ~I2S_TCR4_FSD_MASK; + } + + /* Set Sync mode */ + switch (config->syncMode) + { + case kSAI_ModeAsync: + val = base->TCR2; + val &= ~I2S_TCR2_SYNC_MASK; + base->TCR2 = (val | I2S_TCR2_SYNC(0U)); + break; + case kSAI_ModeSync: + val = base->TCR2; + val &= ~I2S_TCR2_SYNC_MASK; + base->TCR2 = (val | I2S_TCR2_SYNC(1U)); + /* If sync with Rx, should set Rx to async mode */ + val = base->RCR2; + val &= ~I2S_RCR2_SYNC_MASK; + base->RCR2 = (val | I2S_RCR2_SYNC(0U)); + break; + case kSAI_ModeSyncWithOtherTx: + val = base->TCR2; + val &= ~I2S_TCR2_SYNC_MASK; + base->TCR2 = (val | I2S_TCR2_SYNC(2U)); + break; + case kSAI_ModeSyncWithOtherRx: + val = base->TCR2; + val &= ~I2S_TCR2_SYNC_MASK; + base->TCR2 = (val | I2S_TCR2_SYNC(3U)); + break; + default: + break; + } +} + +void SAI_RxInit(I2S_Type *base, const sai_config_t *config) +{ + uint32_t val = 0; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable SAI clock first. */ + CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) + /* Master clock source setting */ + val = (base->MCR & ~I2S_MCR_MICS_MASK); + base->MCR = (val | I2S_MCR_MICS(config->mclkSource)); + + /* Configure Master clock output enable */ + val = (base->MCR & ~I2S_MCR_MOE_MASK); + base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable)); +#endif /* FSL_FEATURE_SAI_HAS_MCR */ + + /* Configure audio protocol */ + switch (config->protocol) + { + case kSAI_BusLeftJustified: + base->RCR2 |= I2S_RCR2_BCP_MASK; + base->RCR3 &= ~I2S_RCR3_WDFL_MASK; + base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U); + break; + + case kSAI_BusRightJustified: + base->RCR2 |= I2S_RCR2_BCP_MASK; + base->RCR3 &= ~I2S_RCR3_WDFL_MASK; + base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U); + break; + + case kSAI_BusI2S: + base->RCR2 |= I2S_RCR2_BCP_MASK; + base->RCR3 &= ~I2S_RCR3_WDFL_MASK; + base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(1U) | I2S_RCR4_FSP(1U) | I2S_RCR4_FRSZ(1U); + break; + + case kSAI_BusPCMA: + base->RCR2 &= ~I2S_RCR2_BCP_MASK; + base->RCR3 &= ~I2S_RCR3_WDFL_MASK; + base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(0U) | I2S_RCR4_FSE(1U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U); + break; + + case kSAI_BusPCMB: + base->RCR2 &= ~I2S_RCR2_BCP_MASK; + base->RCR3 &= ~I2S_RCR3_WDFL_MASK; + base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(0U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U); + break; + + default: + break; + } + + /* Set master or slave */ + if (config->masterSlave == kSAI_Master) + { + base->RCR2 |= I2S_RCR2_BCD_MASK; + base->RCR4 |= I2S_RCR4_FSD_MASK; + + /* Bit clock source setting */ + val = base->RCR2 & (~I2S_RCR2_MSEL_MASK); + base->RCR2 = (val | I2S_RCR2_MSEL(config->bclkSource)); + } + else + { + base->RCR2 &= ~I2S_RCR2_BCD_MASK; + base->RCR4 &= ~I2S_RCR4_FSD_MASK; + } + + /* Set Sync mode */ + switch (config->syncMode) + { + case kSAI_ModeAsync: + val = base->RCR2; + val &= ~I2S_RCR2_SYNC_MASK; + base->RCR2 = (val | I2S_RCR2_SYNC(0U)); + break; + case kSAI_ModeSync: + val = base->RCR2; + val &= ~I2S_RCR2_SYNC_MASK; + base->RCR2 = (val | I2S_RCR2_SYNC(1U)); + /* If sync with Tx, should set Tx to async mode */ + val = base->TCR2; + val &= ~I2S_TCR2_SYNC_MASK; + base->TCR2 = (val | I2S_TCR2_SYNC(0U)); + break; + case kSAI_ModeSyncWithOtherTx: + val = base->RCR2; + val &= ~I2S_RCR2_SYNC_MASK; + base->RCR2 = (val | I2S_RCR2_SYNC(2U)); + break; + case kSAI_ModeSyncWithOtherRx: + val = base->RCR2; + val &= ~I2S_RCR2_SYNC_MASK; + base->RCR2 = (val | I2S_RCR2_SYNC(3U)); + break; + default: + break; + } +} + +void SAI_Deinit(I2S_Type *base) +{ + SAI_TxEnable(base, false); + SAI_RxEnable(base, false); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(s_saiClock[SAI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void SAI_TxGetDefaultConfig(sai_config_t *config) +{ + config->bclkSource = kSAI_BclkSourceMclkDiv; + config->masterSlave = kSAI_Master; + config->mclkSource = kSAI_MclkSourceSysclk; + config->protocol = kSAI_BusLeftJustified; + config->syncMode = kSAI_ModeAsync; +#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) + config->mclkOutputEnable = true; +#endif /* FSL_FEATURE_SAI_HAS_MCR */ +} + +void SAI_RxGetDefaultConfig(sai_config_t *config) +{ + config->bclkSource = kSAI_BclkSourceMclkDiv; + config->masterSlave = kSAI_Master; + config->mclkSource = kSAI_MclkSourceSysclk; + config->protocol = kSAI_BusLeftJustified; + config->syncMode = kSAI_ModeSync; +#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) + config->mclkOutputEnable = true; +#endif /* FSL_FEATURE_SAI_HAS_MCR */ +} + +void SAI_TxReset(I2S_Type *base) +{ + /* Set the software reset and FIFO reset to clear internal state */ + base->TCSR = I2S_TCSR_SR_MASK | I2S_TCSR_FR_MASK; + + /* Clear software reset bit, this should be done by software */ + base->TCSR &= ~I2S_TCSR_SR_MASK; + + /* Reset all Tx register values */ + base->TCR2 = 0; + base->TCR3 = 0; + base->TCR4 = 0; + base->TCR5 = 0; + base->TMR = 0; +} + +void SAI_RxReset(I2S_Type *base) +{ + /* Set the software reset and FIFO reset to clear internal state */ + base->RCSR = I2S_RCSR_SR_MASK | I2S_RCSR_FR_MASK; + + /* Clear software reset bit, this should be done by software */ + base->RCSR &= ~I2S_RCSR_SR_MASK; + + /* Reset all Rx register values */ + base->RCR2 = 0; + base->RCR3 = 0; + base->RCR4 = 0; + base->RCR5 = 0; + base->RMR = 0; +} + +void SAI_TxEnable(I2S_Type *base, bool enable) +{ + if (enable) + { + /* If clock is sync with Rx, should enable RE bit. */ + if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) == 0x1U) + { + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK); + } + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK); + } + else + { + /* Should not close RE even sync with Rx */ + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~I2S_TCSR_TE_MASK)); + } +} + +void SAI_RxEnable(I2S_Type *base, bool enable) +{ + if (enable) + { + /* If clock is sync with Tx, should enable TE bit. */ + if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) == 0x1U) + { + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK); + } + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK); + } + else + { + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~I2S_RCSR_RE_MASK)); + } +} + +void SAI_TxSetFormat(I2S_Type *base, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz) +{ + uint32_t bclk = format->sampleRate_Hz * 32U * 2U; + +/* Compute the mclk */ +#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) + /* Check if master clock divider enabled, then set master clock divider */ + if (base->MCR & I2S_MCR_MOE_MASK) + { + SAI_SetMasterClockDivider(base, format->masterClockHz, mclkSourceClockHz); + } +#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ + + /* Set bclk if needed */ + if (base->TCR2 & I2S_TCR2_BCD_MASK) + { + base->TCR2 &= ~I2S_TCR2_DIV_MASK; + base->TCR2 |= I2S_TCR2_DIV((bclkSourceClockHz / bclk) / 2U - 1U); + } + + /* Set bitWidth */ + if (format->protocol == kSAI_BusRightJustified) + { + base->TCR5 = I2S_TCR5_WNW(31U) | I2S_TCR5_W0W(31U) | I2S_TCR5_FBT(31U); + } + else + { + base->TCR5 = I2S_TCR5_WNW(31U) | I2S_TCR5_W0W(31U) | I2S_TCR5_FBT(format->bitWidth - 1); + } + + /* Set mono or stereo */ + base->TMR = (uint32_t)format->stereo; + + /* Set data channel */ + base->TCR3 &= ~I2S_TCR3_TCE_MASK; + base->TCR3 |= I2S_TCR3_TCE(1U << format->channel); + +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + /* Set watermark */ + base->TCR1 = format->watermark; +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ +} + +void SAI_RxSetFormat(I2S_Type *base, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz) +{ + uint32_t bclk = format->sampleRate_Hz * 32U * 2U; + +/* Compute the mclk */ +#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) + /* Check if master clock divider enabled */ + if (base->MCR & I2S_MCR_MOE_MASK) + { + SAI_SetMasterClockDivider(base, format->masterClockHz, mclkSourceClockHz); + } +#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ + + /* Set bclk if needed */ + if (base->RCR2 & I2S_RCR2_BCD_MASK) + { + base->RCR2 &= ~I2S_RCR2_DIV_MASK; + base->RCR2 |= I2S_RCR2_DIV((bclkSourceClockHz / bclk) / 2U - 1U); + } + + /* Set bitWidth */ + if (format->protocol == kSAI_BusRightJustified) + { + base->RCR5 = I2S_RCR5_WNW(31U) | I2S_RCR5_W0W(31U) | I2S_RCR5_FBT(31U); + } + else + { + base->RCR5 = I2S_RCR5_WNW(31U) | I2S_RCR5_W0W(31U) | I2S_RCR5_FBT(format->bitWidth - 1); + } + + /* Set mono or stereo */ + base->RMR = (uint32_t)format->stereo; + + /* Set data channel */ + base->RCR3 &= ~I2S_RCR3_RCE_MASK; + base->RCR3 |= I2S_RCR3_RCE(1U << format->channel); + +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + /* Set watermark */ + base->RCR1 = format->watermark; +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ +} + +void SAI_WriteBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size) +{ + uint32_t i = 0; + uint8_t bytesPerWord = bitWidth / 8U; + + for (i = 0; i < size; i++) + { + /* Wait until it can write data */ + while (!(base->TCSR & I2S_TCSR_FWF_MASK)) + { + } + + SAI_WriteNonBlocking(base, channel, bitWidth, buffer, bytesPerWord); + buffer += bytesPerWord; + } + + /* Wait until the last data is sent */ + while (!(base->TCSR & I2S_TCSR_FWF_MASK)) + { + } +} + +void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size) +{ + uint32_t i = 0; + uint8_t bytesPerWord = bitWidth / 8U; + + for (i = 0; i < size; i++) + { + /* Wait until data is received */ + while (!(base->RCSR & I2S_RCSR_FWF_MASK)) + { + } + + SAI_ReadNonBlocking(base, channel, bitWidth, buffer, bytesPerWord); + buffer += bytesPerWord; + } +} + +void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData) +{ + assert(handle); + + s_saiHandle[SAI_GetInstance(base)][0] = handle; + + handle->callback = callback; + handle->userData = userData; + + /* Set the isr pointer */ + s_saiTxIsr = SAI_TransferTxHandleIRQ; + + /* Enable Tx irq */ + EnableIRQ(s_saiTxIRQ[SAI_GetInstance(base)]); +} + +void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData) +{ + assert(handle); + + s_saiHandle[SAI_GetInstance(base)][1] = handle; + + handle->callback = callback; + handle->userData = userData; + + /* Set the isr pointer */ + s_saiRxIsr = SAI_TransferRxHandleIRQ; + + /* Enable Rx irq */ + EnableIRQ(s_saiRxIRQ[SAI_GetInstance(base)]); +} + +status_t SAI_TransferTxSetFormat(I2S_Type *base, + sai_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz) +{ + assert(handle); + + if ((mclkSourceClockHz < format->sampleRate_Hz) || (bclkSourceClockHz < format->sampleRate_Hz)) + { + return kStatus_InvalidArgument; + } + + /* Copy format to handle */ + handle->bitWidth = format->bitWidth; +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + handle->watermark = format->watermark; +#endif + handle->channel = format->channel; + + SAI_TxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); + + return kStatus_Success; +} + +status_t SAI_TransferRxSetFormat(I2S_Type *base, + sai_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz) +{ + assert(handle); + + if ((mclkSourceClockHz < format->sampleRate_Hz) || (bclkSourceClockHz < format->sampleRate_Hz)) + { + return kStatus_InvalidArgument; + } + + /* Copy format to handle */ + handle->bitWidth = format->bitWidth; +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + handle->watermark = format->watermark; +#endif + handle->channel = format->channel; + + SAI_RxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); + + return kStatus_Success; +} + +status_t SAI_TransferSendNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer) +{ + assert(handle); + + /* Check if the queue is full */ + if (handle->saiQueue[handle->queueUser].data) + { + return kStatus_SAI_QueueFull; + } + + /* Add into queue */ + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->saiQueue[handle->queueUser].data = xfer->data; + handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE; + + /* Set the state to busy */ + handle->state = kSAI_Busy; + +/* Enable interrupt */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + /* Use FIFO request interrupt and fifo error*/ + SAI_TxEnableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFORequestInterruptEnable); +#else + SAI_TxEnableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFOWarningInterruptEnable); +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + + /* Enable Tx transfer */ + SAI_TxEnable(base, true); + + return kStatus_Success; +} + +status_t SAI_TransferReceiveNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer) +{ + assert(handle); + + /* Check if the queue is full */ + if (handle->saiQueue[handle->queueUser].data) + { + return kStatus_SAI_QueueFull; + } + + /* Add into queue */ + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->saiQueue[handle->queueUser].data = xfer->data; + handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE; + + /* Set state to busy */ + handle->state = kSAI_Busy; + +/* Enable interrupt */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + /* Use FIFO request interrupt and fifo error*/ + SAI_RxEnableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFORequestInterruptEnable); +#else + SAI_RxEnableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFOWarningInterruptEnable); +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + + /* Enable Rx transfer */ + SAI_RxEnable(base, true); + + return kStatus_Success; +} + +status_t SAI_TransferGetSendCount(I2S_Type *base, sai_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kSAI_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = (handle->transferSize[handle->queueDriver] - handle->saiQueue[handle->queueDriver].dataSize); + } + + return status; +} + +status_t SAI_TransferGetReceiveCount(I2S_Type *base, sai_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kSAI_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = (handle->transferSize[handle->queueDriver] - handle->saiQueue[handle->queueDriver].dataSize); + } + + return status; +} + +void SAI_TransferAbortSend(I2S_Type *base, sai_handle_t *handle) +{ + assert(handle); + + /* Stop Tx transfer and disable interrupt */ + SAI_TxEnable(base, false); +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + /* Use FIFO request interrupt and fifo error */ + SAI_TxDisableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFORequestInterruptEnable); +#else + SAI_TxDisableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFOWarningInterruptEnable); +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + + handle->state = kSAI_Idle; + + /* Clear the queue */ + memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * SAI_XFER_QUEUE_SIZE); + handle->queueDriver = 0; + handle->queueUser = 0; +} + +void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle) +{ + assert(handle); + + /* Stop Tx transfer and disable interrupt */ + SAI_RxEnable(base, false); +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + /* Use FIFO request interrupt and fifo error */ + SAI_RxDisableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFORequestInterruptEnable); +#else + SAI_RxDisableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFOWarningInterruptEnable); +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + + handle->state = kSAI_Idle; + + /* Clear the queue */ + memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * SAI_XFER_QUEUE_SIZE); + handle->queueDriver = 0; + handle->queueUser = 0; +} + +void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle) +{ + assert(handle); + + uint8_t *buffer = handle->saiQueue[handle->queueDriver].data; + uint8_t dataSize = handle->bitWidth / 8U; + + /* Handle Error */ + if (base->TCSR & I2S_TCSR_FEF_MASK) + { + /* Clear FIFO error flag to continue transfer */ + SAI_TxClearStatusFlags(base, kSAI_FIFOErrorFlag); + + /* Call the callback */ + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_SAI_TxError, handle->userData); + } + } + +/* Handle transfer */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + if (base->TCSR & I2S_TCSR_FRF_MASK) + { + /* Judge if the data need to transmit is less than space */ + uint8_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), + (size_t)((FSL_FEATURE_SAI_FIFO_COUNT - handle->watermark) * dataSize)); + + /* Copy the data from sai buffer to FIFO */ + SAI_WriteNonBlocking(base, handle->channel, handle->bitWidth, buffer, size); + + /* Update the internal counter */ + handle->saiQueue[handle->queueDriver].dataSize -= size; + handle->saiQueue[handle->queueDriver].data += size; + } +#else + if (base->TCSR & I2S_TCSR_FWF_MASK) + { + uint8_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), dataSize); + + SAI_WriteNonBlocking(base, handle->channel, handle->bitWidth, buffer, size); + + /* Update internal counter */ + handle->saiQueue[handle->queueDriver].dataSize -= size; + handle->saiQueue[handle->queueDriver].data += size; + } +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + + /* If finished a blcok, call the callback function */ + if (handle->saiQueue[handle->queueDriver].dataSize == 0U) + { + memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t)); + handle->queueDriver = (handle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE; + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_SAI_TxIdle, handle->userData); + } + } + + /* If all data finished, just stop the transfer */ + if (handle->saiQueue[handle->queueDriver].data == NULL) + { + SAI_TransferAbortSend(base, handle); + } +} + +void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle) +{ + assert(handle); + + uint8_t *buffer = handle->saiQueue[handle->queueDriver].data; + uint8_t dataSize = handle->bitWidth / 8U; + + /* Handle Error */ + if (base->RCSR & I2S_RCSR_FEF_MASK) + { + /* Clear FIFO error flag to continue transfer */ + SAI_RxClearStatusFlags(base, kSAI_FIFOErrorFlag); + + /* Call the callback */ + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_SAI_RxError, handle->userData); + } + } + +/* Handle transfer */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + if (base->RCSR & I2S_RCSR_FRF_MASK) + { + /* Judge if the data need to transmit is less than space */ + uint8_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), (handle->watermark * dataSize)); + + /* Copy the data from sai buffer to FIFO */ + SAI_ReadNonBlocking(base, handle->channel, handle->bitWidth, buffer, size); + + /* Update the internal counter */ + handle->saiQueue[handle->queueDriver].dataSize -= size; + handle->saiQueue[handle->queueDriver].data += size; + } +#else + if (base->RCSR & I2S_RCSR_FWF_MASK) + { + uint8_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), dataSize); + + SAI_ReadNonBlocking(base, handle->channel, handle->bitWidth, buffer, size); + + /* Update internal state */ + handle->saiQueue[handle->queueDriver].dataSize -= size; + handle->saiQueue[handle->queueDriver].data += size; + } +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + + /* If finished a blcok, call the callback function */ + if (handle->saiQueue[handle->queueDriver].dataSize == 0U) + { + memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t)); + handle->queueDriver = (handle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE; + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_SAI_RxIdle, handle->userData); + } + } + + /* If all data finished, just stop the transfer */ + if (handle->saiQueue[handle->queueDriver].data == NULL) + { + SAI_TransferAbortReceive(base, handle); + } +} + +#if defined(I2S0) +#if defined(FSL_FEATURE_SAI_INT_SOURCE_NUM) && (FSL_FEATURE_SAI_INT_SOURCE_NUM == 1) +void I2S0_DriverIRQHandler(void) +{ + if ((s_saiHandle[0][1]) && ((I2S0->RCSR & kSAI_FIFOWarningFlag) || (I2S0->RCSR & kSAI_FIFOErrorFlag))) + { + s_saiRxIsr(I2S0, s_saiHandle[0][1]); + } + if ((s_saiHandle[0][0]) && ((I2S0->TCSR & kSAI_FIFOWarningFlag) || (I2S0->TCSR & kSAI_FIFOErrorFlag))) + { + s_saiTxIsr(I2S0, s_saiHandle[0][0]); + } +} +#else +void I2S0_Tx_DriverIRQHandler(void) +{ + assert(s_saiHandle[0][0]); + s_saiTxIsr(I2S0, s_saiHandle[0][0]); +} + +void I2S0_Rx_DriverIRQHandler(void) +{ + assert(s_saiHandle[0][1]); + s_saiRxIsr(I2S0, s_saiHandle[0][1]); +} +#endif /* FSL_FEATURE_SAI_INT_SOURCE_NUM */ +#endif /* I2S0*/ + +#if defined(I2S1) +void I2S1_Tx_DriverIRQHandler(void) +{ + assert(s_saiHandle[1][0]); + s_saiTxIsr(I2S1, s_saiHandle[1][0]); +} + +void I2S1_Rx_DriverIRQHandler(void) +{ + assert(s_saiHandle[1][1]); + s_saiRxIsr(I2S1, s_saiHandle[1][1]); +} +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai.h new file mode 100644 index 00000000000..be7563b02e6 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai.h @@ -0,0 +1,849 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_SAI_H_ +#define _FSL_SAI_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup sai + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_SAI_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1 */ +/*@}*/ + +/*! @brief SAI return status*/ +enum _sai_status_t +{ + kStatus_SAI_TxBusy = MAKE_STATUS(kStatusGroup_SAI, 0), /*!< SAI Tx is busy. */ + kStatus_SAI_RxBusy = MAKE_STATUS(kStatusGroup_SAI, 1), /*!< SAI Rx is busy. */ + kStatus_SAI_TxError = MAKE_STATUS(kStatusGroup_SAI, 2), /*!< SAI Tx FIFO error. */ + kStatus_SAI_RxError = MAKE_STATUS(kStatusGroup_SAI, 3), /*!< SAI Rx FIFO error. */ + kStatus_SAI_QueueFull = MAKE_STATUS(kStatusGroup_SAI, 4), /*!< SAI transfer queue is full. */ + kStatus_SAI_TxIdle = MAKE_STATUS(kStatusGroup_SAI, 5), /*!< SAI Tx is idle */ + kStatus_SAI_RxIdle = MAKE_STATUS(kStatusGroup_SAI, 6) /*!< SAI Rx is idle */ +}; + +/*! @brief Define the SAI bus type */ +typedef enum _sai_protocol +{ + kSAI_BusLeftJustified = 0x0U, /*!< Uses left justified format.*/ + kSAI_BusRightJustified, /*!< Uses right justified format. */ + kSAI_BusI2S, /*!< Uses I2S format. */ + kSAI_BusPCMA, /*!< Uses I2S PCM A format.*/ + kSAI_BusPCMB /*!< Uses I2S PCM B format. */ +} sai_protocol_t; + +/*! @brief Master or slave mode */ +typedef enum _sai_master_slave +{ + kSAI_Master = 0x0U, /*!< Master mode */ + kSAI_Slave = 0x1U /*!< Slave mode */ +} sai_master_slave_t; + +/*! @brief Mono or stereo audio format */ +typedef enum _sai_mono_stereo +{ + kSAI_Stereo = 0x0U, /*!< Stereo sound. */ + kSAI_MonoLeft, /*!< Only left channel have sound. */ + kSAI_MonoRight /*!< Only Right channel have sound. */ +} sai_mono_stereo_t; + +/*! @brief Synchronous or asynchronous mode */ +typedef enum _sai_sync_mode +{ + kSAI_ModeAsync = 0x0U, /*!< Asynchronous mode */ + kSAI_ModeSync, /*!< Synchronous mode (with receiver or transmit) */ + kSAI_ModeSyncWithOtherTx, /*!< Synchronous with another SAI transmit */ + kSAI_ModeSyncWithOtherRx /*!< Synchronous with another SAI receiver */ +} sai_sync_mode_t; + +/*! @brief Mater clock source */ +typedef enum _sai_mclk_source +{ + kSAI_MclkSourceSysclk = 0x0U, /*!< Master clock from the system clock */ + kSAI_MclkSourceSelect1, /*!< Master clock from source 1 */ + kSAI_MclkSourceSelect2, /*!< Master clock from source 2 */ + kSAI_MclkSourceSelect3 /*!< Master clock from source 3 */ +} sai_mclk_source_t; + +/*! @brief Bit clock source */ +typedef enum _sai_bclk_source +{ + kSAI_BclkSourceBusclk = 0x0U, /*!< Bit clock using bus clock */ + kSAI_BclkSourceMclkDiv, /*!< Bit clock using master clock divider */ + kSAI_BclkSourceOtherSai0, /*!< Bit clock from other SAI device */ + kSAI_BclkSourceOtherSai1 /*!< Bit clock from other SAI device */ +} sai_bclk_source_t; + +/*! @brief The SAI interrupt enable flag */ +enum _sai_interrupt_enable_t +{ + kSAI_WordStartInterruptEnable = + I2S_TCSR_WSIE_MASK, /*!< Word start flag, means the first word in a frame detected */ + kSAI_SyncErrorInterruptEnable = I2S_TCSR_SEIE_MASK, /*!< Sync error flag, means the sync error is detected */ + kSAI_FIFOWarningInterruptEnable = I2S_TCSR_FWIE_MASK, /*!< FIFO warning flag, means the FIFO is empty */ + kSAI_FIFOErrorInterruptEnable = I2S_TCSR_FEIE_MASK, /*!< FIFO error flag */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + kSAI_FIFORequestInterruptEnable = I2S_TCSR_FRIE_MASK, /*!< FIFO request, means reached watermark */ +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ +}; + +/*! @brief The DMA request sources */ +enum _sai_dma_enable_t +{ + kSAI_FIFOWarningDMAEnable = I2S_TCSR_FWDE_MASK, /*!< FIFO warning caused by the DMA request */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + kSAI_FIFORequestDMAEnable = I2S_TCSR_FRDE_MASK, /*!< FIFO request caused by the DMA request */ +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ +}; + +/*! @brief The SAI status flag */ +enum _sai_flags +{ + kSAI_WordStartFlag = I2S_TCSR_WSF_MASK, /*!< Word start flag, means the first word in a frame detected */ + kSAI_SyncErrorFlag = I2S_TCSR_SEF_MASK, /*!< Sync error flag, means the sync error is detected */ + kSAI_FIFOErrorFlag = I2S_TCSR_FEF_MASK, /*!< FIFO error flag */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + kSAI_FIFORequestFlag = I2S_TCSR_FRF_MASK, /*!< FIFO request flag. */ +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + kSAI_FIFOWarningFlag = I2S_TCSR_FWF_MASK, /*!< FIFO warning flag */ +}; + +/*! @brief The reset type */ +typedef enum _sai_reset_type +{ + kSAI_ResetTypeSoftware = I2S_TCSR_SR_MASK, /*!< Software reset, reset the logic state */ + kSAI_ResetTypeFIFO = I2S_TCSR_FR_MASK, /*!< FIFO reset, reset the FIFO read and write pointer */ + kSAI_ResetAll = I2S_TCSR_SR_MASK | I2S_TCSR_FR_MASK /*!< All reset. */ +} sai_reset_type_t; + +#if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING +/*! + * @brief The SAI packing mode + * The mode includes 8 bit and 16 bit packing. + */ +typedef enum _sai_fifo_packing +{ + kSAI_FifoPackingDisabled = 0x0U, /*!< Packing disabled */ + kSAI_FifoPacking8bit = 0x2U, /*!< 8 bit packing enabled */ + kSAI_FifoPacking16bit = 0x3U /*!< 16bit packing enabled */ +} sai_fifo_packing_t; +#endif /* FSL_FEATURE_SAI_HAS_FIFO_PACKING */ + +/*! @brief SAI user configuration structure */ +typedef struct _sai_config +{ + sai_protocol_t protocol; /*!< Audio bus protocol in SAI */ + sai_sync_mode_t syncMode; /*!< SAI sync mode, control Tx/Rx clock sync */ +#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) + bool mclkOutputEnable; /*!< Master clock output enable, true means master clock divider enabled */ +#endif /* FSL_FEATURE_SAI_HAS_MCR */ + sai_mclk_source_t mclkSource; /*!< Master Clock source */ + sai_bclk_source_t bclkSource; /*!< Bit Clock source */ + sai_master_slave_t masterSlave; /*!< Master or slave */ +} sai_config_t; + +/*!@brief SAI transfer queue size, user can refine it according to use case. */ +#define SAI_XFER_QUEUE_SIZE (4) + +/*! @brief Audio sample rate */ +typedef enum _sai_sample_rate +{ + kSAI_SampleRate8KHz = 8000U, /*!< Sample rate 8000 Hz */ + kSAI_SampleRate11025Hz = 11025U, /*!< Sample rate 11025 Hz */ + kSAI_SampleRate12KHz = 12000U, /*!< Sample rate 12000 Hz */ + kSAI_SampleRate16KHz = 16000U, /*!< Sample rate 16000 Hz */ + kSAI_SampleRate22050Hz = 22050U, /*!< Sample rate 22050 Hz */ + kSAI_SampleRate24KHz = 24000U, /*!< Sample rate 24000 Hz */ + kSAI_SampleRate32KHz = 32000U, /*!< Sample rate 32000 Hz */ + kSAI_SampleRate44100Hz = 44100U, /*!< Sample rate 44100 Hz */ + kSAI_SampleRate48KHz = 48000U, /*!< Sample rate 48000 Hz */ + kSAI_SampleRate96KHz = 96000U /*!< Sample rate 96000 Hz */ +} sai_sample_rate_t; + +/*! @brief Audio word width */ +typedef enum _sai_word_width +{ + kSAI_WordWidth8bits = 8U, /*!< Audio data width 8 bits */ + kSAI_WordWidth16bits = 16U, /*!< Audio data width 16 bits */ + kSAI_WordWidth24bits = 24U, /*!< Audio data width 24 bits */ + kSAI_WordWidth32bits = 32U /*!< Audio data width 32 bits */ +} sai_word_width_t; + +/*! @brief sai transfer format */ +typedef struct _sai_transfer_format +{ + uint32_t sampleRate_Hz; /*!< Sample rate of audio data */ + uint32_t bitWidth; /*!< Data length of audio data, usually 8/16/24/32 bits */ + sai_mono_stereo_t stereo; /*!< Mono or stereo */ + uint32_t masterClockHz; /*!< Master clock frequency in Hz */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + uint8_t watermark; /*!< Watermark value */ +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + uint8_t channel; /*!< Data channel used in transfer.*/ + sai_protocol_t protocol; /*!< Which audio protocol used */ +} sai_transfer_format_t; + +/*! @brief SAI transfer structure */ +typedef struct _sai_transfer +{ + uint8_t *data; /*!< Data start address to transfer. */ + size_t dataSize; /*!< Transfer size. */ +} sai_transfer_t; + +typedef struct _sai_handle sai_handle_t; + +/*! @brief SAI transfer callback prototype */ +typedef void (*sai_transfer_callback_t)(I2S_Type *base, sai_handle_t *handle, status_t status, void *userData); + +/*! @brief SAI handle structure */ +struct _sai_handle +{ + uint32_t state; /*!< Transfer status */ + sai_transfer_callback_t callback; /*!< Callback function called at transfer event*/ + void *userData; /*!< Callback parameter passed to callback function*/ + uint8_t bitWidth; /*!< Bit width for transfer, 8/16/24/32 bits */ + uint8_t channel; /*!< Transfer channel */ + sai_transfer_t saiQueue[SAI_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer */ + size_t transferSize[SAI_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */ + volatile uint8_t queueUser; /*!< Index for user to queue transfer */ + volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + uint8_t watermark; /*!< Watermark value */ +#endif +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes the SAI Tx peripheral. + * + * Ungates the SAI clock, resets the module, and configures SAI Tx with a configuration structure. + * The configuration structure can be custom filled or set with default values by + * SAI_TxGetDefaultConfig(). + * + * @note This API should be called at the beginning of the application to use + * the SAI driver. Otherwise, accessing the SAIM module can cause a hard fault + * because the clock is not enabled. + * + * @param base SAI base pointer + * @param config SAI configuration structure. +*/ +void SAI_TxInit(I2S_Type *base, const sai_config_t *config); + +/*! + * @brief Initializes the the SAI Rx peripheral. + * + * Ungates the SAI clock, resets the module, and configures the SAI Rx with a configuration structure. + * The configuration structure can be custom filled or set with default values by + * SAI_RxGetDefaultConfig(). + * + * @note This API should be called at the beginning of the application to use + * the SAI driver. Otherwise, accessing the SAI module can cause a hard fault + * because the clock is not enabled. + * + * @param base SAI base pointer + * @param config SAI configuration structure. + */ +void SAI_RxInit(I2S_Type *base, const sai_config_t *config); + +/*! + * @brief Sets the SAI Tx configuration structure to default values. + * + * This API initializes the configuration structure for use in SAI_TxConfig(). + * The initialized structure can remain unchanged in SAI_TxConfig(), or it can be modified + * before calling SAI_TxConfig(). + * This is an example. + @code + sai_config_t config; + SAI_TxGetDefaultConfig(&config); + @endcode + * + * @param config pointer to master configuration structure + */ +void SAI_TxGetDefaultConfig(sai_config_t *config); + +/*! + * @brief Sets the SAI Rx configuration structure to default values. + * + * This API initializes the configuration structure for use in SAI_RxConfig(). + * The initialized structure can remain unchanged in SAI_RxConfig() or it can be modified + * before calling SAI_RxConfig(). + * This is an example. + @code + sai_config_t config; + SAI_RxGetDefaultConfig(&config); + @endcode + * + * @param config pointer to master configuration structure + */ +void SAI_RxGetDefaultConfig(sai_config_t *config); + +/*! + * @brief De-initializes the SAI peripheral. + * + * This API gates the SAI clock. The SAI module can't operate unless SAI_TxInit + * or SAI_RxInit is called to enable the clock. + * + * @param base SAI base pointer +*/ +void SAI_Deinit(I2S_Type *base); + +/*! + * @brief Resets the SAI Tx. + * + * This function enables the software reset and FIFO reset of SAI Tx. After reset, clear the reset bit. + * + * @param base SAI base pointer + */ +void SAI_TxReset(I2S_Type *base); + +/*! + * @brief Resets the SAI Rx. + * + * This function enables the software reset and FIFO reset of SAI Rx. After reset, clear the reset bit. + * + * @param base SAI base pointer + */ +void SAI_RxReset(I2S_Type *base); + +/*! + * @brief Enables/disables the SAI Tx. + * + * @param base SAI base pointer + * @param enable True means enable SAI Tx, false means disable. + */ +void SAI_TxEnable(I2S_Type *base, bool enable); + +/*! + * @brief Enables/disables the SAI Rx. + * + * @param base SAI base pointer + * @param enable True means enable SAI Rx, false means disable. + */ +void SAI_RxEnable(I2S_Type *base, bool enable); + +/*! @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the SAI Tx status flag state. + * + * @param base SAI base pointer + * @return SAI Tx status flag value. Use the Status Mask to get the status value needed. + */ +static inline uint32_t SAI_TxGetStatusFlag(I2S_Type *base) +{ + return base->TCSR; +} + +/*! + * @brief Clears the SAI Tx status flag state. + * + * @param base SAI base pointer + * @param mask State mask. It can be a combination of the following source if defined: + * @arg kSAI_WordStartFlag + * @arg kSAI_SyncErrorFlag + * @arg kSAI_FIFOErrorFlag + */ +static inline void SAI_TxClearStatusFlags(I2S_Type *base, uint32_t mask) +{ + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | mask); +} + +/*! + * @brief Gets the SAI Tx status flag state. + * + * @param base SAI base pointer + * @return SAI Rx status flag value. Use the Status Mask to get the status value needed. + */ +static inline uint32_t SAI_RxGetStatusFlag(I2S_Type *base) +{ + return base->RCSR; +} + +/*! + * @brief Clears the SAI Rx status flag state. + * + * @param base SAI base pointer + * @param mask State mask. It can be a combination of the following sources if defined. + * @arg kSAI_WordStartFlag + * @arg kSAI_SyncErrorFlag + * @arg kSAI_FIFOErrorFlag + */ +static inline void SAI_RxClearStatusFlags(I2S_Type *base, uint32_t mask) +{ + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | mask); +} + +/*! @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the SAI Tx interrupt requests. + * + * @param base SAI base pointer + * @param mask interrupt source + * The parameter can be a combination of the following sources if defined. + * @arg kSAI_WordStartInterruptEnable + * @arg kSAI_SyncErrorInterruptEnable + * @arg kSAI_FIFOWarningInterruptEnable + * @arg kSAI_FIFORequestInterruptEnable + * @arg kSAI_FIFOErrorInterruptEnable + */ +static inline void SAI_TxEnableInterrupts(I2S_Type *base, uint32_t mask) +{ + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | mask); +} + +/*! + * @brief Enables the SAI Rx interrupt requests. + * + * @param base SAI base pointer + * @param mask interrupt source + * The parameter can be a combination of the following sources if defined. + * @arg kSAI_WordStartInterruptEnable + * @arg kSAI_SyncErrorInterruptEnable + * @arg kSAI_FIFOWarningInterruptEnable + * @arg kSAI_FIFORequestInterruptEnable + * @arg kSAI_FIFOErrorInterruptEnable + */ +static inline void SAI_RxEnableInterrupts(I2S_Type *base, uint32_t mask) +{ + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | mask); +} + +/*! + * @brief Disables the SAI Tx interrupt requests. + * + * @param base SAI base pointer + * @param mask interrupt source + * The parameter can be a combination of the following sources if defined. + * @arg kSAI_WordStartInterruptEnable + * @arg kSAI_SyncErrorInterruptEnable + * @arg kSAI_FIFOWarningInterruptEnable + * @arg kSAI_FIFORequestInterruptEnable + * @arg kSAI_FIFOErrorInterruptEnable + */ +static inline void SAI_TxDisableInterrupts(I2S_Type *base, uint32_t mask) +{ + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~mask)); +} + +/*! + * @brief Disables the SAI Rx interrupt requests. + * + * @param base SAI base pointer + * @param mask interrupt source + * The parameter can be a combination of the following sources if defined. + * @arg kSAI_WordStartInterruptEnable + * @arg kSAI_SyncErrorInterruptEnable + * @arg kSAI_FIFOWarningInterruptEnable + * @arg kSAI_FIFORequestInterruptEnable + * @arg kSAI_FIFOErrorInterruptEnable + */ +static inline void SAI_RxDisableInterrupts(I2S_Type *base, uint32_t mask) +{ + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~mask)); +} + +/*! @} */ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Enables/disables the SAI Tx DMA requests. + * @param base SAI base pointer + * @param mask DMA source + * The parameter can be combination of the following sources if defined. + * @arg kSAI_FIFOWarningDMAEnable + * @arg kSAI_FIFORequestDMAEnable + * @param enable True means enable DMA, false means disable DMA. + */ +static inline void SAI_TxEnableDMA(I2S_Type *base, uint32_t mask, bool enable) +{ + if (enable) + { + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | mask); + } + else + { + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~mask)); + } +} + +/*! + * @brief Enables/disables the SAI Rx DMA requests. + * @param base SAI base pointer + * @param mask DMA source + * The parameter can be a combination of the following sources if defined. + * @arg kSAI_FIFOWarningDMAEnable + * @arg kSAI_FIFORequestDMAEnable + * @param enable True means enable DMA, false means disable DMA. + */ +static inline void SAI_RxEnableDMA(I2S_Type *base, uint32_t mask, bool enable) +{ + if (enable) + { + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | mask); + } + else + { + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~mask)); + } +} + +/*! + * @brief Gets the SAI Tx data register address. + * + * This API is used to provide a transfer address for the SAI DMA transfer configuration. + * + * @param base SAI base pointer. + * @param channel Which data channel used. + * @return data register address. + */ +static inline uint32_t SAI_TxGetDataRegisterAddress(I2S_Type *base, uint32_t channel) +{ + return (uint32_t)(&(base->TDR)[channel]); +} + +/*! + * @brief Gets the SAI Rx data register address. + * + * This API is used to provide a transfer address for the SAI DMA transfer configuration. + * + * @param base SAI base pointer. + * @param channel Which data channel used. + * @return data register address. + */ +static inline uint32_t SAI_RxGetDataRegisterAddress(I2S_Type *base, uint32_t channel) +{ + return (uint32_t)(&(base->RDR)[channel]); +} + +/*! @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Configures the SAI Tx audio format. + * + * The audio format can be changed at run-time. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base SAI base pointer. + * @param format Pointer to the SAI audio data format structure. + * @param mclkSourceClockHz SAI master clock source frequency in Hz. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If the bit clock source is a master + * clock, this value should equal the masterClockHz. +*/ +void SAI_TxSetFormat(I2S_Type *base, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz); + +/*! + * @brief Configures the SAI Rx audio format. + * + * The audio format can be changed at run-time. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base SAI base pointer. + * @param format Pointer to the SAI audio data format structure. + * @param mclkSourceClockHz SAI master clock source frequency in Hz. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If the bit clock source is a master + * clock, this value should equal the masterClockHz. +*/ +void SAI_RxSetFormat(I2S_Type *base, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz); + +/*! + * @brief Sends data using a blocking method. + * + * @note This function blocks by polling until data is ready to be sent. + * + * @param base SAI base pointer. + * @param channel Data channel used. + * @param bitWidth How many bits in an audio word; usually 8/16/24/32 bits. + * @param buffer Pointer to the data to be written. + * @param size Bytes to be written. + */ +void SAI_WriteBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size); + +/*! + * @brief Writes data into SAI FIFO. + * + * @param base SAI base pointer. + * @param channel Data channel used. + * @param data Data needs to be written. + */ +static inline void SAI_WriteData(I2S_Type *base, uint32_t channel, uint32_t data) +{ + base->TDR[channel] = data; +} + +/*! + * @brief Receives data using a blocking method. + * + * @note This function blocks by polling until data is ready to be sent. + * + * @param base SAI base pointer. + * @param channel Data channel used. + * @param bitWidth How many bits in an audio word; usually 8/16/24/32 bits. + * @param buffer Pointer to the data to be read. + * @param size Bytes to be read. + */ +void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size); + +/*! + * @brief Reads data from the SAI FIFO. + * + * @param base SAI base pointer. + * @param channel Data channel used. + * @return Data in SAI FIFO. + */ +static inline uint32_t SAI_ReadData(I2S_Type *base, uint32_t channel) +{ + return base->RDR[channel]; +} + +/*! @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the SAI Tx handle. + * + * This function initializes the Tx handle for the SAI Tx transactional APIs. Call + * this function once to get the handle initialized. + * + * @param base SAI base pointer + * @param handle SAI handle pointer. + * @param callback Pointer to the user callback function. + * @param userData User parameter passed to the callback function + */ +void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData); + +/*! + * @brief Initializes the SAI Rx handle. + * + * This function initializes the Rx handle for the SAI Rx transactional APIs. Call + * this function once to get the handle initialized. + * + * @param base SAI base pointer. + * @param handle SAI handle pointer. + * @param callback Pointer to the user callback function. + * @param userData User parameter passed to the callback function. + */ +void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData); + +/*! + * @brief Configures the SAI Tx audio format. + * + * The audio format can be changed at run-time. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base SAI base pointer. + * @param handle SAI handle pointer. + * @param format Pointer to the SAI audio data format structure. + * @param mclkSourceClockHz SAI master clock source frequency in Hz. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is a master + * clock, this value should equal the masterClockHz in format. + * @return Status of this function. Return value is the status_t. +*/ +status_t SAI_TransferTxSetFormat(I2S_Type *base, + sai_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz); + +/*! + * @brief Configures the SAI Rx audio format. + * + * The audio format can be changed at run-time. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base SAI base pointer. + * @param handle SAI handle pointer. + * @param format Pointer to the SAI audio data format structure. + * @param mclkSourceClockHz SAI master clock source frequency in Hz. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is a master + * clock, this value should equal the masterClockHz in format. + * @return Status of this function. Return value is one of status_t. +*/ +status_t SAI_TransferRxSetFormat(I2S_Type *base, + sai_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz); + +/*! + * @brief Performs an interrupt non-blocking send transfer on SAI. + * + * @note This API returns immediately after the transfer initiates. + * Call the SAI_TxGetTransferStatusIRQ to poll the transfer status and check whether + * the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer + * is finished. + * + * @param base SAI base pointer. + * @param handle Pointer to the sai_handle_t structure which stores the transfer state. + * @param xfer Pointer to the sai_transfer_t structure. + * @retval kStatus_Success Successfully started the data receive. + * @retval kStatus_SAI_TxBusy Previous receive still not finished. + * @retval kStatus_InvalidArgument The input parameter is invalid. + */ +status_t SAI_TransferSendNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer); + +/*! + * @brief Performs an interrupt non-blocking receive transfer on SAI. + * + * @note This API returns immediately after the transfer initiates. + * Call the SAI_RxGetTransferStatusIRQ to poll the transfer status and check whether + * the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer + * is finished. + * + * @param base SAI base pointer + * @param handle Pointer to the sai_handle_t structure which stores the transfer state. + * @param xfer Pointer to the sai_transfer_t structure. + * @retval kStatus_Success Successfully started the data receive. + * @retval kStatus_SAI_RxBusy Previous receive still not finished. + * @retval kStatus_InvalidArgument The input parameter is invalid. + */ +status_t SAI_TransferReceiveNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer); + +/*! + * @brief Gets a set byte count. + * + * @param base SAI base pointer. + * @param handle Pointer to the sai_handle_t structure which stores the transfer state. + * @param count Bytes count sent. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t SAI_TransferGetSendCount(I2S_Type *base, sai_handle_t *handle, size_t *count); + +/*! + * @brief Gets a received byte count. + * + * @param base SAI base pointer. + * @param handle Pointer to the sai_handle_t structure which stores the transfer state. + * @param count Bytes count received. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t SAI_TransferGetReceiveCount(I2S_Type *base, sai_handle_t *handle, size_t *count); + +/*! + * @brief Aborts the current send. + * + * @note This API can be called any time when an interrupt non-blocking transfer initiates + * to abort the transfer early. + * + * @param base SAI base pointer. + * @param handle Pointer to the sai_handle_t structure which stores the transfer state. + */ +void SAI_TransferAbortSend(I2S_Type *base, sai_handle_t *handle); + +/*! + * @brief Aborts the the current IRQ receive. + * + * @note This API can be called when an interrupt non-blocking transfer initiates + * to abort the transfer early. + * + * @param base SAI base pointer + * @param handle Pointer to the sai_handle_t structure which stores the transfer state. + */ +void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle); + +/*! + * @brief Tx interrupt handler. + * + * @param base SAI base pointer. + * @param handle Pointer to the sai_handle_t structure. + */ +void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle); + +/*! + * @brief Tx interrupt handler. + * + * @param base SAI base pointer. + * @param handle Pointer to the sai_handle_t structure. + */ +void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ + +/*! @} */ + +#endif /* _FSL_SAI_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai_edma.c new file mode 100644 index 00000000000..e3d0705b97e --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai_edma.c @@ -0,0 +1,393 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_sai_edma.h" + +/******************************************************************************* + * Definitations + ******************************************************************************/ +/* Used for 32byte aligned */ +#define STCD_ADDR(address) (edma_tcd_t *)(((uint32_t)address + 32) & ~0x1FU) + +/*handle; + + /* If finished a blcok, call the callback function */ + memset(&saiHandle->saiQueue[saiHandle->queueDriver], 0, sizeof(sai_transfer_t)); + saiHandle->queueDriver = (saiHandle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE; + if (saiHandle->callback) + { + (saiHandle->callback)(privHandle->base, saiHandle, kStatus_SAI_TxIdle, saiHandle->userData); + } + + /* If all data finished, just stop the transfer */ + if (saiHandle->saiQueue[saiHandle->queueDriver].data == NULL) + { + SAI_TransferAbortSendEDMA(privHandle->base, saiHandle); + } +} + +static void SAI_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds) +{ + sai_edma_private_handle_t *privHandle = (sai_edma_private_handle_t *)userData; + sai_edma_handle_t *saiHandle = privHandle->handle; + + /* If finished a blcok, call the callback function */ + memset(&saiHandle->saiQueue[saiHandle->queueDriver], 0, sizeof(sai_transfer_t)); + saiHandle->queueDriver = (saiHandle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE; + if (saiHandle->callback) + { + (saiHandle->callback)(privHandle->base, saiHandle, kStatus_SAI_RxIdle, saiHandle->userData); + } + + /* If all data finished, just stop the transfer */ + if (saiHandle->saiQueue[saiHandle->queueDriver].data == NULL) + { + SAI_TransferAbortReceiveEDMA(privHandle->base, saiHandle); + } +} + +void SAI_TransferTxCreateHandleEDMA( + I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle) +{ + assert(handle && dmaHandle); + + uint32_t instance = SAI_GetInstance(base); + + /* Set sai base to handle */ + handle->dmaHandle = dmaHandle; + handle->callback = callback; + handle->userData = userData; + + /* Set SAI state to idle */ + handle->state = kSAI_Idle; + + s_edmaPrivateHandle[instance][0].base = base; + s_edmaPrivateHandle[instance][0].handle = handle; + + /* Need to use scatter gather */ + EDMA_InstallTCDMemory(dmaHandle, STCD_ADDR(handle->tcd), SAI_XFER_QUEUE_SIZE); + + /* Install callback for Tx dma channel */ + EDMA_SetCallback(dmaHandle, SAI_TxEDMACallback, &s_edmaPrivateHandle[instance][0]); +} + +void SAI_TransferRxCreateHandleEDMA( + I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle) +{ + assert(handle && dmaHandle); + + uint32_t instance = SAI_GetInstance(base); + + /* Set sai base to handle */ + handle->dmaHandle = dmaHandle; + handle->callback = callback; + handle->userData = userData; + + /* Set SAI state to idle */ + handle->state = kSAI_Idle; + + s_edmaPrivateHandle[instance][1].base = base; + s_edmaPrivateHandle[instance][1].handle = handle; + + /* Need to use scatter gather */ + EDMA_InstallTCDMemory(dmaHandle, STCD_ADDR(handle->tcd), SAI_XFER_QUEUE_SIZE); + + /* Install callback for Tx dma channel */ + EDMA_SetCallback(dmaHandle, SAI_RxEDMACallback, &s_edmaPrivateHandle[instance][1]); +} + +void SAI_TransferTxSetFormatEDMA(I2S_Type *base, + sai_edma_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz) +{ + assert(handle && format); + + /* Configure the audio format to SAI registers */ + SAI_TxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); + + /* Get the tranfer size from format, this should be used in EDMA configuration */ + handle->bytesPerFrame = format->bitWidth / 8U; + + /* Update the data channel SAI used */ + handle->channel = format->channel; +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + handle->count = FSL_FEATURE_SAI_FIFO_COUNT - format->watermark; +#else + handle->count = 1U; +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ +} + +void SAI_TransferRxSetFormatEDMA(I2S_Type *base, + sai_edma_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz) +{ + assert(handle && format); + + /* Configure the audio format to SAI registers */ + SAI_RxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); + + /* Get the tranfer size from format, this should be used in EDMA configuration */ + handle->bytesPerFrame = format->bitWidth / 8U; + + /* Update the data channel SAI used */ + handle->channel = format->channel; + +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + handle->count = format->watermark; +#else + handle->count = 1U; +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ +} + +status_t SAI_TransferSendEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer) +{ + assert(handle && xfer); + + edma_transfer_config_t config = {0}; + uint32_t destAddr = SAI_TxGetDataRegisterAddress(base, handle->channel); + + /* Check if input parameter invalid */ + if ((xfer->data == NULL) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + if (handle->saiQueue[handle->queueUser].data) + { + return kStatus_SAI_QueueFull; + } + + /* Change the state of handle */ + handle->state = kSAI_Busy; + + /* Update the queue state */ + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->saiQueue[handle->queueUser].data = xfer->data; + handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE; + + /* Prepare edma configure */ + EDMA_PrepareTransfer(&config, xfer->data, handle->bytesPerFrame, (void *)destAddr, handle->bytesPerFrame, + handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_MemoryToPeripheral); + + /* Store the initially configured eDMA minor byte transfer count into the SAI handle */ + handle->nbytes = handle->count * handle->bytesPerFrame; + + EDMA_SubmitTransfer(handle->dmaHandle, &config); + + /* Start DMA transfer */ + EDMA_StartTransfer(handle->dmaHandle); + + /* Enable DMA enable bit */ + SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, true); + + /* Enable SAI Tx clock */ + SAI_TxEnable(base, true); + + return kStatus_Success; +} + +status_t SAI_TransferReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer) +{ + assert(handle && xfer); + + edma_transfer_config_t config = {0}; + uint32_t srcAddr = SAI_RxGetDataRegisterAddress(base, handle->channel); + + /* Check if input parameter invalid */ + if ((xfer->data == NULL) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + if (handle->saiQueue[handle->queueUser].data) + { + return kStatus_SAI_QueueFull; + } + + /* Change the state of handle */ + handle->state = kSAI_Busy; + + /* Update queue state */ + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->saiQueue[handle->queueUser].data = xfer->data; + handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE; + + /* Prepare edma configure */ + EDMA_PrepareTransfer(&config, (void *)srcAddr, handle->bytesPerFrame, xfer->data, handle->bytesPerFrame, + handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_PeripheralToMemory); + + /* Store the initially configured eDMA minor byte transfer count into the SAI handle */ + handle->nbytes = handle->count * handle->bytesPerFrame; + + EDMA_SubmitTransfer(handle->dmaHandle, &config); + + /* Start DMA transfer */ + EDMA_StartTransfer(handle->dmaHandle); + + /* Enable DMA enable bit */ + SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, true); + + /* Enable SAI Rx clock */ + SAI_RxEnable(base, true); + + return kStatus_Success; +} + +void SAI_TransferAbortSendEDMA(I2S_Type *base, sai_edma_handle_t *handle) +{ + assert(handle); + + /* Disable dma */ + EDMA_AbortTransfer(handle->dmaHandle); + + /* Disable DMA enable bit */ + SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, false); + + /* Disable Tx */ + SAI_TxEnable(base, false); + + /* Set the handle state */ + handle->state = kSAI_Idle; +} + +void SAI_TransferAbortReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle) +{ + assert(handle); + + /* Disable dma */ + EDMA_AbortTransfer(handle->dmaHandle); + + /* Disable DMA enable bit */ + SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, false); + + /* Disable Rx */ + SAI_RxEnable(base, false); + + /* Set the handle state */ + handle->state = kSAI_Idle; +} + +status_t SAI_TransferGetSendCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kSAI_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = (handle->transferSize[handle->queueDriver] - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel)); + } + + return status; +} + +status_t SAI_TransferGetReceiveCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kSAI_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = (handle->transferSize[handle->queueDriver] - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel)); + } + + return status; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai_edma.h new file mode 100644 index 00000000000..1b2057f993b --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sai_edma.h @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_SAI_EDMA_H_ +#define _FSL_SAI_EDMA_H_ + +#include "fsl_sai.h" +#include "fsl_edma.h" + +/*! + * @addtogroup sai_edma + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +typedef struct _sai_edma_handle sai_edma_handle_t; + +/*! @brief SAI eDMA transfer callback function for finish and error */ +typedef void (*sai_edma_callback_t)(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData); + +/*! @brief SAI DMA transfer handle, users should not touch the content of the handle.*/ +struct _sai_edma_handle +{ + edma_handle_t *dmaHandle; /*!< DMA handler for SAI send */ + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + uint8_t bytesPerFrame; /*!< Bytes in a frame */ + uint8_t channel; /*!< Which data channel */ + uint8_t count; /*!< The transfer data count in a DMA request */ + uint32_t state; /*!< Internal state for SAI eDMA transfer */ + sai_edma_callback_t callback; /*!< Callback for users while transfer finish or error occurs */ + void *userData; /*!< User callback parameter */ + edma_tcd_t tcd[SAI_XFER_QUEUE_SIZE + 1U]; /*!< TCD pool for eDMA transfer. */ + sai_transfer_t saiQueue[SAI_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer. */ + size_t transferSize[SAI_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */ + volatile uint8_t queueUser; /*!< Index for user to queue transfer. */ + volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */ +}; + +/******************************************************************************* + * APIs + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name eDMA Transactional + * @{ + */ + +/*! + * @brief Initializes the SAI eDMA handle. + * + * This function initializes the SAI master DMA handle, which can be used for other SAI master transactional APIs. + * Usually, for a specified SAI instance, call this API once to get the initialized handle. + * + * @param base SAI base pointer. + * @param handle SAI eDMA handle pointer. + * @param base SAI peripheral base address. + * @param callback Pointer to user callback function. + * @param userData User parameter passed to the callback function. + * @param dmaHandle eDMA handle pointer, this handle shall be static allocated by users. + */ +void SAI_TransferTxCreateHandleEDMA( + I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle); + +/*! + * @brief Initializes the SAI Rx eDMA handle. + * + * This function initializes the SAI slave DMA handle, which can be used for other SAI master transactional APIs. + * Usually, for a specified SAI instance, call this API once to get the initialized handle. + * + * @param base SAI base pointer. + * @param handle SAI eDMA handle pointer. + * @param base SAI peripheral base address. + * @param callback Pointer to user callback function. + * @param userData User parameter passed to the callback function. + * @param dmaHandle eDMA handle pointer, this handle shall be static allocated by users. + */ +void SAI_TransferRxCreateHandleEDMA( + I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle); + +/*! + * @brief Configures the SAI Tx audio format. + * + * The audio format can be changed at run-time. This function configures the sample rate and audio data + * format to be transferred. This function also sets the eDMA parameter according to formatting requirements. + * + * @param base SAI base pointer. + * @param handle SAI eDMA handle pointer. + * @param format Pointer to SAI audio data format structure. + * @param mclkSourceClockHz SAI master clock source frequency in Hz. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master + * clock, this value should equals to masterClockHz in format. + * @retval kStatus_Success Audio format set successfully. + * @retval kStatus_InvalidArgument The input argument is invalid. +*/ +void SAI_TransferTxSetFormatEDMA(I2S_Type *base, + sai_edma_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz); + +/*! + * @brief Configures the SAI Rx audio format. + * + * The audio format can be changed at run-time. This function configures the sample rate and audio data + * format to be transferred. This function also sets the eDMA parameter according to formatting requirements. + * + * @param base SAI base pointer. + * @param handle SAI eDMA handle pointer. + * @param format Pointer to SAI audio data format structure. + * @param mclkSourceClockHz SAI master clock source frequency in Hz. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is the master + * clock, this value should equal to masterClockHz in format. + * @retval kStatus_Success Audio format set successfully. + * @retval kStatus_InvalidArgument The input argument is invalid. +*/ +void SAI_TransferRxSetFormatEDMA(I2S_Type *base, + sai_edma_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz); + +/*! + * @brief Performs a non-blocking SAI transfer using DMA. + * + * @note This interface returns immediately after the transfer initiates. Call + * SAI_GetTransferStatus to poll the transfer status and check whether the SAI transfer is finished. + * + * @param base SAI base pointer. + * @param handle SAI eDMA handle pointer. + * @param xfer Pointer to the DMA transfer structure. + * @retval kStatus_Success Start a SAI eDMA send successfully. + * @retval kStatus_InvalidArgument The input argument is invalid. + * @retval kStatus_TxBusy SAI is busy sending data. + */ +status_t SAI_TransferSendEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer); + +/*! + * @brief Performs a non-blocking SAI receive using eDMA. + * + * @note This interface returns immediately after the transfer initiates. Call + * the SAI_GetReceiveRemainingBytes to poll the transfer status and check whether the SAI transfer is finished. + * + * @param base SAI base pointer + * @param handle SAI eDMA handle pointer. + * @param xfer Pointer to DMA transfer structure. + * @retval kStatus_Success Start a SAI eDMA receive successfully. + * @retval kStatus_InvalidArgument The input argument is invalid. + * @retval kStatus_RxBusy SAI is busy receiving data. + */ +status_t SAI_TransferReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer); + +/*! + * @brief Aborts a SAI transfer using eDMA. + * + * @param base SAI base pointer. + * @param handle SAI eDMA handle pointer. + */ +void SAI_TransferAbortSendEDMA(I2S_Type *base, sai_edma_handle_t *handle); + +/*! + * @brief Aborts a SAI receive using eDMA. + * + * @param base SAI base pointer + * @param handle SAI eDMA handle pointer. + */ +void SAI_TransferAbortReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle); + +/*! + * @brief Gets byte count sent by SAI. + * + * @param base SAI base pointer. + * @param handle SAI eDMA handle pointer. + * @param count Bytes count sent by SAI. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is no non-blocking transaction in progress. + */ +status_t SAI_TransferGetSendCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count); + +/*! + * @brief Gets byte count received by SAI. + * + * @param base SAI base pointer + * @param handle SAI eDMA handle pointer. + * @param count Bytes count received by SAI. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is no non-blocking transaction in progress. + */ +status_t SAI_TransferGetReceiveCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdhc.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdhc.c new file mode 100644 index 00000000000..30a51761920 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdhc.c @@ -0,0 +1,1356 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this + * list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, + * this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_sdhc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Clock setting */ +/* Max SD clock divisor from base clock */ +#define SDHC_MAX_DVS ((SDHC_SYSCTL_DVS_MASK >> SDHC_SYSCTL_DVS_SHIFT) + 1U) +#define SDHC_INITIAL_DVS (1U) /* Initial value of SD clock divisor */ +#define SDHC_INITIAL_CLKFS (2U) /* Initial value of SD clock frequency selector */ +#define SDHC_NEXT_DVS(x) ((x) += 1U) +#define SDHC_PREV_DVS(x) ((x) -= 1U) +#define SDHC_MAX_CLKFS ((SDHC_SYSCTL_SDCLKFS_MASK >> SDHC_SYSCTL_SDCLKFS_SHIFT) + 1U) +#define SDHC_NEXT_CLKFS(x) ((x) <<= 1U) +#define SDHC_PREV_CLKFS(x) ((x) >>= 1U) + +/* Typedef for interrupt handler. */ +typedef void (*sdhc_isr_t)(SDHC_Type *base, sdhc_handle_t *handle); + +/*! @brief ADMA table configuration */ +typedef struct _sdhc_adma_table_config +{ + uint32_t *admaTable; /*!< ADMA table address, can't be null if transfer way is ADMA1/ADMA2 */ + uint32_t admaTableWords; /*!< ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2 */ +} sdhc_adma_table_config_t; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get the instance. + * + * @param base SDHC peripheral base address. + * @return Instance number. + */ +static uint32_t SDHC_GetInstance(SDHC_Type *base); + +/*! + * @brief Set transfer interrupt. + * + * @param base SDHC peripheral base address. + * @param usingInterruptSignal True to use IRQ signal. + */ +static void SDHC_SetTransferInterrupt(SDHC_Type *base, bool usingInterruptSignal); + +/*! + * @brief Start transfer according to current transfer state + * + * @param base SDHC peripheral base address. + * @param command Command to be sent. + * @param data Data to be transferred. + */ +static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_data_t *data); + +/*! + * @brief Receive command response + * + * @param base SDHC peripheral base address. + * @param command Command to be sent. + */ +static void SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command); + +/*! + * @brief Read DATAPORT when buffer enable bit is set. + * + * @param base SDHC peripheral base address. + * @param data Data to be read. + * @param transferredWords The number of data words have been transferred last time transaction. + * @return The number of total data words have been transferred after this time transaction. + */ +static uint32_t SDHC_ReadDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords); + +/*! + * @brief Read data by using DATAPORT polling way. + * + * @param base SDHC peripheral base address. + * @param data Data to be read. + * @retval kStatus_Fail Read DATAPORT failed. + * @retval kStatus_Success Operate successfully. + */ +static status_t SDHC_ReadByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data); + +/*! + * @brief Write DATAPORT when buffer enable bit is set. + * + * @param base SDHC peripheral base address. + * @param data Data to be read. + * @param transferredWords The number of data words have been transferred last time. + * @return The number of total data words have been transferred after this time transaction. + */ +static uint32_t SDHC_WriteDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords); + +/*! + * @brief Write data by using DATAPORT polling way. + * + * @param base SDHC peripheral base address. + * @param data Data to be transferred. + * @retval kStatus_Fail Write DATAPORT failed. + * @retval kStatus_Success Operate successfully. + */ +static status_t SDHC_WriteByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data); + +/*! + * @brief Send command by using polling way. + * + * @param base SDHC peripheral base address. + * @param command Command to be sent. + * @retval kStatus_Fail Send command failed. + * @retval kStatus_Success Operate successfully. + */ +static status_t SDHC_SendCommandBlocking(SDHC_Type *base, sdhc_command_t *command); + +/*! + * @brief Transfer data by DATAPORT and polling way. + * + * @param base SDHC peripheral base address. + * @param data Data to be transferred. + * @retval kStatus_Fail Transfer data failed. + * @retval kStatus_Success Operate successfully. + */ +static status_t SDHC_TransferByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data); + +/*! + * @brief Transfer data by ADMA2 and polling way. + * + * @param base SDHC peripheral base address. + * @param data Data to be transferred. + * @retval kStatus_Fail Transfer data failed. + * @retval kStatus_Success Operate successfully. + */ +static status_t SDHC_TransferByAdma2Blocking(SDHC_Type *base, sdhc_data_t *data); + +/*! + * @brief Transfer data by polling way. + * + * @param dmaMode DMA mode. + * @param base SDHC peripheral base address. + * @param data Data to be transferred. + * @retval kStatus_Fail Transfer data failed. + * @retval kStatus_InvalidArgument Argument is invalid. + * @retval kStatus_Success Operate successfully. + */ +static status_t SDHC_TransferDataBlocking(sdhc_dma_mode_t dmaMode, SDHC_Type *base, sdhc_data_t *data); + +/*! + * @brief Handle card detect interrupt. + * + * @param handle SDHC handle. + * @param interruptFlags Card detect related interrupt flags. + */ +static void SDHC_TransferHandleCardDetect(sdhc_handle_t *handle, uint32_t interruptFlags); + +/*! + * @brief Handle command interrupt. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle. + * @param interruptFlags Command related interrupt flags. + */ +static void SDHC_TransferHandleCommand(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags); + +/*! + * @brief Handle data interrupt. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle. + * @param interruptFlags Data related interrupt flags. + */ +static void SDHC_TransferHandleData(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags); + +/*! + * @brief Handle SDIO card interrupt signal. + * + * @param handle SDHC handle. + */ +static void SDHC_TransferHandleSdioInterrupt(sdhc_handle_t *handle); + +/*! + * @brief Handle SDIO block gap event. + * + * @param handle SDHC handle. + */ +static void SDHC_TransferHandleSdioBlockGap(sdhc_handle_t *handle); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief SDHC internal handle pointer array */ +static sdhc_handle_t *s_sdhcHandle[FSL_FEATURE_SOC_SDHC_COUNT]; + +/*! @brief SDHC base pointer array */ +static SDHC_Type *const s_sdhcBase[] = SDHC_BASE_PTRS; + +/*! @brief SDHC IRQ name array */ +static const IRQn_Type s_sdhcIRQ[] = SDHC_IRQS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief SDHC clock array name */ +static const clock_ip_name_t s_sdhcClock[] = SDHC_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/* SDHC ISR for transactional APIs. */ +static sdhc_isr_t s_sdhcIsr; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t SDHC_GetInstance(SDHC_Type *base) +{ + uint8_t instance = 0; + + while ((instance < FSL_FEATURE_SOC_SDHC_COUNT) && (s_sdhcBase[instance] != base)) + { + instance++; + } + + assert(instance < FSL_FEATURE_SOC_SDHC_COUNT); + + return instance; +} + +static void SDHC_SetTransferInterrupt(SDHC_Type *base, bool usingInterruptSignal) +{ + uint32_t interruptEnabled; /* The Interrupt status flags to be enabled */ + sdhc_dma_mode_t dmaMode = (sdhc_dma_mode_t)((base->PROCTL & SDHC_PROCTL_DMAS_MASK) >> SDHC_PROCTL_DMAS_SHIFT); + bool cardDetectDat3 = (bool)(base->PROCTL & SDHC_PROCTL_D3CD_MASK); + + /* Disable all interrupts */ + SDHC_DisableInterruptStatus(base, (uint32_t)kSDHC_AllInterruptFlags); + SDHC_DisableInterruptSignal(base, (uint32_t)kSDHC_AllInterruptFlags); + DisableIRQ(s_sdhcIRQ[SDHC_GetInstance(base)]); + + interruptEnabled = + (kSDHC_CommandIndexErrorFlag | kSDHC_CommandCrcErrorFlag | kSDHC_CommandEndBitErrorFlag | + kSDHC_CommandTimeoutFlag | kSDHC_CommandCompleteFlag | kSDHC_DataTimeoutFlag | kSDHC_DataCrcErrorFlag | + kSDHC_DataEndBitErrorFlag | kSDHC_DataCompleteFlag | kSDHC_AutoCommand12ErrorFlag); + if (cardDetectDat3) + { + interruptEnabled |= (kSDHC_CardInsertionFlag | kSDHC_CardRemovalFlag); + } + switch (dmaMode) + { + case kSDHC_DmaModeAdma1: + case kSDHC_DmaModeAdma2: + interruptEnabled |= (kSDHC_DmaErrorFlag | kSDHC_DmaCompleteFlag); + break; + case kSDHC_DmaModeNo: + interruptEnabled |= (kSDHC_BufferReadReadyFlag | kSDHC_BufferWriteReadyFlag); + break; + default: + break; + } + + SDHC_EnableInterruptStatus(base, interruptEnabled); + if (usingInterruptSignal) + { + SDHC_EnableInterruptSignal(base, interruptEnabled); + } +} + +static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_data_t *data) +{ + uint32_t flags = 0U; + sdhc_transfer_config_t sdhcTransferConfig = {0}; + sdhc_dma_mode_t dmaMode; + + /* Define the flag corresponding to each response type. */ + switch (command->responseType) + { + case kSDHC_ResponseTypeNone: + break; + case kSDHC_ResponseTypeR1: /* Response 1 */ + flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); + break; + case kSDHC_ResponseTypeR1b: /* Response 1 with busy */ + flags |= (kSDHC_ResponseLength48BusyFlag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); + break; + case kSDHC_ResponseTypeR2: /* Response 2 */ + flags |= (kSDHC_ResponseLength136Flag | kSDHC_EnableCrcCheckFlag); + break; + case kSDHC_ResponseTypeR3: /* Response 3 */ + flags |= (kSDHC_ResponseLength48Flag); + break; + case kSDHC_ResponseTypeR4: /* Response 4 */ + flags |= (kSDHC_ResponseLength48Flag); + break; + case kSDHC_ResponseTypeR5: /* Response 5 */ + flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); + break; + case kSDHC_ResponseTypeR5b: /* Response 5 with busy */ + flags |= (kSDHC_ResponseLength48BusyFlag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); + break; + case kSDHC_ResponseTypeR6: /* Response 6 */ + flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); + break; + case kSDHC_ResponseTypeR7: /* Response 7 */ + flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); + break; + default: + break; + } + if (command->type == kSDHC_CommandTypeAbort) + { + flags |= kSDHC_CommandTypeAbortFlag; + } + + if (data) + { + flags |= kSDHC_DataPresentFlag; + dmaMode = (sdhc_dma_mode_t)((base->PROCTL & SDHC_PROCTL_DMAS_MASK) >> SDHC_PROCTL_DMAS_SHIFT); + if (dmaMode != kSDHC_DmaModeNo) + { + flags |= kSDHC_EnableDmaFlag; + } + if (data->rxData) + { + flags |= kSDHC_DataReadFlag; + } + if (data->blockCount > 1U) + { + flags |= (kSDHC_MultipleBlockFlag | kSDHC_EnableBlockCountFlag); + if (data->enableAutoCommand12) + { + /* Enable Auto command 12. */ + flags |= kSDHC_EnableAutoCommand12Flag; + } + } + + sdhcTransferConfig.dataBlockSize = data->blockSize; + sdhcTransferConfig.dataBlockCount = data->blockCount; + } + else + { + sdhcTransferConfig.dataBlockSize = 0U; + sdhcTransferConfig.dataBlockCount = 0U; + } + + sdhcTransferConfig.commandArgument = command->argument; + sdhcTransferConfig.commandIndex = command->index; + sdhcTransferConfig.flags = flags; + SDHC_SetTransferConfig(base, &sdhcTransferConfig); +} + +static void SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command) +{ + uint32_t i; + + if (command->responseType != kSDHC_ResponseTypeNone) + { + command->response[0U] = SDHC_GetCommandResponse(base, 0U); + if (command->responseType == kSDHC_ResponseTypeR2) + { + command->response[1U] = SDHC_GetCommandResponse(base, 1U); + command->response[2U] = SDHC_GetCommandResponse(base, 2U); + command->response[3U] = SDHC_GetCommandResponse(base, 3U); + + i = 4U; + /* R3-R2-R1-R0(lowest 8 bit is invalid bit) has the same format as R2 format in SD specification document + after removed internal CRC7 and end bit. */ + do + { + command->response[i - 1U] <<= 8U; + if (i > 1U) + { + command->response[i - 1U] |= ((command->response[i - 2U] & 0xFF000000U) >> 24U); + } + } while (i--); + } + } +} + +static uint32_t SDHC_ReadDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords) +{ + uint32_t i; + uint32_t totalWords; + uint32_t wordsCanBeRead; /* The words can be read at this time. */ + uint32_t readWatermark = ((base->WML & SDHC_WML_RDWML_MASK) >> SDHC_WML_RDWML_SHIFT); + + /* + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ + if (data->blockSize % sizeof(uint32_t) != 0U) + { + data->blockSize += + sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ + } + + totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t)); + + /* If watermark level is equal or bigger than totalWords, transfers totalWords data. */ + if (readWatermark >= totalWords) + { + wordsCanBeRead = totalWords; + } + /* If watermark level is less than totalWords and left words to be sent is equal or bigger than readWatermark, + transfers watermark level words. */ + else if ((readWatermark < totalWords) && ((totalWords - transferredWords) >= readWatermark)) + { + wordsCanBeRead = readWatermark; + } + /* If watermark level is less than totalWords and left words to be sent is less than readWatermark, transfers left + words. */ + else + { + wordsCanBeRead = (totalWords - transferredWords); + } + + i = 0U; + while (i < wordsCanBeRead) + { + data->rxData[transferredWords++] = SDHC_ReadData(base); + i++; + } + + return transferredWords; +} + +static status_t SDHC_ReadByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data) +{ + uint32_t totalWords; + uint32_t transferredWords = 0U; + status_t error = kStatus_Success; + + /* + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ + if (data->blockSize % sizeof(uint32_t) != 0U) + { + data->blockSize += + sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ + } + + totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t)); + + while ((error == kStatus_Success) && (transferredWords < totalWords)) + { + while (!(SDHC_GetInterruptStatusFlags(base) & (kSDHC_BufferReadReadyFlag | kSDHC_DataErrorFlag))) + { + } + + if (SDHC_GetInterruptStatusFlags(base) & kSDHC_DataErrorFlag) + { + if (!(data->enableIgnoreError)) + { + error = kStatus_Fail; + } + } + if (error == kStatus_Success) + { + transferredWords = SDHC_ReadDataPort(base, data, transferredWords); + } + + /* Clear buffer enable flag to trigger transfer. Clear data error flag when SDHC encounter error */ + SDHC_ClearInterruptStatusFlags(base, (kSDHC_BufferReadReadyFlag | kSDHC_DataErrorFlag)); + } + + /* Clear data complete flag after the last read operation. */ + SDHC_ClearInterruptStatusFlags(base, kSDHC_DataCompleteFlag); + + return error; +} + +static uint32_t SDHC_WriteDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords) +{ + uint32_t i; + uint32_t totalWords; + uint32_t wordsCanBeWrote; /* Words can be wrote at this time. */ + uint32_t writeWatermark = ((base->WML & SDHC_WML_WRWML_MASK) >> SDHC_WML_WRWML_SHIFT); + + /* + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ + if (data->blockSize % sizeof(uint32_t) != 0U) + { + data->blockSize += + sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ + } + + totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t)); + + /* If watermark level is equal or bigger than totalWords, transfers totalWords data.*/ + if (writeWatermark >= totalWords) + { + wordsCanBeWrote = totalWords; + } + /* If watermark level is less than totalWords and left words to be sent is equal or bigger than watermark, + transfers watermark level words. */ + else if ((writeWatermark < totalWords) && ((totalWords - transferredWords) >= writeWatermark)) + { + wordsCanBeWrote = writeWatermark; + } + /* If watermark level is less than totalWords and left words to be sent is less than watermark, transfers left + words. */ + else + { + wordsCanBeWrote = (totalWords - transferredWords); + } + + i = 0U; + while (i < wordsCanBeWrote) + { + SDHC_WriteData(base, data->txData[transferredWords++]); + i++; + } + + return transferredWords; +} + +static status_t SDHC_WriteByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data) +{ + uint32_t totalWords; + uint32_t transferredWords = 0U; + status_t error = kStatus_Success; + + /* + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ + if (data->blockSize % sizeof(uint32_t) != 0U) + { + data->blockSize += + sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ + } + + totalWords = (data->blockCount * data->blockSize) / sizeof(uint32_t); + + while ((error == kStatus_Success) && (transferredWords < totalWords)) + { + while (!(SDHC_GetInterruptStatusFlags(base) & (kSDHC_BufferWriteReadyFlag | kSDHC_DataErrorFlag))) + { + } + + if (SDHC_GetInterruptStatusFlags(base) & kSDHC_DataErrorFlag) + { + if (!(data->enableIgnoreError)) + { + error = kStatus_Fail; + } + } + if (error == kStatus_Success) + { + transferredWords = SDHC_WriteDataPort(base, data, transferredWords); + } + + /* Clear buffer enable flag to trigger transfer. Clear error flag when SDHC encounter error. */ + SDHC_ClearInterruptStatusFlags(base, (kSDHC_BufferWriteReadyFlag | kSDHC_DataErrorFlag)); + } + + /* Wait write data complete or data transfer error after the last writing operation. */ + while (!(SDHC_GetInterruptStatusFlags(base) & (kSDHC_DataCompleteFlag | kSDHC_DataErrorFlag))) + { + } + if (SDHC_GetInterruptStatusFlags(base) & kSDHC_DataErrorFlag) + { + if (!(data->enableIgnoreError)) + { + error = kStatus_Fail; + } + } + SDHC_ClearInterruptStatusFlags(base, (kSDHC_DataCompleteFlag | kSDHC_DataErrorFlag)); + + return error; +} + +static status_t SDHC_SendCommandBlocking(SDHC_Type *base, sdhc_command_t *command) +{ + status_t error = kStatus_Success; + + /* Wait command complete or SDHC encounters error. */ + while (!(SDHC_GetInterruptStatusFlags(base) & (kSDHC_CommandCompleteFlag | kSDHC_CommandErrorFlag))) + { + } + + if (SDHC_GetInterruptStatusFlags(base) & kSDHC_CommandErrorFlag) + { + error = kStatus_Fail; + } + /* Receive response when command completes successfully. */ + if (error == kStatus_Success) + { + SDHC_ReceiveCommandResponse(base, command); + } + + SDHC_ClearInterruptStatusFlags(base, (kSDHC_CommandCompleteFlag | kSDHC_CommandErrorFlag)); + + return error; +} + +static status_t SDHC_TransferByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data) +{ + status_t error = kStatus_Success; + + if (data->rxData) + { + error = SDHC_ReadByDataPortBlocking(base, data); + } + else + { + error = SDHC_WriteByDataPortBlocking(base, data); + } + + return error; +} + +static status_t SDHC_TransferByAdma2Blocking(SDHC_Type *base, sdhc_data_t *data) +{ + status_t error = kStatus_Success; + + /* Wait data complete or SDHC encounters error. */ + while (!(SDHC_GetInterruptStatusFlags(base) & (kSDHC_DataCompleteFlag | kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag))) + { + } + if (SDHC_GetInterruptStatusFlags(base) & (kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag)) + { + if (!(data->enableIgnoreError)) + { + error = kStatus_Fail; + } + } + SDHC_ClearInterruptStatusFlags( + base, (kSDHC_DataCompleteFlag | kSDHC_DmaCompleteFlag | kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag)); + return error; +} + +#if defined FSL_SDHC_ENABLE_ADMA1 +#define SDHC_TransferByAdma1Blocking(base, data) SDHC_TransferByAdma2Blocking(base, data) +#endif /* FSL_SDHC_ENABLE_ADMA1 */ + +static status_t SDHC_TransferDataBlocking(sdhc_dma_mode_t dmaMode, SDHC_Type *base, sdhc_data_t *data) +{ + status_t error = kStatus_Success; + + switch (dmaMode) + { + case kSDHC_DmaModeNo: + error = SDHC_TransferByDataPortBlocking(base, data); + break; +#if defined FSL_SDHC_ENABLE_ADMA1 + case kSDHC_DmaModeAdma1: + error = SDHC_TransferByAdma1Blocking(base, data); + break; +#endif /* FSL_SDHC_ENABLE_ADMA1 */ + case kSDHC_DmaModeAdma2: + error = SDHC_TransferByAdma2Blocking(base, data); + break; + default: + error = kStatus_InvalidArgument; + break; + } + + return error; +} + +static void SDHC_TransferHandleCardDetect(sdhc_handle_t *handle, uint32_t interruptFlags) +{ + if (interruptFlags & kSDHC_CardInsertionFlag) + { + if (handle->callback.CardInserted) + { + handle->callback.CardInserted(); + } + } + else + { + if (handle->callback.CardRemoved) + { + handle->callback.CardRemoved(); + } + } +} + +static void SDHC_TransferHandleCommand(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags) +{ + assert(handle->command); + + if ((interruptFlags & kSDHC_CommandErrorFlag) && (!(handle->data)) && (handle->callback.TransferComplete)) + { + handle->callback.TransferComplete(base, handle, kStatus_SDHC_SendCommandFailed, handle->userData); + } + else + { + /* Receive response */ + SDHC_ReceiveCommandResponse(base, handle->command); + if ((!(handle->data)) && (handle->callback.TransferComplete)) + { + handle->callback.TransferComplete(base, handle, kStatus_Success, handle->userData); + } + } +} + +static void SDHC_TransferHandleData(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags) +{ + assert(handle->data); + + if ((!(handle->data->enableIgnoreError)) && (interruptFlags & (kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag)) && + (handle->callback.TransferComplete)) + { + handle->callback.TransferComplete(base, handle, kStatus_SDHC_TransferDataFailed, handle->userData); + } + else + { + if (interruptFlags & kSDHC_BufferReadReadyFlag) + { + handle->transferredWords = SDHC_ReadDataPort(base, handle->data, handle->transferredWords); + } + else if (interruptFlags & kSDHC_BufferWriteReadyFlag) + { + handle->transferredWords = SDHC_WriteDataPort(base, handle->data, handle->transferredWords); + } + else if ((interruptFlags & kSDHC_DataCompleteFlag) && (handle->callback.TransferComplete)) + { + handle->callback.TransferComplete(base, handle, kStatus_Success, handle->userData); + } + else + { + /* Do nothing when DMA complete flag is set. Wait until data complete flag is set. */ + } + } +} + +static void SDHC_TransferHandleSdioInterrupt(sdhc_handle_t *handle) +{ + if (handle->callback.SdioInterrupt) + { + handle->callback.SdioInterrupt(); + } +} + +static void SDHC_TransferHandleSdioBlockGap(sdhc_handle_t *handle) +{ + if (handle->callback.SdioBlockGap) + { + handle->callback.SdioBlockGap(); + } +} + +void SDHC_Init(SDHC_Type *base, const sdhc_config_t *config) +{ + assert(config); +#if !defined FSL_SDHC_ENABLE_ADMA1 + assert(config->dmaMode != kSDHC_DmaModeAdma1); +#endif /* FSL_SDHC_ENABLE_ADMA1 */ + assert((config->writeWatermarkLevel >= 1U) && (config->writeWatermarkLevel <= 128U)); + assert((config->readWatermarkLevel >= 1U) && (config->readWatermarkLevel <= 128U)); + + uint32_t proctl; + uint32_t wml; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable SDHC clock. */ + CLOCK_EnableClock(s_sdhcClock[SDHC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset SDHC. */ + SDHC_Reset(base, kSDHC_ResetAll, 100); + + proctl = base->PROCTL; + wml = base->WML; + + proctl &= ~(SDHC_PROCTL_D3CD_MASK | SDHC_PROCTL_EMODE_MASK | SDHC_PROCTL_DMAS_MASK); + /* Set DAT3 as card detection pin */ + if (config->cardDetectDat3) + { + proctl |= SDHC_PROCTL_D3CD_MASK; + } + /* Endian mode and DMA mode */ + proctl |= (SDHC_PROCTL_EMODE(config->endianMode) | SDHC_PROCTL_DMAS(config->dmaMode)); + + /* Watermark level */ + wml &= ~(SDHC_WML_RDWML_MASK | SDHC_WML_WRWML_MASK); + wml |= (SDHC_WML_RDWML(config->readWatermarkLevel) | SDHC_WML_WRWML(config->writeWatermarkLevel)); + + base->WML = wml; + base->PROCTL = proctl; + + /* Disable all clock auto gated off feature because of DAT0 line logic(card buffer full status) can't be updated + correctly when clock auto gated off is enabled. */ + base->SYSCTL |= (SDHC_SYSCTL_PEREN_MASK | SDHC_SYSCTL_HCKEN_MASK | SDHC_SYSCTL_IPGEN_MASK); + + /* Enable interrupt status but doesn't enable interrupt signal. */ + SDHC_SetTransferInterrupt(base, false); +} + +void SDHC_Deinit(SDHC_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable clock. */ + CLOCK_DisableClock(s_sdhcClock[SDHC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +bool SDHC_Reset(SDHC_Type *base, uint32_t mask, uint32_t timeout) +{ + base->SYSCTL |= (mask & (SDHC_SYSCTL_RSTA_MASK | SDHC_SYSCTL_RSTC_MASK | SDHC_SYSCTL_RSTD_MASK)); + /* Delay some time to wait reset success. */ + while ((base->SYSCTL & mask)) + { + if (!timeout) + { + break; + } + timeout--; + } + + return ((!timeout) ? false : true); +} + +void SDHC_GetCapability(SDHC_Type *base, sdhc_capability_t *capability) +{ + assert(capability); + + uint32_t htCapability; + uint32_t hostVer; + uint32_t maxBlockLength; + + hostVer = base->HOSTVER; + htCapability = base->HTCAPBLT; + + /* Get the capability of SDHC. */ + capability->specVersion = ((hostVer & SDHC_HOSTVER_SVN_MASK) >> SDHC_HOSTVER_SVN_SHIFT); + capability->vendorVersion = ((hostVer & SDHC_HOSTVER_VVN_MASK) >> SDHC_HOSTVER_VVN_SHIFT); + maxBlockLength = ((htCapability & SDHC_HTCAPBLT_MBL_MASK) >> SDHC_HTCAPBLT_MBL_SHIFT); + capability->maxBlockLength = (512U << maxBlockLength); + /* Other attributes not in HTCAPBLT register. */ + capability->maxBlockCount = SDHC_MAX_BLOCK_COUNT; + capability->flags = (htCapability & (kSDHC_SupportAdmaFlag | kSDHC_SupportHighSpeedFlag | kSDHC_SupportDmaFlag | + kSDHC_SupportSuspendResumeFlag | kSDHC_SupportV330Flag)); +#if defined FSL_FEATURE_SDHC_HAS_V300_SUPPORT && FSL_FEATURE_SDHC_HAS_V300_SUPPORT + capability->flags |= (htCapability & kSDHC_SupportV300Flag); +#endif +#if defined FSL_FEATURE_SDHC_HAS_V180_SUPPORT && FSL_FEATURE_SDHC_HAS_V180_SUPPORT + capability->flags |= (htCapability & kSDHC_SupportV180Flag); +#endif + /* eSDHC on all kinetis boards will support 4/8 bit data bus width. */ + capability->flags |= (kSDHC_Support4BitFlag | kSDHC_Support8BitFlag); +} + +uint32_t SDHC_SetSdClock(SDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz) +{ + assert(srcClock_Hz != 0U); + assert((busClock_Hz != 0U) && (busClock_Hz <= srcClock_Hz)); + + uint32_t divisor; + uint32_t prescaler; + uint32_t sysctl; + uint32_t nearestFrequency = 0; + + divisor = SDHC_INITIAL_DVS; + prescaler = SDHC_INITIAL_CLKFS; + + /* Disable SD clock. It should be disabled before changing the SD clock frequency.*/ + base->SYSCTL &= ~SDHC_SYSCTL_SDCLKEN_MASK; + + if (busClock_Hz > 0U) + { + while ((srcClock_Hz / prescaler / SDHC_MAX_DVS > busClock_Hz) && (prescaler < SDHC_MAX_CLKFS)) + { + SDHC_NEXT_CLKFS(prescaler); + } + while ((srcClock_Hz / prescaler / divisor > busClock_Hz) && (divisor < SDHC_MAX_DVS)) + { + SDHC_NEXT_DVS(divisor); + } + nearestFrequency = srcClock_Hz / prescaler / divisor; + SDHC_PREV_CLKFS(prescaler); + SDHC_PREV_DVS(divisor); + + /* Set the SD clock frequency divisor, SD clock frequency select, data timeout counter value. */ + sysctl = base->SYSCTL; + sysctl &= ~(SDHC_SYSCTL_DVS_MASK | SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DTOCV_MASK); + sysctl |= (SDHC_SYSCTL_DVS(divisor) | SDHC_SYSCTL_SDCLKFS(prescaler) | SDHC_SYSCTL_DTOCV(0xEU)); + base->SYSCTL = sysctl; + + /* Wait until the SD clock is stable. */ + while (!(base->PRSSTAT & SDHC_PRSSTAT_SDSTB_MASK)) + { + } + /* Enable the SD clock. */ + base->SYSCTL |= SDHC_SYSCTL_SDCLKEN_MASK; + } + + return nearestFrequency; +} + +bool SDHC_SetCardActive(SDHC_Type *base, uint32_t timeout) +{ + base->SYSCTL |= SDHC_SYSCTL_INITA_MASK; + /* Delay some time to wait card become active state. */ + while ((base->SYSCTL & SDHC_SYSCTL_INITA_MASK)) + { + if (!timeout) + { + break; + } + timeout--; + } + + return ((!timeout) ? false : true); +} + +void SDHC_SetTransferConfig(SDHC_Type *base, const sdhc_transfer_config_t *config) +{ + assert(config); + assert(config->dataBlockSize <= (SDHC_BLKATTR_BLKSIZE_MASK >> SDHC_BLKATTR_BLKSIZE_SHIFT)); + assert(config->dataBlockCount <= (SDHC_BLKATTR_BLKCNT_MASK >> SDHC_BLKATTR_BLKCNT_SHIFT)); + + base->BLKATTR = ((base->BLKATTR & ~(SDHC_BLKATTR_BLKSIZE_MASK | SDHC_BLKATTR_BLKCNT_MASK)) | + (SDHC_BLKATTR_BLKSIZE(config->dataBlockSize) | SDHC_BLKATTR_BLKCNT(config->dataBlockCount))); + base->CMDARG = config->commandArgument; + base->XFERTYP = (((config->commandIndex << SDHC_XFERTYP_CMDINX_SHIFT) & SDHC_XFERTYP_CMDINX_MASK) | + (config->flags & (SDHC_XFERTYP_DMAEN_MASK | SDHC_XFERTYP_MSBSEL_MASK | SDHC_XFERTYP_DPSEL_MASK | + SDHC_XFERTYP_CMDTYP_MASK | SDHC_XFERTYP_BCEN_MASK | SDHC_XFERTYP_CICEN_MASK | + SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP_MASK | SDHC_XFERTYP_DTDSEL_MASK | + SDHC_XFERTYP_AC12EN_MASK))); +} + +void SDHC_EnableSdioControl(SDHC_Type *base, uint32_t mask, bool enable) +{ + uint32_t proctl = base->PROCTL; + uint32_t vendor = base->VENDOR; + + if (enable) + { + if (mask & kSDHC_StopAtBlockGapFlag) + { + proctl |= SDHC_PROCTL_SABGREQ_MASK; + } + if (mask & kSDHC_ReadWaitControlFlag) + { + proctl |= SDHC_PROCTL_RWCTL_MASK; + } + if (mask & kSDHC_InterruptAtBlockGapFlag) + { + proctl |= SDHC_PROCTL_IABG_MASK; + } + if (mask & kSDHC_ExactBlockNumberReadFlag) + { + vendor |= SDHC_VENDOR_EXBLKNU_MASK; + } + } + else + { + if (mask & kSDHC_StopAtBlockGapFlag) + { + proctl &= ~SDHC_PROCTL_SABGREQ_MASK; + } + if (mask & kSDHC_ReadWaitControlFlag) + { + proctl &= ~SDHC_PROCTL_RWCTL_MASK; + } + if (mask & kSDHC_InterruptAtBlockGapFlag) + { + proctl &= ~SDHC_PROCTL_IABG_MASK; + } + if (mask & kSDHC_ExactBlockNumberReadFlag) + { + vendor &= ~SDHC_VENDOR_EXBLKNU_MASK; + } + } + + base->PROCTL = proctl; + base->VENDOR = vendor; +} + +void SDHC_SetMmcBootConfig(SDHC_Type *base, const sdhc_boot_config_t *config) +{ + assert(config); + assert(config->ackTimeoutCount <= (SDHC_MMCBOOT_DTOCVACK_MASK >> SDHC_MMCBOOT_DTOCVACK_SHIFT)); + assert(config->blockCount <= (SDHC_MMCBOOT_BOOTBLKCNT_MASK >> SDHC_MMCBOOT_BOOTBLKCNT_SHIFT)); + + uint32_t mmcboot = 0U; + + mmcboot = (SDHC_MMCBOOT_DTOCVACK(config->ackTimeoutCount) | SDHC_MMCBOOT_BOOTMODE(config->bootMode) | + SDHC_MMCBOOT_BOOTBLKCNT(config->blockCount)); + if (config->enableBootAck) + { + mmcboot |= SDHC_MMCBOOT_BOOTACK_MASK; + } + if (config->enableBoot) + { + mmcboot |= SDHC_MMCBOOT_BOOTEN_MASK; + } + if (config->enableAutoStopAtBlockGap) + { + mmcboot |= SDHC_MMCBOOT_AUTOSABGEN_MASK; + } + base->MMCBOOT = mmcboot; +} + +status_t SDHC_SetAdmaTableConfig(SDHC_Type *base, + sdhc_dma_mode_t dmaMode, + uint32_t *table, + uint32_t tableWords, + const uint32_t *data, + uint32_t dataBytes) +{ + status_t error = kStatus_Success; + const uint32_t *startAddress; + uint32_t entries; + uint32_t i; +#if defined FSL_SDHC_ENABLE_ADMA1 + sdhc_adma1_descriptor_t *adma1EntryAddress; +#endif + sdhc_adma2_descriptor_t *adma2EntryAddress; + + if ((((!table) || (!tableWords)) && ((dmaMode == kSDHC_DmaModeAdma1) || (dmaMode == kSDHC_DmaModeAdma2))) || + (!data) || (!dataBytes) +#if !defined FSL_SDHC_ENABLE_ADMA1 + || (dmaMode == kSDHC_DmaModeAdma1) +#else + /* Buffer address configured in ADMA1 descriptor must be 4KB aligned. */ + || ((dmaMode == kSDHC_DmaModeAdma1) && (((uint32_t)data % SDHC_ADMA1_LENGTH_ALIGN) != 0U)) +#endif /* FSL_SDHC_ENABLE_ADMA1 */ + ) + { + error = kStatus_InvalidArgument; + } + else + { + switch (dmaMode) + { + case kSDHC_DmaModeNo: + break; +#if defined FSL_SDHC_ENABLE_ADMA1 + case kSDHC_DmaModeAdma1: + /* + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ + if (dataBytes % sizeof(uint32_t) != 0U) + { + dataBytes += + sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); /* make the data length as word-aligned */ + } + + startAddress = data; + /* Check if ADMA descriptor's number is enough. */ + entries = ((dataBytes / SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U); + /* ADMA1 needs two descriptors to finish a transfer */ + entries <<= 1U; + if (entries > ((tableWords * sizeof(uint32_t)) / sizeof(sdhc_adma1_descriptor_t))) + { + error = kStatus_OutOfRange; + } + else + { + adma1EntryAddress = (sdhc_adma1_descriptor_t *)(table); + for (i = 0U; i < entries; i += 2U) + { + /* Each descriptor for ADMA1 is 32-bit in length */ + if ((dataBytes - sizeof(uint32_t) * (startAddress - data)) <= + SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + { + /* The last piece of data, setting end flag in descriptor */ + adma1EntryAddress[i] = ((uint32_t)(dataBytes - sizeof(uint32_t) * (startAddress - data)) + << SDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT); + adma1EntryAddress[i] |= kSDHC_Adma1DescriptorTypeSetLength; + adma1EntryAddress[i + 1U] = + ((uint32_t)(startAddress) << SDHC_ADMA1_DESCRIPTOR_ADDRESS_SHIFT); + adma1EntryAddress[i + 1U] |= + (kSDHC_Adma1DescriptorTypeTransfer | kSDHC_Adma1DescriptorEndFlag); + } + else + { + adma1EntryAddress[i] = ((uint32_t)SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY + << SDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT); + adma1EntryAddress[i] |= kSDHC_Adma1DescriptorTypeSetLength; + adma1EntryAddress[i + 1U] = + ((uint32_t)(startAddress) << SDHC_ADMA1_DESCRIPTOR_ADDRESS_SHIFT); + adma1EntryAddress[i + 1U] |= kSDHC_Adma1DescriptorTypeTransfer; + startAddress += SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY / sizeof(uint32_t); + } + } + + /* When use ADMA, disable simple DMA */ + base->DSADDR = 0U; + base->ADSADDR = (uint32_t)table; + } + break; +#endif /* FSL_SDHC_ENABLE_ADMA1 */ + case kSDHC_DmaModeAdma2: + /* + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ + if (dataBytes % sizeof(uint32_t) != 0U) + { + dataBytes += + sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); /* make the data length as word-aligned */ + } + + startAddress = data; + /* Check if ADMA descriptor's number is enough. */ + entries = ((dataBytes / SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U); + if (entries > ((tableWords * sizeof(uint32_t)) / sizeof(sdhc_adma2_descriptor_t))) + { + error = kStatus_OutOfRange; + } + else + { + adma2EntryAddress = (sdhc_adma2_descriptor_t *)(table); + for (i = 0U; i < entries; i++) + { + /* Each descriptor for ADMA2 is 64-bit in length */ + if ((dataBytes - sizeof(uint32_t) * (startAddress - data)) <= + SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + { + /* The last piece of data, setting end flag in descriptor */ + adma2EntryAddress[i].address = startAddress; + adma2EntryAddress[i].attribute = ((dataBytes - sizeof(uint32_t) * (startAddress - data)) + << SDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT); + adma2EntryAddress[i].attribute |= + (kSDHC_Adma2DescriptorTypeTransfer | kSDHC_Adma2DescriptorEndFlag); + } + else + { + adma2EntryAddress[i].address = startAddress; + adma2EntryAddress[i].attribute = + (((SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY / sizeof(uint32_t)) * sizeof(uint32_t)) + << SDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT); + adma2EntryAddress[i].attribute |= kSDHC_Adma2DescriptorTypeTransfer; + startAddress += (SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY / sizeof(uint32_t)); + } + } + + /* When use ADMA, disable simple DMA */ + base->DSADDR = 0U; + base->ADSADDR = (uint32_t)table; + } + break; + default: + break; + } + } + + return error; +} + +status_t SDHC_TransferBlocking(SDHC_Type *base, uint32_t *admaTable, uint32_t admaTableWords, sdhc_transfer_t *transfer) +{ + assert(transfer); + + status_t error = kStatus_Success; + sdhc_dma_mode_t dmaMode = (sdhc_dma_mode_t)((base->PROCTL & SDHC_PROCTL_DMAS_MASK) >> SDHC_PROCTL_DMAS_SHIFT); + sdhc_command_t *command = transfer->command; + sdhc_data_t *data = transfer->data; + + /* make sure the cmd/block count is valid */ + if ((!command) || (data && (data->blockCount > SDHC_MAX_BLOCK_COUNT))) + { + error = kStatus_InvalidArgument; + } + else + { + /* Wait until command/data bus out of busy status. */ + while (SDHC_GetPresentStatusFlags(base) & kSDHC_CommandInhibitFlag) + { + } + while (data && (SDHC_GetPresentStatusFlags(base) & kSDHC_DataInhibitFlag)) + { + } + + /* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/ + if (data && (kStatus_Success != SDHC_SetAdmaTableConfig(base, dmaMode, admaTable, admaTableWords, + (data->rxData ? data->rxData : data->txData), + (data->blockCount * data->blockSize)))) + { + error = kStatus_SDHC_PrepareAdmaDescriptorFailed; + } + else + { + /* Send command and receive data. */ + SDHC_StartTransfer(base, command, data); + if (kStatus_Success != SDHC_SendCommandBlocking(base, command)) + { + error = kStatus_SDHC_SendCommandFailed; + } + else if (data && (kStatus_Success != SDHC_TransferDataBlocking(dmaMode, base, data))) + { + error = kStatus_SDHC_TransferDataFailed; + } + else + { + } + } + } + + return error; +} + +void SDHC_TransferCreateHandle(SDHC_Type *base, + sdhc_handle_t *handle, + const sdhc_transfer_callback_t *callback, + void *userData) +{ + assert(handle); + assert(callback); + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Set the callback. */ + handle->callback.CardInserted = callback->CardInserted; + handle->callback.CardRemoved = callback->CardRemoved; + handle->callback.SdioInterrupt = callback->SdioInterrupt; + handle->callback.SdioBlockGap = callback->SdioBlockGap; + handle->callback.TransferComplete = callback->TransferComplete; + handle->userData = userData; + + /* Save the handle in global variables to support the double weak mechanism. */ + s_sdhcHandle[SDHC_GetInstance(base)] = handle; + + /* Enable interrupt in NVIC. */ + SDHC_SetTransferInterrupt(base, true); + + /* save IRQ handler */ + s_sdhcIsr = SDHC_TransferHandleIRQ; + + EnableIRQ(s_sdhcIRQ[SDHC_GetInstance(base)]); +} + +status_t SDHC_TransferNonBlocking( + SDHC_Type *base, sdhc_handle_t *handle, uint32_t *admaTable, uint32_t admaTableWords, sdhc_transfer_t *transfer) +{ + assert(transfer); + + sdhc_dma_mode_t dmaMode = (sdhc_dma_mode_t)((base->PROCTL & SDHC_PROCTL_DMAS_MASK) >> SDHC_PROCTL_DMAS_SHIFT); + status_t error = kStatus_Success; + sdhc_command_t *command = transfer->command; + sdhc_data_t *data = transfer->data; + + /* make sure cmd/block count is valid */ + if ((!command) || (data && (data->blockCount > SDHC_MAX_BLOCK_COUNT))) + { + error = kStatus_InvalidArgument; + } + else + { + /* Wait until command/data bus out of busy status. */ + if ((SDHC_GetPresentStatusFlags(base) & kSDHC_CommandInhibitFlag) || + (data && (SDHC_GetPresentStatusFlags(base) & kSDHC_DataInhibitFlag))) + { + error = kStatus_SDHC_BusyTransferring; + } + else + { + /* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/ + if (data && (kStatus_Success != SDHC_SetAdmaTableConfig(base, dmaMode, admaTable, admaTableWords, + (data->rxData ? data->rxData : data->txData), + (data->blockCount * data->blockSize)))) + { + error = kStatus_SDHC_PrepareAdmaDescriptorFailed; + } + else + { + /* Save command and data into handle before transferring. */ + handle->command = command; + handle->data = data; + handle->interruptFlags = 0U; + /* transferredWords will only be updated in ISR when transfer way is DATAPORT. */ + handle->transferredWords = 0U; + + SDHC_StartTransfer(base, command, data); + } + } + } + + return error; +} + +void SDHC_TransferHandleIRQ(SDHC_Type *base, sdhc_handle_t *handle) +{ + assert(handle); + + uint32_t interruptFlags; + + interruptFlags = SDHC_GetInterruptStatusFlags(base); + handle->interruptFlags = interruptFlags; + + if (interruptFlags & kSDHC_CardDetectFlag) + { + SDHC_TransferHandleCardDetect(handle, (interruptFlags & kSDHC_CardDetectFlag)); + } + if (interruptFlags & kSDHC_CommandFlag) + { + SDHC_TransferHandleCommand(base, handle, (interruptFlags & kSDHC_CommandFlag)); + } + if (interruptFlags & kSDHC_DataFlag) + { + SDHC_TransferHandleData(base, handle, (interruptFlags & kSDHC_DataFlag)); + } + if (interruptFlags & kSDHC_CardInterruptFlag) + { + SDHC_TransferHandleSdioInterrupt(handle); + } + if (interruptFlags & kSDHC_BlockGapEventFlag) + { + SDHC_TransferHandleSdioBlockGap(handle); + } + + SDHC_ClearInterruptStatusFlags(base, interruptFlags); +} + +#if defined(SDHC) +void SDHC_DriverIRQHandler(void) +{ + assert(s_sdhcHandle[0]); + + s_sdhcIsr(SDHC, s_sdhcHandle[0]); +} +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdhc.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdhc.h new file mode 100644 index 00000000000..4e402425b41 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdhc.h @@ -0,0 +1,1087 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_SDHC_H_ +#define _FSL_SDHC_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup sdhc + * @{ + */ + +/****************************************************************************** + * Definitions. + *****************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief Driver version 2.1.2. */ +#define FSL_SDHC_DRIVER_VERSION (MAKE_VERSION(2U, 1U, 2U)) +/*@}*/ + +/*! @brief Maximum block count can be set one time */ +#define SDHC_MAX_BLOCK_COUNT (SDHC_BLKATTR_BLKCNT_MASK >> SDHC_BLKATTR_BLKCNT_SHIFT) + +/*! @brief SDHC status */ +enum _sdhc_status +{ + kStatus_SDHC_BusyTransferring = MAKE_STATUS(kStatusGroup_SDHC, 0U), /*!< Transfer is on-going */ + kStatus_SDHC_PrepareAdmaDescriptorFailed = MAKE_STATUS(kStatusGroup_SDHC, 1U), /*!< Set DMA descriptor failed */ + kStatus_SDHC_SendCommandFailed = MAKE_STATUS(kStatusGroup_SDHC, 2U), /*!< Send command failed */ + kStatus_SDHC_TransferDataFailed = MAKE_STATUS(kStatusGroup_SDHC, 3U), /*!< Transfer data failed */ +}; + +/*! @brief Host controller capabilities flag mask */ +enum _sdhc_capability_flag +{ + kSDHC_SupportAdmaFlag = SDHC_HTCAPBLT_ADMAS_MASK, /*!< Support ADMA */ + kSDHC_SupportHighSpeedFlag = SDHC_HTCAPBLT_HSS_MASK, /*!< Support high-speed */ + kSDHC_SupportDmaFlag = SDHC_HTCAPBLT_DMAS_MASK, /*!< Support DMA */ + kSDHC_SupportSuspendResumeFlag = SDHC_HTCAPBLT_SRS_MASK, /*!< Support suspend/resume */ + kSDHC_SupportV330Flag = SDHC_HTCAPBLT_VS33_MASK, /*!< Support voltage 3.3V */ +#if defined FSL_FEATURE_SDHC_HAS_V300_SUPPORT && FSL_FEATURE_SDHC_HAS_V300_SUPPORT + kSDHC_SupportV300Flag = SDHC_HTCAPBLT_VS30_MASK, /*!< Support voltage 3.0V */ +#endif +#if defined FSL_FEATURE_SDHC_HAS_V180_SUPPORT && FSL_FEATURE_SDHC_HAS_V180_SUPPORT + kSDHC_SupportV180Flag = SDHC_HTCAPBLT_VS18_MASK, /*!< Support voltage 1.8V */ +#endif + /* Put additional two flags in HTCAPBLT_MBL's position. */ + kSDHC_Support4BitFlag = (SDHC_HTCAPBLT_MBL_SHIFT << 0U), /*!< Support 4 bit mode */ + kSDHC_Support8BitFlag = (SDHC_HTCAPBLT_MBL_SHIFT << 1U), /*!< Support 8 bit mode */ +}; + +/*! @brief Wakeup event mask */ +enum _sdhc_wakeup_event +{ + kSDHC_WakeupEventOnCardInt = SDHC_PROCTL_WECINT_MASK, /*!< Wakeup on card interrupt */ + kSDHC_WakeupEventOnCardInsert = SDHC_PROCTL_WECINS_MASK, /*!< Wakeup on card insertion */ + kSDHC_WakeupEventOnCardRemove = SDHC_PROCTL_WECRM_MASK, /*!< Wakeup on card removal */ + + kSDHC_WakeupEventsAll = (kSDHC_WakeupEventOnCardInt | kSDHC_WakeupEventOnCardInsert | + kSDHC_WakeupEventOnCardRemove), /*!< All wakeup events */ +}; + +/*! @brief Reset type mask */ +enum _sdhc_reset +{ + kSDHC_ResetAll = SDHC_SYSCTL_RSTA_MASK, /*!< Reset all except card detection */ + kSDHC_ResetCommand = SDHC_SYSCTL_RSTC_MASK, /*!< Reset command line */ + kSDHC_ResetData = SDHC_SYSCTL_RSTD_MASK, /*!< Reset data line */ + + kSDHC_ResetsAll = (kSDHC_ResetAll | kSDHC_ResetCommand | kSDHC_ResetData), /*!< All reset types */ +}; + +/*! @brief Transfer flag mask */ +enum _sdhc_transfer_flag +{ + kSDHC_EnableDmaFlag = SDHC_XFERTYP_DMAEN_MASK, /*!< Enable DMA */ + + kSDHC_CommandTypeSuspendFlag = (SDHC_XFERTYP_CMDTYP(1U)), /*!< Suspend command */ + kSDHC_CommandTypeResumeFlag = (SDHC_XFERTYP_CMDTYP(2U)), /*!< Resume command */ + kSDHC_CommandTypeAbortFlag = (SDHC_XFERTYP_CMDTYP(3U)), /*!< Abort command */ + + kSDHC_EnableBlockCountFlag = SDHC_XFERTYP_BCEN_MASK, /*!< Enable block count */ + kSDHC_EnableAutoCommand12Flag = SDHC_XFERTYP_AC12EN_MASK, /*!< Enable auto CMD12 */ + kSDHC_DataReadFlag = SDHC_XFERTYP_DTDSEL_MASK, /*!< Enable data read */ + kSDHC_MultipleBlockFlag = SDHC_XFERTYP_MSBSEL_MASK, /*!< Multiple block data read/write */ + + kSDHC_ResponseLength136Flag = SDHC_XFERTYP_RSPTYP(1U), /*!< 136 bit response length */ + kSDHC_ResponseLength48Flag = SDHC_XFERTYP_RSPTYP(2U), /*!< 48 bit response length */ + kSDHC_ResponseLength48BusyFlag = SDHC_XFERTYP_RSPTYP(3U), /*!< 48 bit response length with busy status */ + + kSDHC_EnableCrcCheckFlag = SDHC_XFERTYP_CCCEN_MASK, /*!< Enable CRC check */ + kSDHC_EnableIndexCheckFlag = SDHC_XFERTYP_CICEN_MASK, /*!< Enable index check */ + kSDHC_DataPresentFlag = SDHC_XFERTYP_DPSEL_MASK, /*!< Data present flag */ +}; + +/*! @brief Present status flag mask */ +enum _sdhc_present_status_flag +{ + kSDHC_CommandInhibitFlag = SDHC_PRSSTAT_CIHB_MASK, /*!< Command inhibit */ + kSDHC_DataInhibitFlag = SDHC_PRSSTAT_CDIHB_MASK, /*!< Data inhibit */ + kSDHC_DataLineActiveFlag = SDHC_PRSSTAT_DLA_MASK, /*!< Data line active */ + kSDHC_SdClockStableFlag = SDHC_PRSSTAT_SDSTB_MASK, /*!< SD bus clock stable */ + kSDHC_WriteTransferActiveFlag = SDHC_PRSSTAT_WTA_MASK, /*!< Write transfer active */ + kSDHC_ReadTransferActiveFlag = SDHC_PRSSTAT_RTA_MASK, /*!< Read transfer active */ + kSDHC_BufferWriteEnableFlag = SDHC_PRSSTAT_BWEN_MASK, /*!< Buffer write enable */ + kSDHC_BufferReadEnableFlag = SDHC_PRSSTAT_BREN_MASK, /*!< Buffer read enable */ + kSDHC_CardInsertedFlag = SDHC_PRSSTAT_CINS_MASK, /*!< Card inserted */ + kSDHC_CommandLineLevelFlag = SDHC_PRSSTAT_CLSL_MASK, /*!< Command line signal level */ + kSDHC_Data0LineLevelFlag = (1U << 24U), /*!< Data0 line signal level */ + kSDHC_Data1LineLevelFlag = (1U << 25U), /*!< Data1 line signal level */ + kSDHC_Data2LineLevelFlag = (1U << 26U), /*!< Data2 line signal level */ + kSDHC_Data3LineLevelFlag = (1U << 27U), /*!< Data3 line signal level */ + kSDHC_Data4LineLevelFlag = (1U << 28U), /*!< Data4 line signal level */ + kSDHC_Data5LineLevelFlag = (1U << 29U), /*!< Data5 line signal level */ + kSDHC_Data6LineLevelFlag = (1U << 30U), /*!< Data6 line signal level */ + kSDHC_Data7LineLevelFlag = (1U << 31U), /*!< Data7 line signal level */ +}; + +/*! @brief Interrupt status flag mask */ +enum _sdhc_interrupt_status_flag +{ + kSDHC_CommandCompleteFlag = SDHC_IRQSTAT_CC_MASK, /*!< Command complete */ + kSDHC_DataCompleteFlag = SDHC_IRQSTAT_TC_MASK, /*!< Data complete */ + kSDHC_BlockGapEventFlag = SDHC_IRQSTAT_BGE_MASK, /*!< Block gap event */ + kSDHC_DmaCompleteFlag = SDHC_IRQSTAT_DINT_MASK, /*!< DMA interrupt */ + kSDHC_BufferWriteReadyFlag = SDHC_IRQSTAT_BWR_MASK, /*!< Buffer write ready */ + kSDHC_BufferReadReadyFlag = SDHC_IRQSTAT_BRR_MASK, /*!< Buffer read ready */ + kSDHC_CardInsertionFlag = SDHC_IRQSTAT_CINS_MASK, /*!< Card inserted */ + kSDHC_CardRemovalFlag = SDHC_IRQSTAT_CRM_MASK, /*!< Card removed */ + kSDHC_CardInterruptFlag = SDHC_IRQSTAT_CINT_MASK, /*!< Card interrupt */ + kSDHC_CommandTimeoutFlag = SDHC_IRQSTAT_CTOE_MASK, /*!< Command timeout error */ + kSDHC_CommandCrcErrorFlag = SDHC_IRQSTAT_CCE_MASK, /*!< Command CRC error */ + kSDHC_CommandEndBitErrorFlag = SDHC_IRQSTAT_CEBE_MASK, /*!< Command end bit error */ + kSDHC_CommandIndexErrorFlag = SDHC_IRQSTAT_CIE_MASK, /*!< Command index error */ + kSDHC_DataTimeoutFlag = SDHC_IRQSTAT_DTOE_MASK, /*!< Data timeout error */ + kSDHC_DataCrcErrorFlag = SDHC_IRQSTAT_DCE_MASK, /*!< Data CRC error */ + kSDHC_DataEndBitErrorFlag = SDHC_IRQSTAT_DEBE_MASK, /*!< Data end bit error */ + kSDHC_AutoCommand12ErrorFlag = SDHC_IRQSTAT_AC12E_MASK, /*!< Auto CMD12 error */ + kSDHC_DmaErrorFlag = SDHC_IRQSTAT_DMAE_MASK, /*!< DMA error */ + + kSDHC_CommandErrorFlag = (kSDHC_CommandTimeoutFlag | kSDHC_CommandCrcErrorFlag | kSDHC_CommandEndBitErrorFlag | + kSDHC_CommandIndexErrorFlag), /*!< Command error */ + kSDHC_DataErrorFlag = (kSDHC_DataTimeoutFlag | kSDHC_DataCrcErrorFlag | kSDHC_DataEndBitErrorFlag | + kSDHC_AutoCommand12ErrorFlag), /*!< Data error */ + kSDHC_ErrorFlag = (kSDHC_CommandErrorFlag | kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag), /*!< All error */ + kSDHC_DataFlag = (kSDHC_DataCompleteFlag | kSDHC_DmaCompleteFlag | kSDHC_BufferWriteReadyFlag | + kSDHC_BufferReadReadyFlag | kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag), /*!< Data interrupts */ + kSDHC_CommandFlag = (kSDHC_CommandErrorFlag | kSDHC_CommandCompleteFlag), /*!< Command interrupts */ + kSDHC_CardDetectFlag = (kSDHC_CardInsertionFlag | kSDHC_CardRemovalFlag), /*!< Card detection interrupts */ + + kSDHC_AllInterruptFlags = (kSDHC_BlockGapEventFlag | kSDHC_CardInterruptFlag | kSDHC_CommandFlag | kSDHC_DataFlag | + kSDHC_ErrorFlag), /*!< All flags mask */ +}; + +/*! @brief Auto CMD12 error status flag mask */ +enum _sdhc_auto_command12_error_status_flag +{ + kSDHC_AutoCommand12NotExecutedFlag = SDHC_AC12ERR_AC12NE_MASK, /*!< Not executed error */ + kSDHC_AutoCommand12TimeoutFlag = SDHC_AC12ERR_AC12TOE_MASK, /*!< Timeout error */ + kSDHC_AutoCommand12EndBitErrorFlag = SDHC_AC12ERR_AC12EBE_MASK, /*!< End bit error */ + kSDHC_AutoCommand12CrcErrorFlag = SDHC_AC12ERR_AC12CE_MASK, /*!< CRC error */ + kSDHC_AutoCommand12IndexErrorFlag = SDHC_AC12ERR_AC12IE_MASK, /*!< Index error */ + kSDHC_AutoCommand12NotIssuedFlag = SDHC_AC12ERR_CNIBAC12E_MASK, /*!< Not issued error */ +}; + +/*! @brief ADMA error status flag mask */ +enum _sdhc_adma_error_status_flag +{ + kSDHC_AdmaLenghMismatchFlag = SDHC_ADMAES_ADMALME_MASK, /*!< Length mismatch error */ + kSDHC_AdmaDescriptorErrorFlag = SDHC_ADMAES_ADMADCE_MASK, /*!< Descriptor error */ +}; + +/*! + * @brief ADMA error state + * + * This state is the detail state when ADMA error has occurred. + */ +typedef enum _sdhc_adma_error_state +{ + kSDHC_AdmaErrorStateStopDma = 0x00U, /*!< Stop DMA */ + kSDHC_AdmaErrorStateFetchDescriptor = 0x01U, /*!< Fetch descriptor */ + kSDHC_AdmaErrorStateChangeAddress = 0x02U, /*!< Change address */ + kSDHC_AdmaErrorStateTransferData = 0x03U, /*!< Transfer data */ +} sdhc_adma_error_state_t; + +/*! @brief Force event mask */ +enum _sdhc_force_event +{ + kSDHC_ForceEventAutoCommand12NotExecuted = SDHC_FEVT_AC12NE_MASK, /*!< Auto CMD12 not executed error */ + kSDHC_ForceEventAutoCommand12Timeout = SDHC_FEVT_AC12TOE_MASK, /*!< Auto CMD12 timeout error */ + kSDHC_ForceEventAutoCommand12CrcError = SDHC_FEVT_AC12CE_MASK, /*!< Auto CMD12 CRC error */ + kSDHC_ForceEventEndBitError = SDHC_FEVT_AC12EBE_MASK, /*!< Auto CMD12 end bit error */ + kSDHC_ForceEventAutoCommand12IndexError = SDHC_FEVT_AC12IE_MASK, /*!< Auto CMD12 index error */ + kSDHC_ForceEventAutoCommand12NotIssued = SDHC_FEVT_CNIBAC12E_MASK, /*!< Auto CMD12 not issued error */ + kSDHC_ForceEventCommandTimeout = SDHC_FEVT_CTOE_MASK, /*!< Command timeout error */ + kSDHC_ForceEventCommandCrcError = SDHC_FEVT_CCE_MASK, /*!< Command CRC error */ + kSDHC_ForceEventCommandEndBitError = SDHC_FEVT_CEBE_MASK, /*!< Command end bit error */ + kSDHC_ForceEventCommandIndexError = SDHC_FEVT_CIE_MASK, /*!< Command index error */ + kSDHC_ForceEventDataTimeout = SDHC_FEVT_DTOE_MASK, /*!< Data timeout error */ + kSDHC_ForceEventDataCrcError = SDHC_FEVT_DCE_MASK, /*!< Data CRC error */ + kSDHC_ForceEventDataEndBitError = SDHC_FEVT_DEBE_MASK, /*!< Data end bit error */ + kSDHC_ForceEventAutoCommand12Error = SDHC_FEVT_AC12E_MASK, /*!< Auto CMD12 error */ + kSDHC_ForceEventCardInt = SDHC_FEVT_CINT_MASK, /*!< Card interrupt */ + kSDHC_ForceEventDmaError = SDHC_FEVT_DMAE_MASK, /*!< Dma error */ + + kSDHC_ForceEventsAll = + (kSDHC_ForceEventAutoCommand12NotExecuted | kSDHC_ForceEventAutoCommand12Timeout | + kSDHC_ForceEventAutoCommand12CrcError | kSDHC_ForceEventEndBitError | kSDHC_ForceEventAutoCommand12IndexError | + kSDHC_ForceEventAutoCommand12NotIssued | kSDHC_ForceEventCommandTimeout | kSDHC_ForceEventCommandCrcError | + kSDHC_ForceEventCommandEndBitError | kSDHC_ForceEventCommandIndexError | kSDHC_ForceEventDataTimeout | + kSDHC_ForceEventDataCrcError | kSDHC_ForceEventDataEndBitError | kSDHC_ForceEventAutoCommand12Error | + kSDHC_ForceEventCardInt | kSDHC_ForceEventDmaError), /*!< All force event flags mask */ +}; + +/*! @brief Data transfer width */ +typedef enum _sdhc_data_bus_width +{ + kSDHC_DataBusWidth1Bit = 0U, /*!< 1-bit mode */ + kSDHC_DataBusWidth4Bit = 1U, /*!< 4-bit mode */ + kSDHC_DataBusWidth8Bit = 2U, /*!< 8-bit mode */ +} sdhc_data_bus_width_t; + +/*! @brief Endian mode */ +typedef enum _sdhc_endian_mode +{ + kSDHC_EndianModeBig = 0U, /*!< Big endian mode */ + kSDHC_EndianModeHalfWordBig = 1U, /*!< Half word big endian mode */ + kSDHC_EndianModeLittle = 2U, /*!< Little endian mode */ +} sdhc_endian_mode_t; + +/*! @brief DMA mode */ +typedef enum _sdhc_dma_mode +{ + kSDHC_DmaModeNo = 0U, /*!< No DMA */ + kSDHC_DmaModeAdma1 = 1U, /*!< ADMA1 is selected */ + kSDHC_DmaModeAdma2 = 2U, /*!< ADMA2 is selected */ +} sdhc_dma_mode_t; + +/*! @brief SDIO control flag mask */ +enum _sdhc_sdio_control_flag +{ + kSDHC_StopAtBlockGapFlag = 0x01, /*!< Stop at block gap */ + kSDHC_ReadWaitControlFlag = 0x02, /*!< Read wait control */ + kSDHC_InterruptAtBlockGapFlag = 0x04, /*!< Interrupt at block gap */ + kSDHC_ExactBlockNumberReadFlag = 0x08, /*!< Exact block number read */ +}; + +/*! @brief MMC card boot mode */ +typedef enum _sdhc_boot_mode +{ + kSDHC_BootModeNormal = 0U, /*!< Normal boot */ + kSDHC_BootModeAlternative = 1U, /*!< Alternative boot */ +} sdhc_boot_mode_t; + +/*! @brief The command type */ +typedef enum _sdhc_command_type +{ + kSDHC_CommandTypeNormal = 0U, /*!< Normal command */ + kSDHC_CommandTypeSuspend = 1U, /*!< Suspend command */ + kSDHC_CommandTypeResume = 2U, /*!< Resume command */ + kSDHC_CommandTypeAbort = 3U, /*!< Abort command */ +} sdhc_command_type_t; + +/*! + * @brief The command response type. + * + * Define the command response type from card to host controller. + */ +typedef enum _sdhc_response_type +{ + kSDHC_ResponseTypeNone = 0U, /*!< Response type: none */ + kSDHC_ResponseTypeR1 = 1U, /*!< Response type: R1 */ + kSDHC_ResponseTypeR1b = 2U, /*!< Response type: R1b */ + kSDHC_ResponseTypeR2 = 3U, /*!< Response type: R2 */ + kSDHC_ResponseTypeR3 = 4U, /*!< Response type: R3 */ + kSDHC_ResponseTypeR4 = 5U, /*!< Response type: R4 */ + kSDHC_ResponseTypeR5 = 6U, /*!< Response type: R5 */ + kSDHC_ResponseTypeR5b = 7U, /*!< Response type: R5b */ + kSDHC_ResponseTypeR6 = 8U, /*!< Response type: R6 */ + kSDHC_ResponseTypeR7 = 9U, /*!< Response type: R7 */ +} sdhc_response_type_t; + +/*! @brief The alignment size for ADDRESS filed in ADMA1's descriptor */ +#define SDHC_ADMA1_ADDRESS_ALIGN (4096U) +/*! @brief The alignment size for LENGTH field in ADMA1's descriptor */ +#define SDHC_ADMA1_LENGTH_ALIGN (4096U) +/*! @brief The alignment size for ADDRESS field in ADMA2's descriptor */ +#define SDHC_ADMA2_ADDRESS_ALIGN (4U) +/*! @brief The alignment size for LENGTH filed in ADMA2's descriptor */ +#define SDHC_ADMA2_LENGTH_ALIGN (4U) + +/* ADMA1 descriptor table + * |------------------------|---------|--------------------------| + * | Address/page field |Reserved | Attribute | + * |------------------------|---------|--------------------------| + * |31 12|11 6|05 |04 |03|02 |01 |00 | + * |------------------------|---------|----|----|--|---|---|-----| + * | address or data length | 000000 |Act2|Act1| 0|Int|End|Valid| + * |------------------------|---------|----|----|--|---|---|-----| + * + * + * |------|------|-----------------|-------|-------------| + * | Act2 | Act1 | Comment | 31-28 | 27 - 12 | + * |------|------|-----------------|---------------------| + * | 0 | 0 | No op | Don't care | + * |------|------|-----------------|-------|-------------| + * | 0 | 1 | Set data length | 0000 | Data Length | + * |------|------|-----------------|-------|-------------| + * | 1 | 0 | Transfer data | Data address | + * |------|------|-----------------|---------------------| + * | 1 | 1 | Link descriptor | Descriptor address | + * |------|------|-----------------|---------------------| + */ +/*! @brief The bit shift for ADDRESS filed in ADMA1's descriptor */ +#define SDHC_ADMA1_DESCRIPTOR_ADDRESS_SHIFT (12U) +/*! @brief The bit mask for ADDRESS field in ADMA1's descriptor */ +#define SDHC_ADMA1_DESCRIPTOR_ADDRESS_MASK (0xFFFFFU) +/*! @brief The bit shift for LENGTH filed in ADMA1's descriptor */ +#define SDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT (12U) +/*! @brief The mask for LENGTH field in ADMA1's descriptor */ +#define SDHC_ADMA1_DESCRIPTOR_LENGTH_MASK (0xFFFFU) +/*! @brief The maximum value of LENGTH filed in ADMA1's descriptor */ +#define SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (SDHC_ADMA1_DESCRIPTOR_LENGTH_MASK + 1U) + +/*! @brief The mask for the control/status field in ADMA1 descriptor */ +enum _sdhc_adma1_descriptor_flag +{ + kSDHC_Adma1DescriptorValidFlag = (1U << 0U), /*!< Valid flag */ + kSDHC_Adma1DescriptorEndFlag = (1U << 1U), /*!< End flag */ + kSDHC_Adma1DescriptorInterrupFlag = (1U << 2U), /*!< Interrupt flag */ + kSDHC_Adma1DescriptorActivity1Flag = (1U << 4U), /*!< Activity 1 flag */ + kSDHC_Adma1DescriptorActivity2Flag = (1U << 5U), /*!< Activity 2 flag */ + kSDHC_Adma1DescriptorTypeNop = (kSDHC_Adma1DescriptorValidFlag), /*!< No operation */ + kSDHC_Adma1DescriptorTypeTransfer = + (kSDHC_Adma1DescriptorActivity2Flag | kSDHC_Adma1DescriptorValidFlag), /*!< Transfer data */ + kSDHC_Adma1DescriptorTypeLink = (kSDHC_Adma1DescriptorActivity1Flag | kSDHC_Adma1DescriptorActivity2Flag | + kSDHC_Adma1DescriptorValidFlag), /*!< Link descriptor */ + kSDHC_Adma1DescriptorTypeSetLength = + (kSDHC_Adma1DescriptorActivity1Flag | kSDHC_Adma1DescriptorValidFlag), /*!< Set data length */ +}; + +/* ADMA2 descriptor table + * |----------------|---------------|-------------|--------------------------| + * | Address field | Length | Reserved | Attribute | + * |----------------|---------------|-------------|--------------------------| + * |63 32|31 16|15 06|05 |04 |03|02 |01 |00 | + * |----------------|---------------|-------------|----|----|--|---|---|-----| + * | 32-bit address | 16-bit length | 0000000000 |Act2|Act1| 0|Int|End|Valid| + * |----------------|---------------|-------------|----|----|--|---|---|-----| + * + * + * | Act2 | Act1 | Comment | Operation | + * |------|------|-----------------|-------------------------------------------------------------------| + * | 0 | 0 | No op | Don't care | + * |------|------|-----------------|-------------------------------------------------------------------| + * | 0 | 1 | Reserved | Read this line and go to next one | + * |------|------|-----------------|-------------------------------------------------------------------| + * | 1 | 0 | Transfer data | Transfer data with address and length set in this descriptor line | + * |------|------|-----------------|-------------------------------------------------------------------| + * | 1 | 1 | Link descriptor | Link to another descriptor | + * |------|------|-----------------|-------------------------------------------------------------------| + */ +/*! @brief The bit shift for LENGTH field in ADMA2's descriptor */ +#define SDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT (16U) +/*! @brief The bit mask for LENGTH field in ADMA2's descriptor */ +#define SDHC_ADMA2_DESCRIPTOR_LENGTH_MASK (0xFFFFU) +/*! @brief The maximum value of LENGTH field in ADMA2's descriptor */ +#define SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (SDHC_ADMA2_DESCRIPTOR_LENGTH_MASK) + +/*! @brief ADMA1 descriptor control and status mask */ +enum _sdhc_adma2_descriptor_flag +{ + kSDHC_Adma2DescriptorValidFlag = (1U << 0U), /*!< Valid flag */ + kSDHC_Adma2DescriptorEndFlag = (1U << 1U), /*!< End flag */ + kSDHC_Adma2DescriptorInterruptFlag = (1U << 2U), /*!< Interrupt flag */ + kSDHC_Adma2DescriptorActivity1Flag = (1U << 4U), /*!< Activity 1 mask */ + kSDHC_Adma2DescriptorActivity2Flag = (1U << 5U), /*!< Activity 2 mask */ + + kSDHC_Adma2DescriptorTypeNop = (kSDHC_Adma2DescriptorValidFlag), /*!< No operation */ + kSDHC_Adma2DescriptorTypeReserved = + (kSDHC_Adma2DescriptorActivity1Flag | kSDHC_Adma2DescriptorValidFlag), /*!< Reserved */ + kSDHC_Adma2DescriptorTypeTransfer = + (kSDHC_Adma2DescriptorActivity2Flag | kSDHC_Adma2DescriptorValidFlag), /*!< Transfer type */ + kSDHC_Adma2DescriptorTypeLink = (kSDHC_Adma2DescriptorActivity1Flag | kSDHC_Adma2DescriptorActivity2Flag | + kSDHC_Adma2DescriptorValidFlag), /*!< Link type */ +}; + +/*! @brief Defines the adma1 descriptor structure. */ +typedef uint32_t sdhc_adma1_descriptor_t; + +/*! @brief Defines the ADMA2 descriptor structure. */ +typedef struct _sdhc_adma2_descriptor +{ + uint32_t attribute; /*!< The control and status field */ + const uint32_t *address; /*!< The address field */ +} sdhc_adma2_descriptor_t; + +/*! + * @brief SDHC capability information. + * + * Defines a structure to save the capability information of SDHC. + */ +typedef struct _sdhc_capability +{ + uint32_t specVersion; /*!< Specification version */ + uint32_t vendorVersion; /*!< Vendor version */ + uint32_t maxBlockLength; /*!< Maximum block length united as byte */ + uint32_t maxBlockCount; /*!< Maximum block count can be set one time */ + uint32_t flags; /*!< Capability flags to indicate the support information(_sdhc_capability_flag) */ +} sdhc_capability_t; + +/*! @brief Card transfer configuration. + * + * Define structure to configure the transfer-related command index/argument/flags and data block + * size/data block numbers. This structure needs to be filled each time a command is sent to the card. + */ +typedef struct _sdhc_transfer_config +{ + size_t dataBlockSize; /*!< Data block size */ + uint32_t dataBlockCount; /*!< Data block count */ + uint32_t commandArgument; /*!< Command argument */ + uint32_t commandIndex; /*!< Command index */ + uint32_t flags; /*!< Transfer flags(_sdhc_transfer_flag) */ +} sdhc_transfer_config_t; + +/*! @brief Data structure to configure the MMC boot feature */ +typedef struct _sdhc_boot_config +{ + uint32_t ackTimeoutCount; /*!< Timeout value for the boot ACK. The available range is 0 ~ 15. */ + sdhc_boot_mode_t bootMode; /*!< Boot mode selection. */ + uint32_t blockCount; /*!< Stop at block gap value of automatic mode. Available range is 0 ~ 65535. */ + bool enableBootAck; /*!< Enable or disable boot ACK */ + bool enableBoot; /*!< Enable or disable fast boot */ + bool enableAutoStopAtBlockGap; /*!< Enable or disable auto stop at block gap function in boot period */ +} sdhc_boot_config_t; + +/*! @brief Data structure to initialize the SDHC */ +typedef struct _sdhc_config +{ + bool cardDetectDat3; /*!< Enable DAT3 as card detection pin */ + sdhc_endian_mode_t endianMode; /*!< Endian mode */ + sdhc_dma_mode_t dmaMode; /*!< DMA mode */ + uint32_t readWatermarkLevel; /*!< Watermark level for DMA read operation. Available range is 1 ~ 128. */ + uint32_t writeWatermarkLevel; /*!< Watermark level for DMA write operation. Available range is 1 ~ 128. */ +} sdhc_config_t; + +/*! + * @brief Card data descriptor + * + * Defines a structure to contain data-related attribute. 'enableIgnoreError' is used for the case that upper card + * driver + * want to ignore the error event to read/write all the data not to stop read/write immediately when error event + * happen for example bus testing procedure for MMC card. + */ +typedef struct _sdhc_data +{ + bool enableAutoCommand12; /*!< Enable auto CMD12 */ + bool enableIgnoreError; /*!< Enable to ignore error event to read/write all the data */ + size_t blockSize; /*!< Block size */ + uint32_t blockCount; /*!< Block count */ + uint32_t *rxData; /*!< Buffer to save data read */ + const uint32_t *txData; /*!< Data buffer to write */ +} sdhc_data_t; + +/*! + * @brief Card command descriptor + * + * Define card command-related attribute. + */ +typedef struct _sdhc_command +{ + uint32_t index; /*!< Command index */ + uint32_t argument; /*!< Command argument */ + sdhc_command_type_t type; /*!< Command type */ + sdhc_response_type_t responseType; /*!< Command response type */ + uint32_t response[4U]; /*!< Response for this command */ +} sdhc_command_t; + +/*! @brief Transfer state */ +typedef struct _sdhc_transfer +{ + sdhc_data_t *data; /*!< Data to transfer */ + sdhc_command_t *command; /*!< Command to send */ +} sdhc_transfer_t; + +/*! @brief SDHC handle typedef */ +typedef struct _sdhc_handle sdhc_handle_t; + +/*! @brief SDHC callback functions. */ +typedef struct _sdhc_transfer_callback +{ + void (*CardInserted)(void); /*!< Card inserted occurs when DAT3/CD pin is for card detect */ + void (*CardRemoved)(void); /*!< Card removed occurs */ + void (*SdioInterrupt)(void); /*!< SDIO card interrupt occurs */ + void (*SdioBlockGap)(void); /*!< SDIO card stopped at block gap occurs */ + void (*TransferComplete)(SDHC_Type *base, + sdhc_handle_t *handle, + status_t status, + void *userData); /*!< Transfer complete callback */ +} sdhc_transfer_callback_t; + +/*! + * @brief SDHC handle + * + * Defines the structure to save the SDHC state information and callback function. The detailed interrupt status when + * sending a command or transfering data can be obtained from the interruptFlags field by using the mask defined in + * sdhc_interrupt_flag_t. + * + * @note All the fields except interruptFlags and transferredWords must be allocated by the user. + */ +struct _sdhc_handle +{ + /* Transfer parameter */ + sdhc_data_t *volatile data; /*!< Data to transfer */ + sdhc_command_t *volatile command; /*!< Command to send */ + + /* Transfer status */ + volatile uint32_t interruptFlags; /*!< Interrupt flags of last transaction */ + volatile uint32_t transferredWords; /*!< Words transferred by DATAPORT way */ + + /* Callback functions */ + sdhc_transfer_callback_t callback; /*!< Callback function */ + void *userData; /*!< Parameter for transfer complete callback */ +}; + +/*! @brief SDHC transfer function. */ +typedef status_t (*sdhc_transfer_function_t)(SDHC_Type *base, sdhc_transfer_t *content); + +/*! @brief SDHC host descriptor */ +typedef struct _sdhc_host +{ + SDHC_Type *base; /*!< SDHC peripheral base address */ + uint32_t sourceClock_Hz; /*!< SDHC source clock frequency united in Hz */ + sdhc_config_t config; /*!< SDHC configuration */ + sdhc_capability_t capability; /*!< SDHC capability information */ + sdhc_transfer_function_t transfer; /*!< SDHC transfer function */ +} sdhc_host_t; + +/************************************************************************************************* + * API + ************************************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief SDHC module initialization function. + * + * Configures the SDHC according to the user configuration. + * + * Example: + @code + sdhc_config_t config; + config.cardDetectDat3 = false; + config.endianMode = kSDHC_EndianModeLittle; + config.dmaMode = kSDHC_DmaModeAdma2; + config.readWatermarkLevel = 128U; + config.writeWatermarkLevel = 128U; + SDHC_Init(SDHC, &config); + @endcode + * + * @param base SDHC peripheral base address. + * @param config SDHC configuration information. + * @retval kStatus_Success Operate successfully. + */ +void SDHC_Init(SDHC_Type *base, const sdhc_config_t *config); + +/*! + * @brief Deinitializes the SDHC. + * + * @param base SDHC peripheral base address. + */ +void SDHC_Deinit(SDHC_Type *base); + +/*! + * @brief Resets the SDHC. + * + * @param base SDHC peripheral base address. + * @param mask The reset type mask(_sdhc_reset). + * @param timeout Timeout for reset. + * @retval true Reset successfully. + * @retval false Reset failed. + */ +bool SDHC_Reset(SDHC_Type *base, uint32_t mask, uint32_t timeout); + +/* @} */ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Sets the ADMA descriptor table configuration. + * + * @param base SDHC peripheral base address. + * @param dmaMode DMA mode. + * @param table ADMA table address. + * @param tableWords ADMA table buffer length united as Words. + * @param data Data buffer address. + * @param dataBytes Data length united as bytes. + * @retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. + * @retval kStatus_Success Operate successfully. + */ +status_t SDHC_SetAdmaTableConfig(SDHC_Type *base, + sdhc_dma_mode_t dmaMode, + uint32_t *table, + uint32_t tableWords, + const uint32_t *data, + uint32_t dataBytes); + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the interrupt status. + * + * @param base SDHC peripheral base address. + * @param mask Interrupt status flags mask(_sdhc_interrupt_status_flag). + */ +static inline void SDHC_EnableInterruptStatus(SDHC_Type *base, uint32_t mask) +{ + base->IRQSTATEN |= mask; +} + +/*! + * @brief Disables the interrupt status. + * + * @param base SDHC peripheral base address. + * @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag). + */ +static inline void SDHC_DisableInterruptStatus(SDHC_Type *base, uint32_t mask) +{ + base->IRQSTATEN &= ~mask; +} + +/*! + * @brief Enables the interrupt signal corresponding to the interrupt status flag. + * + * @param base SDHC peripheral base address. + * @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag). + */ +static inline void SDHC_EnableInterruptSignal(SDHC_Type *base, uint32_t mask) +{ + base->IRQSIGEN |= mask; +} + +/*! + * @brief Disables the interrupt signal corresponding to the interrupt status flag. + * + * @param base SDHC peripheral base address. + * @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag). + */ +static inline void SDHC_DisableInterruptSignal(SDHC_Type *base, uint32_t mask) +{ + base->IRQSIGEN &= ~mask; +} + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the current interrupt status. + * + * @param base SDHC peripheral base address. + * @return Current interrupt status flags mask(_sdhc_interrupt_status_flag). + */ +static inline uint32_t SDHC_GetInterruptStatusFlags(SDHC_Type *base) +{ + return base->IRQSTAT; +} + +/*! + * @brief Clears a specified interrupt status. + * + * @param base SDHC peripheral base address. + * @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag). + */ +static inline void SDHC_ClearInterruptStatusFlags(SDHC_Type *base, uint32_t mask) +{ + base->IRQSTAT = mask; +} + +/*! + * @brief Gets the status of auto command 12 error. + * + * @param base SDHC peripheral base address. + * @return Auto command 12 error status flags mask(_sdhc_auto_command12_error_status_flag). + */ +static inline uint32_t SDHC_GetAutoCommand12ErrorStatusFlags(SDHC_Type *base) +{ + return base->AC12ERR; +} + +/*! + * @brief Gets the status of the ADMA error. + * + * @param base SDHC peripheral base address. + * @return ADMA error status flags mask(_sdhc_adma_error_status_flag). + */ +static inline uint32_t SDHC_GetAdmaErrorStatusFlags(SDHC_Type *base) +{ + return base->ADMAES; +} + +/*! + * @brief Gets a present status. + * + * This function gets the present SDHC's status except for an interrupt status and an error status. + * + * @param base SDHC peripheral base address. + * @return Present SDHC's status flags mask(_sdhc_present_status_flag). + */ +static inline uint32_t SDHC_GetPresentStatusFlags(SDHC_Type *base) +{ + return base->PRSSTAT; +} + +/* @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Gets the capability information. + * + * @param base SDHC peripheral base address. + * @param capability Structure to save capability information. + */ +void SDHC_GetCapability(SDHC_Type *base, sdhc_capability_t *capability); + +/*! + * @brief Enables or disables the SD bus clock. + * + * @param base SDHC peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void SDHC_EnableSdClock(SDHC_Type *base, bool enable) +{ + if (enable) + { + base->SYSCTL |= SDHC_SYSCTL_SDCLKEN_MASK; + } + else + { + base->SYSCTL &= ~SDHC_SYSCTL_SDCLKEN_MASK; + } +} + +/*! + * @brief Sets the SD bus clock frequency. + * + * @param base SDHC peripheral base address. + * @param srcClock_Hz SDHC source clock frequency united in Hz. + * @param busClock_Hz SD bus clock frequency united in Hz. + * + * @return The nearest frequency of busClock_Hz configured to SD bus. + */ +uint32_t SDHC_SetSdClock(SDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz); + +/*! + * @brief Sends 80 clocks to the card to set it to the active state. + * + * This function must be called each time the card is inserted to ensure that the card can receive the command + * correctly. + * + * @param base SDHC peripheral base address. + * @param timeout Timeout to initialize card. + * @retval true Set card active successfully. + * @retval false Set card active failed. + */ +bool SDHC_SetCardActive(SDHC_Type *base, uint32_t timeout); + +/*! + * @brief Sets the data transfer width. + * + * @param base SDHC peripheral base address. + * @param width Data transfer width. + */ +static inline void SDHC_SetDataBusWidth(SDHC_Type *base, sdhc_data_bus_width_t width) +{ + base->PROCTL = ((base->PROCTL & ~SDHC_PROCTL_DTW_MASK) | SDHC_PROCTL_DTW(width)); +} + +/*! + * @brief Sets the card transfer-related configuration. + * + * This function fills the card transfer-related command argument/transfer flag/data size. The command and data are sent + by + * SDHC after calling this function. + * + * Example: + @code + sdhc_transfer_config_t transferConfig; + transferConfig.dataBlockSize = 512U; + transferConfig.dataBlockCount = 2U; + transferConfig.commandArgument = 0x01AAU; + transferConfig.commandIndex = 8U; + transferConfig.flags |= (kSDHC_EnableDmaFlag | kSDHC_EnableAutoCommand12Flag | kSDHC_MultipleBlockFlag); + SDHC_SetTransferConfig(SDHC, &transferConfig); + @endcode + * + * @param base SDHC peripheral base address. + * @param config Command configuration structure. + */ +void SDHC_SetTransferConfig(SDHC_Type *base, const sdhc_transfer_config_t *config); + +/*! + * @brief Gets the command response. + * + * @param base SDHC peripheral base address. + * @param index The index of response register, range from 0 to 3. + * @return Response register transfer. + */ +static inline uint32_t SDHC_GetCommandResponse(SDHC_Type *base, uint32_t index) +{ + assert(index < 4U); + + return base->CMDRSP[index]; +} + +/*! + * @brief Fills the the data port. + * + * This function is used to implement the data transfer by Data Port instead of DMA. + * + * @param base SDHC peripheral base address. + * @param data The data about to be sent. + */ +static inline void SDHC_WriteData(SDHC_Type *base, uint32_t data) +{ + base->DATPORT = data; +} + +/*! + * @brief Retrieves the data from the data port. + * + * This function is used to implement the data transfer by Data Port instead of DMA. + * + * @param base SDHC peripheral base address. + * @return The data has been read. + */ +static inline uint32_t SDHC_ReadData(SDHC_Type *base) +{ + return base->DATPORT; +} + +/*! + * @brief Enables or disables a wakeup event in low-power mode. + * + * @param base SDHC peripheral base address. + * @param mask Wakeup events mask(_sdhc_wakeup_event). + * @param enable True to enable, false to disable. + */ +static inline void SDHC_EnableWakeupEvent(SDHC_Type *base, uint32_t mask, bool enable) +{ + if (enable) + { + base->PROCTL |= mask; + } + else + { + base->PROCTL &= ~mask; + } +} + +/*! + * @brief Enables or disables the card detection level for testing. + * + * @param base SDHC peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void SDHC_EnableCardDetectTest(SDHC_Type *base, bool enable) +{ + if (enable) + { + base->PROCTL |= SDHC_PROCTL_CDSS_MASK; + } + else + { + base->PROCTL &= ~SDHC_PROCTL_CDSS_MASK; + } +} + +/*! + * @brief Sets the card detection test level. + * + * This function sets the card detection test level to indicate whether the card is inserted into the SDHC when DAT[3]/ + * CD pin is selected as a card detection pin. This function can also assert the pin logic when DAT[3]/CD pin is + * selected + * as the card detection pin. + * + * @param base SDHC peripheral base address. + * @param high True to set the card detect level to high. + */ +static inline void SDHC_SetCardDetectTestLevel(SDHC_Type *base, bool high) +{ + if (high) + { + base->PROCTL |= SDHC_PROCTL_CDTL_MASK; + } + else + { + base->PROCTL &= ~SDHC_PROCTL_CDTL_MASK; + } +} + +/*! + * @brief Enables or disables the SDIO card control. + * + * @param base SDHC peripheral base address. + * @param mask SDIO card control flags mask(_sdhc_sdio_control_flag). + * @param enable True to enable, false to disable. + */ +void SDHC_EnableSdioControl(SDHC_Type *base, uint32_t mask, bool enable); + +/*! + * @brief Restarts a transaction which has stopped at the block GAP for the SDIO card. + * + * @param base SDHC peripheral base address. + */ +static inline void SDHC_SetContinueRequest(SDHC_Type *base) +{ + base->PROCTL |= SDHC_PROCTL_CREQ_MASK; +} + +/*! + * @brief Configures the MMC boot feature. + * + * Example: + @code + sdhc_boot_config_t config; + config.ackTimeoutCount = 4; + config.bootMode = kSDHC_BootModeNormal; + config.blockCount = 5; + config.enableBootAck = true; + config.enableBoot = true; + config.enableAutoStopAtBlockGap = true; + SDHC_SetMmcBootConfig(SDHC, &config); + @endcode + * + * @param base SDHC peripheral base address. + * @param config The MMC boot configuration information. + */ +void SDHC_SetMmcBootConfig(SDHC_Type *base, const sdhc_boot_config_t *config); + +/*! + * @brief Forces generating events according to the given mask. + * + * @param base SDHC peripheral base address. + * @param mask The force events mask(_sdhc_force_event). + */ +static inline void SDHC_SetForceEvent(SDHC_Type *base, uint32_t mask) +{ + base->FEVT = mask; +} + +/* @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Transfers the command/data using a blocking method. + * + * This function waits until the command response/data is received or the SDHC encounters an error by polling the status + * flag. + * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support + * the re-entry mechanism. + * + * @note There is no need to call the API 'SDHC_TransferCreateHandle' when calling this API. + * + * @param base SDHC peripheral base address. + * @param admaTable ADMA table address, can't be null if transfer way is ADMA1/ADMA2. + * @param admaTableWords ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2. + * @param transfer Transfer content. + * @retval kStatus_InvalidArgument Argument is invalid. + * @retval kStatus_SDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed. + * @retval kStatus_SDHC_SendCommandFailed Send command failed. + * @retval kStatus_SDHC_TransferDataFailed Transfer data failed. + * @retval kStatus_Success Operate successfully. + */ +status_t SDHC_TransferBlocking(SDHC_Type *base, + uint32_t *admaTable, + uint32_t admaTableWords, + sdhc_transfer_t *transfer); + +/*! + * @brief Creates the SDHC handle. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle pointer. + * @param callback Structure pointer to contain all callback functions. + * @param userData Callback function parameter. + */ +void SDHC_TransferCreateHandle(SDHC_Type *base, + sdhc_handle_t *handle, + const sdhc_transfer_callback_t *callback, + void *userData); + +/*! + * @brief Transfers the command/data using an interrupt and an asynchronous method. + * + * This function sends a command and data and returns immediately. It doesn't wait the transfer complete or encounter an + * error. + * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support + * the re-entry mechanism. + * + * @note Call the API 'SDHC_TransferCreateHandle' when calling this API. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle. + * @param admaTable ADMA table address, can't be null if transfer way is ADMA1/ADMA2. + * @param admaTableWords ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2. + * @param transfer Transfer content. + * @retval kStatus_InvalidArgument Argument is invalid. + * @retval kStatus_SDHC_BusyTransferring Busy transferring. + * @retval kStatus_SDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed. + * @retval kStatus_Success Operate successfully. + */ +status_t SDHC_TransferNonBlocking( + SDHC_Type *base, sdhc_handle_t *handle, uint32_t *admaTable, uint32_t admaTableWords, sdhc_transfer_t *transfer); + +/*! + * @brief IRQ handler for the SDHC. + * + * This function deals with the IRQs on the given host controller. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle. + */ +void SDHC_TransferHandleIRQ(SDHC_Type *base, sdhc_handle_t *handle); + +/* @} */ + +#if defined(__cplusplus) +} +#endif +/*! @} */ + +#endif /* _FSL_SDHC_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdramc.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdramc.c new file mode 100644 index 00000000000..db4146385d5 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdramc.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_sdramc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Define macros for SDRAM driver. */ +#define SDRAMC_ONEMILLSEC_NANOSECONDS (1000000U) +#define SDRAMC_ONESECOND_MILLISECONDS (1000U) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get instance number for SDRAMC module. + * + * @param base SDRAMC peripheral base address + */ +static uint32_t SDRAMC_GetInstance(SDRAM_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to SDRAMC clocks for each instance. */ +static const clock_ip_name_t s_sdramClock[FSL_FEATURE_SOC_SDRAM_COUNT] = SDRAM_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Pointers to SDRAMC bases for each instance. */ +static SDRAM_Type *const s_sdramcBases[] = SDRAM_BASE_PTRS; +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t SDRAMC_GetInstance(SDRAM_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_SDRAM_COUNT; instance++) + { + if (s_sdramcBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_SDRAM_COUNT); + + return instance; +} + +void SDRAMC_Init(SDRAM_Type *base, sdramc_config_t *configure) +{ + assert(configure); + assert(configure->refreshConfig); + assert(configure->blockConfig); + assert(configure->refreshConfig->busClock_Hz); + + sdramc_blockctl_config_t *bctlConfig = configure->blockConfig; + sdramc_refresh_config_t *refreshConfig = configure->refreshConfig; + uint32_t count; + uint32_t index; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Un-gate sdram controller clock. */ + CLOCK_EnableClock(s_sdramClock[SDRAMC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Initialize sdram Auto refresh timing. */ + count = refreshConfig->sdramRefreshRow * (refreshConfig->busClock_Hz / SDRAMC_ONESECOND_MILLISECONDS); + count = (count / SDRAMC_ONEMILLSEC_NANOSECONDS) / 16 - 1; + base->CTRL = SDRAM_CTRL_RC(count) | SDRAM_CTRL_RTIM(refreshConfig->refreshTime); + + for (index = 0; index < configure->numBlockConfig; index++) + { + /* Set the sdram block control. */ + base->BLOCK[index].AC = SDRAM_AC_PS(bctlConfig->portSize) | SDRAM_AC_CASL(bctlConfig->latency) | + SDRAM_AC_CBM(bctlConfig->location) | (bctlConfig->address & SDRAM_AC_BA_MASK); + + base->BLOCK[index].CM = (bctlConfig->addressMask & SDRAM_CM_BAM_MASK) | SDRAM_CM_V_MASK; + + /* Increases to the next sdram block. */ + bctlConfig++; + } +} + +void SDRAMC_Deinit(SDRAM_Type *base) +{ + /* Set the SDRAMC invalid, do not decode DRAM accesses. */ + SDRAMC_EnableOperateValid(base, kSDRAMC_Block0, false); + SDRAMC_EnableOperateValid(base, kSDRAMC_Block1, false); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable SDRAM clock. */ + CLOCK_DisableClock(s_sdramClock[SDRAMC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void SDRAMC_SendCommand(SDRAM_Type *base, sdramc_block_selection_t block, sdramc_command_t command) +{ + switch (command) + { + /* Initiate mrs command. */ + case kSDRAMC_ImrsCommand: + base->BLOCK[block].AC |= SDRAM_AC_IMRS_MASK; + break; + /* Initiate precharge command. */ + case kSDRAMC_PrechargeCommand: + base->BLOCK[block].AC |= SDRAM_AC_IP_MASK; + break; + /* Enable Auto refresh command. */ + case kSDRAMC_AutoRefreshEnableCommand: + base->BLOCK[block].AC |= SDRAM_AC_RE_MASK; + break; + /* Disable Auto refresh command. */ + case kSDRAMC_AutoRefreshDisableCommand: + base->BLOCK[block].AC &= ~SDRAM_AC_RE_MASK; + break; + /* Enter self-refresh command. */ + case kSDRAMC_SelfrefreshEnterCommand: + base->CTRL |= SDRAM_CTRL_IS_MASK; + break; + /* Exit self-refresh command. */ + case kSDRAMC_SelfrefreshExitCommand: + base->CTRL &= ~SDRAM_CTRL_IS_MASK; + break; + default: + break; + } +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdramc.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdramc.h new file mode 100644 index 00000000000..adf8a0c2c5a --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sdramc.h @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_SDRAMC_H_ +#define _FSL_SDRAMC_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup sdramc + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief SDRAMC driver version 2.1.0. */ +#define FSL_SDRAMC_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ + +/*! @brief SDRAM controller auto-refresh timing. */ +typedef enum _sdramc_refresh_time +{ + kSDRAMC_RefreshThreeClocks = 0x0U, /*!< The refresh timing with three bus clocks. */ + kSDRAMC_RefreshSixClocks, /*!< The refresh timing with six bus clocks. */ + kSDRAMC_RefreshNineClocks /*!< The refresh timing with nine bus clocks. */ +} sdramc_refresh_time_t; + +/*! + * @brief Setting latency for SDRAM controller timing specifications. + * + * The latency setting affects the following SDRAM timing specifications: + * - trcd: SRAS assertion to SCAS assertion \n + * - tcasl: SCAS assertion to data out \n + * - tras: ACTV command to Precharge command \n + * - trp: Precharge command to ACTV command \n + * - trwl, trdl: Last data input to Precharge command \n + * - tep: Last data out to Precharge command \n + * The details of the latency setting and timing specifications are shown in the following table list. \n + * latency trcd: tcasl tras trp trwl,trdl tep \n + * 0 1 bus clock 1 bus clock 2 bus clocks 1 bus clock 1 bus clock 1 bus clock \n + * 1 2 bus clock 2 bus clock 4 bus clocks 2 bus clock 1 bus clock 1 bus clock \n + * 2 3 bus clock 3 bus clock 6 bus clocks 3 bus clock 1 bus clock 1 bus clock \n + * 3 3 bus clock 3 bus clock 6 bus clocks 3 bus clock 1 bus clock 1 bus clock \n + */ +typedef enum _sdramc_latency +{ + kSDRAMC_LatencyZero = 0x0U, /*!< Latency 0. */ + kSDRAMC_LatencyOne, /*!< Latency 1. */ + kSDRAMC_LatencyTwo, /*!< Latency 2. */ + kSDRAMC_LatencyThree, /*!< Latency 3. */ +} sdramc_latency_t; + +/*! @brief SDRAM controller command bit location. */ +typedef enum _sdramc_command_bit_location +{ + kSDRAMC_Commandbit17 = 0x0U, /*!< Command bit location is bit 17. */ + kSDRAMC_Commandbit18, /*!< Command bit location is bit 18. */ + kSDRAMC_Commandbit19, /*!< Command bit location is bit 19. */ + kSDRAMC_Commandbit20, /*!< Command bit location is bit 20. */ + kSDRAMC_Commandbit21, /*!< Command bit location is bit 21. */ + kSDRAMC_Commandbit22, /*!< Command bit location is bit 22. */ + kSDRAMC_Commandbit23, /*!< Command bit location is bit 23. */ + kSDRAMC_Commandbit24 /*!< Command bit location is bit 24. */ +} sdramc_command_bit_location_t; + +/*! @brief SDRAM controller command. */ +typedef enum _sdramc_command +{ + kSDRAMC_ImrsCommand = 0x0U, /*!< Initiate MRS command. */ + kSDRAMC_PrechargeCommand, /*!< Initiate precharge command. */ + kSDRAMC_SelfrefreshEnterCommand, /*!< Enter self-refresh command. */ + kSDRAMC_SelfrefreshExitCommand, /*!< Exit self-refresh command. */ + kSDRAMC_AutoRefreshEnableCommand, /*!< Enable Auto refresh command. */ + kSDRAMC_AutoRefreshDisableCommand, /*!< Disable Auto refresh command. */ +} sdramc_command_t; + +/*! @brief SDRAM port size. */ +typedef enum _sdramc_port_size +{ + kSDRAMC_PortSize32Bit = 0x0U, /*!< 32-Bit port size. */ + kSDRAMC_PortSize8Bit, /*!< 8-Bit port size. */ + kSDRAMC_PortSize16Bit /*!< 16-Bit port size. */ +} sdramc_port_size_t; + +/*! @brief SDRAM controller block selection. */ +typedef enum _sdramc_block_selection +{ + kSDRAMC_Block0 = 0x0U, /*!< Select SDRAM block 0. */ + kSDRAMC_Block1, /*!< Select SDRAM block 1. */ +} sdramc_block_selection_t; + +/*! @brief SDRAM controller block control configuration structure. */ +typedef struct _sdramc_blockctl_config +{ + sdramc_block_selection_t block; /*!< The block number. */ + sdramc_port_size_t portSize; /*!< The port size of the associated SDRAM block. */ + sdramc_command_bit_location_t location; /*!< The command bit location. */ + sdramc_latency_t latency; /*!< The latency for some timing specifications. */ + uint32_t address; /*!< The base address of the SDRAM block. */ + uint32_t addressMask; /*!< The base address mask of the SDRAM block. */ +} sdramc_blockctl_config_t; + +/*! @brief SDRAM controller refresh timing configuration structure. */ +typedef struct _sdramc_refresh_config +{ + sdramc_refresh_time_t refreshTime; /*!< Trc:The number of bus clocks inserted + between a REF and next ACTIVE command. */ + uint32_t sdramRefreshRow; /*!< The SDRAM refresh time each row: ns/row. */ + uint32_t busClock_Hz; /*!< The bus clock for SDRAMC. */ +} sdramc_refresh_config_t; + +/*! + * @brief SDRAM controller configuration structure. + * + * Defines a configure structure and uses the SDRAMC_Configure() function to make necessary + * initializations. + */ +typedef struct _sdramc_config_t +{ + sdramc_refresh_config_t *refreshConfig; /*!< Refresh timing configure structure pointer. */ + sdramc_blockctl_config_t *blockConfig; /*!< Block configure structure pointer. If both SDRAM + blocks are used, use the two continuous blockConfig. */ + uint8_t numBlockConfig; /*!< SDRAM block numbers for configuration. */ +} sdramc_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name SDRAM Controller Initialization and De-initialization + * @{ + */ + +/*! + * @brief Initializes the SDRAM controller. + * This function ungates the SDRAM controller clock and initializes the SDRAM controller. + * This function must be called before calling any other SDRAM controller driver functions. + * Example + @code + sdramc_refresh_config_t refreshConfig; + sdramc_blockctl_config_t blockConfig; + sdramc_config_t config; + + refreshConfig.refreshTime = kSDRAM_RefreshThreeClocks; + refreshConfig.sdramRefreshRow = 15625; + refreshConfig.busClock = 60000000; + + blockConfig.block = kSDRAMC_Block0; + blockConfig.portSize = kSDRAMC_PortSize16Bit; + blockConfig.location = kSDRAMC_Commandbit19; + blockConfig.latency = kSDRAMC_RefreshThreeClocks; + blockConfig.address = SDRAM_START_ADDRESS; + blockConfig.addressMask = 0x7c0000; + + config.refreshConfig = &refreshConfig, + config.blockConfig = &blockConfig, + config.totalBlocks = 1; + + SDRAMC_Init(SDRAM, &config); + @endcode + * + * @param base SDRAM controller peripheral base address. + * @param configure The SDRAM configuration structure pointer. + */ +void SDRAMC_Init(SDRAM_Type *base, sdramc_config_t *configure); + +/*! + * @brief Deinitializes the SDRAM controller module and gates the clock. + * This function gates the SDRAM controller clock. As a result, the SDRAM + * controller module doesn't work after calling this function. + * + * @param base SDRAM controller peripheral base address. + */ +void SDRAMC_Deinit(SDRAM_Type *base); + +/* @} */ + +/*! + * @name SDRAM Controller Basic Operation + * @{ + */ + +/*! + * @brief Sends the SDRAM command. + * This function sends commands to SDRAM. The commands are precharge command, initialization MRS command, + * auto-refresh enable/disable command, and self-refresh enter/exit commands. + * Note that the self-refresh enter/exit commands are all blocks setting and "block" + * is ignored. Ensure to set the correct "block" when send other commands. + * + * @param base SDRAM controller peripheral base address. + * @param block The block selection. + * @param command The SDRAM command, see "sdramc_command_t". + * kSDRAMC_ImrsCommand - Initialize MRS command \n + * kSDRAMC_PrechargeCommand - Initialize precharge command \n + * kSDRAMC_SelfrefreshEnterCommand - Enter self-refresh command \n + * kSDRAMC_SelfrefreshExitCommand - Exit self-refresh command \n + * kSDRAMC_AutoRefreshEnableCommand - Enable auto refresh command \n + * kSDRAMC_AutoRefreshDisableCommand - Disable auto refresh command + */ +void SDRAMC_SendCommand(SDRAM_Type *base, sdramc_block_selection_t block, sdramc_command_t command); + +/*! + * @brief Enables/disables the write protection. + * + * @param base SDRAM peripheral base address. + * @param block The block which is selected. + * @param enable True enable write protection, false disable write protection. + */ +static inline void SDRAMC_EnableWriteProtect(SDRAM_Type *base, sdramc_block_selection_t block, bool enable) +{ + if (enable) + { + base->BLOCK[block].CM |= SDRAM_CM_WP_MASK; + } + else + { + base->BLOCK[block].CM &= ~SDRAM_CM_WP_MASK; + } +} + +/*! + * @brief Enables/disables the valid operation. + * + * @param base SDRAM peripheral base address. + * @param block The block which is selected. + * @param enable True enable the valid operation; false disable the valid operation. + */ +static inline void SDRAMC_EnableOperateValid(SDRAM_Type *base, sdramc_block_selection_t block, bool enable) +{ + if (enable) + { + base->BLOCK[block].CM |= SDRAM_CM_V_MASK; + } + else + { + base->BLOCK[block].CM &= ~SDRAM_CM_V_MASK; + } +} + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_SDRAMC_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sim.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sim.c new file mode 100644 index 00000000000..3a4b801b7b3 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sim.c @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "fsl_sim.h" + +/******************************************************************************* + * Codes + ******************************************************************************/ +#if (defined(FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) && FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) +void SIM_SetUsbVoltRegulatorEnableMode(uint32_t mask) +{ + SIM->SOPT1CFG |= (SIM_SOPT1CFG_URWE_MASK | SIM_SOPT1CFG_UVSWE_MASK | SIM_SOPT1CFG_USSWE_MASK); + + SIM->SOPT1 = (SIM->SOPT1 & ~kSIM_UsbVoltRegEnableInAllModes) | mask; +} +#endif /* FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR */ + +void SIM_GetUniqueId(sim_uid_t *uid) +{ +#if defined(SIM_UIDH) + uid->H = SIM->UIDH; +#endif + uid->MH = SIM->UIDMH; + uid->ML = SIM->UIDML; + uid->L = SIM->UIDL; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sim.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sim.h new file mode 100644 index 00000000000..c12b5bf2e1b --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_sim.h @@ -0,0 +1,127 @@ +/* +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _FSL_SIM_H_ +#define _FSL_SIM_H_ + +#include "fsl_common.h" + +/*! @addtogroup sim */ +/*! @{*/ + + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_SIM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Driver version 2.0.0 */ +/*@}*/ + +#if (defined(FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) && FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) +/*!@brief USB voltage regulator enable setting. */ +enum _sim_usb_volt_reg_enable_mode +{ + kSIM_UsbVoltRegEnable = SIM_SOPT1_USBREGEN_MASK, /*!< Enable voltage regulator. */ + kSIM_UsbVoltRegEnableInLowPower = SIM_SOPT1_USBVSTBY_MASK, /*!< Enable voltage regulator in VLPR/VLPW modes. */ + kSIM_UsbVoltRegEnableInStop = SIM_SOPT1_USBSSTBY_MASK, /*!< Enable voltage regulator in STOP/VLPS/LLS/VLLS modes. */ + kSIM_UsbVoltRegEnableInAllModes = SIM_SOPT1_USBREGEN_MASK | SIM_SOPT1_USBSSTBY_MASK | + SIM_SOPT1_USBVSTBY_MASK /*!< Enable voltage regulator in all power modes. */ +}; +#endif /* (defined(FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) && FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) */ + +/*!@brief Unique ID. */ +typedef struct _sim_uid +{ +#if defined(SIM_UIDH) + uint32_t H; /*!< UIDH. */ +#endif + uint32_t MH; /*!< UIDMH. */ + uint32_t ML; /*!< UIDML. */ + uint32_t L; /*!< UIDL. */ +} sim_uid_t; + +/*!@brief Flash enable mode. */ +enum _sim_flash_mode +{ + kSIM_FlashDisableInWait = SIM_FCFG1_FLASHDOZE_MASK, /*!< Disable flash in wait mode. */ + kSIM_FlashDisable = SIM_FCFG1_FLASHDIS_MASK /*!< Disable flash in normal mode. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +#if (defined(FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) && FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) +/*! + * @brief Sets the USB voltage regulator setting. + * + * This function configures whether the USB voltage regulator is enabled in + * normal RUN mode, STOP/VLPS/LLS/VLLS modes, and VLPR/VLPW modes. The configurations + * are passed in as mask value of \ref _sim_usb_volt_reg_enable_mode. For example, to enable + * USB voltage regulator in RUN/VLPR/VLPW modes and disable in STOP/VLPS/LLS/VLLS mode, + * use: + * + * SIM_SetUsbVoltRegulatorEnableMode(kSIM_UsbVoltRegEnable | kSIM_UsbVoltRegEnableInLowPower); + * + * @param mask USB voltage regulator enable setting. + */ +void SIM_SetUsbVoltRegulatorEnableMode(uint32_t mask); +#endif /* FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR */ + +/*! + * @brief Gets the unique identification register value. + * + * @param uid Pointer to the structure to save the UID value. + */ +void SIM_GetUniqueId(sim_uid_t *uid); + +/*! + * @brief Sets the flash enable mode. + * + * @param mode The mode to set; see \ref _sim_flash_mode for mode details. + */ +static inline void SIM_SetFlashMode(uint8_t mode) +{ + SIM->FCFG1 = mode; +} + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/*! @}*/ + +#endif /* _FSL_SIM_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard.h new file mode 100644 index 00000000000..c7e9bef6e75 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard.h @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_SMARTCARD_H_ +#define _FSL_SMARTCARD_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup smartcard + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief Smart card driver version 2.1.2. + */ +#define FSL_SMARTCARD_DRIVER_VERSION (MAKE_VERSION(2, 1, 2)) +/*@}*/ + +/*! @brief Smart card global define which specify number of clock cycles until initial 'TS' character has to be received + */ +#define SMARTCARD_INIT_DELAY_CLOCK_CYCLES (42000u) + +/*! @brief Smart card global define which specify number of clock cycles during which ATR string has to be received */ +#define SMARTCARD_EMV_ATR_DURATION_ETU (20150u) + +/*! @brief Smart card specification initial TS character definition of direct convention */ +#define SMARTCARD_TS_DIRECT_CONVENTION (0x3Bu) + +/*! @brief Smart card specification initial TS character definition of inverse convention */ +#define SMARTCARD_TS_INVERSE_CONVENTION (0x3Fu) + +/*! @brief Smart card Error codes. */ +typedef enum _smartcard_status +{ + kStatus_SMARTCARD_Success = MAKE_STATUS(kStatusGroup_SMARTCARD, 0), /*!< Transfer ends successfully */ + kStatus_SMARTCARD_TxBusy = MAKE_STATUS(kStatusGroup_SMARTCARD, 1), /*!< Transmit in progress */ + kStatus_SMARTCARD_RxBusy = MAKE_STATUS(kStatusGroup_SMARTCARD, 2), /*!< Receiving in progress */ + kStatus_SMARTCARD_NoTransferInProgress = MAKE_STATUS(kStatusGroup_SMARTCARD, 3), /*!< No transfer in progress */ + kStatus_SMARTCARD_Timeout = MAKE_STATUS(kStatusGroup_SMARTCARD, 4), /*!< Transfer ends with time-out */ + kStatus_SMARTCARD_Initialized = + MAKE_STATUS(kStatusGroup_SMARTCARD, 5), /*!< Smart card driver is already initialized */ + kStatus_SMARTCARD_PhyInitialized = + MAKE_STATUS(kStatusGroup_SMARTCARD, 6), /*!< Smart card PHY drive is already initialized */ + kStatus_SMARTCARD_CardNotActivated = MAKE_STATUS(kStatusGroup_SMARTCARD, 7), /*!< Smart card is not activated */ + kStatus_SMARTCARD_InvalidInput = + MAKE_STATUS(kStatusGroup_SMARTCARD, 8), /*!< Function called with invalid input arguments */ + kStatus_SMARTCARD_OtherError = MAKE_STATUS(kStatusGroup_SMARTCARD, 9) /*!< Some other error occur */ +} smartcard_status_t; + +/*! @brief Control codes for the Smart card protocol timers and misc. */ +typedef enum _smartcard_control +{ + kSMARTCARD_EnableADT = 0x0u, + kSMARTCARD_DisableADT = 0x1u, + kSMARTCARD_EnableGTV = 0x2u, + kSMARTCARD_DisableGTV = 0x3u, + kSMARTCARD_ResetWWT = 0x4u, + kSMARTCARD_EnableWWT = 0x5u, + kSMARTCARD_DisableWWT = 0x6u, + kSMARTCARD_ResetCWT = 0x7u, + kSMARTCARD_EnableCWT = 0x8u, + kSMARTCARD_DisableCWT = 0x9u, + kSMARTCARD_ResetBWT = 0xAu, + kSMARTCARD_EnableBWT = 0xBu, + kSMARTCARD_DisableBWT = 0xCu, + kSMARTCARD_EnableInitDetect = 0xDu, + kSMARTCARD_EnableAnack = 0xEu, + kSMARTCARD_DisableAnack = 0xFu, + kSMARTCARD_ConfigureBaudrate = 0x10u, + kSMARTCARD_SetupATRMode = 0x11u, + kSMARTCARD_SetupT0Mode = 0x12u, + kSMARTCARD_SetupT1Mode = 0x13u, + kSMARTCARD_EnableReceiverMode = 0x14u, + kSMARTCARD_DisableReceiverMode = 0x15u, + kSMARTCARD_EnableTransmitterMode = 0x16u, + kSMARTCARD_DisableTransmitterMode = 0x17u, + kSMARTCARD_ResetWaitTimeMultiplier = 0x18u, +} smartcard_control_t; + +/*! @brief Defines Smart card interface voltage class values */ +typedef enum _smartcard_card_voltage_class +{ + kSMARTCARD_VoltageClassUnknown = 0x0u, + kSMARTCARD_VoltageClassA5_0V = 0x1u, + kSMARTCARD_VoltageClassB3_3V = 0x2u, + kSMARTCARD_VoltageClassC1_8V = 0x3u +} smartcard_card_voltage_class_t; + +/*! @brief Defines Smart card I/O transfer states */ +typedef enum _smartcard_transfer_state +{ + kSMARTCARD_IdleState = 0x0u, + kSMARTCARD_WaitingForTSState = 0x1u, + kSMARTCARD_InvalidTSDetecetedState = 0x2u, + kSMARTCARD_ReceivingState = 0x3u, + kSMARTCARD_TransmittingState = 0x4u, +} smartcard_transfer_state_t; + +/*! @brief Defines Smart card reset types */ +typedef enum _smartcard_reset_type +{ + kSMARTCARD_ColdReset = 0x0u, + kSMARTCARD_WarmReset = 0x1u, + kSMARTCARD_NoColdReset = 0x2u, + kSMARTCARD_NoWarmReset = 0x3u, +} smartcard_reset_type_t; + +/*! @brief Defines Smart card transport protocol types */ +typedef enum _smartcard_transport_type +{ + kSMARTCARD_T0Transport = 0x0u, + kSMARTCARD_T1Transport = 0x1u +} smartcard_transport_type_t; + +/*! @brief Defines Smart card data parity types */ +typedef enum _smartcard_parity_type +{ + kSMARTCARD_EvenParity = 0x0u, + kSMARTCARD_OddParity = 0x1u +} smartcard_parity_type_t; + +/*! @brief Defines data Convention format */ +typedef enum _smartcard_card_convention +{ + kSMARTCARD_DirectConvention = 0x0u, + kSMARTCARD_InverseConvention = 0x1u +} smartcard_card_convention_t; + +/*! @brief Defines Smart card interface IC control types */ +typedef enum _smartcard_interface_control +{ + kSMARTCARD_InterfaceSetVcc = 0x00u, + kSMARTCARD_InterfaceSetClockToResetDelay = 0x01u, + kSMARTCARD_InterfaceReadStatus = 0x02u +} smartcard_interface_control_t; + +/*! @brief Defines transfer direction.*/ +typedef enum _smartcard_direction +{ + kSMARTCARD_Receive = 0u, + kSMARTCARD_Transmit = 1u +} smartcard_direction_t; + +/*! @brief Smart card interface interrupt callback function type */ +typedef void (*smartcard_interface_callback_t)(void *smartcardContext, void *param); +/*! @brief Smart card transfer interrupt callback function type */ +typedef void (*smartcard_transfer_callback_t)(void *smartcardContext, void *param); + +/*! @brief Time Delay function used to passive waiting using RTOS [us] */ +typedef void (*smartcard_time_delay_t)(uint32_t us); + +/*! @brief Defines card-specific parameters for Smart card driver */ +typedef struct _smartcard_card_params +{ + /* ISO7816/EMV4.3 specification variables */ + uint16_t Fi; /*!< 4 bits Fi - clock rate conversion integer */ + uint8_t fMax; /*!< Maximum Smart card frequency in MHz */ + uint8_t WI; /*!< 8 bits WI - work wait time integer */ + uint8_t Di; /*!< 4 bits DI - baud rate divisor */ + uint8_t BWI; /*!< 4 bits BWI - block wait time integer */ + uint8_t CWI; /*!< 4 bits CWI - character wait time integer */ + uint8_t BGI; /*!< 4 bits BGI - block guard time integer */ + uint8_t GTN; /*!< 8 bits GTN - extended guard time integer */ + uint8_t IFSC; /*!< Indicates IFSC value of the card */ + uint8_t modeNegotiable; /*!< Indicates if the card acts in negotiable or a specific mode. */ + uint8_t currentD; /*!< 4 bits DI - current baud rate divisor*/ + /* Driver-specific variables */ + uint8_t status; /*!< Indicates smart card status */ + bool t0Indicated; /*!< Indicates ff T=0 indicated in TD1 byte */ + bool t1Indicated; /*!< Indicates if T=1 indicated in TD2 byte */ + bool atrComplete; /*!< Indicates whether the ATR received from the card was complete or not */ + bool atrValid; /*!< Indicates whether the ATR received from the card was valid or not */ + bool present; /*!< Indicates if a smart card is present */ + bool active; /*!< Indicates if the smart card is activated */ + bool faulty; /*!< Indicates whether smart card/interface is faulty */ + smartcard_card_convention_t convention; /*!< Card convention, kSMARTCARD_DirectConvention for direct convention, + kSMARTCARD_InverseConvention for inverse convention */ +} smartcard_card_params_t; + +/*! @brief Smart card defines the state of the EMV timers in the Smart card driver */ +typedef struct _smartcard_timers_state +{ + volatile bool adtExpired; /*!< Indicates whether ADT timer expired */ + volatile bool wwtExpired; /*!< Indicates whether WWT timer expired */ + volatile bool cwtExpired; /*!< Indicates whether CWT timer expired */ + volatile bool bwtExpired; /*!< Indicates whether BWT timer expired */ + volatile bool initCharTimerExpired; /*!< Indicates whether reception timer + for initialization character (TS) after the RST has expired */ +} smartcard_timers_state_t; + +/*! @brief Defines user specified configuration of Smart card interface */ +typedef struct _smartcard_interface_config +{ + uint32_t smartCardClock; /*!< Smart card interface clock [Hz] */ + uint32_t clockToResetDelay; /*!< Indicates clock to RST apply delay [smart card clock cycles] */ + uint8_t clockModule; /*!< Smart card clock module number */ + uint8_t clockModuleChannel; /*!< Smart card clock module channel number */ + uint8_t clockModuleSourceClock; /*!< Smart card clock module source clock [e.g., BusClk] */ + smartcard_card_voltage_class_t vcc; /*!< Smart card voltage class */ + uint8_t controlPort; /*!< Smart card PHY control port instance */ + uint8_t controlPin; /*!< Smart card PHY control pin instance */ + uint8_t irqPort; /*!< Smart card PHY Interrupt port instance */ + uint8_t irqPin; /*!< Smart card PHY Interrupt pin instance */ + uint8_t resetPort; /*!< Smart card reset port instance */ + uint8_t resetPin; /*!< Smart card reset pin instance */ + uint8_t vsel0Port; /*!< Smart card PHY Vsel0 control port instance */ + uint8_t vsel0Pin; /*!< Smart card PHY Vsel0 control pin instance */ + uint8_t vsel1Port; /*!< Smart card PHY Vsel1 control port instance */ + uint8_t vsel1Pin; /*!< Smart card PHY Vsel1 control pin instance */ + uint8_t dataPort; /*!< Smart card PHY data port instance */ + uint8_t dataPin; /*!< Smart card PHY data pin instance */ + uint8_t dataPinMux; /*!< Smart card PHY data pin mux option */ + uint8_t tsTimerId; /*!< Numerical identifier of the External HW timer for Initial character detection */ +} smartcard_interface_config_t; + +/*! @brief Defines user transfer structure used to initialize transfer */ +typedef struct _smartcard_xfer +{ + smartcard_direction_t direction; /*!< Direction of communication. (RX/TX) */ + uint8_t *buff; /*!< The buffer of data. */ + size_t size; /*!< The number of transferred units. */ +} smartcard_xfer_t; + +/*! + * @brief Runtime state of the Smart card driver. + */ +typedef struct _smartcard_context +{ + /* Xfer part */ + void *base; /*!< Smart card module base address */ + smartcard_direction_t direction; /*!< Direction of communication. (RX/TX) */ + uint8_t *xBuff; /*!< The buffer of data being transferred.*/ + volatile size_t xSize; /*!< The number of bytes to be transferred. */ + volatile bool xIsBusy; /*!< True if there is an active transfer. */ + uint8_t txFifoEntryCount; /*!< Number of data word entries in transmit FIFO. */ + /* Smart card Interface part */ + smartcard_interface_callback_t interfaceCallback; /*!< Callback to invoke after interface IC raised interrupt.*/ + smartcard_transfer_callback_t transferCallback; /*!< Callback to invoke after transfer event occur.*/ + void *interfaceCallbackParam; /*!< Interface callback parameter pointer.*/ + void *transferCallbackParam; /*!< Transfer callback parameter pointer.*/ + smartcard_time_delay_t timeDelay; /*!< Function which handles time delay defined by user or RTOS. */ + smartcard_reset_type_t resetType; /*!< Indicates whether a Cold reset or Warm reset was requested. */ + smartcard_transport_type_t tType; /*!< Indicates current transfer protocol (T0 or T1) */ + /* Smart card State part */ + volatile smartcard_transfer_state_t transferState; /*!< Indicates the current transfer state */ + smartcard_timers_state_t timersState; /*!< Indicates the state of different protocol timers used in driver */ + smartcard_card_params_t + cardParams; /*!< Smart card parameters(ATR and current) and interface slots states(ATR and current) */ + uint8_t IFSD; /*!< Indicates the terminal IFSD */ + smartcard_parity_type_t parity; /*!< Indicates current parity even/odd */ + volatile bool rxtCrossed; /*!< Indicates whether RXT thresholds has been crossed */ + volatile bool txtCrossed; /*!< Indicates whether TXT thresholds has been crossed */ + volatile bool wtxRequested; /*!< Indicates whether WTX has been requested or not*/ + volatile bool parityError; /*!< Indicates whether a parity error has been detected */ + uint8_t statusBytes[2]; /*!< Used to store Status bytes SW1, SW2 of the last executed card command response */ + /* Configuration part */ + smartcard_interface_config_t interfaceConfig; /*!< Smart card interface configuration structure */ + +} smartcard_context_t; + +/*! @}*/ +#endif /* _FSL_SMARTCARD_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_emvsim.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_emvsim.c new file mode 100644 index 00000000000..bf487290987 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_emvsim.c @@ -0,0 +1,978 @@ +/* +* Copyright (c) 2015-2016, Freescale Semiconductor, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "fsl_smartcard_emvsim.h" + +/******************************************************************************* +* Variables +******************************************************************************/ +/*! @brief Pointers to emvsim bases for each instance. */ +static EMVSIM_Type *const s_emvsimBases[] = EMVSIM_BASE_PTRS; + +/*! @brief Pointers to emvsim IRQ number for each instance. */ +static const IRQn_Type s_emvsimIRQ[] = EMVSIM_IRQS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to emvsim clocks for each instance. */ +static const clock_ip_name_t s_emvsimClock[] = EMVSIM_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/* #define CARDSIM_EXTRADELAY_USED */ + +/******************************************************************************* +* Private Functions +******************************************************************************/ +static void smartcard_emvsim_CompleteSendData(EMVSIM_Type *base, smartcard_context_t *context); +static void smartcard_emvsim_StartSendData(EMVSIM_Type *base, smartcard_context_t *context); +static void smartcard_emvsim_CompleteReceiveData(EMVSIM_Type *base, smartcard_context_t *context); +static void smartcard_emvsim_StartReceiveData(EMVSIM_Type *base, smartcard_context_t *context); +static void smartcard_emvsim_SetTransferType(EMVSIM_Type *base, + smartcard_context_t *context, + smartcard_control_t control); +static uint32_t smartcard_emvsim_GetInstance(EMVSIM_Type *base); + +/******************************************************************************* +* Code +******************************************************************************/ +/*! + * @brief Get the UART instance from peripheral base address. + * + * @param base UART peripheral base address. + * @return UART instance. + */ +static uint32_t smartcard_emvsim_GetInstance(EMVSIM_Type *base) +{ + uint8_t instance = 0; + uint32_t emvsimArrayCount = (sizeof(s_emvsimBases) / sizeof(s_emvsimBases[0])); + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < emvsimArrayCount; instance++) + { + if (s_emvsimBases[instance] == base) + { + break; + } + } + + assert(instance < emvsimArrayCount); + + return instance; +} +/*! + * @brief Finish up a transmit by completing the process of sending data and disabling the interrupt. + * + * @param base The EMVSIM peripheral base address. + * @param context A pointer to a SMARTCARD driver context structure. + */ +static void smartcard_emvsim_CompleteSendData(EMVSIM_Type *base, smartcard_context_t *context) +{ + assert((NULL != context)); + + /* Reset additional GETU */ + base->TX_GETU = 0x00u; + /* Disable the transmission complete interrupt */ + base->INT_MASK |= EMVSIM_INT_MASK_TC_IM_MASK; + /* Wait for TC bit to set - last byte transmission has finished */ + while ((!(base->TX_STATUS & EMVSIM_TX_STATUS_TCF_MASK))) + { + } + /* Restore previous TX_GETU value */ + base->TX_GETU = context->cardParams.GTN; + /* disable after transmit */ + base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK; + /* Clear receive status flag */ + base->RX_STATUS = EMVSIM_RX_STATUS_RX_DATA_MASK; + /* Enable Receiver */ + base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK; + /* Update the information of the module driver context */ + context->xIsBusy = false; + context->transferState = kSMARTCARD_IdleState; + /* Clear txSize to avoid any spurious transmit from ISR */ + context->xSize = 0u; + /* Invoke user call-back */ + if (NULL != context->transferCallback) + { + context->transferCallback(context, context->transferCallbackParam); + } +} + +/*! + * @brief Finish up a receive by completing the process of receiving data and disabling the interrupt. + * + * @param base The EMVSIM peripheral base address. + * @param context A pointer to a SMARTCARD driver context structure. + */ +static void smartcard_emvsim_CompleteReceiveData(EMVSIM_Type *base, smartcard_context_t *context) +{ + assert((NULL != context)); + + /* Clear receive status flag */ + base->RX_STATUS = EMVSIM_RX_STATUS_RX_DATA_MASK; + /* Disable receive data full interrupt */ + base->INT_MASK |= EMVSIM_INT_MASK_RX_DATA_IM_MASK; + /* Update the information of the module driver context */ + context->xIsBusy = false; + /* Invoke user call-back */ + if (NULL != context->transferCallback) + { + context->transferCallback(context, context->transferCallbackParam); + } +} + +/*! + * @brief Initiate (start) a transmit by beginning the process of sending data and enabling the interrupt. + * + * @param base The EMVSIM peripheral base address. + * @param context A pointer to a SMARTCARD driver context structure. + */ +static void smartcard_emvsim_StartSendData(EMVSIM_Type *base, smartcard_context_t *context) +{ + assert((NULL != context)); + + uint32_t delay = 0u; + uint32_t control = 0u; + + /* Block guard time */ + /* 22 etus (16 Receiver Clocks == 1 etu) */ + delay = 22u * 16u; + /* Disable all functionality like protocol timers, NACK generation */ + control = base->CTRL; + base->CTRL = 0u; + /* Clear Global counter time-out flag */ + base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK; + /* Disable counter interrupt */ + base->INT_MASK |= EMVSIM_INT_MASK_GPCNT1_IM_MASK; + /* Set counter value */ + base->GPCNT1_VAL = delay; + /* Select the clock for GPCNT */ + base->CLKCFG = + (base->CLKCFG & ~EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK) | EMVSIM_CLKCFG_GPCNT1_CLK_SEL(kEMVSIM_GPCRxClock); + /* Trigger the counter */ + base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK; + /* Wait until counter overflow event occur */ + while ((!(base->TX_STATUS & EMVSIM_TX_STATUS_GPCNT1_TO_MASK))) + { + } + /* Clear status flag and disable GPCNT1 clock */ + base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK; + base->CLKCFG &= ~EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK; + /* Restore Control register */ + base->CTRL = control & ~(EMVSIM_CTRL_XMT_EN_MASK | EMVSIM_CTRL_RCV_EN_MASK); + /* Update transferState */ + context->transferState = kSMARTCARD_TransmittingState; + context->xIsBusy = true; + /* Enable transmitter */ + base->CTRL |= EMVSIM_CTRL_XMT_EN_MASK; + /* Enable the transmission complete interrupt. The TC bit will + * set whenever the transmit data is shifted out */ + base->INT_MASK &= ~EMVSIM_INT_MASK_TC_IM_MASK; +} + +/*! + * @brief Initiate (start) a receive by beginning the process of receiving data and enabling the interrupt. + * + * @param base The EMVSIM peripheral base address. + * @param context A pointer to a SMARTCARD driver context structure. + */ +static void smartcard_emvsim_StartReceiveData(EMVSIM_Type *base, smartcard_context_t *context) +{ + assert((NULL != context)); + + /* Initialize the module driver context structure to indicate transfer in progress */ + context->xIsBusy = true; + /* Enable BWT Timer interrupt to occur */ + base->INT_MASK &= ~EMVSIM_INT_MASK_BWT_ERR_IM_MASK; + /* Clear receive status flag */ + base->RX_STATUS = EMVSIM_RX_STATUS_RX_DATA_MASK; + /* Disable transmitter */ + base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK; + /* Enable receiver and switch to receive direction */ + base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK; + /* Enable the receive data full interrupt */ + base->INT_MASK &= ~EMVSIM_INT_MASK_RX_DATA_IM_MASK; +} + +/*! + * @brief Sets up the EMVSIM hardware for T=0 or T=1 protocol data exchange and initialize timer values. + * + * @param base The EMVSIM peripheral base address. + * @param context A pointer to a SMARTCARD driver context structure. + */ +static void smartcard_emvsim_SetTransferType(EMVSIM_Type *base, + smartcard_context_t *context, + smartcard_control_t control) +{ + assert((NULL != context)); + assert((control == kSMARTCARD_SetupATRMode) || (control == kSMARTCARD_SetupT0Mode) || + (control == kSMARTCARD_SetupT1Mode)); + + uint16_t temp16 = 0u; + uint32_t bwiVal = 0u; + uint8_t tdt = 0u; + + if (control == kSMARTCARD_SetupATRMode) + { + /* Disable all functionality at first */ + base->CTRL &= ~(EMVSIM_CTRL_RCVR_11_MASK | EMVSIM_CTRL_XMT_CRC_LRC_MASK | EMVSIM_CTRL_LRC_EN_MASK | + EMVSIM_CTRL_ANACK_MASK | EMVSIM_CTRL_ONACK_MASK | EMVSIM_CTRL_RCV_EN_MASK); + /* Set default values as per EMV specification */ + context->cardParams.Fi = 372u; + context->cardParams.Di = 1u; + context->cardParams.currentD = 1u; + context->cardParams.WI = 0x0Au; + context->cardParams.GTN = 0x00u; + /* Set default baudrate/ETU time based on EMV parameters and card clock */ + base->DIVISOR = ((context->cardParams.Fi / context->cardParams.currentD) & 0x1FFu); + /* EMV expectation: WWT = (960 x D x WI) + (D x 480) + * EMVSIM formula: BWT_VAL[15:0] = CWT_VAL[15:0] */ + temp16 = (960u * context->cardParams.currentD * context->cardParams.WI) + + (context->cardParams.currentD * 480u) + SMARTCARD_WWT_ADJUSTMENT; + base->CWT_VAL = temp16; + base->BWT_VAL = temp16; + /* Set Extended Guard Timer value + * EMV expectation: GT = GTN not equal to 255 -> 12 + GTN = GTN equal to 255 -> 12 + * EMVSIM formula: same as above */ + base->TX_GETU = context->cardParams.GTN; + /* Setting Rx threshold so that an interrupt is generated when a NACK is + sent either due to parity error or wrong INIT char*/ + base->RX_THD = EMVSIM_RX_THD_RDT(1); + /* Setting up Tx NACK threshold */ + tdt = ((base->PARAM & EMVSIM_PARAM_TX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT) - 1; + base->TX_THD = (EMVSIM_TX_THD_TNCK_THD(SMARTCARD_EMV_TX_NACK_THRESHOLD) | EMVSIM_TX_THD_TDT(tdt)); + /* Clear all pending interrupts */ + base->RX_STATUS = 0xFFFFFFFFu; + /* Enable Tx NACK threshold interrupt to occur */ + base->INT_MASK &= ~EMVSIM_INT_MASK_TNACK_IM_MASK; + /* Set transport type to T=0 in SMARTCARD context structure */ + context->tType = kSMARTCARD_T0Transport; + } + else if (control == kSMARTCARD_SetupT0Mode) + { + /* Disable receiver at first if it's not, Disable T=0 mode counters 1st, + * Setup for single wire ISO7816 mode (setup 12 etu mode). + * Set transport protocol type to T=0, Disable initial character detection.*/ + base->CTRL &= + ~(EMVSIM_CTRL_RCV_EN_MASK | EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK | EMVSIM_CTRL_RCVR_11_MASK | + EMVSIM_CTRL_XMT_CRC_LRC_MASK | EMVSIM_CTRL_LRC_EN_MASK | EMVSIM_CTRL_ICM_MASK); + /* EMV expectation: WWT = (960 x D x WI) + (D x 480) + * EMVSIM formula: BWT_VAL[15:0] = CWT_VAL[15:0] */ + temp16 = (960u * context->cardParams.currentD * context->cardParams.WI) + + (context->cardParams.currentD * 480u) + SMARTCARD_WWT_ADJUSTMENT; + base->CWT_VAL = temp16; + base->BWT_VAL = temp16; + /* Set Extended Guard Timer value + * EMV expectation: GT = GTN not equal to 255 -> 12 + GTN = GTN equal to 255 -> 12 + * EMVSIM formula: same as above for range [0:254] + * Fix for EMV. If TX_GETU == 0 in T0 mode, 3 stop bits are inserted. */ + context->cardParams.GTN = (context->cardParams.GTN == 0xFFu) ? 0x00u : context->cardParams.GTN; + base->TX_GETU = context->cardParams.GTN; + /* Setting Rx threshold so that an interrupt is generated when a NACK is + sent either due to parity error or wrong INIT char */ + base->RX_THD = (EMVSIM_RX_THD_RNCK_THD(SMARTCARD_EMV_RX_NACK_THRESHOLD) | EMVSIM_RX_THD_RDT(1)); + /* Setting up Tx NACK threshold */ + tdt = ((base->PARAM & EMVSIM_PARAM_TX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT) - 1; + base->TX_THD = (EMVSIM_TX_THD_TNCK_THD(SMARTCARD_EMV_TX_NACK_THRESHOLD) | EMVSIM_TX_THD_TDT(tdt)); + /* Enable Tx NACK threshold interrupt to occur */ + base->INT_MASK &= ~EMVSIM_INT_MASK_TNACK_IM_MASK; + /* Enable T=0 mode counters, Enable NACK on error interrupt and NACK on overflow interrupt */ + base->CTRL |= + (EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK | EMVSIM_CTRL_ANACK_MASK | EMVSIM_CTRL_ONACK_MASK); + /* Set transport type to T=0 in SMARTCARD context structure */ + context->tType = kSMARTCARD_T0Transport; + } + else + { /* Disable T=1 mode counters 1st, Disable NACK on error interrupt, Disable NACK on overflow interrupt */ + base->CTRL &= ~(EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK | EMVSIM_CTRL_ANACK_MASK | + EMVSIM_CTRL_ONACK_MASK | EMVSIM_CTRL_XMT_CRC_LRC_MASK | EMVSIM_CTRL_LRC_EN_MASK); + /* Calculate and set Block Wait Timer (BWT) value + * EMV expectation: BWT = 11 + (2^BWI x 960 x D) + (D x 960) = 11 + (2^BWI + 1) x 960 x D + * EMVSIM formula: BWT = Same */ + bwiVal = 11 + (((1 << context->cardParams.BWI) + 1u) * 960u * context->cardParams.currentD); +#ifdef CARDSIM_EXTRADELAY_USED + base->BWT_VAL = bwiVal + 100; +#else + base->BWT_VAL = bwiVal; +#endif + /* Calculate and set Character Wait Timer (CWT) value + * EMV expectation: CWT = ((2^CWI + 11) + 4) + * EMVSIM formula: CWT = Same */ + if (context->cardParams.currentD == 1u) + { +#ifdef CARDSIM_EXTRADELAY_USED + temp16 = (1u << context->cardParams.CWI) + 16u; +#else + temp16 = (1u << context->cardParams.CWI) + 15u; +#endif + } + else + { +#ifdef CARDSIM_EXTRADELAY_USED + temp16 = (1u << context->cardParams.CWI) + 20u + SMARTCARD_CWT_ADJUSTMENT; +#else + temp16 = (1u << context->cardParams.CWI) + 15u + SMARTCARD_CWT_ADJUSTMENT; +#endif + } + /* EMV = 15, ISO = 11, + * EMV expectation: BGT = 22 + * EMVSIM formula: BGT = Same */ + base->CWT_VAL = temp16; + context->cardParams.BGI = 22u; + base->BGT_VAL = context->cardParams.BGI; + /* Set Extended Guard Timer value + * EMV expectation: GT = GTN not equal to 255 -> 12 + GTN = GTN equal to 255 -> 11 + * EMVSIM formula: same as above */ + base->TX_GETU = context->cardParams.GTN; + /* Setup for single wire ISO7816 mode, + * Set transport protocol type to T=1, Enable T=0 mode counters */ + base->CTRL |= (EMVSIM_CTRL_RCVR_11_MASK | EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK); + /* Setting Rx threshold */ + base->RX_THD = (EMVSIM_RX_THD_RNCK_THD(SMARTCARD_EMV_RX_NACK_THRESHOLD) | EMVSIM_RX_THD_RDT(1)); + /* Setting up Tx threshold */ + tdt = ((base->PARAM & EMVSIM_PARAM_TX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT) - 1; + base->TX_THD = (EMVSIM_TX_THD_TDT(tdt) | EMVSIM_TX_THD_TNCK_THD(SMARTCARD_EMV_TX_NACK_THRESHOLD)); + /* Set transport type to T=1 in SMARTCARD context structure */ + context->tType = kSMARTCARD_T1Transport; + } +} + +void SMARTCARD_EMVSIM_GetDefaultConfig(smartcard_card_params_t *cardParams) +{ + /* EMV default values */ + cardParams->Fi = 372u; + cardParams->Di = 1u; + cardParams->currentD = 1u; + cardParams->WI = 0x0Au; + cardParams->GTN = 0x00u; +} + +status_t SMARTCARD_EMVSIM_Init(EMVSIM_Type *base, smartcard_context_t *context, uint32_t srcClock_Hz) +{ + assert((NULL != base)); + + if ((NULL == context) || (srcClock_Hz == 0u)) + { + return kStatus_SMARTCARD_InvalidInput; + } + + uint32_t instance = smartcard_emvsim_GetInstance(base); +/* Set source clock for EMVSIM MCGPLLCLK */ +#if !(defined(FSL_FEATURE_SOC_SCG_COUNT) && FSL_FEATURE_SOC_SCG_COUNT) + CLOCK_SetEmvsimClock(1u); +#endif +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable emvsim clock */ + CLOCK_EnableClock(s_emvsimClock[instance]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + context->base = base; + /* Initialize EMVSIM to a known context. */ + base->CLKCFG = 0u; + base->DIVISOR = 372u; + base->CTRL = 0x300u; + base->INT_MASK = 0x7FFFu; + base->RX_THD = 1u; + base->TX_THD = 0u; + base->PCSR = 0x1000000u; + base->TX_GETU = 0u; + base->CWT_VAL = 0xFFFFu; + base->BWT_VAL = 0xFFFFFFFFu; + base->BGT_VAL = 0u; + base->GPCNT0_VAL = 0xFFFFu; + base->GPCNT1_VAL = 0xFFFFu; + /* Initialize EMVSIM module for SMARTCARD mode of default operation */ + smartcard_emvsim_SetTransferType(base, context, kSMARTCARD_SetupATRMode); + /* For modules that do not support a FIFO, they have a data buffer that + * essentially acts likes a one-entry FIFO, thus to make the code cleaner, + * we'll equate txFifoEntryCount to 1. Also note that TDRE flag will set + * only when the tx buffer is empty. */ + context->txFifoEntryCount = 1u; +/* Enable EMVSIM interrupt on NVIC level. */ +#if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && FSL_FEATURE_SOC_INTMUX_COUNT + if (s_emvsimIRQ[instance] >= FSL_FEATURE_INTMUX_IRQ_START_INDEX) + { + INTMUX0->CHANNEL[0].CHn_IER_31_0 |= 1U << (s_emvsimIRQ[instance] - FSL_FEATURE_INTERRUPT_IRQ_MAX - 1U); + NVIC_EnableIRQ(INTMUX0_0_IRQn); + } + else + { + NVIC_EnableIRQ(s_emvsimIRQ[instance]); + } +#else + NVIC_EnableIRQ(s_emvsimIRQ[instance]); +#endif + /* Finally, disable the EMVSIM receiver and transmitter */ + base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK & ~EMVSIM_CTRL_RCV_EN_MASK; + + return kStatus_SMARTCARD_Success; +} + +void SMARTCARD_EMVSIM_Deinit(EMVSIM_Type *base) +{ + uint32_t instance = 0u; + /* In case there is still data in the TX FIFO or shift register that is + * being transmitted wait till transmit is complete. + * Wait until the data is completely shifted out of shift register */ + while ((!(base->TX_STATUS & EMVSIM_TX_STATUS_TCF_MASK))) + { + } + instance = smartcard_emvsim_GetInstance(base); + /* Disable TX and RX */ + base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK & ~EMVSIM_CTRL_RCV_EN_MASK; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate EMVSIM module clock */ + CLOCK_DisableClock(s_emvsimClock[instance]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +/* Disable emvsim interrupt in NVIC */ +#if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && FSL_FEATURE_SOC_INTMUX_COUNT + if (s_emvsimIRQ[instance] >= FSL_FEATURE_INTMUX_IRQ_START_INDEX) + { + INTMUX0->CHANNEL[0].CHn_IER_31_0 &= ~(1U << (s_emvsimIRQ[instance] - FSL_FEATURE_INTERRUPT_IRQ_MAX - 1U)); + NVIC_DisableIRQ(INTMUX0_0_IRQn); + } + else + { + NVIC_DisableIRQ(s_emvsimIRQ[instance]); + } +#else + NVIC_DisableIRQ(s_emvsimIRQ[instance]); +#endif +} + +status_t SMARTCARD_EMVSIM_TransferNonBlocking(EMVSIM_Type *base, smartcard_context_t *context, smartcard_xfer_t *xfer) +{ + if ((NULL == context) || (NULL == xfer) || (xfer->buff == NULL)) + { + return kStatus_SMARTCARD_InvalidInput; + } + + /* Check input parameters */ + if ((0u == xfer->size)) + { + return kStatus_SMARTCARD_Success; + } + /* Check if some transfer is in progress */ + if (0u != SMARTCARD_EMVSIM_GetTransferRemainingBytes(base, context)) + { + if (kSMARTCARD_Receive == context->direction) + { + return kStatus_SMARTCARD_RxBusy; + } + else + { + return kStatus_SMARTCARD_TxBusy; + } + } + /* Initialize error check flags */ + context->rxtCrossed = false; + context->txtCrossed = false; + context->parityError = false; + /* Initialize SMARTCARD context structure to start transfer */ + context->xBuff = xfer->buff; + context->xSize = xfer->size; + + if (kSMARTCARD_Receive == xfer->direction) + { + context->direction = xfer->direction; + context->transferState = kSMARTCARD_ReceivingState; + /* Start transfer */ + smartcard_emvsim_StartReceiveData(base, context); + } + else if (kSMARTCARD_Transmit == xfer->direction) + { + context->direction = xfer->direction; + context->transferState = kSMARTCARD_TransmittingState; + /* Start transfer */ + smartcard_emvsim_StartSendData(base, context); + } + else + { + return kStatus_SMARTCARD_InvalidInput; + } + + return kStatus_SMARTCARD_Success; +} + +int32_t SMARTCARD_EMVSIM_GetTransferRemainingBytes(EMVSIM_Type *base, smartcard_context_t *context) +{ + if ((NULL == context)) + { + return -1; + } + + /* Return kStatus_SMARTCARD_(Tx/Rx)Busy or kStatus_SMARTCARD_Success depending on whether + * or not the EMVSIM has a FIFO. If TX transfer and it does have a FIFO, we'll need to wait + * until the FIFO is completely drained before indicating success in addition to xIsBusy = 0. + * If there is no FIFO, then we need to only worry about xIsBusy. */ + if (context->xIsBusy) + { + return context->xSize; + } + + return 0; +} + +status_t SMARTCARD_EMVSIM_AbortTransfer(EMVSIM_Type *base, smartcard_context_t *context) +{ + if ((NULL == context)) + { + return kStatus_SMARTCARD_InvalidInput; + } + + /* Check if a transfer is running. */ + if ((!context->xIsBusy)) + { + return kStatus_SMARTCARD_NoTransferInProgress; + } + /* Call transfer complete to abort transfer */ + if (kSMARTCARD_Receive == context->direction) + { /* Stop the running transfer. */ + smartcard_emvsim_CompleteReceiveData(base, context); + } + else if (kSMARTCARD_Transmit == context->direction) + { /* Stop the running transfer. */ + smartcard_emvsim_CompleteSendData(base, context); + } + else + { + return kStatus_SMARTCARD_InvalidInput; + } + + return kStatus_SMARTCARD_Success; +} + +void SMARTCARD_EMVSIM_IRQHandler(EMVSIM_Type *base, smartcard_context_t *context) +{ + uint8_t temp8 = 0u; + + if (NULL == context) + { + return; + } + + /* Check card insertion/removal interrupt occurs, only EMVSIM DIRECT interface driver using enables this interrupt + * to occur */ + if ((!(base->PCSR & EMVSIM_PCSR_SPDIM_MASK)) && (base->PCSR & EMVSIM_PCSR_SPDIF_MASK)) + { + /* Clear card presence interrupt status */ + base->PCSR |= EMVSIM_PCSR_SPDIF_MASK; + /* Set PD signal edge behaviour */ + if (((emvsim_presence_detect_edge_t)((base->PCSR & EMVSIM_PCSR_SPDES_MASK) >> EMVSIM_PCSR_SPDES_SHIFT) == + kEMVSIM_DetectOnFallingEdge) && + ((emvsim_presence_detect_status_t)((base->PCSR & EMVSIM_PCSR_SPDP_MASK) >> EMVSIM_PCSR_SPDP_SHIFT) == + kEMVSIM_DetectPinIsLow)) + { /* Set rising edge interrupt */ + base->PCSR |= EMVSIM_PCSR_SPDES_MASK; + } + if (((emvsim_presence_detect_edge_t)((base->PCSR & EMVSIM_PCSR_SPDES_MASK) >> EMVSIM_PCSR_SPDES_SHIFT) == + kEMVSIM_DetectOnRisingEdge) && + ((emvsim_presence_detect_status_t)((base->PCSR & EMVSIM_PCSR_SPDP_MASK) >> EMVSIM_PCSR_SPDP_SHIFT) == + kEMVSIM_DetectPinIsHigh)) + { /* Set falling edge interrupt */ + base->PCSR &= ~EMVSIM_PCSR_SPDES_MASK; + } + /* Card presence(insertion)/removal detected */ + /* Invoke callback if there is one */ + if (NULL != context->interfaceCallback) + { + context->interfaceCallback(context, context->interfaceCallbackParam); + } + return; + } + /* Check if timer for initial character (TS) detection has expired */ + if (((base->INT_MASK & EMVSIM_INT_MASK_GPCNT0_IM_MASK) >> EMVSIM_INT_MASK_GPCNT0_IM_SHIFT == 0) && + (base->TX_STATUS & EMVSIM_TX_STATUS_GPCNT0_TO_MASK)) + { + /* Disable TS and ADT timers by clearing source clock to 0 */ + base->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK); + context->timersState.initCharTimerExpired = true; + /* Disable and clear GPCNT interrupt */ + base->INT_MASK |= EMVSIM_INT_MASK_GPCNT0_IM_MASK; + base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT0_TO_MASK; + /* Down counter trigger, and clear any pending counter status flag */ + base->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK; + base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK; + context->transferState = kSMARTCARD_IdleState; + /* Unblock the caller */ + smartcard_emvsim_CompleteReceiveData(base, context); + return; + } + /* Check if timer for ATR duration timer has expired */ + if ((!(base->INT_MASK & EMVSIM_INT_MASK_GPCNT1_IM_MASK)) && (base->TX_STATUS & EMVSIM_TX_STATUS_GPCNT1_TO_MASK)) + { /* Disable clock counter by clearing source clock to 0 */ + base->CLKCFG &= ~EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK; + /* Disable and clear GPCNT interrupt */ + base->INT_MASK |= EMVSIM_INT_MASK_GPCNT1_IM_MASK; + base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK; + context->timersState.adtExpired = true; + /* Unblock the caller */ + smartcard_emvsim_CompleteReceiveData(base, context); + return; + } + /* + * Check if a parity error was indicated. + * A parity error will cause transmission of NACK if ANACK bit is set in + * CTRL register and PEF bit will not be asserted. When ANACK is not set, + * PEF will be asserted. + */ + if ((base->RX_STATUS & EMVSIM_RX_STATUS_PEF_MASK)) + { + context->parityError = true; + /* Clear parity error indication */ + base->RX_STATUS = EMVSIM_RX_STATUS_PEF_MASK; + } + /* Check if transmit NACK generation threshold was reached */ + if ((base->TX_STATUS & EMVSIM_TX_STATUS_TNTE_MASK)) + { + context->txtCrossed = true; + } + /* Check if receive NACK generation threshold was reached */ + if (base->RX_STATUS & EMVSIM_RX_STATUS_RTE_MASK) + { + context->rxtCrossed = true; + /* Clear receiver NACK threshold interrupt status */ + base->RX_STATUS = EMVSIM_RX_STATUS_RTE_MASK; + if (context->xIsBusy) + { /* Unblock the caller */ + smartcard_emvsim_CompleteReceiveData(base, context); + } + } + /* Check if a Character Wait Timer expired */ + if ((!(base->INT_MASK & EMVSIM_INT_MASK_CWT_ERR_IM_MASK)) && (base->RX_STATUS & EMVSIM_RX_STATUS_CWT_ERR_MASK)) + { /* Disable Character Wait Timer interrupt */ + base->INT_MASK |= EMVSIM_INT_MASK_CWT_ERR_IM_MASK; + /* Reset the counter */ + base->CTRL &= ~EMVSIM_CTRL_CWT_EN_MASK; + /* Clear interrupt status */ + base->RX_STATUS = EMVSIM_RX_STATUS_CWT_ERR_MASK; + /* Enable CWT timer */ + base->CTRL |= EMVSIM_CTRL_CWT_EN_MASK; + context->transferState = kSMARTCARD_IdleState; + + if (kSMARTCARD_T0Transport == context->tType) + { /* Indicate WWT expired */ + context->timersState.wwtExpired = true; + } + else + { /* Indicate CWT expired */ + context->timersState.cwtExpired = true; + } + if (context->xIsBusy) + { /* Terminate and unblock any caller */ + smartcard_emvsim_CompleteReceiveData(base, context); + } + } + /* Check if a Block Wait Timer expired */ + if ((!(base->INT_MASK & EMVSIM_INT_MASK_BWT_ERR_IM_MASK)) && (base->RX_STATUS & EMVSIM_RX_STATUS_BWT_ERR_MASK)) + { /* Disable Block Wait Timer interrupt */ + base->INT_MASK |= EMVSIM_INT_MASK_BWT_ERR_IM_MASK; + /* Clear interrupt status flag */ + base->CTRL &= ~EMVSIM_CTRL_BWT_EN_MASK; + /* Clear error */ + base->RX_STATUS = EMVSIM_RX_STATUS_BWT_ERR_MASK; + /* Enable BWT timer */ + base->CTRL |= EMVSIM_CTRL_BWT_EN_MASK; + + if (kSMARTCARD_T0Transport == context->tType) + { /* Indicate WWT expired */ + context->timersState.wwtExpired = true; + } + else + { /* Indicate BWT expired */ + context->timersState.bwtExpired = true; + } + /* Check if Wait Time Extension(WTX) was requested */ + if (context->wtxRequested) + { /* Reset WTX to default */ + SMARTCARD_EMVSIM_Control(base, context, kSMARTCARD_ResetWaitTimeMultiplier, 1); + } + if (context->xIsBusy) + { /* Terminate and unblock any caller */ + smartcard_emvsim_CompleteReceiveData(base, context); + } + } + /* Handle receive data register full interrupt, if rx data register full + * interrupt is enabled AND there is data available. */ + if ((!(base->INT_MASK & EMVSIM_INT_MASK_RX_DATA_IM_MASK)) && (base->RX_STATUS & EMVSIM_RX_STATUS_RX_DATA_MASK)) + { + if (kSMARTCARD_WaitingForTSState == context->transferState) + { + temp8 = (uint8_t)(base->RX_BUF); + + if (base->CTRL & EMVSIM_CTRL_ICM_MASK) + { /* ICM mode still enabled, this is due to parity error */ + context->transferState = kSMARTCARD_InvalidTSDetecetedState; + } + else + { /* Received valid TS */ + context->transferState = kSMARTCARD_ReceivingState; + /* Get Data Convention form by reading IC bit of EMVSIM_CTRL register */ + context->cardParams.convention = + (smartcard_card_convention_t)((base->CTRL & EMVSIM_CTRL_IC_MASK) >> EMVSIM_CTRL_IC_SHIFT); + } + if (kSMARTCARD_InvalidTSDetecetedState == context->transferState) + { /* Stop initial character (TS) detection timer, ADT timer and it's interrupt to occur */ + base->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK); + base->INT_MASK |= EMVSIM_INT_MASK_GPCNT0_IM_MASK; + smartcard_emvsim_CompleteReceiveData(base, context); + } + if (kSMARTCARD_ReceivingState == context->transferState) + { /* Stop initial character (TS) detection timer and disable ATR duration timer to reset it */ + base->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK); + /* Start ATR duration counter (restart GPCNT) */ + base->CLKCFG |= EMVSIM_CLKCFG_GPCNT1_CLK_SEL(kEMVSIM_GPCTxClock); + /* Start ATR duration counter, Disable counter 0 interrupt and Enable counter 1 interrupt */ + base->INT_MASK = (base->INT_MASK & ~EMVSIM_INT_MASK_GPCNT1_IM_MASK) | EMVSIM_INT_MASK_GPCNT0_IM_MASK; + /* Complete receive transfer */ + smartcard_emvsim_CompleteReceiveData(base, context); + } + /* Return anyway */ + return; + } + /* Get data and put into receive buffer */ + *context->xBuff = (uint8_t)(base->RX_BUF); + /* Clear received data interrupt status */ + base->RX_STATUS = EMVSIM_RX_STATUS_RX_DATA_MASK; + + ++context->xBuff; + --context->xSize; + + if ((context->tType == kSMARTCARD_T1Transport) && (context->xSize > 0u) && + (!(base->INT_MASK & EMVSIM_INT_MASK_BWT_ERR_IM_MASK))) + { + /* And, enable CWT interrupt */ + context->timersState.cwtExpired = false; + /* Clear interrupt status */ + base->RX_STATUS = EMVSIM_RX_STATUS_CWT_ERR_MASK; + base->CTRL |= EMVSIM_CTRL_CWT_EN_MASK; + /* Only the 1st byte has been received, now time to disable BWT interrupt */ + base->INT_MASK = (base->INT_MASK & ~EMVSIM_INT_MASK_CWT_ERR_IM_MASK) | EMVSIM_INT_MASK_BWT_ERR_IM_MASK; + } + /* Check and see if this was the last byte received */ + if (0u == context->xSize) + { + smartcard_emvsim_CompleteReceiveData(base, context); + } + } + /* Handle transmit data register empty interrupt and + * last data was shifted out of IO line */ + if ((!(base->INT_MASK & EMVSIM_INT_MASK_TC_IM_MASK)) && + (base->TX_STATUS & (EMVSIM_TX_STATUS_TFE_MASK | EMVSIM_TX_STATUS_TCF_MASK))) + { + if (context->txtCrossed) + { /* Disable and Clear TNTE interrupt */ + base->INT_MASK |= EMVSIM_INT_MASK_TNACK_IM_MASK; + base->TX_STATUS = EMVSIM_TX_STATUS_TNTE_MASK; + /* Unblock the caller */ + smartcard_emvsim_CompleteSendData(base, context); + return; + } + /* Check to see if there are any more bytes to send */ + if (context->xSize > 0u) + { + temp8 = context->txFifoEntryCount; + + while (temp8--) + { + /* Transmit data and update TX size/buff */ + base->TX_BUF = *(context->xBuff); + /* Clear TCF interrupt */ + base->TX_STATUS = EMVSIM_TX_STATUS_TCF_MASK; + /* Move buffer pointer and transfer data size */ + ++context->xBuff; + --context->xSize; + + if (!context->xSize) + { + smartcard_emvsim_CompleteSendData(base, context); + break; + } + } + } + } +} + +status_t SMARTCARD_EMVSIM_Control(EMVSIM_Type *base, + smartcard_context_t *context, + smartcard_control_t control, + uint32_t param) +{ + if ((NULL == context)) + { + return kStatus_SMARTCARD_InvalidInput; + } + + uint32_t temp32 = 0u; + + switch (control) + { + case kSMARTCARD_EnableADT: + /* Do nothing, ADT counter has been loaded and started after reset + * and during starting TS delay counter only. This is because, once + * TS counter has been triggered with RCV_EN down-up, we should not + * trigger again after TS is received(to avoid missing next character to + * TS. Rather, after TS is received, the ATR duration counter should just + * be restarted w/o re-triggering the counter. */ + break; + case kSMARTCARD_DisableADT: + base->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK; + /* Stop ADT specific counter and it's interrupt to occur */ + base->CLKCFG &= ~EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK; + base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK; + base->INT_MASK |= EMVSIM_INT_MASK_GPCNT1_IM_MASK; + break; + case kSMARTCARD_EnableGTV: + /* Enable GTV specific interrupt */ + base->INT_MASK &= ~EMVSIM_INT_MASK_BGT_ERR_IM_MASK; + break; + case kSMARTCARD_DisableGTV: + /* Disable GTV specific interrupt */ + base->INT_MASK |= EMVSIM_INT_MASK_BGT_ERR_IM_MASK; + break; + case kSMARTCARD_ResetWWT: + /* Reset WWT Timer */ + base->CTRL &= ~(EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK); + base->CTRL |= (EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK); + break; + case kSMARTCARD_EnableWWT: + /* BGT must be masked */ + base->INT_MASK |= EMVSIM_INT_MASK_BGT_ERR_IM_MASK; + /* Enable WWT Timer interrupt to occur */ + base->INT_MASK &= (~EMVSIM_INT_MASK_CWT_ERR_IM_MASK & ~EMVSIM_INT_MASK_BWT_ERR_IM_MASK); + break; + case kSMARTCARD_DisableWWT: + /* Disable WWT Timer interrupt to occur */ + base->INT_MASK |= (EMVSIM_INT_MASK_CWT_ERR_IM_MASK | EMVSIM_INT_MASK_BWT_ERR_IM_MASK); + break; + case kSMARTCARD_ResetCWT: + /* Reset CWT Timer */ + base->CTRL &= ~EMVSIM_CTRL_CWT_EN_MASK; + base->CTRL |= EMVSIM_CTRL_CWT_EN_MASK; + break; + case kSMARTCARD_EnableCWT: + base->CTRL |= EMVSIM_CTRL_CWT_EN_MASK; + /* Enable CWT Timer interrupt to occur */ + base->INT_MASK &= ~EMVSIM_INT_MASK_CWT_ERR_IM_MASK; + break; + case kSMARTCARD_DisableCWT: + /* CWT counter is for receive mode only */ + base->CTRL &= ~EMVSIM_CTRL_CWT_EN_MASK; + /* Disable CWT Timer interrupt to occur */ + base->INT_MASK |= EMVSIM_INT_MASK_CWT_ERR_IM_MASK; + break; + case kSMARTCARD_ResetBWT: + /* Reset BWT Timer */ + base->CTRL &= ~EMVSIM_CTRL_BWT_EN_MASK; + base->CTRL |= EMVSIM_CTRL_BWT_EN_MASK; + break; + case kSMARTCARD_EnableBWT: + base->CTRL |= EMVSIM_CTRL_BWT_EN_MASK; + /* Enable BWT Timer interrupt to occur */ + base->INT_MASK &= ~EMVSIM_INT_MASK_BWT_ERR_IM_MASK; + break; + case kSMARTCARD_DisableBWT: + /* Disable BWT Timer interrupt to occur */ + base->INT_MASK |= EMVSIM_INT_MASK_BWT_ERR_IM_MASK; + break; + case kSMARTCARD_EnableInitDetect: + /* Clear all ISO7816 interrupt flags */ + base->RX_STATUS = 0xFFFFFFFFu; + /* Enable initial character detection : hardware method */ + context->transferState = kSMARTCARD_WaitingForTSState; + /* Enable initial character detection */ + base->CTRL |= EMVSIM_CTRL_ICM_MASK; + base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK; + break; + case kSMARTCARD_EnableAnack: + /* Enable NACK-on-error interrupt to occur */ + base->CTRL |= EMVSIM_CTRL_ANACK_MASK; + break; + case kSMARTCARD_DisableAnack: + /* Disable NACK-on-error interrupt to occur */ + base->CTRL &= ~EMVSIM_CTRL_ANACK_MASK; + break; + case kSMARTCARD_ConfigureBaudrate: + /* Set default baudrate/ETU time based on EMV parameters and card clock */ + base->DIVISOR = ((context->cardParams.Fi / context->cardParams.currentD) & 0x1FFu); + break; + case kSMARTCARD_SetupATRMode: + /* Set in default ATR mode */ + smartcard_emvsim_SetTransferType(base, context, kSMARTCARD_SetupATRMode); + break; + case kSMARTCARD_SetupT0Mode: + /* Set transport protocol type to T=0 */ + smartcard_emvsim_SetTransferType(base, context, kSMARTCARD_SetupT0Mode); + break; + case kSMARTCARD_SetupT1Mode: + /* Set transport protocol type to T=1 */ + smartcard_emvsim_SetTransferType(base, context, kSMARTCARD_SetupT1Mode); + break; + case kSMARTCARD_EnableReceiverMode: + /* Enable receiver mode and switch to receive direction */ + base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK; + /* Enable RX_DATA interrupt */ + base->INT_MASK &= ~EMVSIM_INT_MASK_RX_DATA_IM_MASK; + break; + case kSMARTCARD_DisableReceiverMode: + /* Disable receiver */ + base->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK; + break; + case kSMARTCARD_EnableTransmitterMode: + /* Enable transmitter mode and switch to transmit direction */ + base->CTRL |= EMVSIM_CTRL_XMT_EN_MASK; + break; + case kSMARTCARD_DisableTransmitterMode: + /* Disable transmitter */ + base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK; + break; + case kSMARTCARD_ResetWaitTimeMultiplier: + base->CTRL &= ~EMVSIM_CTRL_BWT_EN_MASK; + /* Reset Wait Timer Multiplier + * EMV Formula : WTX x (11 + ((2^BWI + 1) x 960 x D)) */ + temp32 = ((uint8_t)param) * + (11u + (((1 << context->cardParams.BWI) + 1u) * 960u * context->cardParams.currentD)); +#ifdef CARDSIM_EXTRADELAY_USED + temp32 += context->cardParams.currentD * 50; +#endif + base->BWT_VAL = temp32; + /* Set flag to SMARTCARD context accordingly */ + if (param > 1u) + { + context->wtxRequested = true; + } + else + { + context->wtxRequested = false; + } + base->CTRL |= EMVSIM_CTRL_BWT_EN_MASK; + break; + default: + return kStatus_SMARTCARD_InvalidInput; + } + return kStatus_SMARTCARD_Success; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_emvsim.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_emvsim.h new file mode 100644 index 00000000000..85d10d99eff --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_emvsim.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_SMARTCARD_EMVSIM_H_ +#define _FSL_SMARTCARD_EMVSIM_H_ + +#include "fsl_smartcard.h" + +/*! + * @addtogroup smartcard_emvsim_driver + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief EMV RX NACK interrupt generation threshold */ +#define SMARTCARD_EMV_RX_NACK_THRESHOLD (5u) + +/*! @brief EMV TX NACK interrupt generation threshold */ +#define SMARTCARD_EMV_TX_NACK_THRESHOLD (5u) + +/*! @brief Smart card Word Wait Timer adjustment value */ +#define SMARTCARD_WWT_ADJUSTMENT (160u) + +/*! @brief Smart card Character Wait Timer adjustment value */ +#define SMARTCARD_CWT_ADJUSTMENT (3u) + +/*! @brief General Purpose Counter clock selections */ +typedef enum _emvsim_gpc_clock_select +{ + kEMVSIM_GPCClockDisable = 0u, /*!< Disabled */ + kEMVSIM_GPCCardClock = 1u, /*!< Card clock */ + kEMVSIM_GPCRxClock = 2u, /*!< Receive clock */ + kEMVSIM_GPCTxClock = 3u, /*!< Transmit ETU clock */ +} emvsim_gpc_clock_select_t; + +/*! @brief EMVSIM card presence detection edge control */ +typedef enum _presence_detect_edge +{ + kEMVSIM_DetectOnFallingEdge = 0u, /*!< Presence detected on the falling edge */ + kEMVSIM_DetectOnRisingEdge = 1u, /*!< Presence detected on the rising edge */ +} emvsim_presence_detect_edge_t; + +/*! @brief EMVSIM card presence detection status */ +typedef enum _presence_detect_status +{ + kEMVSIM_DetectPinIsLow = 0u, /*!< Presence detected pin is logic low */ + kEMVSIM_DetectPinIsHigh = 1u, /*!< Presence detected pin is logic high */ +} emvsim_presence_detect_status_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Smart card EMVSIM Driver + * @{ + */ + +/*! + * @brief Fills in the smartcard_card_params structure with default values according to the EMV 4.3 specification. + * + * @param cardParams The configuration structure of type smartcard_interface_config_t. + * Function fill in members: + * Fi = 372; + * Di = 1; + * currentD = 1; + * WI = 0x0A; + * GTN = 0x00; + * with default values. + */ +void SMARTCARD_EMVSIM_GetDefaultConfig(smartcard_card_params_t *cardParams); + +/*! + * @brief Initializes an EMVSIM peripheral for the Smart card/ISO-7816 operation. + * + * This function un-gates the EMVSIM clock, initializes the module to EMV default settings, + * configures the IRQ, enables the module-level interrupt to the core and, initializes the driver context. + * + * @param base The EMVSIM peripheral base address. + * @param context A pointer to the smart card driver context structure. + * @param srcClock_Hz Smart card clock generation module source clock. + * + * @return An error code or kStatus_SMARTCARD_Success. + */ +status_t SMARTCARD_EMVSIM_Init(EMVSIM_Type *base, smartcard_context_t *context, uint32_t srcClock_Hz); + +/*! + * @brief This function disables the EMVSIM interrupts, disables the transmitter and receiver, + * flushes the FIFOs, and gates EMVSIM clock in SIM. + * + * @param base The EMVSIM module base address. + */ +void SMARTCARD_EMVSIM_Deinit(EMVSIM_Type *base); + +/*! + * @brief Returns whether the previous EMVSIM transfer has finished. + * + * When performing an async transfer, call this function to ascertain the context of the + * current transfer: in progress (or busy) or complete (success). If the + * transfer is still in progress, the user can obtain the number of words that have not been + * transferred. + * + * @param base The EMVSIM module base address. + * @param context A pointer to a smart card driver context structure. + * + * @return The number of bytes not transferred. + */ +int32_t SMARTCARD_EMVSIM_GetTransferRemainingBytes(EMVSIM_Type *base, smartcard_context_t *context); + +/*! + * @brief Terminates an asynchronous EMVSIM transfer early. + * + * During an async EMVSIM transfer, the user can terminate the transfer early + * if the transfer is still in progress. + * + * @param base The EMVSIM peripheral address. + * @param context A pointer to a smart card driver context structure. + * @retval kStatus_SMARTCARD_Success The transmit abort was successful. + * @retval kStatus_SMARTCARD_NoTransmitInProgress No transmission is currently in progress. + */ +status_t SMARTCARD_EMVSIM_AbortTransfer(EMVSIM_Type *base, smartcard_context_t *context); + +/*! + * @brief Transfer data using interrupts. + * + * A non-blocking (also known as asynchronous) function means that the function returns + * immediately after initiating the transfer function. The application has to get the + * transfer status to see when the transfer is complete. In other words, after calling the non-blocking + * (asynchronous) transfer function, the application must get the transfer status to check if the transmit + * is completed or not. + * + * @param base The EMVSIM peripheral base address. + * @param context A pointer to a smart card driver context structure. + * @param xfer A pointer to the smart card transfer structure where the linked buffers and sizes are stored. + * + * @return An error code or kStatus_SMARTCARD_Success. + */ +status_t SMARTCARD_EMVSIM_TransferNonBlocking(EMVSIM_Type *base, smartcard_context_t *context, smartcard_xfer_t *xfer); + +/*! + * @brief Controls the EMVSIM module per different user request. + * + * @param base The EMVSIM peripheral base address. + * @param context A pointer to a smart card driver context structure. + * @param control Control type. + * @param param Integer value of specific to control command. + * + * return kStatus_SMARTCARD_Success in success. + * return kStatus_SMARTCARD_OtherError in case of error. + */ +status_t SMARTCARD_EMVSIM_Control(EMVSIM_Type *base, + smartcard_context_t *context, + smartcard_control_t control, + uint32_t param); + +/*! + * @brief Handles EMVSIM module interrupts. + * + * @param base The EMVSIM peripheral base address. + * @param context A pointer to a smart card driver context structure. + */ +void SMARTCARD_EMVSIM_IRQHandler(EMVSIM_Type *base, smartcard_context_t *context); +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_SMARTCARD_EMVSIM_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_emvsim.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_emvsim.c new file mode 100644 index 00000000000..feaea3a24d4 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_emvsim.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_smartcard_emvsim.h" +#include "fsl_smartcard_phy_emvsim.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static uint32_t smartcard_phy_emvsim_InterfaceClockInit(EMVSIM_Type *base, + const smartcard_interface_config_t *config, + uint32_t srcClock_Hz); + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief This function initializes clock module used for card clock generation + */ +static uint32_t smartcard_phy_emvsim_InterfaceClockInit(EMVSIM_Type *base, + const smartcard_interface_config_t *config, + uint32_t srcClock_Hz) +{ + assert((NULL != config) && (0u != srcClock_Hz)); + + uint32_t emvsimClkMhz = 0u; + uint8_t emvsimPRSCValue; + + /* Retrieve EMV SIM clock */ + emvsimClkMhz = srcClock_Hz / 1000000u; + /* Calculate MOD value */ + emvsimPRSCValue = (emvsimClkMhz * 1000u) / (config->smartCardClock / 1000u); + /* Set clock prescaler */ + base->CLKCFG = (base->CLKCFG & ~EMVSIM_CLKCFG_CLK_PRSC_MASK) | EMVSIM_CLKCFG_CLK_PRSC(emvsimPRSCValue); + + return config->smartCardClock; +} + +void SMARTCARD_PHY_EMVSIM_GetDefaultConfig(smartcard_interface_config_t *config) +{ + assert((NULL != config)); + + config->clockToResetDelay = SMARTCARD_INIT_DELAY_CLOCK_CYCLES; + config->vcc = kSMARTCARD_VoltageClassB3_3V; +} + +status_t SMARTCARD_PHY_EMVSIM_Init(EMVSIM_Type *base, smartcard_interface_config_t const *config, uint32_t srcClock_Hz) +{ + if ((NULL == config) || (0u == srcClock_Hz)) + { + return kStatus_SMARTCARD_InvalidInput; + } + + /* SMARTCARD clock initialization. Clock is still not active after this call */ + if (config->smartCardClock != smartcard_phy_emvsim_InterfaceClockInit(base, config, srcClock_Hz)) + { + return kStatus_SMARTCARD_OtherError; + } + /* Configure EMVSIM direct interface driver interrupt occur according card presence */ + if (base->PCSR & EMVSIM_PCSR_SPDP_MASK) + { + base->PCSR &= ~EMVSIM_PCSR_SPDES_MASK; + } + else + { + base->PCSR |= EMVSIM_PCSR_SPDES_MASK; + } + /* Un-mask presence detect interrupt flag */ + base->PCSR &= ~EMVSIM_PCSR_SPDIM_MASK; + + return kStatus_SMARTCARD_Success; +} + +void SMARTCARD_PHY_EMVSIM_Deinit(EMVSIM_Type *base, const smartcard_interface_config_t *config) +{ + assert((NULL != config)); + /* Deactivate VCC, CLOCK */ + base->PCSR &= ~(EMVSIM_PCSR_SCEN_MASK | EMVSIM_PCSR_SVCC_EN_MASK); +} + +status_t SMARTCARD_PHY_EMVSIM_Activate(EMVSIM_Type *base, + smartcard_context_t *context, + smartcard_reset_type_t resetType) +{ + if ((NULL == context) || (NULL == context->timeDelay)) + { + return kStatus_SMARTCARD_InvalidInput; + } + assert(context->interfaceConfig.vcc == kSMARTCARD_VoltageClassB3_3V); + + context->timersState.initCharTimerExpired = false; + context->resetType = resetType; + + /* Disable receiver to deactivate GPC timers trigger */ + base->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK; + if (resetType == kSMARTCARD_ColdReset) + { /* Set polarity of VCC to active high, Enable VCC for SMARTCARD, Enable smart card clock */ + base->PCSR = (base->PCSR & ~EMVSIM_PCSR_VCCENP_MASK) | (EMVSIM_PCSR_SVCC_EN_MASK | EMVSIM_PCSR_SCEN_MASK); + /* Set transfer inversion to default(direct) value */ + base->CTRL &= ~EMVSIM_CTRL_IC_MASK; + } + else if (resetType == kSMARTCARD_WarmReset) + { /* Ensure that card is already active */ + if (!context->cardParams.active) + { /* Card is not active;hence return */ + return kStatus_SMARTCARD_CardNotActivated; + } + } + else + { + return kStatus_SMARTCARD_InvalidInput; + } + /* Set Reset low */ + base->PCSR &= ~EMVSIM_PCSR_SRST_MASK; + /* Calculate time delay needed for reset */ + uint32_t temp = (uint32_t)((float)(1 + (float)(((float)(1000u * context->interfaceConfig.clockToResetDelay)) / + ((float)context->interfaceConfig.smartCardClock / 1000)))); + context->timeDelay(temp); + /* Pull reset HIGH Now to mark the end of Activation sequence */ + base->PCSR |= EMVSIM_PCSR_SRST_MASK; + /* Disable GPC timers input clock */ + base->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK); + /* Down counter trigger, and clear any pending counter status flag */ + base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK | EMVSIM_TX_STATUS_GPCNT0_TO_MASK; + /* Set counter value for TS detection delay */ + base->GPCNT0_VAL = (SMARTCARD_INIT_DELAY_CLOCK_CYCLES + SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT); + /* Pre-load counter value for ATR duration delay */ + base->GPCNT1_VAL = (SMARTCARD_EMV_ATR_DURATION_ETU + SMARTCARD_ATR_DURATION_ADJUSTMENT); + /* Select the clock for GPCNT for both TS detection and early start of ATR duration counter */ + base->CLKCFG |= + (EMVSIM_CLKCFG_GPCNT0_CLK_SEL(kEMVSIM_GPCCardClock) | EMVSIM_CLKCFG_GPCNT1_CLK_SEL(kEMVSIM_GPCTxClock)); + /* Set receiver to ICM mode, Flush RX FIFO */ + base->CTRL |= (EMVSIM_CTRL_ICM_MASK | EMVSIM_CTRL_FLSH_RX_MASK); + /* Enable counter interrupt for TS detection */ + base->INT_MASK &= ~EMVSIM_INT_MASK_GPCNT0_IM_MASK; + /* Clear any pending status flags */ + base->RX_STATUS = 0xFFFFFFFFu; + /* Enable receiver */ + base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK; + /* Here the card was activated */ + context->cardParams.active = true; + + return kStatus_SMARTCARD_Success; +} + +status_t SMARTCARD_PHY_EMVSIM_Deactivate(EMVSIM_Type *base, smartcard_context_t *context) +{ + if ((NULL == context)) + { + return kStatus_SMARTCARD_InvalidInput; + } + + /* Assert Reset */ + base->PCSR &= ~EMVSIM_PCSR_SRST_MASK; + /* Stop SMARTCARD clock generation */ + base->PCSR &= ~EMVSIM_PCSR_SCEN_MASK; + /* Deactivate card by disabling VCC */ + base->PCSR &= ~EMVSIM_PCSR_SVCC_EN_MASK; + /* According EMV 4.3 specification deactivation sequence should be done within 100ms. + * The period is measured from the time that RST is set to state L to the time that Vcc + * reaches 0.4 V or less. + */ + context->timeDelay(100 * 1000); + /* Here the card was deactivated */ + context->cardParams.active = false; + + return kStatus_SMARTCARD_Success; +} + +status_t SMARTCARD_PHY_EMVSIM_Control(EMVSIM_Type *base, + smartcard_context_t *context, + smartcard_interface_control_t control, + uint32_t param) +{ + if ((NULL == context)) + { + return kStatus_SMARTCARD_InvalidInput; + } + + switch (control) + { + case kSMARTCARD_InterfaceSetVcc: + /* Only 3.3V interface supported by the direct interface */ + assert((smartcard_card_voltage_class_t)param == kSMARTCARD_VoltageClassB3_3V); + context->interfaceConfig.vcc = (smartcard_card_voltage_class_t)param; + break; + case kSMARTCARD_InterfaceSetClockToResetDelay: + /* Set interface clock to Reset delay set by caller */ + context->interfaceConfig.clockToResetDelay = param; + break; + case kSMARTCARD_InterfaceReadStatus: + /* Expecting active low present detect */ + context->cardParams.present = + (emvsim_presence_detect_status_t)((base->PCSR & EMVSIM_PCSR_SPDP_MASK) >> EMVSIM_PCSR_SPDP_SHIFT) == + kEMVSIM_DetectPinIsLow; + break; + default: + return kStatus_SMARTCARD_InvalidInput; + } + + return kStatus_SMARTCARD_Success; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_emvsim.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_emvsim.h new file mode 100644 index 00000000000..fa4112396dc --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_emvsim.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_SMARTCARD_PHY_EMVSIM_H_ +#define _FSL_SMARTCARD_PHY_EMVSIM_H_ + +#include "fsl_smartcard.h" + +/*! + * @addtogroup smartcard_phy_emvsim_driver + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Smart card define which specifies the adjustment number of clock cycles during which an ATR string has to be received. + */ +#define SMARTCARD_ATR_DURATION_ADJUSTMENT (360u) + +/*! @brief Smart card define which specifies the adjustment number of clock cycles until an initial 'TS' character has to be + * received. */ +#define SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT (4200u) + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Fills in the smartcardInterfaceConfig structure with default values. + * + * @param config The user configuration structure of type smartcard_interface_config_t. + * Function fill in members: + * clockToResetDelay = 42000, + * vcc = kSmartcardVoltageClassB3_3V, + * with default values. + */ +void SMARTCARD_PHY_EMVSIM_GetDefaultConfig(smartcard_interface_config_t *config); + +/*! + * @brief Configures a Smart card interface. + * + * @param base The Smart card peripheral module base address. + * @param config The user configuration structure of type smartcard_interface_config_t. The user + * is responsible to fill out the members of this structure and to pass the pointer of this structure + * into this function or call SMARTCARD_PHY_EMVSIMInitUserConfigDefault to fill out structure with default values. + * @param srcClock_Hz Smart card clock generation module source clock. + * + * @retval kStatus_SMARTCARD_Success or kStatus_SMARTCARD_OtherError for an error. + */ +status_t SMARTCARD_PHY_EMVSIM_Init(EMVSIM_Type *base, const smartcard_interface_config_t *config, uint32_t srcClock_Hz); + +/*! + * @brief De-initializes a Smart card interface, stops the Smart card clock, and disables the VCC. + * + * @param base Smart card peripheral module base address. + * @param config Smart card configuration structure. + */ +void SMARTCARD_PHY_EMVSIM_Deinit(EMVSIM_Type *base, const smartcard_interface_config_t *config); + +/*! + * @brief Activates the Smart card IC. + * + * @param base The EMVSIM peripheral base address. + * @param context A pointer to a Smart card driver context structure. + * @param resetType type of reset to be performed, possible values + * = kSmartcardColdReset, kSmartcardWarmReset + * + * @retval kStatus_SMARTCARD_Success or kStatus_SMARTCARD_OtherError for an error. + */ +status_t SMARTCARD_PHY_EMVSIM_Activate(EMVSIM_Type *base, + smartcard_context_t *context, + smartcard_reset_type_t resetType); + +/*! + * @brief De-activates the Smart card IC. + * + * @param base The EMVSIM peripheral base address. + * @param context A pointer to a Smart card driver context structure. + * + * @retval kStatus_SMARTCARD_Success or kStatus_SMARTCARD_OtherError for an error. + */ +status_t SMARTCARD_PHY_EMVSIM_Deactivate(EMVSIM_Type *base, smartcard_context_t *context); + +/*! + * @brief Controls the Smart card interface IC. + * + * @param base The EMVSIM peripheral base address. + * @param context A pointer to a Smart card driver context structure. + * @param control A interface command type. + * @param param Integer value specific to control type + * + * @retval kStatus_SMARTCARD_Success or kStatus_SMARTCARD_OtherError for an error. + */ +status_t SMARTCARD_PHY_EMVSIM_Control(EMVSIM_Type *base, + smartcard_context_t *context, + smartcard_interface_control_t control, + uint32_t param); +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_SMARTCARD_PHY_EMVSIM_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_ncn8025.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_ncn8025.c new file mode 100644 index 00000000000..7116896e189 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_ncn8025.c @@ -0,0 +1,506 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_smartcard_phy_ncn8025.h" +#if (defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT)) +#include "fsl_smartcard_emvsim.h" +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* +* Prototypes +******************************************************************************/ +static uint32_t smartcard_phy_ncn8025_InterfaceClockInit(void *base, + smartcard_interface_config_t const *config, + uint32_t srcClock_Hz); +static void smartcard_phy_ncn8025_InterfaceClockDeinit(void *base, smartcard_interface_config_t const *config); +#if !(defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT)) +extern void smartcard_uart_TimerStart(uint8_t channel, uint32_t time); +#endif + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* +* Code +******************************************************************************/ +/*! + * @brief This function initializes clock module used for card clock generation + */ +static uint32_t smartcard_phy_ncn8025_InterfaceClockInit(void *base, + smartcard_interface_config_t const *config, + uint32_t srcClock_Hz) +{ + assert((NULL != config)); +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + assert(config->clockModule < FSL_FEATURE_SOC_EMVSIM_COUNT); + + uint32_t emvsimClkMhz = 0u; + uint8_t emvsimPRSCValue; + + /* Retrieve EMV SIM clock */ + emvsimClkMhz = srcClock_Hz / 1000000u; + /* Calculate MOD value */ + emvsimPRSCValue = (emvsimClkMhz * 1000u) / (config->smartCardClock / 1000u); + /* Set clock prescaler */ + ((EMVSIM_Type *)base)->CLKCFG = + (((EMVSIM_Type *)base)->CLKCFG & ~EMVSIM_CLKCFG_CLK_PRSC_MASK) | EMVSIM_CLKCFG_CLK_PRSC(emvsimPRSCValue); + /* Enable smart card clock */ + ((EMVSIM_Type *)base)->PCSR |= EMVSIM_PCSR_SCEN_MASK; + + return config->smartCardClock; +#elif defined(FSL_FEATURE_SOC_FTM_COUNT) && (FSL_FEATURE_SOC_FTM_COUNT) + assert(config->clockModule < FSL_FEATURE_SOC_FTM_COUNT); + + uint32_t periph_clk_mhz = 0u; + uint16_t ftmModValue; + uint32_t ftm_base[] = FTM_BASE_ADDRS; + FTM_Type *ftmBase = (FTM_Type *)ftm_base[config->clockModule]; + + /* Retrieve FTM system clock */ + periph_clk_mhz = srcClock_Hz / 1000000u; + /* Calculate MOD value */ + ftmModValue = ((periph_clk_mhz * 1000u / 2u) / (config->smartCardClock / 1000u)) - 1u; + /* un-gate FTM peripheral clock */ + switch (config->clockModule) + { + case 0u: + CLOCK_EnableClock(kCLOCK_Ftm0); + break; +#if FSL_FEATURE_SOC_FTM_COUNT > 1 + case 1u: + CLOCK_EnableClock(kCLOCK_Ftm1); + break; +#endif +#if FSL_FEATURE_SOC_FTM_COUNT > 2 + case 2u: + CLOCK_EnableClock(kCLOCK_Ftm2); + break; +#endif +#if FSL_FEATURE_SOC_FTM_COUNT > 3 + case 3u: + CLOCK_EnableClock(kCLOCK_Ftm3); + break; +#endif + default: + return 0u; + } + /* Initialize FTM driver */ + /* Reset FTM prescaler to 'Divide by 1', i.e., to be same clock as peripheral clock + * Disable FTM counter, Set counter to operates in Up-counting mode */ + ftmBase->SC &= ~(FTM_SC_PS_MASK | FTM_SC_CLKS_MASK | FTM_SC_CPWMS_MASK); + /* Set initial counter value */ + ftmBase->CNTIN = 0u; + /* Set MOD value */ + ftmBase->MOD = ftmModValue; + /* Configure mode to output compare, toggle output on match */ + ftmBase->CONTROLS[config->clockModuleChannel].CnSC = (FTM_CnSC_ELSA_MASK | FTM_CnSC_MSA_MASK); + /* Configure a match value to toggle output at */ + ftmBase->CONTROLS[config->clockModuleChannel].CnV = 1; + /* Set clock source to start the counter : System clock */ + ftmBase->SC = FTM_SC_CLKS(1); + /* Re-calculate the actually configured smartcard clock and return to caller */ + return (uint32_t)(((periph_clk_mhz * 1000u / 2u) / (ftmBase->MOD + 1u)) * 1000u); +#else + return 0u; +#endif +} + +/*! + * @brief This function de-initialize clock module used for card clock generation + */ +static void smartcard_phy_ncn8025_InterfaceClockDeinit(void *base, smartcard_interface_config_t const *config) +{ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + assert((config->clockModule < FSL_FEATURE_SOC_EMVSIM_COUNT) && (NULL != base)); + + /* Disable smart card clock */ + ((EMVSIM_Type *)base)->PCSR &= ~EMVSIM_PCSR_SCEN_MASK; +#elif defined(FSL_FEATURE_SOC_FTM_COUNT) && (FSL_FEATURE_SOC_FTM_COUNT) + assert(config->clockModule < FSL_FEATURE_SOC_FTM_COUNT); + /* gate FTM peripheral clock */ + switch (config->clockModule) + { + case 0u: + CLOCK_DisableClock(kCLOCK_Ftm0); + break; +#if FSL_FEATURE_SOC_FTM_COUNT > 1 + case 1u: + CLOCK_DisableClock(kCLOCK_Ftm1); + break; +#endif +#if FSL_FEATURE_SOC_FTM_COUNT > 2 + case 2u: + CLOCK_DisableClock(kCLOCK_Ftm2); + break; +#endif +#if FSL_FEATURE_SOC_FTM_COUNT > 3 + case 3u: + CLOCK_DisableClock(kCLOCK_Ftm3); + break; +#endif + default: + break; + } +#endif +} + +void SMARTCARD_PHY_NCN8025_GetDefaultConfig(smartcard_interface_config_t *config) +{ + assert((NULL != config)); + + config->clockToResetDelay = SMARTCARD_INIT_DELAY_CLOCK_CYCLES; + config->vcc = kSMARTCARD_VoltageClassB3_3V; +} + +status_t SMARTCARD_PHY_NCN8025_Init(void *base, smartcard_interface_config_t const *config, uint32_t srcClock_Hz) +{ + if ((NULL == config) || (0u == srcClock_Hz)) + { + return kStatus_SMARTCARD_InvalidInput; + } + + /* Configure GPIO(CMDVCC, RST, INT, VSEL0, VSEL1) pins */ + uint32_t gpio_base[] = GPIO_BASE_ADDRS; + IRQn_Type port_irq[] = PORT_IRQS; + /* Set VSEL pins to low level context */ + ((GPIO_Type *)gpio_base[config->vsel0Port])->PCOR |= (1u << config->vsel0Pin); + ((GPIO_Type *)gpio_base[config->vsel1Port])->PCOR |= (1u << config->vsel1Pin); + /* Set VSEL pins to output pins */ + ((GPIO_Type *)gpio_base[config->vsel0Port])->PDDR |= (1u << config->vsel0Pin); + ((GPIO_Type *)gpio_base[config->vsel1Port])->PDDR |= (1u << config->vsel1Pin); +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + /* Set CMD_VCC pin to logic level '1', to allow card detection interrupt from NCN8025 */ + ((EMVSIM_Type *)base)->PCSR |= EMVSIM_PCSR_SVCC_EN_MASK; + ((EMVSIM_Type *)base)->PCSR &= ~EMVSIM_PCSR_VCCENP_MASK; +#else + /* Set RST pin to zero context and CMDVCC to high context */ + ((GPIO_Type *)gpio_base[config->resetPort])->PCOR |= (1u << config->resetPin); + ((GPIO_Type *)gpio_base[config->controlPort])->PSOR |= (1u << config->controlPin); + /* Set CMDVCC, RESET pins as output pins */ + ((GPIO_Type *)gpio_base[config->resetPort])->PDDR |= (1u << config->resetPin); + ((GPIO_Type *)gpio_base[config->controlPort])->PDDR |= (1u << config->controlPin); + +#endif + /* Initialize INT pin */ + ((GPIO_Type *)gpio_base[config->irqPort])->PDDR &= ~(1u << config->irqPin); + /* Enable Port IRQ for smartcard presence detection */ + NVIC_EnableIRQ(port_irq[config->irqPort]); + /* Smartcard clock initialization */ + if (config->smartCardClock != smartcard_phy_ncn8025_InterfaceClockInit(base, config, srcClock_Hz)) + { + return kStatus_SMARTCARD_OtherError; + } + + return kStatus_SMARTCARD_Success; +} + +void SMARTCARD_PHY_NCN8025_Deinit(void *base, smartcard_interface_config_t *config) +{ + assert((NULL != config)); + + IRQn_Type port_irq[] = PORT_IRQS; + NVIC_DisableIRQ(port_irq[config->irqPort]); + /* Stop smartcard clock */ + smartcard_phy_ncn8025_InterfaceClockDeinit(base, config); +} + +status_t SMARTCARD_PHY_NCN8025_Activate(void *base, smartcard_context_t *context, smartcard_reset_type_t resetType) +{ + if ((NULL == context) || (NULL == context->timeDelay)) + { + return kStatus_SMARTCARD_InvalidInput; + } + + context->timersState.initCharTimerExpired = false; + context->resetType = resetType; + uint32_t gpio_base[] = GPIO_BASE_ADDRS; +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + EMVSIM_Type *emvsimBase = (EMVSIM_Type *)base; +#endif + + if (resetType == kSMARTCARD_ColdReset) + { /* Ensure that RST is LOW and CMD is high here so that PHY goes in normal mode */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + emvsimBase->PCSR = + (emvsimBase->PCSR & ~(EMVSIM_PCSR_VCCENP_MASK | EMVSIM_PCSR_SRST_MASK)) | EMVSIM_PCSR_SVCC_EN_MASK; +#else + ((GPIO_Type *)gpio_base[context->interfaceConfig.resetPort])->PCOR |= (1u << context->interfaceConfig.resetPin); + ((GPIO_Type *)gpio_base[context->interfaceConfig.controlPort])->PSOR |= + (1u << context->interfaceConfig.controlPin); +#endif + /* vcc = 5v: vsel0=0,vsel1= 1 + * vcc = 3.3v: vsel0=x,vsel1= 0 + * vcc = 1.8v: vsel0=1,vsel1= 1 */ + /* Setting of VSEL1 pin */ + if ((kSMARTCARD_VoltageClassA5_0V == context->interfaceConfig.vcc) || + (kSMARTCARD_VoltageClassC1_8V == context->interfaceConfig.vcc)) + { + ((GPIO_Type *)gpio_base[context->interfaceConfig.vsel1Port])->PSOR |= + (1u << context->interfaceConfig.vsel1Pin); + } + else + { + ((GPIO_Type *)gpio_base[context->interfaceConfig.vsel1Port])->PCOR |= + (1u << context->interfaceConfig.vsel1Pin); + } + /* Setting of VSEL0 pin */ + if (kSMARTCARD_VoltageClassC1_8V == context->interfaceConfig.vcc) + { + ((GPIO_Type *)gpio_base[context->interfaceConfig.vsel0Port])->PSOR |= + (1u << context->interfaceConfig.vsel0Pin); + } + else + { + ((GPIO_Type *)gpio_base[context->interfaceConfig.vsel0Port])->PCOR |= + (1u << context->interfaceConfig.vsel0Pin); + } +/* Set PHY to start Activation sequence by pulling CMDVCC low */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + emvsimBase->PCSR |= EMVSIM_PCSR_VCCENP_MASK; +#else + ((GPIO_Type *)gpio_base[context->interfaceConfig.controlPort])->PCOR |= + (1u << context->interfaceConfig.controlPin); +#endif + } + else if (resetType == kSMARTCARD_WarmReset) + { /* Ensure that card is already active */ + if (!context->cardParams.active) + { /* Card is not active;hence return */ + return kStatus_SMARTCARD_CardNotActivated; + } +/* Pull RESET low to start warm Activation sequence */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + emvsimBase->PCSR &= ~EMVSIM_PCSR_SRST_MASK; +#else + ((GPIO_Type *)gpio_base[context->interfaceConfig.resetPort])->PCOR |= (1u << context->interfaceConfig.resetPin); +#endif + } + else + { + return kStatus_SMARTCARD_InvalidInput; + } + /* Wait for sometime as specified by EMV before pulling RST High + * As per EMV delay <= 42000 Clock cycles + * as per PHY delay >= 1us + */ + uint32_t temp = (uint32_t)((float)(1 + (float)(((float)(1000u * context->interfaceConfig.clockToResetDelay)) / + ((float)context->interfaceConfig.smartCardClock)))); + context->timeDelay(temp); + +/* Pull reset HIGH Now to mark the end of Activation sequence */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + emvsimBase->PCSR |= EMVSIM_PCSR_SRST_MASK; +#else + ((GPIO_Type *)gpio_base[context->interfaceConfig.resetPort])->PSOR |= (1u << context->interfaceConfig.resetPin); +#endif + +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + /* Down counter trigger, and clear any pending counter status flag */ + emvsimBase->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK | EMVSIM_TX_STATUS_GPCNT0_TO_MASK; + /* Set counter value for TS detection delay */ + emvsimBase->GPCNT0_VAL = (SMARTCARD_INIT_DELAY_CLOCK_CYCLES + SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT); + /* Pre-load counter value for ATR duration delay */ + emvsimBase->GPCNT1_VAL = (SMARTCARD_EMV_ATR_DURATION_ETU + SMARTCARD_ATR_DURATION_ADJUSTMENT); + /* Select the clock for GPCNT for both TS detection and early start of ATR duration counter */ + emvsimBase->CLKCFG = + (emvsimBase->CLKCFG & ~EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK) | EMVSIM_CLKCFG_GPCNT0_CLK_SEL(kEMVSIM_GPCCardClock); + /* Set receiver to ICM mode, Flush RX FIFO */ + emvsimBase->CTRL |= (EMVSIM_CTRL_ICM_MASK | EMVSIM_CTRL_FLSH_RX_MASK); + /* Enable counter interrupt for TS detection */ + emvsimBase->INT_MASK &= ~EMVSIM_INT_MASK_GPCNT0_IM_MASK; + /* Clear any pending status flags */ + emvsimBase->RX_STATUS = 0xFFFFFFFFu; + /* Enable receiver */ + emvsimBase->CTRL |= EMVSIM_CTRL_RCV_EN_MASK; +#else + /* Enable external timer for TS detection time-out */ + smartcard_uart_TimerStart(context->interfaceConfig.tsTimerId, + (SMARTCARD_INIT_DELAY_CLOCK_CYCLES + SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT) * + (CLOCK_GetFreq(kCLOCK_CoreSysClk) / context->interfaceConfig.smartCardClock)); +#endif + /* Here the card was activated */ + context->cardParams.active = true; + + return kStatus_SMARTCARD_Success; +} + +status_t SMARTCARD_PHY_NCN8025_Deactivate(void *base, smartcard_context_t *context) +{ + if ((NULL == context)) + { + return kStatus_SMARTCARD_InvalidInput; + } + +#if !(defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT)) + uint32_t gpio_base[] = GPIO_BASE_ADDRS; +#endif +/* Tell PHY to start Deactivation sequence by pulling CMD high and reset low */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + ((EMVSIM_Type *)base)->PCSR |= EMVSIM_PCSR_SVCC_EN_MASK; + ((EMVSIM_Type *)base)->PCSR &= ~EMVSIM_PCSR_VCCENP_MASK; + ((EMVSIM_Type *)base)->PCSR &= ~EMVSIM_PCSR_SRST_MASK; +#else + ((GPIO_Type *)gpio_base[context->interfaceConfig.controlPort])->PSOR |= (1u << context->interfaceConfig.controlPin); + ((GPIO_Type *)gpio_base[context->interfaceConfig.resetPort])->PCOR |= (1u << context->interfaceConfig.resetPin); +#endif + /* According EMV 4.3 specification deactivation sequence should be done within 100ms. + * The period is measured from the time that RST is set to state L to the time that Vcc + * reaches 0.4 V or less. + */ + context->timeDelay(100); + /* Here the card was deactivated */ + context->cardParams.active = false; + + return kStatus_SMARTCARD_Success; +} + +status_t SMARTCARD_PHY_NCN8025_Control(void *base, + smartcard_context_t *context, + smartcard_interface_control_t control, + uint32_t param) +{ + if ((NULL == context)) + { + return kStatus_SMARTCARD_InvalidInput; + } + +#if !(defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT)) + uint32_t gpio_base[] = GPIO_BASE_ADDRS; +#endif + + switch (control) + { + case kSMARTCARD_InterfaceSetVcc: + /* Set card parameter to VCC level set by caller */ + context->interfaceConfig.vcc = (smartcard_card_voltage_class_t)param; + break; + case kSMARTCARD_InterfaceSetClockToResetDelay: + /* Set interface clock to Reset delay set by caller */ + context->interfaceConfig.clockToResetDelay = param; + break; + case kSMARTCARD_InterfaceReadStatus: +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + /* Expecting active low present detect */ + context->cardParams.present = + ((emvsim_presence_detect_status_t)((((EMVSIM_Type *)base)->PCSR & EMVSIM_PCSR_SPDP_MASK) >> + EMVSIM_PCSR_SPDP_SHIFT) == kEMVSIM_DetectPinIsLow); +#else + if (((GPIO_Type *)gpio_base[context->interfaceConfig.controlPort])->PDIR & + (1u << context->interfaceConfig.controlPin)) + { + if (((GPIO_Type *)gpio_base[context->interfaceConfig.irqPort])->PDIR & + (1u << context->interfaceConfig.irqPin)) + { /* CMDVCC is high => session is inactive and INT is high => card is present */ + context->cardParams.present = true; + context->cardParams.active = false; + context->cardParams.faulty = false; + context->cardParams.status = SMARTCARD_NCN8025_STATUS_PRES; + } + else + { /* CMDVCC is high => session is inactive and INT is low => card is absent */ + context->cardParams.present = false; + context->cardParams.active = false; + context->cardParams.faulty = false; + context->cardParams.status = 0u; + } + } + else + { + if (((GPIO_Type *)gpio_base[context->interfaceConfig.irqPort])->PDIR & + (1u << context->interfaceConfig.irqPin)) + { /* CMDVCC is low => session is active and INT is high => card is present */ + context->cardParams.present = true; + context->cardParams.active = true; + context->cardParams.faulty = false; + context->cardParams.status = SMARTCARD_NCN8025_STATUS_PRES | SMARTCARD_NCN8025_STATUS_ACTIVE; + } + else + { /* CMDVCC is low => session is active and INT is low => card is absent/deactivated due to some fault + */ + /* A fault has been detected (card has been deactivated) but The cause of the deactivation is not + * yet known. + * Lets determine the cause of fault by pulling CMD high + */ + ((GPIO_Type *)gpio_base[context->interfaceConfig.controlPort])->PSOR |= + (1u << context->interfaceConfig.controlPin); + + if (((GPIO_Type *)gpio_base[context->interfaceConfig.irqPort])->PDIR & + (1u << context->interfaceConfig.irqPin)) + { /* The fault detected was not a card removal (card is still present) */ + /* If INT follows CMDVCCN, the fault is due to a supply voltage drop, a VCC over-current + * detection or overheating. */ + context->cardParams.present = true; + context->cardParams.active = false; + context->cardParams.faulty = true; + context->cardParams.status = SMARTCARD_NCN8025_STATUS_PRES | SMARTCARD_NCN8025_STATUS_FAULTY | + SMARTCARD_NCN8025_STATUS_CARD_DEACTIVATED; + } + else + { /* The fault detected was the card removal + * Setting CMDVCCN allows checking if the deactivation is due to card removal. + * In this case the INT pin will stay low after CMDVCCN is high. + */ + context->cardParams.present = false; + context->cardParams.active = false; + context->cardParams.faulty = false; + context->cardParams.status = + SMARTCARD_NCN8025_STATUS_CARD_REMOVED | SMARTCARD_NCN8025_STATUS_CARD_DEACTIVATED; + } + } + } +#endif + break; + default: + return kStatus_SMARTCARD_InvalidInput; + } + + return kStatus_SMARTCARD_Success; +} + +void SMARTCARD_PHY_NCN8025_IRQHandler(void *base, smartcard_context_t *context) +{ + if ((NULL == context)) + { + return; + } + + /* Read interface/card status */ + SMARTCARD_PHY_NCN8025_Control(base, context, kSMARTCARD_InterfaceReadStatus, 0u); + /* Invoke callback if there is one */ + if (NULL != context->interfaceCallback) + { + context->interfaceCallback(context, context->interfaceCallbackParam); + } +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_ncn8025.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_ncn8025.h new file mode 100644 index 00000000000..026f717ad0f --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_ncn8025.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_SMARTCARD_PHY_NCN8025_H_ +#define _FSL_SMARTCARD_PHY_NCN8025_H_ + +#include "fsl_smartcard.h" + +/*! + * @addtogroup smartcard_phy_ncn8025_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief SMARTCARD define which specify adjustment number of clock cycles during which ATR string has to be received + */ +#define SMARTCARD_ATR_DURATION_ADJUSTMENT (360u) + +/*! @brief SMARTCARD define which specify adjustment number of clock cycles until initial 'TS' character has to be + * received */ +#define SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT (4200u) + +/*! @brief Masks for NCN8025 status register */ +#define SMARTCARD_NCN8025_STATUS_PRES (0x01u) /*!< SMARTCARD phy NCN8025 smartcard present status */ +#define SMARTCARD_NCN8025_STATUS_ACTIVE (0x02u) /*!< SMARTCARD phy NCN8025 smartcard active status */ +#define SMARTCARD_NCN8025_STATUS_FAULTY (0x04u) /*!< SMARTCARD phy NCN8025 smartcard faulty status */ +#define SMARTCARD_NCN8025_STATUS_CARD_REMOVED (0x08u) /*!< SMARTCARD phy NCN8025 smartcard removed status */ +#define SMARTCARD_NCN8025_STATUS_CARD_DEACTIVATED (0x10u) /*!< SMARTCARD phy NCN8025 smartcard deactivated status */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Fill in config structure with default values. + * + * @param config The smartcard user configuration structure which contains configuration structure of type + * smartcard_interface_config_t. + * Function fill in members: + * clockToResetDelay = 42000, + * vcc = kSmartcardVoltageClassB3_3V, + * with default values. + */ +void SMARTCARD_PHY_NCN8025_GetDefaultConfig(smartcard_interface_config_t *config); + +/*! + * @brief Initializes an SMARTCARD interface instance for operation. + * + * @param base The SMARTCARD peripheral base address. + * @param config The user configuration structure of type smartcard_interface_config_t. The user + * can call to fill out configuration structure function SMARTCARD_PHY_NCN8025_GetDefaultConfig(). + * @param srcClock_Hz Smartcard clock generation module source clock. + * + * @retval kStatus_SMARTCARD_Success or kStatus_SMARTCARD_OtherError in case of error. + */ +status_t SMARTCARD_PHY_NCN8025_Init(void *base, smartcard_interface_config_t const *config, uint32_t srcClock_Hz); + +/*! + * @brief De-initializes an SMARTCARD interface. Stops smartcard clock and disable VCC. + * + * @param base The SMARTCARD peripheral module base address. + * @param config The user configuration structure of type smartcard_interface_config_t. + */ +void SMARTCARD_PHY_NCN8025_Deinit(void *base, smartcard_interface_config_t *config); + +/*! + * @brief Activates the smart card IC. + * + * @param base The SMARTCARD peripheral module base address. + * @param context A pointer to a smartcard driver context structure. + * @param resetType type of reset to be performed, possible values + * = kSmartcardColdReset, kSmartcardWarmReset + * + * @retval kStatus_SMARTCARD_Success or kStatus_SMARTCARD_OtherError in case of error. + */ +status_t SMARTCARD_PHY_NCN8025_Activate(void *base, smartcard_context_t *context, smartcard_reset_type_t resetType); + +/*! + * @brief De-activates the smart card IC. + * + * @param base The SMARTCARD peripheral module base address. + * @param context A pointer to a smartcard driver context structure. + * + * @retval kStatus_SMARTCARD_Success or kStatus_SMARTCARD_OtherError in case of error. + */ +status_t SMARTCARD_PHY_NCN8025_Deactivate(void *base, smartcard_context_t *context); + +/*! + * @brief Controls SMARTCARD interface IC. + * + * @param base The SMARTCARD peripheral module base address. + * @param context A pointer to a smartcard driver context structure. + * @param control A interface command type. + * @param param Integer value specific to control type + * + * @retval kStatus_SMARTCARD_Success or kStatus_SMARTCARD_OtherError in case of error. + */ +status_t SMARTCARD_PHY_NCN8025_Control(void *base, + smartcard_context_t *context, + smartcard_interface_control_t control, + uint32_t param); + +/*! + * @brief SMARTCARD interface IC IRQ ISR. + * + * @param base The SMARTCARD peripheral module base address. + * @param context The smartcard context pointer. + */ +void SMARTCARD_PHY_NCN8025_IRQHandler(void *base, smartcard_context_t *context); +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_SMARTCARD_NCN8025_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_tda8035.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_tda8035.c new file mode 100644 index 00000000000..99733133218 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_tda8035.c @@ -0,0 +1,563 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_smartcard_phy_tda8035.h" +#if (defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT)) +#include "fsl_smartcard_emvsim.h" +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* +* Prototypes +******************************************************************************/ +static uint32_t smartcard_phy_tda8035_InterfaceClockInit(void *base, + smartcard_interface_config_t const *config, + uint32_t srcClock_Hz); +static void smartcard_phy_tda8035_InterfaceClockDeinit(void *base, smartcard_interface_config_t const *config); +static void smartcard_phy_tda8035_InterfaceClockEnable(void *base, smartcard_interface_config_t const *config); +#if !(defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT)) +extern void smartcard_uart_TimerStart(uint8_t channel, uint32_t time); +#endif + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* +* Code +******************************************************************************/ + +/*! + * @brief This function initializes clock module used for card clock generation + */ +static uint32_t smartcard_phy_tda8035_InterfaceClockInit(void *base, + smartcard_interface_config_t const *config, + uint32_t srcClock_Hz) +{ + assert((NULL != config)); +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + assert(config->clockModule < FSL_FEATURE_SOC_EMVSIM_COUNT); + + uint32_t emvsimClkMhz = 0u; + uint8_t emvsimPRSCValue; + + /* Retrieve EMV SIM clock */ + emvsimClkMhz = srcClock_Hz / 1000000u; + /* Calculate MOD value */ + emvsimPRSCValue = (emvsimClkMhz * 1000u) / (config->smartCardClock / 1000u); + /* Set clock prescaler */ + ((EMVSIM_Type *)base)->CLKCFG = + (((EMVSIM_Type *)base)->CLKCFG & ~EMVSIM_CLKCFG_CLK_PRSC_MASK) | EMVSIM_CLKCFG_CLK_PRSC(emvsimPRSCValue); + + return config->smartCardClock; +#elif defined(FSL_FEATURE_SOC_FTM_COUNT) && (FSL_FEATURE_SOC_FTM_COUNT) + assert(config->clockModule < FSL_FEATURE_SOC_FTM_COUNT); + + uint32_t periph_clk_mhz = 0u; + uint16_t ftmModValue; + uint32_t ftm_base[] = FTM_BASE_ADDRS; + FTM_Type *ftmBase = (FTM_Type *)ftm_base[config->clockModule]; + + /* Retrieve FTM system clock */ + periph_clk_mhz = srcClock_Hz / 1000000u; + /* Calculate MOD value */ + ftmModValue = ((periph_clk_mhz * 1000u / 2u) / (config->smartCardClock / 1000u)) - 1u; + /* un-gate FTM peripheral clock */ + switch (config->clockModule) + { + case 0u: +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(kCLOCK_Ftm0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + break; +#if FSL_FEATURE_SOC_FTM_COUNT > 1 + case 1u: +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(kCLOCK_Ftm1); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + break; +#endif +#if FSL_FEATURE_SOC_FTM_COUNT > 2 + case 2u: +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(kCLOCK_Ftm2); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + break; +#endif +#if FSL_FEATURE_SOC_FTM_COUNT > 3 + case 3u: +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(kCLOCK_Ftm3); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + break; +#endif + default: + return 0u; + } + /* Initialize FTM driver */ + /* Reset FTM prescaler to 'Divide by 1', i.e., to be same clock as peripheral clock + * Disable FTM counter, Set counter to operates in Up-counting mode */ + ftmBase->SC &= ~(FTM_SC_PS_MASK | FTM_SC_CLKS_MASK | FTM_SC_CPWMS_MASK); + /* Set initial counter value */ + ftmBase->CNTIN = 0u; + /* Set MOD value */ + ftmBase->MOD = ftmModValue; + /* Configure mode to output compare, toggle output on match */ + ftmBase->CONTROLS[config->clockModuleChannel].CnSC = (FTM_CnSC_ELSA_MASK | FTM_CnSC_MSA_MASK); + /* Configure a match value to toggle output at */ + ftmBase->CONTROLS[config->clockModuleChannel].CnV = 1; + /* Re-calculate the actually configured smartcard clock and return to caller */ + return (uint32_t)(((periph_clk_mhz * 1000u / 2u) / (ftmBase->MOD + 1u)) * 1000u); +#else + return 0u; +#endif +} + +/*! + * @brief This function de-initialize clock module used for card clock generation + */ +static void smartcard_phy_tda8035_InterfaceClockDeinit(void *base, smartcard_interface_config_t const *config) +{ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + assert((config->clockModule < FSL_FEATURE_SOC_EMVSIM_COUNT) && (NULL != base)); + + /* Disable smart card clock */ + ((EMVSIM_Type *)base)->PCSR &= ~EMVSIM_PCSR_SCEN_MASK; +#elif defined(FSL_FEATURE_SOC_FTM_COUNT) && (FSL_FEATURE_SOC_FTM_COUNT) + assert(config->clockModule < FSL_FEATURE_SOC_FTM_COUNT); + /* gate FTM peripheral clock */ + switch (config->clockModule) + { + case 0u: +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(kCLOCK_Ftm0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + break; +#if FSL_FEATURE_SOC_FTM_COUNT > 1 + case 1u: +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(kCLOCK_Ftm1); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + break; +#endif +#if FSL_FEATURE_SOC_FTM_COUNT > 2 + case 2u: +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(kCLOCK_Ftm2); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + break; +#endif +#if FSL_FEATURE_SOC_FTM_COUNT > 3 + case 3u: +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(kCLOCK_Ftm3); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + break; +#endif + default: + break; + } +#endif +} + +/*! + * @brief This function activate smart card clock + */ +static void smartcard_phy_tda8035_InterfaceClockEnable(void *base, smartcard_interface_config_t const *config) +{ +/* Enable smart card clock */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + ((EMVSIM_Type *)base)->PCSR |= EMVSIM_PCSR_SCEN_MASK; +#elif defined(FSL_FEATURE_SOC_FTM_COUNT) && (FSL_FEATURE_SOC_FTM_COUNT) + uint32_t ftm_base[] = FTM_BASE_ADDRS; + FTM_Type *ftmBase = (FTM_Type *)ftm_base[config->clockModule]; + /* Set clock source to start the counter : System clock */ + ftmBase->SC = FTM_SC_CLKS(1); +#endif +} + +/*! + * @brief This function deactivate smart card clock + */ +static void smartcard_phy_tda8035_InterfaceClockDisable(void *base, smartcard_interface_config_t const *config) +{ +/* Enable smart card clock */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + ((EMVSIM_Type *)base)->PCSR &= ~EMVSIM_PCSR_SCEN_MASK; +#elif defined(FSL_FEATURE_SOC_FTM_COUNT) && (FSL_FEATURE_SOC_FTM_COUNT) + uint32_t ftm_base[] = FTM_BASE_ADDRS; + FTM_Type *ftmBase = (FTM_Type *)ftm_base[config->clockModule]; + /* Set clock source to start the counter : System clock */ + ftmBase->SC &= ~FTM_SC_CLKS_MASK; +#endif +} + +void SMARTCARD_PHY_TDA8035_GetDefaultConfig(smartcard_interface_config_t *config) +{ + assert((NULL != config)); + + config->clockToResetDelay = SMARTCARD_INIT_DELAY_CLOCK_CYCLES; + config->vcc = kSMARTCARD_VoltageClassB3_3V; +} + +status_t SMARTCARD_PHY_TDA8035_Init(void *base, smartcard_interface_config_t const *config, uint32_t srcClock_Hz) +{ + if ((NULL == config) || (0u == srcClock_Hz)) + { + return kStatus_SMARTCARD_InvalidInput; + } + + /* Configure GPIO(CMDVCC, RST, INT, VSEL0, VSEL1) pins */ + uint32_t gpio_base[] = GPIO_BASE_ADDRS; + IRQn_Type port_irq[] = PORT_IRQS; + /* Set VSEL pins to low level context */ + ((GPIO_Type *)gpio_base[config->vsel0Port])->PCOR |= (1u << config->vsel0Pin); + ((GPIO_Type *)gpio_base[config->vsel1Port])->PCOR |= (1u << config->vsel1Pin); + /* Set VSEL pins to output pins */ + ((GPIO_Type *)gpio_base[config->vsel0Port])->PDDR |= (1u << config->vsel0Pin); + ((GPIO_Type *)gpio_base[config->vsel1Port])->PDDR |= (1u << config->vsel1Pin); + + /* vcc = 5v: vsel0=1,vsel1=1 + * vcc = 3.3v: vsel0=0,vsel1=1 + * vcc = 1.8v: vsel0=x,vsel1=0 */ + /* Setting of VSEL1 pin */ + if ((kSMARTCARD_VoltageClassA5_0V == config->vcc) || (kSMARTCARD_VoltageClassB3_3V == config->vcc)) + { + ((GPIO_Type *)gpio_base[config->vsel1Port])->PSOR |= (1u << config->vsel1Pin); + } + else + { + ((GPIO_Type *)gpio_base[config->vsel1Port])->PCOR |= (1u << config->vsel1Pin); + } + /* Setting of VSEL0 pin */ + if (kSMARTCARD_VoltageClassA5_0V == config->vcc) + { + ((GPIO_Type *)gpio_base[config->vsel0Port])->PSOR |= (1u << config->vsel0Pin); + } + else + { + ((GPIO_Type *)gpio_base[config->vsel0Port])->PCOR |= (1u << config->vsel0Pin); + } + +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + /* Set CMD_VCC pin to logic level '1', to allow card detection interrupt from TDA8035 */ + ((EMVSIM_Type *)base)->PCSR |= EMVSIM_PCSR_SVCC_EN_MASK; + ((EMVSIM_Type *)base)->PCSR &= ~EMVSIM_PCSR_VCCENP_MASK; +#else + /* Set RST pin to zero context and CMDVCC to high context */ + ((GPIO_Type *)gpio_base[config->resetPort])->PCOR |= (1u << config->resetPin); + ((GPIO_Type *)gpio_base[config->controlPort])->PSOR |= (1u << config->controlPin); + /* Set CMDVCC, RESET pins as output pins */ + ((GPIO_Type *)gpio_base[config->resetPort])->PDDR |= (1u << config->resetPin); + ((GPIO_Type *)gpio_base[config->controlPort])->PDDR |= (1u << config->controlPin); + +#endif + /* Initialize INT pin */ + ((GPIO_Type *)gpio_base[config->irqPort])->PDDR &= ~(1u << config->irqPin); + /* Enable Port IRQ for smartcard presence detection */ + NVIC_EnableIRQ(port_irq[config->irqPort]); + /* Smartcard clock initialization */ + if (config->smartCardClock != smartcard_phy_tda8035_InterfaceClockInit(base, config, srcClock_Hz)) + { + return kStatus_SMARTCARD_OtherError; + } + + return kStatus_SMARTCARD_Success; +} + +void SMARTCARD_PHY_TDA8035_Deinit(void *base, smartcard_interface_config_t *config) +{ + assert((NULL != config)); + + IRQn_Type port_irq[] = PORT_IRQS; + NVIC_DisableIRQ(port_irq[config->irqPort]); + /* Stop smartcard clock */ + smartcard_phy_tda8035_InterfaceClockDeinit(base, config); +} + +status_t SMARTCARD_PHY_TDA8035_Activate(void *base, smartcard_context_t *context, smartcard_reset_type_t resetType) +{ + if ((NULL == context) || (NULL == context->timeDelay)) + { + return kStatus_SMARTCARD_InvalidInput; + } + + context->timersState.initCharTimerExpired = false; + context->resetType = resetType; +#if !(defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT)) + uint32_t gpio_base[] = GPIO_BASE_ADDRS; +#endif +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + EMVSIM_Type *emvsimBase = (EMVSIM_Type *)base; + /* Disable receiver to deactivate GPC timers trigger */ + emvsimBase->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK; +#endif + + if (resetType == kSMARTCARD_ColdReset) + { /* Ensure that RST is HIGH and CMD is high here so that PHY goes in normal mode */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + emvsimBase->PCSR = + (emvsimBase->PCSR & ~(EMVSIM_PCSR_VCCENP_MASK | EMVSIM_PCSR_SRST_MASK)) | EMVSIM_PCSR_SVCC_EN_MASK; + emvsimBase->PCSR &= ~EMVSIM_PCSR_SRST_MASK; +#else + ((GPIO_Type *)gpio_base[context->interfaceConfig.resetPort])->PCOR |= (1u << context->interfaceConfig.resetPin); + ((GPIO_Type *)gpio_base[context->interfaceConfig.controlPort])->PSOR |= + (1u << context->interfaceConfig.controlPin); +#endif + +/* Set PHY to start Activation sequence by pulling CMDVCC low */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + emvsimBase->PCSR |= EMVSIM_PCSR_VCCENP_MASK; +#else + ((GPIO_Type *)gpio_base[context->interfaceConfig.controlPort])->PCOR |= + (1u << context->interfaceConfig.controlPin); +#endif + /* wait 3.42ms then enable clock an10997 P29 + During t0, the TDA8035 checks for the XTAL1 pin to detect if a crystal is present or if the clock is supplied + from the micro-controller, and then waits for the crystal to start. + This time is fixed, even if there is no crystal, and its maximum value is 3.1 ms. + t1 is the time between the beginning of the activation and the start of the clock on the smart card side. This + time depends on the internal oscillator frequency and + lasts at maximum 320 us. */ + + /* Set counter value , no card clock ,so use OS delay */ + context->timeDelay(3500u); + smartcard_phy_tda8035_InterfaceClockEnable(base, &context->interfaceConfig); + } + else if (resetType == kSMARTCARD_WarmReset) + { /* Ensure that card is already active */ + if (!context->cardParams.active) + { /* Card is not active;hence return */ + return kStatus_SMARTCARD_CardNotActivated; + } +/* Pull RESET low to start warm Activation sequence */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + emvsimBase->PCSR &= ~EMVSIM_PCSR_SRST_MASK; +#else + ((GPIO_Type *)gpio_base[context->interfaceConfig.resetPort])->PCOR |= (1u << context->interfaceConfig.resetPin); +#endif + } + else + { + return kStatus_SMARTCARD_InvalidInput; + } + /* Wait for sometime as specified by EMV before pulling RST High + * As per EMV delay <= 42000 Clock cycles + * as per PHY delay >= 1us */ + uint32_t temp = (uint32_t)((float)(1 + (float)(((float)(1000u * context->interfaceConfig.clockToResetDelay)) / + ((float)context->interfaceConfig.smartCardClock / 1000)))); + context->timeDelay(temp); +/* Pull reset HIGH Now to mark the end of Activation sequence */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + emvsimBase->PCSR |= EMVSIM_PCSR_SRST_MASK; +#else + ((GPIO_Type *)gpio_base[context->interfaceConfig.resetPort])->PSOR |= (1u << context->interfaceConfig.resetPin); +#endif +/* Configure TS character and ATR duration timers and enable receiver */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + emvsimBase->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK); + /* Down counter trigger, and clear any pending counter status flag */ + emvsimBase->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK | EMVSIM_TX_STATUS_GPCNT0_TO_MASK; + /* Set counter value for TS detection delay */ + emvsimBase->GPCNT0_VAL = (SMARTCARD_INIT_DELAY_CLOCK_CYCLES + SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT); + /* Pre-load counter value for ATR duration delay */ + emvsimBase->GPCNT1_VAL = (SMARTCARD_EMV_ATR_DURATION_ETU + SMARTCARD_ATR_DURATION_ADJUSTMENT); + /* Select the clock for GPCNT for both TS detection and early start of ATR duration counter */ + emvsimBase->CLKCFG |= + (EMVSIM_CLKCFG_GPCNT0_CLK_SEL(kEMVSIM_GPCCardClock) | EMVSIM_CLKCFG_GPCNT1_CLK_SEL(kEMVSIM_GPCTxClock)); + /* Set receiver to ICM mode, Flush RX FIFO */ + emvsimBase->CTRL |= (EMVSIM_CTRL_ICM_MASK | EMVSIM_CTRL_FLSH_RX_MASK); + /* Enable counter interrupt for TS detection */ + emvsimBase->INT_MASK &= ~EMVSIM_INT_MASK_GPCNT0_IM_MASK; + /* Clear any pending status flags */ + emvsimBase->RX_STATUS = 0xFFFFFFFFu; + /* Enable receiver */ + emvsimBase->CTRL |= EMVSIM_CTRL_RCV_EN_MASK; +#else + /* Enable external timer for TS detection time-out */ + smartcard_uart_TimerStart(context->interfaceConfig.tsTimerId, + (SMARTCARD_INIT_DELAY_CLOCK_CYCLES + SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT) * + (CLOCK_GetFreq(kCLOCK_BusClk) / context->interfaceConfig.smartCardClock)); +#endif + /* Here the card was activated */ + context->cardParams.active = true; + + return kStatus_SMARTCARD_Success; +} + +status_t SMARTCARD_PHY_TDA8035_Deactivate(void *base, smartcard_context_t *context) +{ + if ((NULL == context)) + { + return kStatus_SMARTCARD_InvalidInput; + } + +#if !(defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT)) + uint32_t gpio_base[] = GPIO_BASE_ADDRS; +#endif +/* Tell PHY to start Deactivation sequence by pulling CMD high and reset low */ +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + ((EMVSIM_Type *)base)->PCSR |= EMVSIM_PCSR_SVCC_EN_MASK; + ((EMVSIM_Type *)base)->PCSR &= ~EMVSIM_PCSR_VCCENP_MASK; + ((EMVSIM_Type *)base)->PCSR &= ~EMVSIM_PCSR_SRST_MASK; +#else + ((GPIO_Type *)gpio_base[context->interfaceConfig.controlPort])->PSOR |= (1u << context->interfaceConfig.controlPin); + ((GPIO_Type *)gpio_base[context->interfaceConfig.resetPort])->PCOR |= (1u << context->interfaceConfig.resetPin); +#endif + /* According EMV 4.3 specification deactivation sequence should be done within 100ms. + * The period is measured from the time that RST is set to state L to the time that Vcc + * reaches 0.4 V or less. */ + context->timeDelay(100 * 1000); + /* Here the card was deactivated */ + context->cardParams.active = false; + + /* Fix for EMV Analog: Deactivate Clock after deactivation is completed. * + * Otherwise the CLK line has a bump during EMVCo analog test, which cause a fail. + */ + smartcard_phy_tda8035_InterfaceClockDisable(base, &context->interfaceConfig); + + return kStatus_SMARTCARD_Success; +} + +status_t SMARTCARD_PHY_TDA8035_Control(void *base, + smartcard_context_t *context, + smartcard_interface_control_t control, + uint32_t param) +{ + if ((NULL == context)) + { + return kStatus_SMARTCARD_InvalidInput; + } +#if !(defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT)) + uint32_t gpio_base[] = GPIO_BASE_ADDRS; +#endif + + switch (control) + { + case kSMARTCARD_InterfaceSetVcc: + /* Set card parameter to VCC level set by caller */ + context->interfaceConfig.vcc = (smartcard_card_voltage_class_t)param; + break; + case kSMARTCARD_InterfaceSetClockToResetDelay: + /* Set interface clock to Reset delay set by caller */ + context->interfaceConfig.clockToResetDelay = param; + break; + case kSMARTCARD_InterfaceReadStatus: +#if defined(FSL_FEATURE_SOC_EMVSIM_COUNT) && (FSL_FEATURE_SOC_EMVSIM_COUNT) + /* Expecting active low present detect */ + context->cardParams.present = + ((emvsim_presence_detect_status_t)((((EMVSIM_Type *)base)->PCSR & EMVSIM_PCSR_SPDP_MASK) >> + EMVSIM_PCSR_SPDP_SHIFT) == kEMVSIM_DetectPinIsLow); +#else + if (((GPIO_Type *)gpio_base[context->interfaceConfig.controlPort])->PDIR & + (1u << context->interfaceConfig.controlPin)) + { + if (((GPIO_Type *)gpio_base[context->interfaceConfig.irqPort])->PDIR & + (1u << context->interfaceConfig.irqPin)) + { /* CMDVCC is high => session is inactive and INT is high => card is present */ + context->cardParams.present = true; + context->cardParams.active = false; + context->cardParams.faulty = false; + context->cardParams.status = SMARTCARD_TDA8035_STATUS_PRES; + } + else + { /* CMDVCC is high => session is inactive and INT is low => card is absent */ + context->cardParams.present = false; + context->cardParams.active = false; + context->cardParams.faulty = false; + context->cardParams.status = 0u; + } + } + else + { + if (((GPIO_Type *)gpio_base[context->interfaceConfig.irqPort])->PDIR & + (1u << context->interfaceConfig.irqPin)) + { /* CMDVCC is low => session is active and INT is high => card is present */ + context->cardParams.present = true; + context->cardParams.active = true; + context->cardParams.faulty = false; + context->cardParams.status = SMARTCARD_TDA8035_STATUS_PRES | SMARTCARD_TDA8035_STATUS_ACTIVE; + } + else + { + /* CMDVCC is low => session is active and INT is high => card is absent/deactivated due to some + * fault + * A fault has been detected (card has been deactivated) but The cause of the deactivation is not + * yet known. + * Lets determine the cause of fault by pulling CMD high */ + if (((GPIO_Type *)gpio_base[context->interfaceConfig.irqPort])->PDIR & + (1u << context->interfaceConfig.irqPin)) + { /* The fault detected was not a card removal (card is still present) */ + /* If INT follows CMDVCCN, the fault is due to a supply voltage drop, a VCC over-current + * detection or overheating. */ + context->cardParams.present = true; + context->cardParams.active = false; + context->cardParams.faulty = true; + context->cardParams.status = SMARTCARD_TDA8035_STATUS_PRES | SMARTCARD_TDA8035_STATUS_FAULTY | + SMARTCARD_TDA8035_STATUS_CARD_DEACTIVATED; + } + else + { /* The fault detected was the card removal + * Setting CMDVCCN allows checking if the deactivation is due to card removal. + * In this case the INT pin will stay low after CMDVCCN is high. */ + context->cardParams.present = false; + context->cardParams.active = false; + context->cardParams.faulty = false; + context->cardParams.status = + SMARTCARD_TDA8035_STATUS_CARD_REMOVED | SMARTCARD_TDA8035_STATUS_CARD_DEACTIVATED; + } + } + } +#endif + break; + default: + return kStatus_SMARTCARD_InvalidInput; + } + + return kStatus_SMARTCARD_Success; +} + +void SMARTCARD_PHY_TDA8035_IRQHandler(void *base, smartcard_context_t *context) +{ + if ((NULL == context)) + { + return; + } + /* Read interface/card status */ + SMARTCARD_PHY_TDA8035_Control(base, context, kSMARTCARD_InterfaceReadStatus, 0u); + /* Invoke callback if there is one */ + if (NULL != context->interfaceCallback) + { + context->interfaceCallback(context, context->interfaceCallbackParam); + } +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_tda8035.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_tda8035.h new file mode 100644 index 00000000000..d76c3ca0eac --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_tda8035.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_SMARTCARD_PHY_TDA8035_H_ +#define _FSL_SMARTCARD_PHY_TDA8035_H_ + +#include "fsl_smartcard.h" + +/*! + * @addtogroup smartcard_phy_tda8035_driver + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Smart card definition which specifies the adjustment number of clock cycles during which an ATR string has to be received. + */ +#define SMARTCARD_ATR_DURATION_ADJUSTMENT (360u) + +/*! @brief Smart card definition which specifies the adjustment number of clock cycles until an initial 'TS' character has to be + * received. */ +#define SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT (4200u) + +/*! @brief Masks for TDA8035 status register */ +#define SMARTCARD_TDA8035_STATUS_PRES (0x01u) /*!< Smart card PHY TDA8035 Smart card present status */ +#define SMARTCARD_TDA8035_STATUS_ACTIVE (0x02u) /*!< Smart card PHY TDA8035 Smart card active status */ +#define SMARTCARD_TDA8035_STATUS_FAULTY (0x04u) /*!< Smart card PHY TDA8035 Smart card faulty status */ +#define SMARTCARD_TDA8035_STATUS_CARD_REMOVED (0x08u) /*!< Smart card PHY TDA8035 Smart card removed status */ +#define SMARTCARD_TDA8035_STATUS_CARD_DEACTIVATED (0x10u) /*!< Smart card PHY TDA8035 Smart card deactivated status */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Fills in the configuration structure with default values. + * + * @param config The Smart card user configuration structure which contains configuration structure of type + * smartcard_interface_config_t. + * Function fill in members: + * clockToResetDelay = 42000, + * vcc = kSmartcardVoltageClassB3_3V, + * with default values. + */ +void SMARTCARD_PHY_TDA8035_GetDefaultConfig(smartcard_interface_config_t *config); + +/*! + * @brief Initializes a Smart card interface instance. + * + * @param base The Smart card peripheral base address. + * @param config The user configuration structure of type smartcard_interface_config_t. The user + * can call to fill out configuration structure function SMARTCARD_PHY_TDA8035_GetDefaultConfig(). + * @param srcClock_Hz Smart card clock generation module source clock. + * + * @retval kStatus_SMARTCARD_Success or kStatus_SMARTCARD_OtherError for an error. + */ +status_t SMARTCARD_PHY_TDA8035_Init(void *base, smartcard_interface_config_t const *config, uint32_t srcClock_Hz); + +/*! + * @brief De-initializes a Smart card interface, stops the Smart card clock, and disables the VCC. + * + * @param base The Smart card peripheral module base address. + * @param config The user configuration structure of type smartcard_interface_config_t. + */ +void SMARTCARD_PHY_TDA8035_Deinit(void *base, smartcard_interface_config_t *config); + +/*! + * @brief Activates the Smart card IC. + * + * @param base The Smart card peripheral module base address. + * @param context A pointer to a Smart card driver context structure. + * @param resetType type of reset to be performed, possible values + * = kSmartcardColdReset, kSmartcardWarmReset + * + * @retval kStatus_SMARTCARD_Success or kStatus_SMARTCARD_OtherError for an error. + */ +status_t SMARTCARD_PHY_TDA8035_Activate(void *base, smartcard_context_t *context, smartcard_reset_type_t resetType); + +/*! + * @brief De-activates the Smart card IC. + * + * @param base The Smart card peripheral module base address. + * @param context A pointer to a Smart card driver context structure. + * + * @retval kStatus_SMARTCARD_Success or kStatus_SMARTCARD_OtherError for an error. + */ +status_t SMARTCARD_PHY_TDA8035_Deactivate(void *base, smartcard_context_t *context); + +/*! + * @brief Controls the Smart card interface IC. + * + * @param base The Smart card peripheral module base address. + * @param context A pointer to a Smart card driver context structure. + * @param control A interface command type. + * @param param Integer value specific to control type + * + * @retval kStatus_SMARTCARD_Success or kStatus_SMARTCARD_OtherError for an error. + */ +status_t SMARTCARD_PHY_TDA8035_Control(void *base, + smartcard_context_t *context, + smartcard_interface_control_t control, + uint32_t param); + +/*! + * @brief Smart card interface IC IRQ ISR. + * + * @param base The Smart card peripheral module base address. + * @param context The Smart card context pointer. + */ +void SMARTCARD_PHY_TDA8035_IRQHandler(void *base, smartcard_context_t *context); +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_SMARTCARD_TDA8035_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smc.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smc.c new file mode 100644 index 00000000000..5c86e3366b1 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smc.c @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_smc.h" +#include "fsl_flash.h" + +#if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +void SMC_GetParam(SMC_Type *base, smc_param_t *param) +{ + uint32_t reg = base->PARAM; + param->hsrunEnable = (bool)(reg & SMC_PARAM_EHSRUN_MASK); + param->llsEnable = (bool)(reg & SMC_PARAM_ELLS_MASK); + param->lls2Enable = (bool)(reg & SMC_PARAM_ELLS2_MASK); + param->vlls0Enable = (bool)(reg & SMC_PARAM_EVLLS0_MASK); +} +#endif /* FSL_FEATURE_SMC_HAS_PARAM */ + +void SMC_PreEnterStopModes(void) +{ + flash_prefetch_speculation_status_t speculationStatus = + { + kFLASH_prefetchSpeculationOptionDisable, /* Disable instruction speculation.*/ + kFLASH_prefetchSpeculationOptionDisable, /* Disable data speculation.*/ + }; + + __disable_irq(); + __ISB(); + + /* + * Before enter stop modes, the flash cache prefetch should be disabled. + * Otherwise the prefetch might be interrupted by stop, then the data and + * and instruction from flash are wrong. + */ + FLASH_PflashSetPrefetchSpeculation(&speculationStatus); +} + +void SMC_PostExitStopModes(void) +{ + flash_prefetch_speculation_status_t speculationStatus = + { + kFLASH_prefetchSpeculationOptionEnable, /* Enable instruction speculation.*/ + kFLASH_prefetchSpeculationOptionEnable, /* Enable data speculation.*/ + }; + + FLASH_PflashSetPrefetchSpeculation(&speculationStatus); + + __enable_irq(); + __ISB(); +} + +status_t SMC_SetPowerModeRun(SMC_Type *base) +{ + uint8_t reg; + + reg = base->PMCTRL; + /* configure Normal RUN mode */ + reg &= ~SMC_PMCTRL_RUNM_MASK; + reg |= (kSMC_RunNormal << SMC_PMCTRL_RUNM_SHIFT); + base->PMCTRL = reg; + + return kStatus_Success; +} + +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) +status_t SMC_SetPowerModeHsrun(SMC_Type *base) +{ + uint8_t reg; + + reg = base->PMCTRL; + /* configure High Speed RUN mode */ + reg &= ~SMC_PMCTRL_RUNM_MASK; + reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + base->PMCTRL = reg; + + return kStatus_Success; +} +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ + +status_t SMC_SetPowerModeWait(SMC_Type *base) +{ + /* configure Normal Wait mode */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __DSB(); + __WFI(); + __ISB(); + + return kStatus_Success; +} + +status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) +{ + uint8_t reg; + +#if (defined(FSL_FEATURE_SMC_HAS_PSTOPO) && FSL_FEATURE_SMC_HAS_PSTOPO) + /* configure the Partial Stop mode in Noraml Stop mode */ + reg = base->STOPCTRL; + reg &= ~SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + base->STOPCTRL = reg; +#endif + + /* configure Normal Stop mode */ + reg = base->PMCTRL; + reg &= ~SMC_PMCTRL_STOPM_MASK; + reg |= (kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); + base->PMCTRL = reg; + + /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* read back to make sure the configuration valid before enter stop mode */ + (void)base->PMCTRL; + __DSB(); + __WFI(); + __ISB(); + + /* check whether the power mode enter Stop mode succeed */ + if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + { + return kStatus_SMC_StopAbort; + } + else + { + return kStatus_Success; + } +} + +status_t SMC_SetPowerModeVlpr(SMC_Type *base +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) + , + bool wakeupMode +#endif + ) +{ + uint8_t reg; + + reg = base->PMCTRL; +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) + /* configure whether the system remains in VLP mode on an interrupt */ + if (wakeupMode) + { + /* exits to RUN mode on an interrupt */ + reg |= SMC_PMCTRL_LPWUI_MASK; + } + else + { + /* remains in VLP mode on an interrupt */ + reg &= ~SMC_PMCTRL_LPWUI_MASK; + } +#endif /* FSL_FEATURE_SMC_HAS_LPWUI */ + + /* configure VLPR mode */ + reg &= ~SMC_PMCTRL_RUNM_MASK; + reg |= (kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); + base->PMCTRL = reg; + + return kStatus_Success; +} + +status_t SMC_SetPowerModeVlpw(SMC_Type *base) +{ + /* configure VLPW mode */ + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __DSB(); + __WFI(); + __ISB(); + + return kStatus_Success; +} + +status_t SMC_SetPowerModeVlps(SMC_Type *base) +{ + uint8_t reg; + + /* configure VLPS mode */ + reg = base->PMCTRL; + reg &= ~SMC_PMCTRL_STOPM_MASK; + reg |= (kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); + base->PMCTRL = reg; + + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* read back to make sure the configuration valid before enter stop mode */ + (void)base->PMCTRL; + __DSB(); + __WFI(); + __ISB(); + + /* check whether the power mode enter VLPS mode succeed */ + if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + { + return kStatus_SMC_StopAbort; + } + else + { + return kStatus_Success; + } +} + +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +status_t SMC_SetPowerModeLls(SMC_Type *base +#if ((defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \ + (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)) + , + const smc_power_mode_lls_config_t *config +#endif + ) +{ + uint8_t reg; + + /* configure to LLS mode */ + reg = base->PMCTRL; + reg &= ~SMC_PMCTRL_STOPM_MASK; + reg |= (kSMC_StopLls << SMC_PMCTRL_STOPM_SHIFT); + base->PMCTRL = reg; + +/* configure LLS sub-mode*/ +#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + reg = base->STOPCTRL; + reg &= ~SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint32_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); + base->STOPCTRL = reg; +#endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ + +#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO) + if (config->enableLpoClock) + { + base->STOPCTRL &= ~SMC_STOPCTRL_LPOPO_MASK; + } + else + { + base->STOPCTRL |= SMC_STOPCTRL_LPOPO_MASK; + } +#endif /* FSL_FEATURE_SMC_HAS_LPOPO */ + + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* read back to make sure the configuration valid before enter stop mode */ + (void)base->PMCTRL; + __DSB(); + __WFI(); + __ISB(); + + /* check whether the power mode enter LLS mode succeed */ + if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + { + return kStatus_SMC_StopAbort; + } + else + { + return kStatus_Success; + } +} +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ + +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) +status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) +{ + uint8_t reg; + +#if (defined(FSL_FEATURE_SMC_HAS_PORPO) && FSL_FEATURE_SMC_HAS_PORPO) +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) || \ + (defined(FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) && FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) || \ + (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + if (config->subMode == kSMC_StopSub0) +#endif + { + /* configure whether the Por Detect work in Vlls0 mode */ + if (config->enablePorDetectInVlls0) + { +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + base->VLLSCTRL &= ~SMC_VLLSCTRL_PORPO_MASK; +#else + base->STOPCTRL &= ~SMC_STOPCTRL_PORPO_MASK; +#endif + } + else + { +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + base->VLLSCTRL |= SMC_VLLSCTRL_PORPO_MASK; +#else + base->STOPCTRL |= SMC_STOPCTRL_PORPO_MASK; +#endif + } + } +#endif /* FSL_FEATURE_SMC_HAS_PORPO */ + +#if (defined(FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) && FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) + else if (config->subMode == kSMC_StopSub2) + { + /* configure whether the Por Detect work in Vlls0 mode */ + if (config->enableRam2InVlls2) + { +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; +#else + base->STOPCTRL |= SMC_STOPCTRL_RAM2PO_MASK; +#endif + } + else + { +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + base->VLLSCTRL &= ~SMC_VLLSCTRL_RAM2PO_MASK; +#else + base->STOPCTRL &= ~SMC_STOPCTRL_RAM2PO_MASK; +#endif + } + } + else + { + } +#endif /* FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION */ + + /* configure to VLLS mode */ + reg = base->PMCTRL; + reg &= ~SMC_PMCTRL_STOPM_MASK; + reg |= (kSMC_StopVlls << SMC_PMCTRL_STOPM_SHIFT); + base->PMCTRL = reg; + +/* configure the VLLS sub-mode */ +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + reg = base->VLLSCTRL; + reg &= ~SMC_VLLSCTRL_VLLSM_MASK; + reg |= ((uint32_t)config->subMode << SMC_VLLSCTRL_VLLSM_SHIFT); + base->VLLSCTRL = reg; +#else +#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + reg = base->STOPCTRL; + reg &= ~SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint32_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); + base->STOPCTRL = reg; +#else + reg = base->STOPCTRL; + reg &= ~SMC_STOPCTRL_VLLSM_MASK; + reg |= ((uint32_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); + base->STOPCTRL = reg; +#endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ +#endif + +#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO) + if (config->enableLpoClock) + { + base->STOPCTRL &= ~SMC_STOPCTRL_LPOPO_MASK; + } + else + { + base->STOPCTRL |= SMC_STOPCTRL_LPOPO_MASK; + } +#endif /* FSL_FEATURE_SMC_HAS_LPOPO */ + + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* read back to make sure the configuration valid before enter stop mode */ + (void)base->PMCTRL; + __DSB(); + __WFI(); + __ISB(); + + /* check whether the power mode enter LLS mode succeed */ + if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + { + return kStatus_SMC_StopAbort; + } + else + { + return kStatus_Success; + } +} +#endif /* FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smc.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smc.h new file mode 100644 index 00000000000..b901468e702 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_smc.h @@ -0,0 +1,456 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_SMC_H_ +#define _FSL_SMC_H_ + +#include "fsl_common.h" + +/*! @addtogroup smc */ +/*! @{ */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief SMC driver version 2.0.3. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 3)) +/*@}*/ + +/*! + * @brief Power Modes Protection + */ +typedef enum _smc_power_mode_protection +{ +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) + kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-low-leakage Stop Mode. */ +#endif +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) + kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-leakage Stop Mode. */ +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ + kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-power Mode. */ +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) + kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High-speed Run mode. */ +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ + kSMC_AllowPowerModeAll = (0U +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) + | + SMC_PMPROT_AVLLS_MASK +#endif +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) + | + SMC_PMPROT_ALLS_MASK +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ + | + SMC_PMPROT_AVLP_MASK +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) + | + kSMC_AllowPowerModeHsrun +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ + ) /*!< Allow all power mode. */ +} smc_power_mode_protection_t; + +/*! + * @brief Power Modes in PMSTAT + */ +typedef enum _smc_power_state +{ + kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ + kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */ + kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */ + kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */ + kSMC_PowerStateVlps = 0x01U << 4U, /*!< 0001_0000 - Current power mode is VLPS */ +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) + kSMC_PowerStateLls = 0x01U << 5U, /*!< 0010_0000 - Current power mode is LLS */ +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) + kSMC_PowerStateVlls = 0x01U << 6U, /*!< 0100_0000 - Current power mode is VLLS */ +#endif +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) + kSMC_PowerStateHsrun = 0x01U << 7U /*!< 1000_0000 - Current power mode is HSRUN */ +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +} smc_power_state_t; + +/*! + * @brief Run mode definition + */ +typedef enum _smc_run_mode +{ + kSMC_RunNormal = 0U, /*!< Normal RUN mode. */ + kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) + kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */ +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +} smc_run_mode_t; + +/*! + * @brief Stop mode definition + */ +typedef enum _smc_stop_mode +{ + kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ + kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) + kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */ +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) + kSMC_StopVlls = 4U /*!< Very-low-leakage Stop mode. */ +#endif +} smc_stop_mode_t; + +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) || \ + (defined(FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) && FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) || \ + (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) +/*! + * @brief VLLS/LLS stop sub mode definition + */ +typedef enum _smc_stop_submode +{ + kSMC_StopSub0 = 0U, /*!< Stop submode 0, for VLLS0/LLS0. */ + kSMC_StopSub1 = 1U, /*!< Stop submode 1, for VLLS1/LLS1. */ + kSMC_StopSub2 = 2U, /*!< Stop submode 2, for VLLS2/LLS2. */ + kSMC_StopSub3 = 3U /*!< Stop submode 3, for VLLS3/LLS3. */ +} smc_stop_submode_t; +#endif + +/*! + * @brief Partial STOP option + */ +typedef enum _smc_partial_stop_mode +{ + kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ + kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/ + kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/ +} smc_partial_stop_option_t; + +/*! + * @brief SMC configuration status. + */ +enum _smc_status +{ + kStatus_SMC_StopAbort = MAKE_STATUS(kStatusGroup_POWER, 0) /*!< Entering Stop mode is abort*/ +}; + +#if (defined(FSL_FEATURE_SMC_HAS_VERID) && FSL_FEATURE_SMC_HAS_VERID) +/*! + * @brief IP version ID definition. + */ +typedef struct _smc_version_id +{ + uint16_t feature; /*!< Feature Specification Number. */ + uint8_t minor; /*!< Minor version number. */ + uint8_t major; /*!< Major version number. */ +} smc_version_id_t; +#endif /* FSL_FEATURE_SMC_HAS_VERID */ + +#if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * @brief IP parameter definition. + */ +typedef struct _smc_param +{ + bool hsrunEnable; /*!< HSRUN mode enable. */ + bool llsEnable; /*!< LLS mode enable. */ + bool lls2Enable; /*!< LLS2 mode enable. */ + bool vlls0Enable; /*!< VLLS0 mode enable. */ +} smc_param_t; +#endif /* FSL_FEATURE_SMC_HAS_PARAM */ + +#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \ + (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO) +/*! + * @brief SMC Low-Leakage Stop power mode configuration. + */ +typedef struct _smc_power_mode_lls_config +{ +#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + smc_stop_submode_t subMode; /*!< Low-leakage Stop sub-mode */ +#endif +#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO) + bool enableLpoClock; /*!< Enable LPO clock in LLS mode */ +#endif +} smc_power_mode_lls_config_t; +#endif /* (FSL_FEATURE_SMC_HAS_LLS_SUBMODE || FSL_FEATURE_SMC_HAS_LPOPO) */ + +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) +/*! + * @brief SMC Very Low-Leakage Stop power mode configuration. + */ +typedef struct _smc_power_mode_vlls_config +{ +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) || \ + (defined(FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) && FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) || \ + (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + smc_stop_submode_t subMode; /*!< Very Low-leakage Stop sub-mode */ +#endif +#if (defined(FSL_FEATURE_SMC_HAS_PORPO) && FSL_FEATURE_SMC_HAS_PORPO) + bool enablePorDetectInVlls0; /*!< Enable Power on reset detect in VLLS mode */ +#endif +#if (defined(FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) && FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) + bool enableRam2InVlls2; /*!< Enable RAM2 power in VLLS2 */ +#endif +#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO) + bool enableLpoClock; /*!< Enable LPO clock in VLLS mode */ +#endif +} smc_power_mode_vlls_config_t; +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! @name System mode controller APIs*/ +/*@{*/ + +#if (defined(FSL_FEATURE_SMC_HAS_VERID) && FSL_FEATURE_SMC_HAS_VERID) +/*! + * @brief Gets the SMC version ID. + * + * This function gets the SMC version ID, including major version number, + * minor version number, and feature specification number. + * + * @param base SMC peripheral base address. + * @param versionId Pointer to the version ID structure. + */ +static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) +{ + *((uint32_t *)versionId) = base->VERID; +} +#endif /* FSL_FEATURE_SMC_HAS_VERID */ + +#if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * @brief Gets the SMC parameter. + * + * This function gets the SMC parameter including the enabled power mdoes. + * + * @param base SMC peripheral base address. + * @param param Pointer to the SMC param structure. + */ +void SMC_GetParam(SMC_Type *base, smc_param_t *param); +#endif + +/*! + * @brief Configures all power mode protection settings. + * + * This function configures the power mode protection settings for + * supported power modes in the specified chip family. The available power modes + * are defined in the smc_power_mode_protection_t. This should be done at an early + * system level initialization stage. See the reference manual for details. + * This register can only write once after the power reset. + * + * The allowed modes are passed as bit map. For example, to allow LLS and VLLS, + * use SMC_SetPowerModeProtection(kSMC_AllowPowerModeVlls | kSMC_AllowPowerModeVlps). + * To allow all modes, use SMC_SetPowerModeProtection(kSMC_AllowPowerModeAll). + * + * @param base SMC peripheral base address. + * @param allowedModes Bitmap of the allowed power modes. + */ +static inline void SMC_SetPowerModeProtection(SMC_Type *base, uint8_t allowedModes) +{ + base->PMPROT = allowedModes; +} + +/*! + * @brief Gets the current power mode status. + * + * This function returns the current power mode status. After the application + * switches the power mode, it should always check the status to check whether it + * runs into the specified mode or not. The application should check + * this mode before switching to a different mode. The system requires that + * only certain modes can switch to other specific modes. See the + * reference manual for details and the smc_power_state_t for information about + * the power status. + * + * @param base SMC peripheral base address. + * @return Current power mode status. + */ +static inline smc_power_state_t SMC_GetPowerModeState(SMC_Type *base) +{ + return (smc_power_state_t)base->PMSTAT; +} + +/*! + * @brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with @ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void); + +/*! + * @brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +static inline void SMC_PreEnterWaitModes(void) +{ + __disable_irq(); + __ISB(); +} + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with @ref SMC_PreEnterWaitModes. + */ +static inline void SMC_PostExitWaitModes(void) +{ + __enable_irq(); + __ISB(); +} + +/*! + * @brief Configures the system to RUN power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeRun(SMC_Type *base); + +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) +/*! + * @brief Configures the system to HSRUN power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeHsrun(SMC_Type *base); +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ + +/*! + * @brief Configures the system to WAIT power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeWait(SMC_Type *base); + +/*! + * @brief Configures the system to Stop power mode. + * + * @param base SMC peripheral base address. + * @param option Partial Stop mode option. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); + +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) +/*! + * @brief Configures the system to VLPR power mode. + * + * @param base SMC peripheral base address. + * @param wakeupMode Enter Normal Run mode if true, else stay in VLPR mode. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeVlpr(SMC_Type *base, bool wakeupMode); +#else +/*! + * @brief Configures the system to VLPR power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeVlpr(SMC_Type *base); +#endif /* FSL_FEATURE_SMC_HAS_LPWUI */ + +/*! + * @brief Configures the system to VLPW power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeVlpw(SMC_Type *base); + +/*! + * @brief Configures the system to VLPS power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeVlps(SMC_Type *base); + +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +#if ((defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \ + (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)) +/*! + * @brief Configures the system to LLS power mode. + * + * @param base SMC peripheral base address. + * @param config The LLS power mode configuration structure + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeLls(SMC_Type *base, const smc_power_mode_lls_config_t *config); +#else +/*! + * @brief Configures the system to LLS power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeLls(SMC_Type *base); +#endif +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ + +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) +/*! + * @brief Configures the system to VLLS power mode. + * + * @param base SMC peripheral base address. + * @param config The VLLS power mode configuration structure. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config); +#endif /* FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE */ + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_SMC_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tpm.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tpm.c new file mode 100644 index 00000000000..c8017064cbf --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tpm.c @@ -0,0 +1,731 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_tpm.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define TPM_COMBINE_SHIFT (8U) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address + * + * @param base TPM peripheral base address + * + * @return The TPM instance + */ +static uint32_t TPM_GetInstance(TPM_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to TPM bases for each instance. */ +static TPM_Type *const s_tpmBases[] = TPM_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to TPM clocks for each instance. */ +static const clock_ip_name_t s_tpmClocks[] = TPM_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t TPM_GetInstance(TPM_Type *base) +{ + uint32_t instance; + uint32_t tpmArrayCount = (sizeof(s_tpmBases) / sizeof(s_tpmBases[0])); + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < tpmArrayCount; instance++) + { + if (s_tpmBases[instance] == base) + { + break; + } + } + + assert(instance < tpmArrayCount); + + return instance; +} + +void TPM_Init(TPM_Type *base, const tpm_config_t *config) +{ + assert(config); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the module clock */ + CLOCK_EnableClock(s_tpmClocks[TPM_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if defined(FSL_FEATURE_TPM_HAS_GLOBAL) && FSL_FEATURE_TPM_HAS_GLOBAL + /* TPM reset is available on certain SoC's */ + TPM_Reset(base); +#endif + + /* Set the clock prescale factor */ + base->SC = TPM_SC_PS(config->prescale); + + /* Setup the counter operation */ + base->CONF = TPM_CONF_DOZEEN(config->enableDoze) | TPM_CONF_GTBEEN(config->useGlobalTimeBase) | + TPM_CONF_CROT(config->enableReloadOnTrigger) | TPM_CONF_CSOT(config->enableStartOnTrigger) | + TPM_CONF_CSOO(config->enableStopOnOverflow) | +#if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER + TPM_CONF_CPOT(config->enablePauseOnTrigger) | +#endif +#if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION + TPM_CONF_TRGSRC(config->triggerSource) | +#endif + TPM_CONF_TRGSEL(config->triggerSelect); + if (config->enableDebugMode) + { + base->CONF |= TPM_CONF_DBGMODE_MASK; + } + else + { + base->CONF &= ~TPM_CONF_DBGMODE_MASK; + } +} + +void TPM_Deinit(TPM_Type *base) +{ + /* Stop the counter */ + base->SC &= ~TPM_SC_CMOD_MASK; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate the TPM clock */ + CLOCK_DisableClock(s_tpmClocks[TPM_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void TPM_GetDefaultConfig(tpm_config_t *config) +{ + assert(config); + + /* TPM clock divide by 1 */ + config->prescale = kTPM_Prescale_Divide_1; + /* Use internal TPM counter as timebase */ + config->useGlobalTimeBase = false; + /* TPM counter continues in doze mode */ + config->enableDoze = false; + /* TPM counter pauses when in debug mode */ + config->enableDebugMode = false; + /* TPM counter will not be reloaded on input trigger */ + config->enableReloadOnTrigger = false; + /* TPM counter continues running after overflow */ + config->enableStopOnOverflow = false; + /* TPM counter starts immediately once it is enabled */ + config->enableStartOnTrigger = false; +#if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER + config->enablePauseOnTrigger = false; +#endif + /* Choose trigger select 0 as input trigger for controlling counter operation */ + config->triggerSelect = kTPM_Trigger_Select_0; +#if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION + /* Choose external trigger source to control counter operation */ + config->triggerSource = kTPM_TriggerSource_External; +#endif +} + +status_t TPM_SetupPwm(TPM_Type *base, + const tpm_chnl_pwm_signal_param_t *chnlParams, + uint8_t numOfChnls, + tpm_pwm_mode_t mode, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz) +{ + assert(chnlParams); + assert(pwmFreq_Hz); + assert(numOfChnls); + assert(srcClock_Hz); + + uint32_t mod; + uint32_t tpmClock = (srcClock_Hz / (1U << (base->SC & TPM_SC_PS_MASK))); + uint16_t cnv; + uint8_t i; + +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL + /* Clear quadrature Decoder mode because in quadrature Decoder mode PWM doesn't operate*/ + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; +#endif + + switch (mode) + { + case kTPM_EdgeAlignedPwm: +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + case kTPM_CombinedPwm: +#endif + base->SC &= ~TPM_SC_CPWMS_MASK; + mod = (tpmClock / pwmFreq_Hz) - 1; + break; + case kTPM_CenterAlignedPwm: + base->SC |= TPM_SC_CPWMS_MASK; + mod = tpmClock / (pwmFreq_Hz * 2); + break; + default: + return kStatus_Fail; + } + + /* Return an error in case we overflow the registers, probably would require changing + * clock source to get the desired frequency */ + if (mod > 65535U) + { + return kStatus_Fail; + } + /* Set the PWM period */ + base->MOD = mod; + + /* Setup each TPM channel */ + for (i = 0; i < numOfChnls; i++) + { + /* Return error if requested dutycycle is greater than the max allowed */ + if (chnlParams->dutyCyclePercent > 100) + { + return kStatus_Fail; + } +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + if (mode == kTPM_CombinedPwm) + { + uint16_t cnvFirstEdge; + + /* This check is added for combined mode as the channel number should be the pair number */ + if (chnlParams->chnlNumber >= (FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2)) + { + return kStatus_Fail; + } + + /* Return error if requested value is greater than the max allowed */ + if (chnlParams->firstEdgeDelayPercent > 100) + { + return kStatus_Fail; + } + /* Configure delay of the first edge */ + if (chnlParams->firstEdgeDelayPercent == 0) + { + /* No delay for the first edge */ + cnvFirstEdge = 0; + } + else + { + cnvFirstEdge = (mod * chnlParams->firstEdgeDelayPercent) / 100; + } + /* Configure dutycycle */ + if (chnlParams->dutyCyclePercent == 0) + { + /* Signal stays low */ + cnv = 0; + cnvFirstEdge = 0; + } + else + { + cnv = (mod * chnlParams->dutyCyclePercent) / 100; + /* For 100% duty cycle */ + if (cnv >= mod) + { + cnv = mod + 1; + } + } + + /* Set the combine bit for the channel pair */ + base->COMBINE |= (1U << (TPM_COMBINE_COMBINE0_SHIFT + (TPM_COMBINE_SHIFT * chnlParams->chnlNumber))); + + /* When switching mode, disable channel n first */ + base->CONTROLS[chnlParams->chnlNumber * 2].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlParams->chnlNumber * 2].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Set the requested PWM mode for channel n, PWM output requires mode select to be set to 2 */ + base->CONTROLS[chnlParams->chnlNumber * 2].CnSC |= + ((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT)); + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[chnlParams->chnlNumber * 2].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + /* Set the channel pair values */ + base->CONTROLS[chnlParams->chnlNumber * 2].CnV = cnvFirstEdge; + + /* When switching mode, disable channel n + 1 first */ + base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Set the requested PWM mode for channel n + 1, PWM output requires mode select to be set to 2 */ + base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC |= + ((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT)); + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + /* Set the channel pair values */ + base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv; + } + else + { +#endif + if (chnlParams->dutyCyclePercent == 0) + { + /* Signal stays low */ + cnv = 0; + } + else + { + cnv = (mod * chnlParams->dutyCyclePercent) / 100; + /* For 100% duty cycle */ + if (cnv >= mod) + { + cnv = mod + 1; + } + } + + /* When switching mode, disable channel first */ + base->CONTROLS[chnlParams->chnlNumber].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlParams->chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Set the requested PWM mode, PWM output requires mode select to be set to 2 */ + base->CONTROLS[chnlParams->chnlNumber].CnSC |= + ((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT)); + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[chnlParams->chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + base->CONTROLS[chnlParams->chnlNumber].CnV = cnv; +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + } +#endif + + chnlParams++; + } + + return kStatus_Success; +} + +void TPM_UpdatePwmDutycycle(TPM_Type *base, + tpm_chnl_t chnlNumber, + tpm_pwm_mode_t currentPwmMode, + uint8_t dutyCyclePercent) +{ + assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base)); + + uint16_t cnv, mod; + + mod = base->MOD; +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + if (currentPwmMode == kTPM_CombinedPwm) + { + uint16_t cnvFirstEdge; + + /* This check is added for combined mode as the channel number should be the pair number */ + if (chnlNumber >= (FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2)) + { + return; + } + cnv = (mod * dutyCyclePercent) / 100; + cnvFirstEdge = base->CONTROLS[chnlNumber * 2].CnV; + /* For 100% duty cycle */ + if (cnv >= mod) + { + cnv = mod + 1; + } + base->CONTROLS[(chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv; + } + else + { +#endif + cnv = (mod * dutyCyclePercent) / 100; + /* For 100% duty cycle */ + if (cnv >= mod) + { + cnv = mod + 1; + } + base->CONTROLS[chnlNumber].CnV = cnv; +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + } +#endif +} + +void TPM_UpdateChnlEdgeLevelSelect(TPM_Type *base, tpm_chnl_t chnlNumber, uint8_t level) +{ + assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base)); + + uint32_t reg = base->CONTROLS[chnlNumber].CnSC & ~(TPM_CnSC_CHF_MASK); + + /* When switching mode, disable channel first */ + base->CONTROLS[chnlNumber].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Clear the field and write the new level value */ + reg &= ~(TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + reg |= ((uint32_t)level << TPM_CnSC_ELSA_SHIFT) & (TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + base->CONTROLS[chnlNumber].CnSC = reg; + + /* Wait till mode change is acknowledged */ + reg &= (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + while (reg != (base->CONTROLS[chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } +} + +void TPM_SetupInputCapture(TPM_Type *base, tpm_chnl_t chnlNumber, tpm_input_capture_edge_t captureMode) +{ + assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base)); + +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL + /* Clear quadrature Decoder mode for channel 0 or 1*/ + if ((chnlNumber == 0) || (chnlNumber == 1)) + { + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + } +#endif + +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + /* Clear the combine bit for chnlNumber */ + base->COMBINE &= ~(1U << TPM_COMBINE_SHIFT * (chnlNumber / 2)); +#endif + + /* When switching mode, disable channel first */ + base->CONTROLS[chnlNumber].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Set the requested input capture mode */ + base->CONTROLS[chnlNumber].CnSC |= captureMode; + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } +} + +void TPM_SetupOutputCompare(TPM_Type *base, + tpm_chnl_t chnlNumber, + tpm_output_compare_mode_t compareMode, + uint32_t compareValue) +{ + assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base)); + +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL + /* Clear quadrature Decoder mode for channel 0 or 1 */ + if ((chnlNumber == 0) || (chnlNumber == 1)) + { + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + } +#endif + + /* When switching mode, disable channel first */ + base->CONTROLS[chnlNumber].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Setup the channel output behaviour when a match occurs with the compare value */ + base->CONTROLS[chnlNumber].CnSC |= compareMode; + + /* Setup the compare value */ + base->CONTROLS[chnlNumber].CnV = compareValue; + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } +} + +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE +void TPM_SetupDualEdgeCapture(TPM_Type *base, + tpm_chnl_t chnlPairNumber, + const tpm_dual_edge_capture_param_t *edgeParam, + uint32_t filterValue) +{ + assert(edgeParam); + assert(chnlPairNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2); + + uint32_t reg; +/* Clear quadrature Decoder mode for channel 0 or 1*/ +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL + if (chnlPairNumber == 0) + { + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + } +#endif + + /* Unlock: When switching mode, disable channel first */ + base->CONTROLS[chnlPairNumber * 2].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlPairNumber * 2].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + base->CONTROLS[chnlPairNumber * 2 + 1].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlPairNumber * 2 + 1].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Now, the registers for input mode can be operated. */ + if (edgeParam->enableSwap) + { + /* Set the combine and swap bits for the channel pair */ + base->COMBINE |= (TPM_COMBINE_COMBINE0_MASK | TPM_COMBINE_COMSWAP0_MASK) + << (TPM_COMBINE_SHIFT * chnlPairNumber); + + /* Input filter setup for channel n+1 input */ + reg = base->FILTER; + reg &= ~(TPM_FILTER_CH0FVAL_MASK << (TPM_FILTER_CH1FVAL_SHIFT * (chnlPairNumber + 1))); + reg |= (filterValue << (TPM_FILTER_CH1FVAL_SHIFT * (chnlPairNumber + 1))); + base->FILTER = reg; + } + else + { + reg = base->COMBINE; + /* Clear the swap bit for the channel pair */ + reg &= ~(TPM_COMBINE_COMSWAP0_MASK << (TPM_COMBINE_COMSWAP0_SHIFT * chnlPairNumber)); + + /* Set the combine bit for the channel pair */ + reg |= TPM_COMBINE_COMBINE0_MASK << (TPM_COMBINE_SHIFT * chnlPairNumber); + base->COMBINE = reg; + + /* Input filter setup for channel n input */ + reg = base->FILTER; + reg &= ~(TPM_FILTER_CH0FVAL_MASK << (TPM_FILTER_CH1FVAL_SHIFT * chnlPairNumber)); + reg |= (filterValue << (TPM_FILTER_CH1FVAL_SHIFT * chnlPairNumber)); + base->FILTER = reg; + } + + /* Setup the edge detection from channel n */ + base->CONTROLS[chnlPairNumber * 2].CnSC |= edgeParam->currChanEdgeMode; + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[chnlPairNumber * 2].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Setup the edge detection from channel n+1 */ + base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC |= edgeParam->nextChanEdgeMode; + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } +} +#endif + +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL +void TPM_SetupQuadDecode(TPM_Type *base, + const tpm_phase_params_t *phaseAParams, + const tpm_phase_params_t *phaseBParams, + tpm_quad_decode_mode_t quadMode) +{ + assert(phaseAParams); + assert(phaseBParams); + + base->CONTROLS[0].CnSC &= ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[0].CnSC & (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + uint32_t reg; + + /* Set Phase A filter value */ + reg = base->FILTER; + reg &= ~(TPM_FILTER_CH0FVAL_MASK); + reg |= TPM_FILTER_CH0FVAL(phaseAParams->phaseFilterVal); + base->FILTER = reg; + +#if defined(FSL_FEATURE_TPM_HAS_POL) && FSL_FEATURE_TPM_HAS_POL + /* Set Phase A polarity */ + if (phaseAParams->phasePolarity) + { + base->POL |= TPM_POL_POL0_MASK; + } + else + { + base->POL &= ~TPM_POL_POL0_MASK; + } +#endif + + base->CONTROLS[1].CnSC &= ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[1].CnSC & (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + /* Set Phase B filter value */ + reg = base->FILTER; + reg &= ~(TPM_FILTER_CH1FVAL_MASK); + reg |= TPM_FILTER_CH1FVAL(phaseBParams->phaseFilterVal); + base->FILTER = reg; +#if defined(FSL_FEATURE_TPM_HAS_POL) && FSL_FEATURE_TPM_HAS_POL + /* Set Phase B polarity */ + if (phaseBParams->phasePolarity) + { + base->POL |= TPM_POL_POL1_MASK; + } + else + { + base->POL &= ~TPM_POL_POL1_MASK; + } +#endif + + /* Set Quadrature mode */ + reg = base->QDCTRL; + reg &= ~(TPM_QDCTRL_QUADMODE_MASK); + reg |= TPM_QDCTRL_QUADMODE(quadMode); + base->QDCTRL = reg; + + /* Enable Quad decode */ + base->QDCTRL |= TPM_QDCTRL_QUADEN_MASK; +} + +#endif + +void TPM_EnableInterrupts(TPM_Type *base, uint32_t mask) +{ + uint32_t chnlInterrupts = (mask & 0xFF); + uint8_t chnlNumber = 0; + + /* Enable the timer overflow interrupt */ + if (mask & kTPM_TimeOverflowInterruptEnable) + { + base->SC |= TPM_SC_TOIE_MASK; + } + + /* Enable the channel interrupts */ + while (chnlInterrupts) + { + if (chnlInterrupts & 0x1) + { + base->CONTROLS[chnlNumber].CnSC |= TPM_CnSC_CHIE_MASK; + } + chnlNumber++; + chnlInterrupts = chnlInterrupts >> 1U; + } +} + +void TPM_DisableInterrupts(TPM_Type *base, uint32_t mask) +{ + uint32_t chnlInterrupts = (mask & 0xFF); + uint8_t chnlNumber = 0; + + /* Disable the timer overflow interrupt */ + if (mask & kTPM_TimeOverflowInterruptEnable) + { + base->SC &= ~TPM_SC_TOIE_MASK; + } + + /* Disable the channel interrupts */ + while (chnlInterrupts) + { + if (chnlInterrupts & 0x1) + { + base->CONTROLS[chnlNumber].CnSC &= ~TPM_CnSC_CHIE_MASK; + } + chnlNumber++; + chnlInterrupts = chnlInterrupts >> 1U; + } +} + +uint32_t TPM_GetEnabledInterrupts(TPM_Type *base) +{ + uint32_t enabledInterrupts = 0; + int8_t chnlCount = FSL_FEATURE_TPM_CHANNEL_COUNTn(base); + + /* The CHANNEL_COUNT macro returns -1 if it cannot match the TPM instance */ + assert(chnlCount != -1); + + /* Check if timer overflow interrupt is enabled */ + if (base->SC & TPM_SC_TOIE_MASK) + { + enabledInterrupts |= kTPM_TimeOverflowInterruptEnable; + } + + /* Check if the channel interrupts are enabled */ + while (chnlCount > 0) + { + chnlCount--; + if (base->CONTROLS[chnlCount].CnSC & TPM_CnSC_CHIE_MASK) + { + enabledInterrupts |= (1U << chnlCount); + } + } + + return enabledInterrupts; +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tpm.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tpm.h new file mode 100644 index 00000000000..e83a92ab52d --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tpm.h @@ -0,0 +1,589 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_TPM_H_ +#define _FSL_TPM_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup tpm + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_TPM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2 */ +/*@}*/ + +/*! + * @brief List of TPM channels. + * @note Actual number of available channels is SoC dependent + */ +typedef enum _tpm_chnl +{ + kTPM_Chnl_0 = 0U, /*!< TPM channel number 0*/ + kTPM_Chnl_1, /*!< TPM channel number 1 */ + kTPM_Chnl_2, /*!< TPM channel number 2 */ + kTPM_Chnl_3, /*!< TPM channel number 3 */ + kTPM_Chnl_4, /*!< TPM channel number 4 */ + kTPM_Chnl_5, /*!< TPM channel number 5 */ + kTPM_Chnl_6, /*!< TPM channel number 6 */ + kTPM_Chnl_7 /*!< TPM channel number 7 */ +} tpm_chnl_t; + +/*! @brief TPM PWM operation modes */ +typedef enum _tpm_pwm_mode +{ + kTPM_EdgeAlignedPwm = 0U, /*!< Edge aligned PWM */ + kTPM_CenterAlignedPwm, /*!< Center aligned PWM */ +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + kTPM_CombinedPwm /*!< Combined PWM */ +#endif +} tpm_pwm_mode_t; + +/*! @brief TPM PWM output pulse mode: high-true, low-true or no output */ +typedef enum _tpm_pwm_level_select +{ + kTPM_NoPwmSignal = 0U, /*!< No PWM output on pin */ + kTPM_LowTrue, /*!< Low true pulses */ + kTPM_HighTrue /*!< High true pulses */ +} tpm_pwm_level_select_t; + +/*! @brief Options to configure a TPM channel's PWM signal */ +typedef struct _tpm_chnl_pwm_signal_param +{ + tpm_chnl_t chnlNumber; /*!< TPM channel to configure. + In combined mode (available in some SoC's, this represents the + channel pair number */ + tpm_pwm_level_select_t level; /*!< PWM output active level select */ + uint8_t dutyCyclePercent; /*!< PWM pulse width, value should be between 0 to 100 + 0=inactive signal(0% duty cycle)... + 100=always active signal (100% duty cycle)*/ +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + uint8_t firstEdgeDelayPercent; /*!< Used only in combined PWM mode to generate asymmetrical PWM. + Specifies the delay to the first edge in a PWM period. + If unsure, leave as 0; Should be specified as + percentage of the PWM period */ +#endif +} tpm_chnl_pwm_signal_param_t; + +/*! + * @brief Trigger options available. + * + * This is used for both internal & external trigger sources (external option available in certain SoC's) + * + * @note The actual trigger options available is SoC-specific. + */ +typedef enum _tpm_trigger_select +{ + kTPM_Trigger_Select_0 = 0U, + kTPM_Trigger_Select_1, + kTPM_Trigger_Select_2, + kTPM_Trigger_Select_3, + kTPM_Trigger_Select_4, + kTPM_Trigger_Select_5, + kTPM_Trigger_Select_6, + kTPM_Trigger_Select_7, + kTPM_Trigger_Select_8, + kTPM_Trigger_Select_9, + kTPM_Trigger_Select_10, + kTPM_Trigger_Select_11, + kTPM_Trigger_Select_12, + kTPM_Trigger_Select_13, + kTPM_Trigger_Select_14, + kTPM_Trigger_Select_15 +} tpm_trigger_select_t; + +#if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION +/*! + * @brief Trigger source options available + * + * @note This selection is available only on some SoC's. For SoC's without this selection, the only + * trigger source available is internal triger. + */ +typedef enum _tpm_trigger_source +{ + kTPM_TriggerSource_External = 0U, /*!< Use external trigger input */ + kTPM_TriggerSource_Internal /*!< Use internal trigger */ +} tpm_trigger_source_t; +#endif + +/*! @brief TPM output compare modes */ +typedef enum _tpm_output_compare_mode +{ + kTPM_NoOutputSignal = (1U << TPM_CnSC_MSA_SHIFT), /*!< No channel output when counter reaches CnV */ + kTPM_ToggleOnMatch = ((1U << TPM_CnSC_MSA_SHIFT) | (1U << TPM_CnSC_ELSA_SHIFT)), /*!< Toggle output */ + kTPM_ClearOnMatch = ((1U << TPM_CnSC_MSA_SHIFT) | (2U << TPM_CnSC_ELSA_SHIFT)), /*!< Clear output */ + kTPM_SetOnMatch = ((1U << TPM_CnSC_MSA_SHIFT) | (3U << TPM_CnSC_ELSA_SHIFT)), /*!< Set output */ + kTPM_HighPulseOutput = ((3U << TPM_CnSC_MSA_SHIFT) | (1U << TPM_CnSC_ELSA_SHIFT)), /*!< Pulse output high */ + kTPM_LowPulseOutput = ((3U << TPM_CnSC_MSA_SHIFT) | (2U << TPM_CnSC_ELSA_SHIFT)) /*!< Pulse output low */ +} tpm_output_compare_mode_t; + +/*! @brief TPM input capture edge */ +typedef enum _tpm_input_capture_edge +{ + kTPM_RisingEdge = (1U << TPM_CnSC_ELSA_SHIFT), /*!< Capture on rising edge only */ + kTPM_FallingEdge = (2U << TPM_CnSC_ELSA_SHIFT), /*!< Capture on falling edge only */ + kTPM_RiseAndFallEdge = (3U << TPM_CnSC_ELSA_SHIFT) /*!< Capture on rising or falling edge */ +} tpm_input_capture_edge_t; + +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE +/*! + * @brief TPM dual edge capture parameters + * + * @note This mode is available only on some SoC's. + */ +typedef struct _tpm_dual_edge_capture_param +{ + bool enableSwap; /*!< true: Use channel n+1 input, channel n input is ignored; + false: Use channel n input, channel n+1 input is ignored */ + tpm_input_capture_edge_t currChanEdgeMode; /*!< Input capture edge select for channel n */ + tpm_input_capture_edge_t nextChanEdgeMode; /*!< Input capture edge select for channel n+1 */ +} tpm_dual_edge_capture_param_t; +#endif + +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL +/*! + * @brief TPM quadrature decode modes + * + * @note This mode is available only on some SoC's. + */ +typedef enum _tpm_quad_decode_mode +{ + kTPM_QuadPhaseEncode = 0U, /*!< Phase A and Phase B encoding mode */ + kTPM_QuadCountAndDir /*!< Count and direction encoding mode */ +} tpm_quad_decode_mode_t; + +/*! @brief TPM quadrature phase polarities */ +typedef enum _tpm_phase_polarity +{ + kTPM_QuadPhaseNormal = 0U, /*!< Phase input signal is not inverted */ + kTPM_QuadPhaseInvert /*!< Phase input signal is inverted */ +} tpm_phase_polarity_t; + +/*! @brief TPM quadrature decode phase parameters */ +typedef struct _tpm_phase_param +{ + uint32_t phaseFilterVal; /*!< Filter value, filter is disabled when the value is zero */ + tpm_phase_polarity_t phasePolarity; /*!< Phase polarity */ +} tpm_phase_params_t; +#endif + +/*! @brief TPM clock source selection*/ +typedef enum _tpm_clock_source +{ + kTPM_SystemClock = 1U, /*!< System clock */ + kTPM_ExternalClock /*!< External clock */ +} tpm_clock_source_t; + +/*! @brief TPM prescale value selection for the clock source*/ +typedef enum _tpm_clock_prescale +{ + kTPM_Prescale_Divide_1 = 0U, /*!< Divide by 1 */ + kTPM_Prescale_Divide_2, /*!< Divide by 2 */ + kTPM_Prescale_Divide_4, /*!< Divide by 4 */ + kTPM_Prescale_Divide_8, /*!< Divide by 8 */ + kTPM_Prescale_Divide_16, /*!< Divide by 16 */ + kTPM_Prescale_Divide_32, /*!< Divide by 32 */ + kTPM_Prescale_Divide_64, /*!< Divide by 64 */ + kTPM_Prescale_Divide_128 /*!< Divide by 128 */ +} tpm_clock_prescale_t; + +/*! + * @brief TPM config structure + * + * This structure holds the configuration settings for the TPM peripheral. To initialize this + * structure to reasonable defaults, call the TPM_GetDefaultConfig() function and pass a + * pointer to your config structure instance. + * + * The config struct can be made const so it resides in flash + */ +typedef struct _tpm_config +{ + tpm_clock_prescale_t prescale; /*!< Select TPM clock prescale value */ + bool useGlobalTimeBase; /*!< true: Use of an external global time base is enabled; + false: disabled */ + tpm_trigger_select_t triggerSelect; /*!< Input trigger to use for controlling the counter operation */ +#if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION + tpm_trigger_source_t triggerSource; /*!< Decides if we use external or internal trigger. */ +#endif + bool enableDoze; /*!< true: TPM counter is paused in doze mode; + false: TPM counter continues in doze mode */ + bool enableDebugMode; /*!< true: TPM counter continues in debug mode; + false: TPM counter is paused in debug mode */ + bool enableReloadOnTrigger; /*!< true: TPM counter is reloaded on trigger; + false: TPM counter not reloaded */ + bool enableStopOnOverflow; /*!< true: TPM counter stops after overflow; + false: TPM counter continues running after overflow */ + bool enableStartOnTrigger; /*!< true: TPM counter only starts when a trigger is detected; + false: TPM counter starts immediately */ +#if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER + bool enablePauseOnTrigger; /*!< true: TPM counter will pause while trigger remains asserted; + false: TPM counter continues running */ +#endif +} tpm_config_t; + +/*! @brief List of TPM interrupts */ +typedef enum _tpm_interrupt_enable +{ + kTPM_Chnl0InterruptEnable = (1U << 0), /*!< Channel 0 interrupt.*/ + kTPM_Chnl1InterruptEnable = (1U << 1), /*!< Channel 1 interrupt.*/ + kTPM_Chnl2InterruptEnable = (1U << 2), /*!< Channel 2 interrupt.*/ + kTPM_Chnl3InterruptEnable = (1U << 3), /*!< Channel 3 interrupt.*/ + kTPM_Chnl4InterruptEnable = (1U << 4), /*!< Channel 4 interrupt.*/ + kTPM_Chnl5InterruptEnable = (1U << 5), /*!< Channel 5 interrupt.*/ + kTPM_Chnl6InterruptEnable = (1U << 6), /*!< Channel 6 interrupt.*/ + kTPM_Chnl7InterruptEnable = (1U << 7), /*!< Channel 7 interrupt.*/ + kTPM_TimeOverflowInterruptEnable = (1U << 8) /*!< Time overflow interrupt.*/ +} tpm_interrupt_enable_t; + +/*! @brief List of TPM flags */ +typedef enum _tpm_status_flags +{ + kTPM_Chnl0Flag = (1U << 0), /*!< Channel 0 flag */ + kTPM_Chnl1Flag = (1U << 1), /*!< Channel 1 flag */ + kTPM_Chnl2Flag = (1U << 2), /*!< Channel 2 flag */ + kTPM_Chnl3Flag = (1U << 3), /*!< Channel 3 flag */ + kTPM_Chnl4Flag = (1U << 4), /*!< Channel 4 flag */ + kTPM_Chnl5Flag = (1U << 5), /*!< Channel 5 flag */ + kTPM_Chnl6Flag = (1U << 6), /*!< Channel 6 flag */ + kTPM_Chnl7Flag = (1U << 7), /*!< Channel 7 flag */ + kTPM_TimeOverflowFlag = (1U << 8) /*!< Time overflow flag */ +} tpm_status_flags_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the TPM clock and configures the peripheral for basic operation. + * + * @note This API should be called at the beginning of the application using the TPM driver. + * + * @param base TPM peripheral base address + * @param config Pointer to user's TPM config structure. + */ +void TPM_Init(TPM_Type *base, const tpm_config_t *config); + +/*! + * @brief Stops the counter and gates the TPM clock + * + * @param base TPM peripheral base address + */ +void TPM_Deinit(TPM_Type *base); + +/*! + * @brief Fill in the TPM config struct with the default settings + * + * The default values are: + * @code + * config->prescale = kTPM_Prescale_Divide_1; + * config->useGlobalTimeBase = false; + * config->dozeEnable = false; + * config->dbgMode = false; + * config->enableReloadOnTrigger = false; + * config->enableStopOnOverflow = false; + * config->enableStartOnTrigger = false; + *#if FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER + * config->enablePauseOnTrigger = false; + *#endif + * config->triggerSelect = kTPM_Trigger_Select_0; + *#if FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION + * config->triggerSource = kTPM_TriggerSource_External; + *#endif + * @endcode + * @param config Pointer to user's TPM config structure. + */ +void TPM_GetDefaultConfig(tpm_config_t *config); + +/*! @}*/ + +/*! + * @name Channel mode operations + * @{ + */ + +/*! + * @brief Configures the PWM signal parameters + * + * User calls this function to configure the PWM signals period, mode, dutycycle and edge. Use this + * function to configure all the TPM channels that will be used to output a PWM signal + * + * @param base TPM peripheral base address + * @param chnlParams Array of PWM channel parameters to configure the channel(s) + * @param numOfChnls Number of channels to configure, this should be the size of the array passed in + * @param mode PWM operation mode, options available in enumeration ::tpm_pwm_mode_t + * @param pwmFreq_Hz PWM signal frequency in Hz + * @param srcClock_Hz TPM counter clock in Hz + * + * @return kStatus_Success if the PWM setup was successful, + * kStatus_Error on failure + */ +status_t TPM_SetupPwm(TPM_Type *base, + const tpm_chnl_pwm_signal_param_t *chnlParams, + uint8_t numOfChnls, + tpm_pwm_mode_t mode, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz); + +/*! + * @brief Update the duty cycle of an active PWM signal + * + * @param base TPM peripheral base address + * @param chnlNumber The channel number. In combined mode, this represents + * the channel pair number + * @param currentPwmMode The current PWM mode set during PWM setup + * @param dutyCyclePercent New PWM pulse width, value should be between 0 to 100 + * 0=inactive signal(0% duty cycle)... + * 100=active signal (100% duty cycle) + */ +void TPM_UpdatePwmDutycycle(TPM_Type *base, + tpm_chnl_t chnlNumber, + tpm_pwm_mode_t currentPwmMode, + uint8_t dutyCyclePercent); + +/*! + * @brief Update the edge level selection for a channel + * + * @param base TPM peripheral base address + * @param chnlNumber The channel number + * @param level The level to be set to the ELSnB:ELSnA field; valid values are 00, 01, 10, 11. + * See the appropriate SoC reference manual for details about this field. + */ +void TPM_UpdateChnlEdgeLevelSelect(TPM_Type *base, tpm_chnl_t chnlNumber, uint8_t level); + +/*! + * @brief Enables capturing an input signal on the channel using the function parameters. + * + * When the edge specified in the captureMode argument occurs on the channel, the TPM counter is captured into + * the CnV register. The user has to read the CnV register separately to get this value. + * + * @param base TPM peripheral base address + * @param chnlNumber The channel number + * @param captureMode Specifies which edge to capture + */ +void TPM_SetupInputCapture(TPM_Type *base, tpm_chnl_t chnlNumber, tpm_input_capture_edge_t captureMode); + +/*! + * @brief Configures the TPM to generate timed pulses. + * + * When the TPM counter matches the value of compareVal argument (this is written into CnV reg), the channel + * output is changed based on what is specified in the compareMode argument. + * + * @param base TPM peripheral base address + * @param chnlNumber The channel number + * @param compareMode Action to take on the channel output when the compare condition is met + * @param compareValue Value to be programmed in the CnV register. + */ +void TPM_SetupOutputCompare(TPM_Type *base, + tpm_chnl_t chnlNumber, + tpm_output_compare_mode_t compareMode, + uint32_t compareValue); + +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE +/*! + * @brief Configures the dual edge capture mode of the TPM. + * + * This function allows to measure a pulse width of the signal on the input of channel of a + * channel pair. The filter function is disabled if the filterVal argument passed is zero. + * + * @param base TPM peripheral base address + * @param chnlPairNumber The TPM channel pair number; options are 0, 1, 2, 3 + * @param edgeParam Sets up the dual edge capture function + * @param filterValue Filter value, specify 0 to disable filter. + */ +void TPM_SetupDualEdgeCapture(TPM_Type *base, + tpm_chnl_t chnlPairNumber, + const tpm_dual_edge_capture_param_t *edgeParam, + uint32_t filterValue); +#endif + +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL +/*! + * @brief Configures the parameters and activates the quadrature decode mode. + * + * @param base TPM peripheral base address + * @param phaseAParams Phase A configuration parameters + * @param phaseBParams Phase B configuration parameters + * @param quadMode Selects encoding mode used in quadrature decoder mode + */ +void TPM_SetupQuadDecode(TPM_Type *base, + const tpm_phase_params_t *phaseAParams, + const tpm_phase_params_t *phaseBParams, + tpm_quad_decode_mode_t quadMode); +#endif + +/*! @}*/ + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected TPM interrupts. + * + * @param base TPM peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::tpm_interrupt_enable_t + */ +void TPM_EnableInterrupts(TPM_Type *base, uint32_t mask); + +/*! + * @brief Disables the selected TPM interrupts. + * + * @param base TPM peripheral base address + * @param mask The interrupts to disable. This is a logical OR of members of the + * enumeration ::tpm_interrupt_enable_t + */ +void TPM_DisableInterrupts(TPM_Type *base, uint32_t mask); + +/*! + * @brief Gets the enabled TPM interrupts. + * + * @param base TPM peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::tpm_interrupt_enable_t + */ +uint32_t TPM_GetEnabledInterrupts(TPM_Type *base); + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the TPM status flags + * + * @param base TPM peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::tpm_status_flags_t + */ +static inline uint32_t TPM_GetStatusFlags(TPM_Type *base) +{ + return base->STATUS; +} + +/*! + * @brief Clears the TPM status flags + * + * @param base TPM peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::tpm_status_flags_t + */ +static inline void TPM_ClearStatusFlags(TPM_Type *base, uint32_t mask) +{ + /* Clear the status flags */ + base->STATUS = mask; +} + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ + +/*! + * @brief Starts the TPM counter. + * + * + * @param base TPM peripheral base address + * @param clockSource TPM clock source; once clock source is set the counter will start running + */ +static inline void TPM_StartTimer(TPM_Type *base, tpm_clock_source_t clockSource) +{ + uint32_t reg = base->SC; + + reg &= ~(TPM_SC_CMOD_MASK); + reg |= TPM_SC_CMOD(clockSource); + base->SC = reg; +} + +/*! + * @brief Stops the TPM counter. + * + * @param base TPM peripheral base address + */ +static inline void TPM_StopTimer(TPM_Type *base) +{ + /* Set clock source to none to disable counter */ + base->SC &= ~(TPM_SC_CMOD_MASK); + + /* Wait till this reads as zero acknowledging the counter is disabled */ + while (base->SC & TPM_SC_CMOD_MASK) + { + } +} + +/*! @}*/ + +#if defined(FSL_FEATURE_TPM_HAS_GLOBAL) && FSL_FEATURE_TPM_HAS_GLOBAL +/*! + * @brief Performs a software reset on the TPM module. + * + * Reset all internal logic and registers, except the Global Register. Remains set until cleared by software.. + * + * @note TPM software reset is available on certain SoC's only + * + * @param base TPM peripheral base address + */ +static inline void TPM_Reset(TPM_Type *base) +{ + base->GLOBAL |= TPM_GLOBAL_RST_MASK; + base->GLOBAL &= ~TPM_GLOBAL_RST_MASK; +} +#endif + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_TPM_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_trng.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_trng.c new file mode 100644 index 00000000000..959fb6050ca --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_trng.c @@ -0,0 +1,1622 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_trng.h" + +#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && FSL_FEATURE_SOC_TRNG_COUNT + +/******************************************************************************* + * Definitions + *******************************************************************************/ +/* Default values for user configuration structure.*/ +#if (defined(KW40Z4_SERIES) || defined(KW41Z4_SERIES) || defined(KW31Z4_SERIES) || defined(KW21Z4_SERIES)) +#define TRNG_USER_CONFIG_DEFAULT_OSC_DIV kTRNG_RingOscDiv8 +#elif(defined(KV56F24_SERIES) || defined(KV58F24_SERIES) || defined(KL28Z7_SERIES) || defined(KL81Z7_SERIES) || \ + defined(KL82Z7_SERIES)) +#define TRNG_USER_CONFIG_DEFAULT_OSC_DIV kTRNG_RingOscDiv4 +#elif defined(K81F25615_SERIES) +#define TRNG_USER_CONFIG_DEFAULT_OSC_DIV kTRNG_RingOscDiv2 +#else +#define TRNG_USER_CONFIG_DEFAULT_OSC_DIV kTRNG_RingOscDiv0 +#endif + +#define TRNG_USER_CONFIG_DEFAULT_LOCK 0 +#define TRNG_USER_CONFIG_DEFAULT_ENTROPY_DELAY 3200 +#define TRNG_USER_CONFIG_DEFAULT_SAMPLE_SIZE 2500 +#define TRNG_USER_CONFIG_DEFAULT_SPARSE_BIT_LIMIT 63 +#define TRNG_USER_CONFIG_DEFAULT_RETRY_COUNT 1 +#define TRNG_USER_CONFIG_DEFAULT_RUN_MAX_LIMIT 34 + +#define TRNG_USER_CONFIG_DEFAULT_MONOBIT_MAXIMUM 1384 +#define TRNG_USER_CONFIG_DEFAULT_MONOBIT_MINIMUM (TRNG_USER_CONFIG_DEFAULT_MONOBIT_MAXIMUM - 268) +#define TRNG_USER_CONFIG_DEFAULT_RUNBIT1_MAXIMUM 405 +#define TRNG_USER_CONFIG_DEFAULT_RUNBIT1_MINIMUM (TRNG_USER_CONFIG_DEFAULT_RUNBIT1_MAXIMUM - 178) +#define TRNG_USER_CONFIG_DEFAULT_RUNBIT2_MAXIMUM 220 +#define TRNG_USER_CONFIG_DEFAULT_RUNBIT2_MINIMUM (TRNG_USER_CONFIG_DEFAULT_RUNBIT2_MAXIMUM - 122) +#define TRNG_USER_CONFIG_DEFAULT_RUNBIT3_MAXIMUM 125 +#define TRNG_USER_CONFIG_DEFAULT_RUNBIT3_MINIMUM (TRNG_USER_CONFIG_DEFAULT_RUNBIT3_MAXIMUM - 88) +#define TRNG_USER_CONFIG_DEFAULT_RUNBIT4_MAXIMUM 75 +#define TRNG_USER_CONFIG_DEFAULT_RUNBIT4_MINIMUM (TRNG_USER_CONFIG_DEFAULT_RUNBIT4_MAXIMUM - 64) +#define TRNG_USER_CONFIG_DEFAULT_RUNBIT5_MAXIMUM 47 +#define TRNG_USER_CONFIG_DEFAULT_RUNBIT5_MINIMUM (TRNG_USER_CONFIG_DEFAULT_RUNBIT5_MAXIMUM - 46) +#define TRNG_USER_CONFIG_DEFAULT_RUNBIT6PLUS_MAXIMUM 47 +#define TRNG_USER_CONFIG_DEFAULT_RUNBIT6PLUS_MINIMUM (TRNG_USER_CONFIG_DEFAULT_RUNBIT6PLUS_MAXIMUM - 46) +#define TRNG_USER_CONFIG_DEFAULT_POKER_MAXIMUM 26912 +#define TRNG_USER_CONFIG_DEFAULT_POKER_MINIMUM (TRNG_USER_CONFIG_DEFAULT_POKER_MAXIMUM - 2467) +#define TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MAXIMUM 25600 +#define TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MINIMUM 1600 + +/*! @brief TRNG work mode */ +typedef enum _trng_work_mode +{ + kTRNG_WorkModeRun = 0U, /*!< Run Mode. */ + kTRNG_WorkModeProgram = 1U /*!< Program Mode. */ +} trng_work_mode_t; + +/*! @brief TRNG statistical check type*/ +typedef enum _trng_statistical_check +{ + kTRNG_StatisticalCheckMonobit = + 1U, /*!< Statistical check of number of ones/zero detected during entropy generation. */ + kTRNG_StatisticalCheckRunBit1, /*!< Statistical check of number of runs of length 1 detected during entropy + generation. */ + kTRNG_StatisticalCheckRunBit2, /*!< Statistical check of number of runs of length 2 detected during entropy + generation. */ + kTRNG_StatisticalCheckRunBit3, /*!< Statistical check of number of runs of length 3 detected during entropy + generation. */ + kTRNG_StatisticalCheckRunBit4, /*!< Statistical check of number of runs of length 4 detected during entropy + generation. */ + kTRNG_StatisticalCheckRunBit5, /*!< Statistical check of number of runs of length 5 detected during entropy + generation. */ + kTRNG_StatisticalCheckRunBit6Plus, /*!< Statistical check of number of runs of length 6 or more detected during + entropy generation. */ + kTRNG_StatisticalCheckPoker, /*!< Statistical check of "Poker Test". */ + kTRNG_StatisticalCheckFrequencyCount /*!< Statistical check of entropy sample frequency count. */ +} trng_statistical_check_t; + +/******************************************************************************* + * TRNG_SCMISC - RNG Statistical Check Miscellaneous Register + ******************************************************************************/ +/*! + * @name Register TRNG_SCMISC, field RTY_CT[19:16] (RW) + * + * RETRY COUNT. If a statistical check fails during the TRNG Entropy Generation, + * the RTY_CT value indicates the number of times a retry should occur before + * generating an error. This field is writable only if MCTL[PRGM] bit is 1. This + * field will read zeroes if MCTL[PRGM] = 0. This field is cleared to 1h by writing + * the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCMISC_RTY_CT field. */ +#define TRNG_RD_SCMISC_RTY_CT(base) ((TRNG_SCMISC_REG(base) & TRNG_SCMISC_RTY_CT_MASK) >> TRNG_SCMISC_RTY_CT_SHIFT) + +/*! @brief Set the RTY_CT field to a new value. */ +#define TRNG_WR_SCMISC_RTY_CT(base, value) (TRNG_RMW_SCMISC(base, TRNG_SCMISC_RTY_CT_MASK, TRNG_SCMISC_RTY_CT(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_SCML - RNG Statistical Check Monobit Limit Register + ******************************************************************************/ +/*! + * @brief TRNG_SCML - RNG Statistical Check Monobit Limit Register (RW) + * + * Reset value: 0x010C0568U + * + * The RNG Statistical Check Monobit Limit Register defines the allowable + * maximum and minimum number of ones/zero detected during entropy generation. To pass + * the test, the number of ones/zeroes generated must be less than the programmed + * maximum value, and the number of ones/zeroes generated must be greater than + * (maximum - range). If this test fails, the Retry Counter in SCMISC will be + * decremented, and a retry will occur if the Retry Count has not reached zero. If + * the Retry Count has reached zero, an error will be generated. Note that this + * offset (0xBASE_0620) is used as SCML only if MCTL[PRGM] is 1. If MCTL[PRGM] is 0, + * this offset is used as SCMC readback register. + */ +/*! + * @name Constants and macros for entire TRNG_SCML register + */ +/*@{*/ +#define TRNG_SCML_REG(base) ((base)->SCML) +#define TRNG_RD_SCML(base) (TRNG_SCML_REG(base)) +#define TRNG_WR_SCML(base, value) (TRNG_SCML_REG(base) = (value)) +#define TRNG_RMW_SCML(base, mask, value) (TRNG_WR_SCML(base, (TRNG_RD_SCML(base) & ~(mask)) | (value))) +/*@}*/ +/*! + * @name Register TRNG_SCML, field MONO_MAX[15:0] (RW) + * + * Monobit Maximum Limit. Defines the maximum allowable count taken during + * entropy generation. The number of ones/zeroes detected during entropy generation + * must be less than MONO_MAX, else a retry or error will occur. This register is + * cleared to 00056Bh (decimal 1387) by writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCML_MONO_MAX field. */ +#define TRNG_RD_SCML_MONO_MAX(base) ((TRNG_SCML_REG(base) & TRNG_SCML_MONO_MAX_MASK) >> TRNG_SCML_MONO_MAX_SHIFT) + +/*! @brief Set the MONO_MAX field to a new value. */ +#define TRNG_WR_SCML_MONO_MAX(base, value) (TRNG_RMW_SCML(base, TRNG_SCML_MONO_MAX_MASK, TRNG_SCML_MONO_MAX(value))) +/*@}*/ +/*! + * @name Register TRNG_SCML, field MONO_RNG[31:16] (RW) + * + * Monobit Range. The number of ones/zeroes detected during entropy generation + * must be greater than MONO_MAX - MONO_RNG, else a retry or error will occur. + * This register is cleared to 000112h (decimal 274) by writing the MCTL[RST_DEF] + * bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCML_MONO_RNG field. */ +#define TRNG_RD_SCML_MONO_RNG(base) ((TRNG_SCML_REG(base) & TRNG_SCML_MONO_RNG_MASK) >> TRNG_SCML_MONO_RNG_SHIFT) + +/*! @brief Set the MONO_RNG field to a new value. */ +#define TRNG_WR_SCML_MONO_RNG(base, value) (TRNG_RMW_SCML(base, TRNG_SCML_MONO_RNG_MASK, TRNG_SCML_MONO_RNG(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_SCR1L - RNG Statistical Check Run Length 1 Limit Register + ******************************************************************************/ + +/*! + * @brief TRNG_SCR1L - RNG Statistical Check Run Length 1 Limit Register (RW) + * + * Reset value: 0x00B20195U + * + * The RNG Statistical Check Run Length 1 Limit Register defines the allowable + * maximum and minimum number of runs of length 1 detected during entropy + * generation. To pass the test, the number of runs of length 1 (for samples of both 0 + * and 1) must be less than the programmed maximum value, and the number of runs of + * length 1 must be greater than (maximum - range). If this test fails, the + * Retry Counter in SCMISC will be decremented, and a retry will occur if the Retry + * Count has not reached zero. If the Retry Count has reached zero, an error will + * be generated. Note that this address (0xBASE_0624) is used as SCR1L only if + * MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this address is used as SCR1C readback + * register. + */ +/*! + * @name Constants and macros for entire TRNG_SCR1L register + */ +/*@{*/ +#define TRNG_SCR1L_REG(base) ((base)->SCR1L) +#define TRNG_RD_SCR1L(base) (TRNG_SCR1L_REG(base)) +#define TRNG_WR_SCR1L(base, value) (TRNG_SCR1L_REG(base) = (value)) +#define TRNG_RMW_SCR1L(base, mask, value) (TRNG_WR_SCR1L(base, (TRNG_RD_SCR1L(base) & ~(mask)) | (value))) +/*@}*/ + +/*! + * @name Register TRNG_SCR1L, field RUN1_MAX[14:0] (RW) + * + * Run Length 1 Maximum Limit. Defines the maximum allowable runs of length 1 + * (for both 0 and 1) detected during entropy generation. The number of runs of + * length 1 detected during entropy generation must be less than RUN1_MAX, else a + * retry or error will occur. This register is cleared to 01E5h (decimal 485) by + * writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCR1L_RUN1_MAX field. */ +#define TRNG_RD_SCR1L_RUN1_MAX(base) ((TRNG_SCR1L_REG(base) & TRNG_SCR1L_RUN1_MAX_MASK) >> TRNG_SCR1L_RUN1_MAX_SHIFT) + +/*! @brief Set the RUN1_MAX field to a new value. */ +#define TRNG_WR_SCR1L_RUN1_MAX(base, value) (TRNG_RMW_SCR1L(base, TRNG_SCR1L_RUN1_MAX_MASK, TRNG_SCR1L_RUN1_MAX(value))) +/*@}*/ + +/*! + * @name Register TRNG_SCR1L, field RUN1_RNG[30:16] (RW) + * + * Run Length 1 Range. The number of runs of length 1 (for both 0 and 1) + * detected during entropy generation must be greater than RUN1_MAX - RUN1_RNG, else a + * retry or error will occur. This register is cleared to 0102h (decimal 258) by + * writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCR1L_RUN1_RNG field. */ +#define TRNG_RD_SCR1L_RUN1_RNG(base) ((TRNG_SCR1L_REG(base) & TRNG_SCR1L_RUN1_RNG_MASK) >> TRNG_SCR1L_RUN1_RNG_SHIFT) + +/*! @brief Set the RUN1_RNG field to a new value. */ +#define TRNG_WR_SCR1L_RUN1_RNG(base, value) (TRNG_RMW_SCR1L(base, TRNG_SCR1L_RUN1_RNG_MASK, TRNG_SCR1L_RUN1_RNG(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_SCR2L - RNG Statistical Check Run Length 2 Limit Register + ******************************************************************************/ + +/*! + * @brief TRNG_SCR2L - RNG Statistical Check Run Length 2 Limit Register (RW) + * + * Reset value: 0x007A00DCU + * + * The RNG Statistical Check Run Length 2 Limit Register defines the allowable + * maximum and minimum number of runs of length 2 detected during entropy + * generation. To pass the test, the number of runs of length 2 (for samples of both 0 + * and 1) must be less than the programmed maximum value, and the number of runs of + * length 2 must be greater than (maximum - range). If this test fails, the + * Retry Counter in SCMISC will be decremented, and a retry will occur if the Retry + * Count has not reached zero. If the Retry Count has reached zero, an error will + * be generated. Note that this address (0xBASE_0628) is used as SCR2L only if + * MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this address is used as SCR2C readback + * register. + */ +/*! + * @name Constants and macros for entire TRNG_SCR2L register + */ +/*@{*/ +#define TRNG_SCR2L_REG(base) ((base)->SCR2L) +#define TRNG_RD_SCR2L(base) (TRNG_SCR2L_REG(base)) +#define TRNG_WR_SCR2L(base, value) (TRNG_SCR2L_REG(base) = (value)) +#define TRNG_RMW_SCR2L(base, mask, value) (TRNG_WR_SCR2L(base, (TRNG_RD_SCR2L(base) & ~(mask)) | (value))) +/*@}*/ + +/* + * Constants & macros for individual TRNG_SCR2L bitfields + */ + +/*! + * @name Register TRNG_SCR2L, field RUN2_MAX[13:0] (RW) + * + * Run Length 2 Maximum Limit. Defines the maximum allowable runs of length 2 + * (for both 0 and 1) detected during entropy generation. The number of runs of + * length 2 detected during entropy generation must be less than RUN2_MAX, else a + * retry or error will occur. This register is cleared to 00DCh (decimal 220) by + * writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCR2L_RUN2_MAX field. */ +#define TRNG_RD_SCR2L_RUN2_MAX(base) ((TRNG_SCR2L_REG(base) & TRNG_SCR2L_RUN2_MAX_MASK) >> TRNG_SCR2L_RUN2_MAX_SHIFT) + +/*! @brief Set the RUN2_MAX field to a new value. */ +#define TRNG_WR_SCR2L_RUN2_MAX(base, value) (TRNG_RMW_SCR2L(base, TRNG_SCR2L_RUN2_MAX_MASK, TRNG_SCR2L_RUN2_MAX(value))) +/*@}*/ + +/*! + * @name Register TRNG_SCR2L, field RUN2_RNG[29:16] (RW) + * + * Run Length 2 Range. The number of runs of length 2 (for both 0 and 1) + * detected during entropy generation must be greater than RUN2_MAX - RUN2_RNG, else a + * retry or error will occur. This register is cleared to 007Ah (decimal 122) by + * writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCR2L_RUN2_RNG field. */ +#define TRNG_RD_SCR2L_RUN2_RNG(base) ((TRNG_SCR2L_REG(base) & TRNG_SCR2L_RUN2_RNG_MASK) >> TRNG_SCR2L_RUN2_RNG_SHIFT) + +/*! @brief Set the RUN2_RNG field to a new value. */ +#define TRNG_WR_SCR2L_RUN2_RNG(base, value) (TRNG_RMW_SCR2L(base, TRNG_SCR2L_RUN2_RNG_MASK, TRNG_SCR2L_RUN2_RNG(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_SCR3L - RNG Statistical Check Run Length 3 Limit Register + ******************************************************************************/ + +/*! + * @brief TRNG_SCR3L - RNG Statistical Check Run Length 3 Limit Register (RW) + * + * Reset value: 0x0058007DU + * + * The RNG Statistical Check Run Length 3 Limit Register defines the allowable + * maximum and minimum number of runs of length 3 detected during entropy + * generation. To pass the test, the number of runs of length 3 (for samples of both 0 + * and 1) must be less than the programmed maximum value, and the number of runs of + * length 3 must be greater than (maximum - range). If this test fails, the + * Retry Counter in SCMISC will be decremented, and a retry will occur if the Retry + * Count has not reached zero. If the Retry Count has reached zero, an error will + * be generated. Note that this address (0xBASE_062C) is used as SCR3L only if + * MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this address is used as SCR3C readback + * register. + */ +/*! + * @name Constants and macros for entire TRNG_SCR3L register + */ +/*@{*/ +#define TRNG_SCR3L_REG(base) ((base)->SCR3L) +#define TRNG_RD_SCR3L(base) (TRNG_SCR3L_REG(base)) +#define TRNG_WR_SCR3L(base, value) (TRNG_SCR3L_REG(base) = (value)) +#define TRNG_RMW_SCR3L(base, mask, value) (TRNG_WR_SCR3L(base, (TRNG_RD_SCR3L(base) & ~(mask)) | (value))) +/*@}*/ + +/* + * Constants & macros for individual TRNG_SCR3L bitfields + */ + +/*! + * @name Register TRNG_SCR3L, field RUN3_MAX[12:0] (RW) + * + * Run Length 3 Maximum Limit. Defines the maximum allowable runs of length 3 + * (for both 0 and 1) detected during entropy generation. The number of runs of + * length 3 detected during entropy generation must be less than RUN3_MAX, else a + * retry or error will occur. This register is cleared to 007Dh (decimal 125) by + * writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCR3L_RUN3_MAX field. */ +#define TRNG_RD_SCR3L_RUN3_MAX(base) ((TRNG_SCR3L_REG(base) & TRNG_SCR3L_RUN3_MAX_MASK) >> TRNG_SCR3L_RUN3_MAX_SHIFT) + +/*! @brief Set the RUN3_MAX field to a new value. */ +#define TRNG_WR_SCR3L_RUN3_MAX(base, value) (TRNG_RMW_SCR3L(base, TRNG_SCR3L_RUN3_MAX_MASK, TRNG_SCR3L_RUN3_MAX(value))) +/*@}*/ + +/*! + * @name Register TRNG_SCR3L, field RUN3_RNG[28:16] (RW) + * + * Run Length 3 Range. The number of runs of length 3 (for both 0 and 1) + * detected during entropy generation must be greater than RUN3_MAX - RUN3_RNG, else a + * retry or error will occur. This register is cleared to 0058h (decimal 88) by + * writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCR3L_RUN3_RNG field. */ +#define TRNG_RD_SCR3L_RUN3_RNG(base) ((TRNG_SCR3L_REG(base) & TRNG_SCR3L_RUN3_RNG_MASK) >> TRNG_SCR3L_RUN3_RNG_SHIFT) + +/*! @brief Set the RUN3_RNG field to a new value. */ +#define TRNG_WR_SCR3L_RUN3_RNG(base, value) (TRNG_RMW_SCR3L(base, TRNG_SCR3L_RUN3_RNG_MASK, TRNG_SCR3L_RUN3_RNG(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_SCR4L - RNG Statistical Check Run Length 4 Limit Register + ******************************************************************************/ + +/*! + * @brief TRNG_SCR4L - RNG Statistical Check Run Length 4 Limit Register (RW) + * + * Reset value: 0x0040004BU + * + * The RNG Statistical Check Run Length 4 Limit Register defines the allowable + * maximum and minimum number of runs of length 4 detected during entropy + * generation. To pass the test, the number of runs of length 4 (for samples of both 0 + * and 1) must be less than the programmed maximum value, and the number of runs of + * length 4 must be greater than (maximum - range). If this test fails, the + * Retry Counter in SCMISC will be decremented, and a retry will occur if the Retry + * Count has not reached zero. If the Retry Count has reached zero, an error will + * be generated. Note that this address (0xBASE_0630) is used as SCR4L only if + * MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this address is used as SCR4C readback + * register. + */ +/*! + * @name Constants and macros for entire TRNG_SCR4L register + */ +/*@{*/ +#define TRNG_SCR4L_REG(base) ((base)->SCR4L) +#define TRNG_RD_SCR4L(base) (TRNG_SCR4L_REG(base)) +#define TRNG_WR_SCR4L(base, value) (TRNG_SCR4L_REG(base) = (value)) +#define TRNG_RMW_SCR4L(base, mask, value) (TRNG_WR_SCR4L(base, (TRNG_RD_SCR4L(base) & ~(mask)) | (value))) +/*@}*/ + +/* + * Constants & macros for individual TRNG_SCR4L bitfields + */ + +/*! + * @name Register TRNG_SCR4L, field RUN4_MAX[11:0] (RW) + * + * Run Length 4 Maximum Limit. Defines the maximum allowable runs of length 4 + * (for both 0 and 1) detected during entropy generation. The number of runs of + * length 4 detected during entropy generation must be less than RUN4_MAX, else a + * retry or error will occur. This register is cleared to 004Bh (decimal 75) by + * writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCR4L_RUN4_MAX field. */ +#define TRNG_RD_SCR4L_RUN4_MAX(base) ((TRNG_SCR4L_REG(base) & TRNG_SCR4L_RUN4_MAX_MASK) >> TRNG_SCR4L_RUN4_MAX_SHIFT) + +/*! @brief Set the RUN4_MAX field to a new value. */ +#define TRNG_WR_SCR4L_RUN4_MAX(base, value) (TRNG_RMW_SCR4L(base, TRNG_SCR4L_RUN4_MAX_MASK, TRNG_SCR4L_RUN4_MAX(value))) +/*@}*/ + +/*! + * @name Register TRNG_SCR4L, field RUN4_RNG[27:16] (RW) + * + * Run Length 4 Range. The number of runs of length 4 (for both 0 and 1) + * detected during entropy generation must be greater than RUN4_MAX - RUN4_RNG, else a + * retry or error will occur. This register is cleared to 0040h (decimal 64) by + * writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCR4L_RUN4_RNG field. */ +#define TRNG_RD_SCR4L_RUN4_RNG(base) ((TRNG_SCR4L_REG(base) & TRNG_SCR4L_RUN4_RNG_MASK) >> TRNG_SCR4L_RUN4_RNG_SHIFT) + +/*! @brief Set the RUN4_RNG field to a new value. */ +#define TRNG_WR_SCR4L_RUN4_RNG(base, value) (TRNG_RMW_SCR4L(base, TRNG_SCR4L_RUN4_RNG_MASK, TRNG_SCR4L_RUN4_RNG(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_SCR5L - RNG Statistical Check Run Length 5 Limit Register + ******************************************************************************/ + +/*! + * @brief TRNG_SCR5L - RNG Statistical Check Run Length 5 Limit Register (RW) + * + * Reset value: 0x002E002FU + * + * The RNG Statistical Check Run Length 5 Limit Register defines the allowable + * maximum and minimum number of runs of length 5 detected during entropy + * generation. To pass the test, the number of runs of length 5 (for samples of both 0 + * and 1) must be less than the programmed maximum value, and the number of runs of + * length 5 must be greater than (maximum - range). If this test fails, the + * Retry Counter in SCMISC will be decremented, and a retry will occur if the Retry + * Count has not reached zero. If the Retry Count has reached zero, an error will + * be generated. Note that this address (0xBASE_0634) is used as SCR5L only if + * MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this address is used as SCR5C readback + * register. + */ +/*! + * @name Constants and macros for entire TRNG_SCR5L register + */ +/*@{*/ +#define TRNG_SCR5L_REG(base) ((base)->SCR5L) +#define TRNG_RD_SCR5L(base) (TRNG_SCR5L_REG(base)) +#define TRNG_WR_SCR5L(base, value) (TRNG_SCR5L_REG(base) = (value)) +#define TRNG_RMW_SCR5L(base, mask, value) (TRNG_WR_SCR5L(base, (TRNG_RD_SCR5L(base) & ~(mask)) | (value))) +/*@}*/ + +/* + * Constants & macros for individual TRNG_SCR5L bitfields + */ + +/*! + * @name Register TRNG_SCR5L, field RUN5_MAX[10:0] (RW) + * + * Run Length 5 Maximum Limit. Defines the maximum allowable runs of length 5 + * (for both 0 and 1) detected during entropy generation. The number of runs of + * length 5 detected during entropy generation must be less than RUN5_MAX, else a + * retry or error will occur. This register is cleared to 002Fh (decimal 47) by + * writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCR5L_RUN5_MAX field. */ +#define TRNG_RD_SCR5L_RUN5_MAX(base) ((TRNG_SCR5L_REG(base) & TRNG_SCR5L_RUN5_MAX_MASK) >> TRNG_SCR5L_RUN5_MAX_SHIFT) + +/*! @brief Set the RUN5_MAX field to a new value. */ +#define TRNG_WR_SCR5L_RUN5_MAX(base, value) (TRNG_RMW_SCR5L(base, TRNG_SCR5L_RUN5_MAX_MASK, TRNG_SCR5L_RUN5_MAX(value))) +/*@}*/ + +/*! + * @name Register TRNG_SCR5L, field RUN5_RNG[26:16] (RW) + * + * Run Length 5 Range. The number of runs of length 5 (for both 0 and 1) + * detected during entropy generation must be greater than RUN5_MAX - RUN5_RNG, else a + * retry or error will occur. This register is cleared to 002Eh (decimal 46) by + * writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCR5L_RUN5_RNG field. */ +#define TRNG_RD_SCR5L_RUN5_RNG(base) ((TRNG_SCR5L_REG(base) & TRNG_SCR5L_RUN5_RNG_MASK) >> TRNG_SCR5L_RUN5_RNG_SHIFT) + +/*! @brief Set the RUN5_RNG field to a new value. */ +#define TRNG_WR_SCR5L_RUN5_RNG(base, value) (TRNG_RMW_SCR5L(base, TRNG_SCR5L_RUN5_RNG_MASK, TRNG_SCR5L_RUN5_RNG(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_SCR6PL - RNG Statistical Check Run Length 6+ Limit Register + ******************************************************************************/ + +/*! + * @brief TRNG_SCR6PL - RNG Statistical Check Run Length 6+ Limit Register (RW) + * + * Reset value: 0x002E002FU + * + * The RNG Statistical Check Run Length 6+ Limit Register defines the allowable + * maximum and minimum number of runs of length 6 or more detected during entropy + * generation. To pass the test, the number of runs of length 6 or more (for + * samples of both 0 and 1) must be less than the programmed maximum value, and the + * number of runs of length 6 or more must be greater than (maximum - range). If + * this test fails, the Retry Counter in SCMISC will be decremented, and a retry + * will occur if the Retry Count has not reached zero. If the Retry Count has + * reached zero, an error will be generated. Note that this offset (0xBASE_0638) is + * used as SCR6PL only if MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this offset is + * used as SCR6PC readback register. + */ +/*! + * @name Constants and macros for entire TRNG_SCR6PL register + */ +/*@{*/ +#define TRNG_SCR6PL_REG(base) ((base)->SCR6PL) +#define TRNG_RD_SCR6PL(base) (TRNG_SCR6PL_REG(base)) +#define TRNG_WR_SCR6PL(base, value) (TRNG_SCR6PL_REG(base) = (value)) +#define TRNG_RMW_SCR6PL(base, mask, value) (TRNG_WR_SCR6PL(base, (TRNG_RD_SCR6PL(base) & ~(mask)) | (value))) +/*@}*/ + +/* + * Constants & macros for individual TRNG_SCR6PL bitfields + */ + +/*! + * @name Register TRNG_SCR6PL, field RUN6P_MAX[10:0] (RW) + * + * Run Length 6+ Maximum Limit. Defines the maximum allowable runs of length 6 + * or more (for both 0 and 1) detected during entropy generation. The number of + * runs of length 6 or more detected during entropy generation must be less than + * RUN6P_MAX, else a retry or error will occur. This register is cleared to 002Fh + * (decimal 47) by writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCR6PL_RUN6P_MAX field. */ +#define TRNG_RD_SCR6PL_RUN6P_MAX(base) \ + ((TRNG_SCR6PL_REG(base) & TRNG_SCR6PL_RUN6P_MAX_MASK) >> TRNG_SCR6PL_RUN6P_MAX_SHIFT) + +/*! @brief Set the RUN6P_MAX field to a new value. */ +#define TRNG_WR_SCR6PL_RUN6P_MAX(base, value) \ + (TRNG_RMW_SCR6PL(base, TRNG_SCR6PL_RUN6P_MAX_MASK, TRNG_SCR6PL_RUN6P_MAX(value))) +/*@}*/ + +/*! + * @name Register TRNG_SCR6PL, field RUN6P_RNG[26:16] (RW) + * + * Run Length 6+ Range. The number of runs of length 6 or more (for both 0 and + * 1) detected during entropy generation must be greater than RUN6P_MAX - + * RUN6P_RNG, else a retry or error will occur. This register is cleared to 002Eh + * (decimal 46) by writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCR6PL_RUN6P_RNG field. */ +#define TRNG_RD_SCR6PL_RUN6P_RNG(base) \ + ((TRNG_SCR6PL_REG(base) & TRNG_SCR6PL_RUN6P_RNG_MASK) >> TRNG_SCR6PL_RUN6P_RNG_SHIFT) + +/*! @brief Set the RUN6P_RNG field to a new value. */ +#define TRNG_WR_SCR6PL_RUN6P_RNG(base, value) \ + (TRNG_RMW_SCR6PL(base, TRNG_SCR6PL_RUN6P_RNG_MASK, TRNG_SCR6PL_RUN6P_RNG(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_PKRMAX - RNG Poker Maximum Limit Register + ******************************************************************************/ + +/*! + * @brief TRNG_PKRMAX - RNG Poker Maximum Limit Register (RW) + * + * Reset value: 0x00006920U + * + * The RNG Poker Maximum Limit Register defines Maximum Limit allowable during + * the TRNG Statistical Check Poker Test. Note that this offset (0xBASE_060C) is + * used as PKRMAX only if MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this offset is used + * as the PKRSQ readback register. + */ +/*! + * @name Constants and macros for entire TRNG_PKRMAX register + */ +/*@{*/ +#define TRNG_PKRMAX_REG(base) ((base)->PKRMAX) +#define TRNG_RD_PKRMAX(base) (TRNG_PKRMAX_REG(base)) +#define TRNG_WR_PKRMAX(base, value) (TRNG_PKRMAX_REG(base) = (value)) +#define TRNG_RMW_PKRMAX(base, mask, value) (TRNG_WR_PKRMAX(base, (TRNG_RD_PKRMAX(base) & ~(mask)) | (value))) +/*@}*/ + +/* + * Constants & macros for individual TRNG_PKRMAX bitfields + */ + +/*! + * @name Register TRNG_PKRMAX, field PKR_MAX[23:0] (RW) + * + * Poker Maximum Limit. During the TRNG Statistical Checks, a "Poker Test" is + * run which requires a maximum and minimum limit. The maximum allowable result is + * programmed in the PKRMAX[PKR_MAX] register. This field is writable only if + * MCTL[PRGM] bit is 1. This register is cleared to 006920h (decimal 26912) by + * writing the MCTL[RST_DEF] bit to 1. Note that the PKRMAX and PKRRNG registers + * combined are used to define the minimum allowable Poker result, which is PKR_MAX - + * PKR_RNG + 1. Note that if MCTL[PRGM] bit is 0, this register address is used + * to read the Poker Test Square Calculation result in register PKRSQ, as defined + * in the following section. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_PKRMAX_PKR_MAX field. */ +#define TRNG_RD_PKRMAX_PKR_MAX(base) ((TRNG_PKRMAX_REG(base) & TRNG_PKRMAX_PKR_MAX_MASK) >> TRNG_PKRMAX_PKR_MAX_SHIFT) + +/*! @brief Set the PKR_MAX field to a new value. */ +#define TRNG_WR_PKRMAX_PKR_MAX(base, value) \ + (TRNG_RMW_PKRMAX(base, TRNG_PKRMAX_PKR_MAX_MASK, TRNG_PKRMAX_PKR_MAX(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_PKRRNG - RNG Poker Range Register + ******************************************************************************/ + +/*! + * @brief TRNG_PKRRNG - RNG Poker Range Register (RW) + * + * Reset value: 0x000009A3U + * + * The RNG Poker Range Register defines the difference between the TRNG Poker + * Maximum Limit and the minimum limit. These limits are used during the TRNG + * Statistical Check Poker Test. + */ +/*! + * @name Constants and macros for entire TRNG_PKRRNG register + */ +/*@{*/ +#define TRNG_PKRRNG_REG(base) ((base)->PKRRNG) +#define TRNG_RD_PKRRNG(base) (TRNG_PKRRNG_REG(base)) +#define TRNG_WR_PKRRNG(base, value) (TRNG_PKRRNG_REG(base) = (value)) +#define TRNG_RMW_PKRRNG(base, mask, value) (TRNG_WR_PKRRNG(base, (TRNG_RD_PKRRNG(base) & ~(mask)) | (value))) +/*@}*/ + +/* + * Constants & macros for individual TRNG_PKRRNG bitfields + */ + +/*! + * @name Register TRNG_PKRRNG, field PKR_RNG[15:0] (RW) + * + * Poker Range. During the TRNG Statistical Checks, a "Poker Test" is run which + * requires a maximum and minimum limit. The maximum is programmed in the + * RTPKRMAX[PKR_MAX] register, and the minimum is derived by subtracting the PKR_RNG + * value from the programmed maximum value. This field is writable only if + * MCTL[PRGM] bit is 1. This field will read zeroes if MCTL[PRGM] = 0. This field is + * cleared to 09A3h (decimal 2467) by writing the MCTL[RST_DEF] bit to 1. Note that + * the minimum allowable Poker result is PKR_MAX - PKR_RNG + 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_PKRRNG_PKR_RNG field. */ +#define TRNG_RD_PKRRNG_PKR_RNG(base) ((TRNG_PKRRNG_REG(base) & TRNG_PKRRNG_PKR_RNG_MASK) >> TRNG_PKRRNG_PKR_RNG_SHIFT) + +/*! @brief Set the PKR_RNG field to a new value. */ +#define TRNG_WR_PKRRNG_PKR_RNG(base, value) \ + (TRNG_RMW_PKRRNG(base, TRNG_PKRRNG_PKR_RNG_MASK, TRNG_PKRRNG_PKR_RNG(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_FRQMAX - RNG Frequency Count Maximum Limit Register + ******************************************************************************/ + +/*! + * @brief TRNG_FRQMAX - RNG Frequency Count Maximum Limit Register (RW) + * + * Reset value: 0x00006400U + * + * The RNG Frequency Count Maximum Limit Register defines the maximum allowable + * count taken by the Entropy sample counter during each Entropy sample. During + * any sample period, if the count is greater than this programmed maximum, a + * Frequency Count Fail is flagged in MCTL[FCT_FAIL] and an error is generated. Note + * that this address (061C) is used as FRQMAX only if MCTL[PRGM] is 1. If + * MCTL[PRGM] is 0, this address is used as FRQCNT readback register. + */ +/*! + * @name Constants and macros for entire TRNG_FRQMAX register + */ +/*@{*/ +#define TRNG_FRQMAX_REG(base) ((base)->FRQMAX) +#define TRNG_RD_FRQMAX(base) (TRNG_FRQMAX_REG(base)) +#define TRNG_WR_FRQMAX(base, value) (TRNG_FRQMAX_REG(base) = (value)) +#define TRNG_RMW_FRQMAX(base, mask, value) (TRNG_WR_FRQMAX(base, (TRNG_RD_FRQMAX(base) & ~(mask)) | (value))) +/*@}*/ + +/* + * Constants & macros for individual TRNG_FRQMAX bitfields + */ + +/*! + * @name Register TRNG_FRQMAX, field FRQ_MAX[21:0] (RW) + * + * Frequency Counter Maximum Limit. Defines the maximum allowable count taken + * during each entropy sample. This field is writable only if MCTL[PRGM] bit is 1. + * This register is cleared to 000640h by writing the MCTL[RST_DEF] bit to 1. + * Note that if MCTL[PRGM] bit is 0, this register address is used to read the + * Frequency Count result in register FRQCNT, as defined in the following section. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_FRQMAX_FRQ_MAX field. */ +#define TRNG_RD_FRQMAX_FRQ_MAX(base) ((TRNG_FRQMAX_REG(base) & TRNG_FRQMAX_FRQ_MAX_MASK) >> TRNG_FRQMAX_FRQ_MAX_SHIFT) + +/*! @brief Set the FRQ_MAX field to a new value. */ +#define TRNG_WR_FRQMAX_FRQ_MAX(base, value) \ + (TRNG_RMW_FRQMAX(base, TRNG_FRQMAX_FRQ_MAX_MASK, TRNG_FRQMAX_FRQ_MAX(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_FRQMIN - RNG Frequency Count Minimum Limit Register + ******************************************************************************/ + +/*! + * @brief TRNG_FRQMIN - RNG Frequency Count Minimum Limit Register (RW) + * + * Reset value: 0x00000640U + * + * The RNG Frequency Count Minimum Limit Register defines the minimum allowable + * count taken by the Entropy sample counter during each Entropy sample. During + * any sample period, if the count is less than this programmed minimum, a + * Frequency Count Fail is flagged in MCTL[FCT_FAIL] and an error is generated. + */ +/*! + * @name Constants and macros for entire TRNG_FRQMIN register + */ +/*@{*/ +#define TRNG_FRQMIN_REG(base) ((base)->FRQMIN) +#define TRNG_RD_FRQMIN(base) (TRNG_FRQMIN_REG(base)) +#define TRNG_WR_FRQMIN(base, value) (TRNG_FRQMIN_REG(base) = (value)) +#define TRNG_RMW_FRQMIN(base, mask, value) (TRNG_WR_FRQMIN(base, (TRNG_RD_FRQMIN(base) & ~(mask)) | (value))) +/*@}*/ + +/* + * Constants & macros for individual TRNG_FRQMIN bitfields + */ + +/*! + * @name Register TRNG_FRQMIN, field FRQ_MIN[21:0] (RW) + * + * Frequency Count Minimum Limit. Defines the minimum allowable count taken + * during each entropy sample. This field is writable only if MCTL[PRGM] bit is 1. + * This field will read zeroes if MCTL[PRGM] = 0. This field is cleared to 0000h64 + * by writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_FRQMIN_FRQ_MIN field. */ +#define TRNG_RD_FRQMIN_FRQ_MIN(base) ((TRNG_FRQMIN_REG(base) & TRNG_FRQMIN_FRQ_MIN_MASK) >> TRNG_FRQMIN_FRQ_MIN_SHIFT) + +/*! @brief Set the FRQ_MIN field to a new value. */ +#define TRNG_WR_FRQMIN_FRQ_MIN(base, value) \ + (TRNG_RMW_FRQMIN(base, TRNG_FRQMIN_FRQ_MIN_MASK, TRNG_FRQMIN_FRQ_MIN(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_MCTL - RNG Miscellaneous Control Register + ******************************************************************************/ + +/*! + * @brief TRNG_MCTL - RNG Miscellaneous Control Register (RW) + * + * Reset value: 0x00012001U + * + * This register is intended to be used for programming, configuring and testing + * the RNG. It is the main register to read/write, in order to enable Entropy + * generation, to stop entropy generation and to block access to entropy registers. + * This is done via the special TRNG_ACC and PRGM bits below. The RNG + * Miscellaneous Control Register is a read/write register used to control the RNG's True + * Random Number Generator (TRNG) access, operation and test. Note that in many + * cases two RNG registers share the same address, and a particular register at the + * shared address is selected based upon the value in the PRGM field of the MCTL + * register. + */ +/*! + * @name Constants and macros for entire TRNG_MCTL register + */ +/*@{*/ +#define TRNG_MCTL_REG(base) ((base)->MCTL) +#define TRNG_RD_MCTL(base) (TRNG_MCTL_REG(base)) +#define TRNG_WR_MCTL(base, value) (TRNG_MCTL_REG(base) = (value)) +#define TRNG_RMW_MCTL(base, mask, value) (TRNG_WR_MCTL(base, (TRNG_RD_MCTL(base) & ~(mask)) | (value))) +/*@}*/ + +/*! + * @name Register TRNG_MCTL, field FOR_SCLK[7] (RW) + * + * Force System Clock. If set, the system clock is used to operate the TRNG, + * instead of the ring oscillator. This is for test use only, and indeterminate + * results may occur. This bit is writable only if PRGM bit is 1, or PRGM bit is + * being written to 1 simultaneously to writing this bit. This bit is cleared by + * writing the RST_DEF bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_MCTL_FOR_SCLK field. */ +#define TRNG_RD_MCTL_FOR_SCLK(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_FOR_SCLK_MASK) >> TRNG_MCTL_FOR_SCLK_SHIFT) + +/*! @brief Set the FOR_SCLK field to a new value. */ +#define TRNG_WR_MCTL_FOR_SCLK(base, value) \ + (TRNG_RMW_MCTL(base, (TRNG_MCTL_FOR_SCLK_MASK | TRNG_MCTL_ERR_MASK), TRNG_MCTL_FOR_SCLK(value))) +/*@}*/ + +/*! + * @name Register TRNG_MCTL, field OSC_DIV[3:2] (RW) + * + * Oscillator Divide. Determines the amount of dividing done to the ring + * oscillator before it is used by the TRNG.This field is writable only if PRGM bit is + * 1, or PRGM bit is being written to 1 simultaneously to writing this field. This + * field is cleared to 00 by writing the RST_DEF bit to 1. + * + * Values: + * - 0b00 - use ring oscillator with no divide + * - 0b01 - use ring oscillator divided-by-2 + * - 0b10 - use ring oscillator divided-by-4 + * - 0b11 - use ring oscillator divided-by-8 + */ +/*@{*/ +/*! @brief Read current value of the TRNG_MCTL_OSC_DIV field. */ +#define TRNG_RD_MCTL_OSC_DIV(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_OSC_DIV_MASK) >> TRNG_MCTL_OSC_DIV_SHIFT) + +/*! @brief Set the OSC_DIV field to a new value. */ +#define TRNG_WR_MCTL_OSC_DIV(base, value) \ + (TRNG_RMW_MCTL(base, (TRNG_MCTL_OSC_DIV_MASK | TRNG_MCTL_ERR_MASK), TRNG_MCTL_OSC_DIV(value))) +/*@}*/ + +/*! + * @name Register TRNG_MCTL, field SAMP_MODE[1:0] (RW) + * + * Sample Mode. Determines the method of sampling the ring oscillator while + * generating the Entropy value:This field is writable only if PRGM bit is 1, or PRGM + * bit is being written to 1 simultaneously with writing this field. This field + * is cleared to 01 by writing the RST_DEF bit to 1. + * + * Values: + * - 0b00 - use Von Neumann data into both Entropy shifter and Statistical + * Checker + * - 0b01 - use raw data into both Entropy shifter and Statistical Checker + * - 0b10 - use Von Neumann data into Entropy shifter. Use raw data into + * Statistical Checker + * - 0b11 - reserved. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_MCTL_SAMP_MODE field. */ +#define TRNG_RD_MCTL_SAMP_MODE(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_SAMP_MODE_MASK) >> TRNG_MCTL_SAMP_MODE_SHIFT) + +/*! @brief Set the SAMP_MODE field to a new value. */ +#define TRNG_WR_MCTL_SAMP_MODE(base, value) \ + (TRNG_RMW_MCTL(base, (TRNG_MCTL_SAMP_MODE_MASK | TRNG_MCTL_ERR_MASK), TRNG_MCTL_SAMP_MODE(value))) +/*@}*/ + +/*! + * @name Register TRNG_MCTL, field PRGM[16] (RW) + * + * Programming Mode Select. When this bit is 1, the TRNG is in Program Mode, + * otherwise it is in Run Mode. No Entropy value will be generated while the TRNG is + * in Program Mode. Note that different RNG registers are accessible at the same + * address depending on whether PRGM is set to 1 or 0. This is noted in the RNG + * register descriptions. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_MCTL_PRGM field. */ +#define TRNG_RD_MCTL_PRGM(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_PRGM_MASK) >> TRNG_MCTL_PRGM_SHIFT) + +/*! @brief Set the PRGM field to a new value. */ +#define TRNG_WR_MCTL_PRGM(base, value) \ + (TRNG_RMW_MCTL(base, (TRNG_MCTL_PRGM_MASK | TRNG_MCTL_ERR_MASK), TRNG_MCTL_PRGM(value))) +/*@}*/ + +/*! + * @name Register TRNG_MCTL, field RST_DEF[6] (WO) + * + * Reset Defaults. Writing a 1 to this bit clears various TRNG registers, and + * bits within registers, to their default state. This bit is writable only if PRGM + * bit is 1, or PRGM bit is being written to 1 simultaneously to writing this + * bit. Reading this bit always produces a 0. + */ +/*@{*/ +/*! @brief Set the RST_DEF field to a new value. */ +#define TRNG_WR_MCTL_RST_DEF(base, value) \ + (TRNG_RMW_MCTL(base, (TRNG_MCTL_RST_DEF_MASK | TRNG_MCTL_ERR_MASK), TRNG_MCTL_RST_DEF(value))) +/*@}*/ + +/*! + * @name Register TRNG_MCTL, field TRNG_ACC[5] (RW) + * + * TRNG Access Mode. If this bit is set to 1, the TRNG will generate an Entropy + * value that can be read via the ENT0-ENT15 registers. The Entropy value may be + * read once the ENT VAL bit is asserted. Also see ENTa register descriptions + * (For a = 0 to 15). + */ +/*@{*/ +/*! @brief Read current value of the TRNG_MCTL_TRNG_ACC field. */ +#define TRNG_RD_MCTL_TRNG_ACC(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_TRNG_ACC_MASK) >> TRNG_MCTL_TRNG_ACC_SHIFT) + +/*! @brief Set the TRNG_ACC field to a new value. */ +#define TRNG_WR_MCTL_TRNG_ACC(base, value) \ + (TRNG_RMW_MCTL(base, (TRNG_MCTL_TRNG_ACC_MASK | TRNG_MCTL_ERR_MASK), TRNG_MCTL_TRNG_ACC(value))) +/*@}*/ + +/*! + * @name Register TRNG_MCTL, field TSTOP_OK[13] (RO) + * + * TRNG_OK_TO_STOP. Software should check that this bit is a 1 before + * transitioning RNG to low power mode (RNG clock stopped). RNG turns on the TRNG + * free-running ring oscillator whenever new entropy is being generated and turns off the + * ring oscillator when entropy generation is complete. If the RNG clock is + * stopped while the TRNG ring oscillator is running, the oscillator will continue + * running even though the RNG clock is stopped. TSTOP_OK is asserted when the TRNG + * ring oscillator is not running. and therefore it is ok to stop the RNG clock. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_MCTL_TSTOP_OK field. */ +#define TRNG_RD_MCTL_TSTOP_OK(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_TSTOP_OK_MASK) >> TRNG_MCTL_TSTOP_OK_SHIFT) +/*@}*/ + +/*! + * @name Register TRNG_MCTL, field ENT_VAL[10] (RO) + * + * Read only: Entropy Valid. Will assert only if TRNG ACC bit is set, and then + * after an entropy value is generated. Will be cleared when ENT15 is read. (ENT0 + * through ENT14 should be read before reading ENT15). + */ +/*@{*/ +/*! @brief Read current value of the TRNG_MCTL_ENT_VAL field. */ +#define TRNG_RD_MCTL_ENT_VAL(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_ENT_VAL_MASK) >> TRNG_MCTL_ENT_VAL_SHIFT) +/*@}*/ + +/*! + * @name Register TRNG_MCTL, field ERR[12] (W1C) + * + * Read: Error status. 1 = error detected. 0 = no error.Write: Write 1 to clear + * errors. Writing 0 has no effect. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_MCTL_ERR field. */ +#define TRNG_RD_MCTL_ERR(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_ERR_MASK) >> TRNG_MCTL_ERR_SHIFT) + +/*! @brief Set the ERR field to a new value. */ +#define TRNG_WR_MCTL_ERR(base, value) (TRNG_RMW_MCTL(base, TRNG_MCTL_ERR_MASK, TRNG_MCTL_ERR(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_SDCTL - RNG Seed Control Register + ******************************************************************************/ + +/*! + * @brief TRNG_SDCTL - RNG Seed Control Register (RW) + * + * Reset value: 0x0C8009C4U + * + * The RNG Seed Control Register contains two fields. One field defines the + * length (in system clocks) of each Entropy sample (ENT_DLY), and the other field + * indicates the number of samples that will taken during each TRNG Entropy + * generation (SAMP_SIZE). + */ +/*! + * @name Constants and macros for entire TRNG_SDCTL register + */ +/*@{*/ +#define TRNG_SDCTL_REG(base) ((base)->SDCTL) +#define TRNG_RD_SDCTL(base) (TRNG_SDCTL_REG(base)) +#define TRNG_WR_SDCTL(base, value) (TRNG_SDCTL_REG(base) = (value)) +#define TRNG_RMW_SDCTL(base, mask, value) (TRNG_WR_SDCTL(base, (TRNG_RD_SDCTL(base) & ~(mask)) | (value))) +/*@}*/ + +/* + * Constants & macros for individual TRNG_SDCTL bitfields + */ + +/*! + * @name Register TRNG_SDCTL, field SAMP_SIZE[15:0] (RW) + * + * Sample Size. Defines the total number of Entropy samples that will be taken + * during Entropy generation. This field is writable only if MCTL[PRGM] bit is 1. + * This field will read zeroes if MCTL[PRGM] = 0. This field is cleared to 09C4h + * (decimal 2500) by writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SDCTL_SAMP_SIZE field. */ +#define TRNG_RD_SDCTL_SAMP_SIZE(base) ((TRNG_SDCTL_REG(base) & TRNG_SDCTL_SAMP_SIZE_MASK) >> TRNG_SDCTL_SAMP_SIZE_SHIFT) + +/*! @brief Set the SAMP_SIZE field to a new value. */ +#define TRNG_WR_SDCTL_SAMP_SIZE(base, value) \ + (TRNG_RMW_SDCTL(base, TRNG_SDCTL_SAMP_SIZE_MASK, TRNG_SDCTL_SAMP_SIZE(value))) +/*@}*/ + +/*! + * @name Register TRNG_SDCTL, field ENT_DLY[31:16] (RW) + * + * Entropy Delay. Defines the length (in system clocks) of each Entropy sample + * taken. This field is writable only if MCTL[PRGM] bit is 1. This field will read + * zeroes if MCTL[PRGM] = 0. This field is cleared to 0C80h (decimal 3200) by + * writing the MCTL[RST_DEF] bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SDCTL_ENT_DLY field. */ +#define TRNG_RD_SDCTL_ENT_DLY(base) ((TRNG_SDCTL_REG(base) & TRNG_SDCTL_ENT_DLY_MASK) >> TRNG_SDCTL_ENT_DLY_SHIFT) + +/*! @brief Set the ENT_DLY field to a new value. */ +#define TRNG_WR_SDCTL_ENT_DLY(base, value) (TRNG_RMW_SDCTL(base, TRNG_SDCTL_ENT_DLY_MASK, TRNG_SDCTL_ENT_DLY(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_SBLIM - RNG Sparse Bit Limit Register + ******************************************************************************/ + +/*! + * @brief TRNG_SBLIM - RNG Sparse Bit Limit Register (RW) + * + * Reset value: 0x0000003FU + * + * The RNG Sparse Bit Limit Register is used when Von Neumann sampling is + * selected during Entropy Generation. It defines the maximum number of consecutive Von + * Neumann samples which may be discarded before an error is generated. Note + * that this address (0xBASE_0614) is used as SBLIM only if MCTL[PRGM] is 1. If + * MCTL[PRGM] is 0, this address is used as TOTSAM readback register. + */ +/*! + * @name Constants and macros for entire TRNG_SBLIM register + */ +/*@{*/ +#define TRNG_SBLIM_REG(base) ((base)->SBLIM) +#define TRNG_RD_SBLIM(base) (TRNG_SBLIM_REG(base)) +#define TRNG_WR_SBLIM(base, value) (TRNG_SBLIM_REG(base) = (value)) +#define TRNG_RMW_SBLIM(base, mask, value) (TRNG_WR_SBLIM(base, (TRNG_RD_SBLIM(base) & ~(mask)) | (value))) +/*@}*/ + +/* + * Constants & macros for individual TRNG_SBLIM bitfields + */ + +/*! + * @name Register TRNG_SBLIM, field SB_LIM[9:0] (RW) + * + * Sparse Bit Limit. During Von Neumann sampling (if enabled by MCTL[SAMP_MODE], + * samples are discarded if two consecutive raw samples are both 0 or both 1. If + * this discarding occurs for a long period of time, it indicates that there is + * insufficient Entropy. The Sparse Bit Limit defines the maximum number of + * consecutive samples that may be discarded before an error is generated. This field + * is writable only if MCTL[PRGM] bit is 1. This register is cleared to 03hF by + * writing the MCTL[RST_DEF] bit to 1. Note that if MCTL[PRGM] bit is 0, this + * register address is used to read the Total Samples count in register TOTSAM, as + * defined in the following section. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SBLIM_SB_LIM field. */ +#define TRNG_RD_SBLIM_SB_LIM(base) ((TRNG_SBLIM_REG(base) & TRNG_SBLIM_SB_LIM_MASK) >> TRNG_SBLIM_SB_LIM_SHIFT) + +/*! @brief Set the SB_LIM field to a new value. */ +#define TRNG_WR_SBLIM_SB_LIM(base, value) (TRNG_RMW_SBLIM(base, TRNG_SBLIM_SB_LIM_MASK, TRNG_SBLIM_SB_LIM(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_SCMISC - RNG Statistical Check Miscellaneous Register + ******************************************************************************/ + +/*! + * @brief TRNG_SCMISC - RNG Statistical Check Miscellaneous Register (RW) + * + * Reset value: 0x0001001FU + * + * The RNG Statistical Check Miscellaneous Register contains the Long Run + * Maximum Limit value and the Retry Count value. This register is accessible only when + * the MCTL[PRGM] bit is 1, otherwise this register will read zeroes, and cannot + * be written. + */ +/*! + * @name Constants and macros for entire TRNG_SCMISC register + */ +/*@{*/ +#define TRNG_SCMISC_REG(base) ((base)->SCMISC) +#define TRNG_RD_SCMISC(base) (TRNG_SCMISC_REG(base)) +#define TRNG_WR_SCMISC(base, value) (TRNG_SCMISC_REG(base) = (value)) +#define TRNG_RMW_SCMISC(base, mask, value) (TRNG_WR_SCMISC(base, (TRNG_RD_SCMISC(base) & ~(mask)) | (value))) +/*@}*/ + +/* + * Constants & macros for individual TRNG_SCMISC bitfields + */ + +/*! + * @name Register TRNG_SCMISC, field LRUN_MAX[7:0] (RW) + * + * LONG RUN MAX LIMIT. This value is the largest allowable number of consecutive + * samples of all 1, or all 0, that is allowed during the Entropy generation. + * This field is writable only if MCTL[PRGM] bit is 1. This field will read zeroes + * if MCTL[PRGM] = 0. This field is cleared to 22h by writing the MCTL[RST_DEF] + * bit to 1. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SCMISC_LRUN_MAX field. */ +#define TRNG_RD_SCMISC_LRUN_MAX(base) \ + ((TRNG_SCMISC_REG(base) & TRNG_SCMISC_LRUN_MAX_MASK) >> TRNG_SCMISC_LRUN_MAX_SHIFT) + +/*! @brief Set the LRUN_MAX field to a new value. */ +#define TRNG_WR_SCMISC_LRUN_MAX(base, value) \ + (TRNG_RMW_SCMISC(base, TRNG_SCMISC_LRUN_MAX_MASK, TRNG_SCMISC_LRUN_MAX(value))) +/*@}*/ + +/******************************************************************************* + * TRNG_ENT - RNG TRNG Entropy Read Register + ******************************************************************************/ + +/*! + * @brief TRNG_ENT - RNG TRNG Entropy Read Register (RO) + * + * Reset value: 0x00000000U + * + * The RNG TRNG can be programmed to generate an entropy value that is readable + * via the SkyBlue bus. To do this, set the MCTL[TRNG_ACC] bit to 1. Once the + * entropy value has been generated, the MCTL[ENT_VAL] bit will be set to 1. At this + * point, ENT0 through ENT15 may be read to retrieve the 512-bit entropy value. + * Note that once ENT15 is read, the entropy value will be cleared and a new + * value will begin generation, so it is important that ENT15 be read last. These + * registers are readable only when MCTL[PRGM] = 0 (Run Mode), MCTL[TRNG_ACC] = 1 + * (TRNG access mode) and MCTL[ENT_VAL] = 1, otherwise zeroes will be read. + */ +/*! + * @name Constants and macros for entire TRNG_ENT register + */ +/*@{*/ +#define TRNG_ENT_REG(base, index) ((base)->ENT[index]) +#define TRNG_RD_ENT(base, index) (TRNG_ENT_REG(base, index)) +/*@}*/ + +/******************************************************************************* + * TRNG_SEC_CFG - RNG Security Configuration Register + ******************************************************************************/ + +/*! + * @brief TRNG_SEC_CFG - RNG Security Configuration Register (RW) + * + * Reset value: 0x00000000U + * + * The RNG Security Configuration Register is a read/write register used to + * control the test mode, programmability and state modes of the RNG. Many bits are + * place holders for this version. More configurability will be added here. Clears + * on asynchronous reset. For SA-TRNG releases before 2014/July/01, offsets 0xA0 + * to 0xAC used to be 0xB0 to 0xBC respectively. So, update newer tests that use + * these registers, if hard coded. + */ +/*! + * @name Constants and macros for entire TRNG_SEC_CFG register + */ +/*@{*/ +#define TRNG_SEC_CFG_REG(base) ((base)->SEC_CFG) +#define TRNG_RD_SEC_CFG(base) (TRNG_SEC_CFG_REG(base)) +#define TRNG_WR_SEC_CFG(base, value) (TRNG_SEC_CFG_REG(base) = (value)) +#define TRNG_RMW_SEC_CFG(base, mask, value) (TRNG_WR_SEC_CFG(base, (TRNG_RD_SEC_CFG(base) & ~(mask)) | (value))) +/*@}*/ + +/*! + * @name Register TRNG_SEC_CFG, field NO_PRGM[1] (RW) + * + * If set the TRNG registers cannot be programmed. That is, regardless of the + * TRNG access mode in the SA-TRNG Miscellaneous Control Register. + * + * Values: + * - 0b0 - Programability of registers controlled only by the RNG Miscellaneous + * Control Register's access mode bit. + * - 0b1 - Overides RNG Miscellaneous Control Register access mode and prevents + * TRNG register programming. + */ +/*@{*/ +/*! @brief Read current value of the TRNG_SEC_CFG_NO_PRGM field. */ +#define TRNG_RD_SEC_CFG_NO_PRGM(base) \ + ((TRNG_SEC_CFG_REG(base) & TRNG_SEC_CFG_NO_PRGM_MASK) >> TRNG_SEC_CFG_NO_PRGM_SHIFT) + +/*! @brief Set the NO_PRGM field to a new value. */ +#define TRNG_WR_SEC_CFG_NO_PRGM(base, value) \ + (TRNG_RMW_SEC_CFG(base, TRNG_SEC_CFG_NO_PRGM_MASK, TRNG_SEC_CFG_NO_PRGM(value))) +/*@}*/ + +/******************************************************************************* + * Prototypes + *******************************************************************************/ +static status_t trng_ApplyUserConfig(TRNG_Type *base, const trng_config_t *userConfig); +static status_t trng_SetRetryCount(TRNG_Type *base, uint8_t retry_count); +static status_t trng_SetStatisticalCheckLimit(TRNG_Type *base, + trng_statistical_check_t statistical_check, + const trng_statistical_check_limit_t *limit); +static uint32_t trng_ReadEntropy(TRNG_Type *base, uint32_t index); + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************* + * + * Function Name : TRNG_InitUserConfigDefault + * Description : Initializes user configuration structure to default settings. + * + *END*************************************************************************/ +status_t TRNG_GetDefaultConfig(trng_config_t *userConfig) +{ + status_t result; + + if (userConfig != 0) + { + userConfig->lock = TRNG_USER_CONFIG_DEFAULT_LOCK; + userConfig->clockMode = kTRNG_ClockModeRingOscillator; + userConfig->ringOscDiv = TRNG_USER_CONFIG_DEFAULT_OSC_DIV; + userConfig->sampleMode = kTRNG_SampleModeRaw; + userConfig->entropyDelay = TRNG_USER_CONFIG_DEFAULT_ENTROPY_DELAY; + userConfig->sampleSize = TRNG_USER_CONFIG_DEFAULT_SAMPLE_SIZE; + userConfig->sparseBitLimit = TRNG_USER_CONFIG_DEFAULT_SPARSE_BIT_LIMIT; + + /* Statistical Check Parameters.*/ + userConfig->retryCount = TRNG_USER_CONFIG_DEFAULT_RETRY_COUNT; + userConfig->longRunMaxLimit = TRNG_USER_CONFIG_DEFAULT_RUN_MAX_LIMIT; + + userConfig->monobitLimit.maximum = TRNG_USER_CONFIG_DEFAULT_MONOBIT_MAXIMUM; + userConfig->monobitLimit.minimum = TRNG_USER_CONFIG_DEFAULT_MONOBIT_MINIMUM; + userConfig->runBit1Limit.maximum = TRNG_USER_CONFIG_DEFAULT_RUNBIT1_MAXIMUM; + userConfig->runBit1Limit.minimum = TRNG_USER_CONFIG_DEFAULT_RUNBIT1_MINIMUM; + userConfig->runBit2Limit.maximum = TRNG_USER_CONFIG_DEFAULT_RUNBIT2_MAXIMUM; + userConfig->runBit2Limit.minimum = TRNG_USER_CONFIG_DEFAULT_RUNBIT2_MINIMUM; + userConfig->runBit3Limit.maximum = TRNG_USER_CONFIG_DEFAULT_RUNBIT3_MAXIMUM; + userConfig->runBit3Limit.minimum = TRNG_USER_CONFIG_DEFAULT_RUNBIT3_MINIMUM; + userConfig->runBit4Limit.maximum = TRNG_USER_CONFIG_DEFAULT_RUNBIT4_MAXIMUM; + userConfig->runBit4Limit.minimum = TRNG_USER_CONFIG_DEFAULT_RUNBIT4_MINIMUM; + userConfig->runBit5Limit.maximum = TRNG_USER_CONFIG_DEFAULT_RUNBIT5_MAXIMUM; + userConfig->runBit5Limit.minimum = TRNG_USER_CONFIG_DEFAULT_RUNBIT5_MINIMUM; + userConfig->runBit6PlusLimit.maximum = TRNG_USER_CONFIG_DEFAULT_RUNBIT6PLUS_MAXIMUM; + userConfig->runBit6PlusLimit.minimum = TRNG_USER_CONFIG_DEFAULT_RUNBIT6PLUS_MINIMUM; + userConfig->pokerLimit.maximum = TRNG_USER_CONFIG_DEFAULT_POKER_MAXIMUM; + userConfig->pokerLimit.minimum = TRNG_USER_CONFIG_DEFAULT_POKER_MINIMUM; + userConfig->frequencyCountLimit.maximum = TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MAXIMUM; + userConfig->frequencyCountLimit.minimum = TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MINIMUM; + + result = kStatus_Success; + } + else + { + result = kStatus_InvalidArgument; + } + + return result; +} + +/*! + * @brief Sets the TRNG retry count. + * + * This function sets the retry counter which defines the number of times a + * statistical check may fails during the TRNG Entropy Generation before + * generating an error. +*/ +static status_t trng_SetRetryCount(TRNG_Type *base, uint8_t retry_count) +{ + status_t status; + + if ((retry_count >= 1u) && (retry_count <= 15u)) + { + /* Set retry count.*/ + TRNG_WR_SCMISC_RTY_CT(base, retry_count); + status = kStatus_Success; + } + else + { + status = kStatus_InvalidArgument; + } + return status; +} + +/*! + * @brief Sets statistical check limits. + * + * This function is used to set minimum and maximum limits of statistical checks. + * + */ +static status_t trng_SetStatisticalCheckLimit(TRNG_Type *base, + trng_statistical_check_t statistical_check, + const trng_statistical_check_limit_t *limit) +{ + uint32_t range; + status_t status = kStatus_Success; + + if (limit && (limit->maximum > limit->minimum)) + { + range = limit->maximum - limit->minimum; /* Registers use range instead of minimum value.*/ + + switch (statistical_check) + { + case kTRNG_StatisticalCheckMonobit: /* Allowable maximum and minimum number of ones/zero detected during + entropy generation. */ + if ((range <= 0xffffu) && (limit->maximum <= 0xffffu)) + { + TRNG_WR_SCML_MONO_MAX(base, limit->maximum); + TRNG_WR_SCML_MONO_RNG(base, range); + } + else + { + status = kStatus_InvalidArgument; + } + break; + case kTRNG_StatisticalCheckRunBit1: /* Allowable maximum and minimum number of runs of length 1 detected + during entropy generation. */ + if ((range <= 0x7fffu) && (limit->maximum <= 0x7fffu)) + { + TRNG_WR_SCR1L_RUN1_MAX(base, limit->maximum); + TRNG_WR_SCR1L_RUN1_RNG(base, range); + } + else + { + status = kStatus_InvalidArgument; + } + break; + case kTRNG_StatisticalCheckRunBit2: /* Allowable maximum and minimum number of runs of length 2 detected + during entropy generation. */ + if ((range <= 0x3fffu) && (limit->maximum <= 0x3fffu)) + { + TRNG_WR_SCR2L_RUN2_MAX(base, limit->maximum); + TRNG_WR_SCR2L_RUN2_RNG(base, range); + } + else + { + status = kStatus_InvalidArgument; + } + break; + case kTRNG_StatisticalCheckRunBit3: /* Allowable maximum and minimum number of runs of length 3 detected + during entropy generation. */ + if ((range <= 0x1fffu) && (limit->maximum <= 0x1fffu)) + { + TRNG_WR_SCR3L_RUN3_MAX(base, limit->maximum); + TRNG_WR_SCR3L_RUN3_RNG(base, range); + } + else + { + status = kStatus_InvalidArgument; + } + break; + case kTRNG_StatisticalCheckRunBit4: /* Allowable maximum and minimum number of runs of length 4 detected + during entropy generation. */ + if ((range <= 0xfffu) && (limit->maximum <= 0xfffu)) + { + TRNG_WR_SCR4L_RUN4_MAX(base, limit->maximum); + TRNG_WR_SCR4L_RUN4_RNG(base, range); + } + else + { + status = kStatus_InvalidArgument; + } + break; + case kTRNG_StatisticalCheckRunBit5: /* Allowable maximum and minimum number of runs of length 5 detected + during entropy generation. */ + if ((range <= 0x7ffu) && (limit->maximum <= 0x7ffu)) + { + TRNG_WR_SCR5L_RUN5_MAX(base, limit->maximum); + TRNG_WR_SCR5L_RUN5_RNG(base, range); + } + else + { + status = kStatus_InvalidArgument; + } + break; + case kTRNG_StatisticalCheckRunBit6Plus: /* Allowable maximum and minimum number of length 6 or more detected + during entropy generation */ + if ((range <= 0x7ffu) && (limit->maximum <= 0x7ffu)) + { + TRNG_WR_SCR6PL_RUN6P_MAX(base, limit->maximum); + TRNG_WR_SCR6PL_RUN6P_RNG(base, range); + } + else + { + status = kStatus_InvalidArgument; + } + break; + case kTRNG_StatisticalCheckPoker: /* Allowable maximum and minimum limit of "Poker Test" detected during + entropy generation . */ + if ((range <= 0xffffu) && (limit->maximum <= 0xffffffu)) + { + TRNG_WR_PKRMAX_PKR_MAX(base, limit->maximum); + TRNG_WR_PKRRNG_PKR_RNG(base, range); + } + else + { + status = kStatus_InvalidArgument; + } + break; + case kTRNG_StatisticalCheckFrequencyCount: /* Allowable maximum and minimum limit of entropy sample frquency + count during entropy generation . */ + if ((limit->minimum <= 0x3fffffu) && (limit->maximum <= 0x3fffffu)) + { + TRNG_WR_FRQMAX_FRQ_MAX(base, limit->maximum); + TRNG_WR_FRQMIN_FRQ_MIN(base, limit->minimum); + } + else + { + status = kStatus_InvalidArgument; + } + break; + default: + status = kStatus_InvalidArgument; + break; + } + } + + return status; +} + +/*FUNCTION********************************************************************* + * + * Function Name : trng_ApplyUserConfig + * Description : Apply user configuration settings to TRNG module. + * + *END*************************************************************************/ +static status_t trng_ApplyUserConfig(TRNG_Type *base, const trng_config_t *userConfig) +{ + status_t status; + + if (((status = trng_SetRetryCount(base, userConfig->retryCount)) == kStatus_Success) && + ((status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckMonobit, &userConfig->monobitLimit)) == + kStatus_Success) && + ((status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckRunBit1, &userConfig->runBit1Limit)) == + kStatus_Success) && + ((status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckRunBit2, &userConfig->runBit2Limit)) == + kStatus_Success) && + ((status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckRunBit3, &userConfig->runBit3Limit)) == + kStatus_Success) && + ((status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckRunBit4, &userConfig->runBit4Limit)) == + kStatus_Success) && + ((status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckRunBit5, &userConfig->runBit5Limit)) == + kStatus_Success) && + ((status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckRunBit6Plus, + &userConfig->runBit6PlusLimit)) == kStatus_Success) && + ((status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckPoker, &userConfig->pokerLimit)) == + kStatus_Success) && + ((status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckFrequencyCount, + &userConfig->frequencyCountLimit)) == kStatus_Success)) + { + TRNG_WR_MCTL_FOR_SCLK(base, userConfig->clockMode); + TRNG_WR_MCTL_OSC_DIV(base, userConfig->ringOscDiv); + TRNG_WR_MCTL_SAMP_MODE(base, userConfig->sampleMode); + TRNG_WR_SDCTL_ENT_DLY(base, userConfig->entropyDelay); + TRNG_WR_SDCTL_SAMP_SIZE(base, userConfig->sampleSize); + TRNG_WR_SBLIM_SB_LIM(base, userConfig->sparseBitLimit); + TRNG_WR_SCMISC_LRUN_MAX(base, userConfig->longRunMaxLimit); + } + + return status; +} + +/*! + * @brief Gets a entry data from the TRNG. + * + * This function gets an entropy data from TRNG. + * Entropy data is spread over TRNG_ENT_COUNT registers. + * Read register number is defined by index parameter. +*/ +static uint32_t trng_ReadEntropy(TRNG_Type *base, uint32_t index) +{ + uint32_t data; + + index = index % TRNG_ENT_COUNT; /* This way we can use incremental index without limit control from application.*/ + + data = TRNG_RD_ENT(base, index); + + if (index == (TRNG_ENT_COUNT - 1)) + { + /* Dummy read. Defect workaround. + * TRNG could not clear ENT_VAL flag automatically, application + * had to do a dummy reading operation for anyone TRNG register + * to clear it firstly, then to read the RTENT0 to RTENT15 again */ + index = TRNG_RD_ENT(base, 0); + } + + return data; +} + +status_t TRNG_Init(TRNG_Type *base, const trng_config_t *userConfig) +{ + status_t result; + + /* Check input parameters.*/ + if ((base != 0) && (userConfig != 0)) + { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the clock gate. */ + CLOCK_EnableClock(kCLOCK_Trng0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset the registers of TRNG module to reset state. */ + /* Must be in program mode.*/ + TRNG_WR_MCTL_PRGM(base, kTRNG_WorkModeProgram); + /* Reset Defaults.*/ + TRNG_WR_MCTL_RST_DEF(base, 1); + + /* Set configuration.*/ + if ((result = trng_ApplyUserConfig(base, userConfig)) == kStatus_Success) + { + /* Start entropy generation.*/ + /* Set to Run mode.*/ + TRNG_WR_MCTL_PRGM(base, kTRNG_WorkModeRun); + /* Enable TRNG Access Mode. To generate an Entropy + * value that can be read via the true0-true15 registers.*/ + TRNG_WR_MCTL_TRNG_ACC(base, 1); + + if (userConfig->lock == 1) /* Disable programmability of TRNG registers. */ + { + TRNG_WR_SEC_CFG_NO_PRGM(base, 1); + } + + result = kStatus_Success; + } + } + else + { + result = kStatus_InvalidArgument; + } + + return result; +} + +void TRNG_Deinit(TRNG_Type *base) +{ + /* Check input parameters.*/ + if (base) + { + /* Move to program mode. Stop entropy generation.*/ + TRNG_WR_MCTL_PRGM(base, kTRNG_WorkModeProgram); + + /* Check before clock stop. + TRNG turns on the TRNG free-running ring oscillator whenever new entropy + is being generated and turns off the ring oscillator when entropy generation + is complete. If the TRNG clock is stopped while the TRNG ring oscillator + is running, the oscillator continues running though the RNG clock. + is stopped. */ + while (TRNG_RD_MCTL_TSTOP_OK(base) == 0) + { + } + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable Clock*/ + CLOCK_DisableClock(kCLOCK_Trng0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + } +} + +status_t TRNG_GetRandomData(TRNG_Type *base, void *data, size_t dataSize) +{ + status_t result = kStatus_Success; + uint32_t random_32; + uint8_t *random_p; + uint32_t random_size; + uint8_t *data_p = (uint8_t *)data; + uint32_t i; + int index = 0; + + /* Check input parameters.*/ + if (base && data && dataSize) + { + do + { + /* Wait for Valid or Error flag*/ + while ((TRNG_RD_MCTL_ENT_VAL(base) == 0) && (TRNG_RD_MCTL_ERR(base) == 0)) + { + } + + /* Check HW error.*/ + if (TRNG_RD_MCTL_ERR(base)) + { + result = kStatus_Fail; /* TRNG module error occurred */ + /* Clear error.*/ + TRNG_WR_MCTL_ERR(base, 1); + break; /* No sense stay here.*/ + } + + /* Read Entropy.*/ + random_32 = trng_ReadEntropy(base, index++); + + random_p = (uint8_t *)&random_32; + + if (dataSize < sizeof(random_32)) + { + random_size = dataSize; + } + else + { + random_size = sizeof(random_32); + } + + for (i = 0U; i < random_size; i++) + { + *data_p++ = *random_p++; + } + + dataSize -= random_size; + } while (dataSize > 0); + + /* Start a new entropy generation. + It is done by reading of the last entropy register.*/ + if ((index % TRNG_ENT_COUNT) != (TRNG_ENT_COUNT - 1)) + { + trng_ReadEntropy(base, (TRNG_ENT_COUNT - 1)); + } + } + else + { + result = kStatus_InvalidArgument; + } + + return result; +} + +#endif /* FSL_FEATURE_SOC_TRNG_COUNT */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_trng.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_trng.h new file mode 100644 index 00000000000..242ad259f0b --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_trng.h @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_TRNG_DRIVER_H_ +#define _FSL_TRNG_DRIVER_H_ + +#include "fsl_common.h" + +#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && FSL_FEATURE_SOC_TRNG_COUNT + +/*! + * @addtogroup trng_driver + * @{ + */ + + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief TRNG driver version 2.0.1. + * + * Current version: 2.0.1 + * + * Change log: + * - Version 2.0.1 + * - add support for KL8x and KL28Z + * - update default OSCDIV for K81 to divide by 2 + */ +#define FSL_TRNG_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! @brief TRNG sample mode. Used by trng_config_t. */ +typedef enum _trng_sample_mode +{ + kTRNG_SampleModeVonNeumann = 0U, /*!< Use von Neumann data in both Entropy shifter and Statistical Checker. */ + kTRNG_SampleModeRaw = 1U, /*!< Use raw data into both Entropy shifter and Statistical Checker. */ + kTRNG_SampleModeVonNeumannRaw = + 2U /*!< Use von Neumann data in Entropy shifter. Use raw data into Statistical Checker. */ +} trng_sample_mode_t; + +/*! @brief TRNG clock mode. Used by trng_config_t. */ +typedef enum _trng_clock_mode +{ + kTRNG_ClockModeRingOscillator = 0U, /*!< Ring oscillator is used to operate the TRNG (default). */ + kTRNG_ClockModeSystem = 1U /*!< System clock is used to operate the TRNG. This is for test use only, and + indeterminate results may occur. */ +} trng_clock_mode_t; + +/*! @brief TRNG ring oscillator divide. Used by trng_config_t. */ +typedef enum _trng_ring_osc_div +{ + kTRNG_RingOscDiv0 = 0U, /*!< Ring oscillator with no divide */ + kTRNG_RingOscDiv2 = 1U, /*!< Ring oscillator divided-by-2. */ + kTRNG_RingOscDiv4 = 2U, /*!< Ring oscillator divided-by-4. */ + kTRNG_RingOscDiv8 = 3U /*!< Ring oscillator divided-by-8. */ +} trng_ring_osc_div_t; + +/*! @brief Data structure for definition of statistical check limits. Used by trng_config_t. */ +typedef struct _trng_statistical_check_limit +{ + uint32_t maximum; /*!< Maximum limit.*/ + uint32_t minimum; /*!< Minimum limit.*/ +} trng_statistical_check_limit_t; + +/*! + * @brief Data structure for the TRNG initialization + * + * This structure initializes the TRNG by calling the the TRNG_Init() function. + * It contains all TRNG configurations. + */ +typedef struct _trng_user_config +{ + bool lock; /*!< @brief Disable programmability of TRNG registers. */ + trng_clock_mode_t clockMode; /*!< @brief Clock mode used to operate TRNG.*/ + trng_ring_osc_div_t ringOscDiv; /*!< @brief Ring oscillator divide used by TRNG. */ + trng_sample_mode_t sampleMode; /*!< @brief Sample mode of the TRNG ring oscillator. */ + /* Seed Control*/ + uint16_t + entropyDelay; /*!< @brief Entropy Delay. Defines the length (in system clocks) of each Entropy sample taken. */ + uint16_t sampleSize; /*!< @brief Sample Size. Defines the total number of Entropy samples that will be taken during + Entropy generation. */ + uint16_t + sparseBitLimit; /*!< @brief Sparse Bit Limit which defines the maximum number of + * consecutive samples that may be discarded before an error is generated. + * This limit is used only for during von Neumann sampling (enabled by TRNG_HAL_SetSampleMode()). + * Samples are discarded if two consecutive raw samples are both 0 or both 1. If + * this discarding occurs for a long period of time, it indicates that there is + * insufficient Entropy. */ + /* Statistical Check Parameters.*/ + uint8_t retryCount; /*!< @brief Retry count. It defines the number of times a statistical check may fails + * during the TRNG Entropy Generation before generating an error. */ + uint8_t longRunMaxLimit; /*!< @brief Largest allowable number of consecutive samples of all 1, or all 0, + * that is allowed during the Entropy generation. */ + trng_statistical_check_limit_t + monobitLimit; /*!< @brief Maximum and minimum limits for statistical check of number of ones/zero detected + during entropy generation. */ + trng_statistical_check_limit_t + runBit1Limit; /*!< @brief Maximum and minimum limits for statistical check of number of runs of length 1 + detected during entropy generation. */ + trng_statistical_check_limit_t + runBit2Limit; /*!< @brief Maximum and minimum limits for statistical check of number of runs of length 2 + detected during entropy generation. */ + trng_statistical_check_limit_t + runBit3Limit; /*!< @brief Maximum and minimum limits for statistical check of number of runs of length 3 + detected during entropy generation. */ + trng_statistical_check_limit_t + runBit4Limit; /*!< @brief Maximum and minimum limits for statistical check of number of runs of length 4 + detected during entropy generation. */ + trng_statistical_check_limit_t + runBit5Limit; /*!< @brief Maximum and minimum limits for statistical check of number of runs of length 5 + detected during entropy generation. */ + trng_statistical_check_limit_t runBit6PlusLimit; /*!< @brief Maximum and minimum limits for statistical check of + number of runs of length 6 or more detected during entropy + generation. */ + trng_statistical_check_limit_t + pokerLimit; /*!< @brief Maximum and minimum limits for statistical check of "Poker Test". */ + trng_statistical_check_limit_t + frequencyCountLimit; /*!< @brief Maximum and minimum limits for statistical check of entropy sample frequency + count. */ +} trng_config_t; + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the user configuration structure to default values. + * + * This function initializes the configuration structure to default values. The default + * values are as follows. + * @code + * user_config->lock = 0; + * user_config->clockMode = kTRNG_ClockModeRingOscillator; + * user_config->ringOscDiv = kTRNG_RingOscDiv0; Or to other kTRNG_RingOscDiv[2|8] depending on the platform. + * user_config->sampleMode = kTRNG_SampleModeRaw; + * user_config->entropyDelay = 3200; + * user_config->sampleSize = 2500; + * user_config->sparseBitLimit = TRNG_USER_CONFIG_DEFAULT_SPARSE_BIT_LIMIT; + * user_config->retryCount = 63; + * user_config->longRunMaxLimit = 34; + * user_config->monobitLimit.maximum = 1384; + * user_config->monobitLimit.minimum = 1116; + * user_config->runBit1Limit.maximum = 405; + * user_config->runBit1Limit.minimum = 227; + * user_config->runBit2Limit.maximum = 220; + * user_config->runBit2Limit.minimum = 98; + * user_config->runBit3Limit.maximum = 125; + * user_config->runBit3Limit.minimum = 37; + * user_config->runBit4Limit.maximum = 75; + * user_config->runBit4Limit.minimum = 11; + * user_config->runBit5Limit.maximum = 47; + * user_config->runBit5Limit.minimum = 1; + * user_config->runBit6PlusLimit.maximum = 47; + * user_config->runBit6PlusLimit.minimum = 1; + * user_config->pokerLimit.maximum = 26912; + * user_config->pokerLimit.minimum = 24445; + * user_config->frequencyCountLimit.maximum = 25600; + * user_config->frequencyCountLimit.minimum = 1600; + * @endcode + * + * @param user_config User configuration structure. + * @return If successful, returns the kStatus_TRNG_Success. Otherwise, it returns an error. + */ +status_t TRNG_GetDefaultConfig(trng_config_t *userConfig); + +/*! + * @brief Initializes the TRNG. + * + * This function initializes the TRNG. + * When called, the TRNG entropy generation starts immediately. + * + * @param base TRNG base address + * @param userConfig Pointer to the initialization configuration structure. + * @return If successful, returns the kStatus_TRNG_Success. Otherwise, it returns an error. + */ +status_t TRNG_Init(TRNG_Type *base, const trng_config_t *userConfig); + +/*! + * @brief Shuts down the TRNG. + * + * This function shuts down the TRNG. + * + * @param base TRNG base address. + */ +void TRNG_Deinit(TRNG_Type *base); + +/*! + * @brief Gets random data. + * + * This function gets random data from the TRNG. + * + * @param base TRNG base address. + * @param data Pointer address used to store random data. + * @param dataSize Size of the buffer pointed by the data parameter. + * @return random data + */ +status_t TRNG_GetRandomData(TRNG_Type *base, void *data, size_t dataSize); + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* FSL_FEATURE_SOC_TRNG_COUNT */ +#endif /*_FSL_TRNG_H_*/ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tsi_v4.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tsi_v4.c new file mode 100644 index 00000000000..950cc6e3368 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tsi_v4.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_tsi_v4.h" + +void TSI_Init(TSI_Type *base, const tsi_config_t *config) +{ + assert(config != NULL); + + bool is_module_enabled = false; + bool is_int_enabled = false; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(kCLOCK_Tsi0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + if (base->GENCS & TSI_GENCS_TSIEN_MASK) + { + is_module_enabled = true; + TSI_EnableModule(base, false); + } + if (base->GENCS & TSI_GENCS_TSIIEN_MASK) + { + is_int_enabled = true; + TSI_DisableInterrupts(base, kTSI_GlobalInterruptEnable); + } + + if(config->mode == kTSI_AnalogModeSel_Capacitive) + { + TSI_SetHighThreshold(base, config->thresh); + TSI_SetLowThreshold(base, config->thresl); + TSI_SetElectrodeOSCPrescaler(base, config->prescaler); + TSI_SetReferenceChargeCurrent(base, config->refchrg); + TSI_SetElectrodeChargeCurrent(base, config->extchrg); + TSI_SetNumberOfScans(base, config->nscn); + TSI_SetAnalogMode(base, config->mode); + TSI_SetOscVoltageRails(base, config->dvolt); + } + else /* For noise modes */ + { + TSI_SetHighThreshold(base, config->thresh); + TSI_SetLowThreshold(base, config->thresl); + TSI_SetElectrodeOSCPrescaler(base, config->prescaler); + TSI_SetReferenceChargeCurrent(base, config->refchrg); + TSI_SetNumberOfScans(base, config->nscn); + TSI_SetAnalogMode(base, config->mode); + TSI_SetOscVoltageRails(base, config->dvolt); + TSI_SetElectrodeSeriesResistor(base, config->resistor); + TSI_SetFilterBits(base, config->filter); + } + + if (is_module_enabled) + { + TSI_EnableModule(base, true); + } + if (is_int_enabled) + { + TSI_EnableInterrupts(base, kTSI_GlobalInterruptEnable); + } +} + +void TSI_Deinit(TSI_Type *base) +{ + base->GENCS = 0U; + base->DATA = 0U; + base->TSHD = 0U; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(kCLOCK_Tsi0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void TSI_GetNormalModeDefaultConfig(tsi_config_t *userConfig) +{ + userConfig->thresh = 0U; + userConfig->thresl = 0U; + userConfig->prescaler = kTSI_ElecOscPrescaler_2div; + userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA; + userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA; + userConfig->nscn = kTSI_ConsecutiveScansNumber_5time; + userConfig->mode = kTSI_AnalogModeSel_Capacitive; + userConfig->dvolt = kTSI_OscVolRailsOption_0; +} + +void TSI_GetLowPowerModeDefaultConfig(tsi_config_t *userConfig) +{ + userConfig->thresh = 400U; + userConfig->thresl = 0U; + userConfig->prescaler = kTSI_ElecOscPrescaler_2div; + userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA; + userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA; + userConfig->nscn = kTSI_ConsecutiveScansNumber_5time; + userConfig->mode = kTSI_AnalogModeSel_Capacitive; + userConfig->dvolt = kTSI_OscVolRailsOption_0; +} + +void TSI_Calibrate(TSI_Type *base, tsi_calibration_data_t *calBuff) +{ + assert(calBuff != NULL); + + uint8_t i = 0U; + bool is_int_enabled = false; + + if (base->GENCS & TSI_GENCS_TSIIEN_MASK) + { + is_int_enabled = true; + TSI_DisableInterrupts(base, kTSI_GlobalInterruptEnable); + } + for (i = 0U; i < FSL_FEATURE_TSI_CHANNEL_COUNT; i++) + { + TSI_SetMeasuredChannelNumber(base, i); + TSI_StartSoftwareTrigger(base); + while (!(TSI_GetStatusFlags(base) & kTSI_EndOfScanFlag)) + { + } + calBuff->calibratedData[i] = TSI_GetCounter(base); + TSI_ClearStatusFlags(base, kTSI_EndOfScanFlag); + } + if (is_int_enabled) + { + TSI_EnableInterrupts(base, kTSI_GlobalInterruptEnable); + } +} + +void TSI_EnableInterrupts(TSI_Type *base, uint32_t mask) +{ + uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK); + + if (mask & kTSI_GlobalInterruptEnable) + { + regValue |= TSI_GENCS_TSIIEN_MASK; + } + if (mask & kTSI_OutOfRangeInterruptEnable) + { + regValue &= (~TSI_GENCS_ESOR_MASK); + } + if (mask & kTSI_EndOfScanInterruptEnable) + { + regValue |= TSI_GENCS_ESOR_MASK; + } + + base->GENCS = regValue; /* write value to register */ +} + +void TSI_DisableInterrupts(TSI_Type *base, uint32_t mask) +{ + uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK); + + if (mask & kTSI_GlobalInterruptEnable) + { + regValue &= (~TSI_GENCS_TSIIEN_MASK); + } + if (mask & kTSI_OutOfRangeInterruptEnable) + { + regValue |= TSI_GENCS_ESOR_MASK; + } + if (mask & kTSI_EndOfScanInterruptEnable) + { + regValue &= (~TSI_GENCS_ESOR_MASK); + } + + base->GENCS = regValue; /* write value to register */ +} + +void TSI_ClearStatusFlags(TSI_Type *base, uint32_t mask) +{ + uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK); + + if (mask & kTSI_EndOfScanFlag) + { + regValue |= TSI_GENCS_EOSF_MASK; + } + if (mask & kTSI_OutOfRangeFlag) + { + regValue |= TSI_GENCS_OUTRGF_MASK; + } + + base->GENCS = regValue; /* write value to register */ +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tsi_v4.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tsi_v4.h new file mode 100644 index 00000000000..e2e1595e5da --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_tsi_v4.h @@ -0,0 +1,706 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_TSI_V4_H_ +#define _FSL_TSI_V4_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup tsi_v4_driver + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief TSI driver version */ +#define FSL_TSI_DRIVER_VERSION (MAKE_VERSION(2, 1, 2)) +/*@}*/ + +/*! @brief TSI status flags macro collection */ +#define ALL_FLAGS_MASK (TSI_GENCS_EOSF_MASK | TSI_GENCS_OUTRGF_MASK) + +/*! @brief resistor bit shift in EXTCHRG bit-field */ +#define TSI_V4_EXTCHRG_RESISTOR_BIT_SHIFT TSI_GENCS_EXTCHRG_SHIFT + +/*! @brief filter bits shift in EXTCHRG bit-field */ +#define TSI_V4_EXTCHRG_FILTER_BITS_SHIFT (1U + TSI_GENCS_EXTCHRG_SHIFT) + +/*! @brief macro of clearing the resistor bit in EXTCHRG bit-field */ +#define TSI_V4_EXTCHRG_RESISTOR_BIT_CLEAR \ + ((uint32_t)((~(ALL_FLAGS_MASK | TSI_GENCS_EXTCHRG_MASK)) | (3U << TSI_V4_EXTCHRG_FILTER_BITS_SHIFT))) + +/*! @brief macro of clearing the filter bits in EXTCHRG bit-field */ +#define TSI_V4_EXTCHRG_FILTER_BITS_CLEAR \ + ((uint32_t)((~(ALL_FLAGS_MASK | TSI_GENCS_EXTCHRG_MASK)) | (1U << TSI_V4_EXTCHRG_RESISTOR_BIT_SHIFT))) + +/*! + * @brief TSI number of scan intervals for each electrode. + * + * These constants define the tsi number of consecutive scans in a TSI instance for each electrode. + */ +typedef enum _tsi_n_consecutive_scans +{ + kTSI_ConsecutiveScansNumber_1time = 0U, /*!< Once per electrode */ + kTSI_ConsecutiveScansNumber_2time = 1U, /*!< Twice per electrode */ + kTSI_ConsecutiveScansNumber_3time = 2U, /*!< 3 times consecutive scan */ + kTSI_ConsecutiveScansNumber_4time = 3U, /*!< 4 times consecutive scan */ + kTSI_ConsecutiveScansNumber_5time = 4U, /*!< 5 times consecutive scan */ + kTSI_ConsecutiveScansNumber_6time = 5U, /*!< 6 times consecutive scan */ + kTSI_ConsecutiveScansNumber_7time = 6U, /*!< 7 times consecutive scan */ + kTSI_ConsecutiveScansNumber_8time = 7U, /*!< 8 times consecutive scan */ + kTSI_ConsecutiveScansNumber_9time = 8U, /*!< 9 times consecutive scan */ + kTSI_ConsecutiveScansNumber_10time = 9U, /*!< 10 times consecutive scan */ + kTSI_ConsecutiveScansNumber_11time = 10U, /*!< 11 times consecutive scan */ + kTSI_ConsecutiveScansNumber_12time = 11U, /*!< 12 times consecutive scan */ + kTSI_ConsecutiveScansNumber_13time = 12U, /*!< 13 times consecutive scan */ + kTSI_ConsecutiveScansNumber_14time = 13U, /*!< 14 times consecutive scan */ + kTSI_ConsecutiveScansNumber_15time = 14U, /*!< 15 times consecutive scan */ + kTSI_ConsecutiveScansNumber_16time = 15U, /*!< 16 times consecutive scan */ + kTSI_ConsecutiveScansNumber_17time = 16U, /*!< 17 times consecutive scan */ + kTSI_ConsecutiveScansNumber_18time = 17U, /*!< 18 times consecutive scan */ + kTSI_ConsecutiveScansNumber_19time = 18U, /*!< 19 times consecutive scan */ + kTSI_ConsecutiveScansNumber_20time = 19U, /*!< 20 times consecutive scan */ + kTSI_ConsecutiveScansNumber_21time = 20U, /*!< 21 times consecutive scan */ + kTSI_ConsecutiveScansNumber_22time = 21U, /*!< 22 times consecutive scan */ + kTSI_ConsecutiveScansNumber_23time = 22U, /*!< 23 times consecutive scan */ + kTSI_ConsecutiveScansNumber_24time = 23U, /*!< 24 times consecutive scan */ + kTSI_ConsecutiveScansNumber_25time = 24U, /*!< 25 times consecutive scan */ + kTSI_ConsecutiveScansNumber_26time = 25U, /*!< 26 times consecutive scan */ + kTSI_ConsecutiveScansNumber_27time = 26U, /*!< 27 times consecutive scan */ + kTSI_ConsecutiveScansNumber_28time = 27U, /*!< 28 times consecutive scan */ + kTSI_ConsecutiveScansNumber_29time = 28U, /*!< 29 times consecutive scan */ + kTSI_ConsecutiveScansNumber_30time = 29U, /*!< 30 times consecutive scan */ + kTSI_ConsecutiveScansNumber_31time = 30U, /*!< 31 times consecutive scan */ + kTSI_ConsecutiveScansNumber_32time = 31U /*!< 32 times consecutive scan */ +} tsi_n_consecutive_scans_t; + +/*! + * @brief TSI electrode oscillator prescaler. + * + * These constants define the TSI electrode oscillator prescaler in a TSI instance. + */ +typedef enum _tsi_electrode_osc_prescaler +{ + kTSI_ElecOscPrescaler_1div = 0U, /*!< Electrode oscillator frequency divided by 1 */ + kTSI_ElecOscPrescaler_2div = 1U, /*!< Electrode oscillator frequency divided by 2 */ + kTSI_ElecOscPrescaler_4div = 2U, /*!< Electrode oscillator frequency divided by 4 */ + kTSI_ElecOscPrescaler_8div = 3U, /*!< Electrode oscillator frequency divided by 8 */ + kTSI_ElecOscPrescaler_16div = 4U, /*!< Electrode oscillator frequency divided by 16 */ + kTSI_ElecOscPrescaler_32div = 5U, /*!< Electrode oscillator frequency divided by 32 */ + kTSI_ElecOscPrescaler_64div = 6U, /*!< Electrode oscillator frequency divided by 64 */ + kTSI_ElecOscPrescaler_128div = 7U /*!< Electrode oscillator frequency divided by 128 */ +} tsi_electrode_osc_prescaler_t; + +/*! + * @brief TSI analog mode select. + * + * Set up TSI analog modes in a TSI instance. + */ +typedef enum _tsi_analog_mode +{ + kTSI_AnalogModeSel_Capacitive = 0U, /*!< Active TSI capacitive sensing mode */ + kTSI_AnalogModeSel_NoiseNoFreqLim = 4U, /*!< Single threshold noise detection mode with no freq. limitation. */ + kTSI_AnalogModeSel_NoiseFreqLim = 8U, /*!< Single threshold noise detection mode with freq. limitation. */ + kTSI_AnalogModeSel_AutoNoise = 12U /*!< Active TSI analog in automatic noise detection mode */ +} tsi_analog_mode_t; + +/*! + * @brief TSI Reference oscillator charge and discharge current select. + * + * These constants define the TSI Reference oscillator charge current select in a TSI (REFCHRG) instance. + */ +typedef enum _tsi_reference_osc_charge_current +{ + kTSI_RefOscChargeCurrent_500nA = 0U, /*!< Reference oscillator charge current is 500 µA */ + kTSI_RefOscChargeCurrent_1uA = 1U, /*!< Reference oscillator charge current is 1 µA */ + kTSI_RefOscChargeCurrent_2uA = 2U, /*!< Reference oscillator charge current is 2 µA */ + kTSI_RefOscChargeCurrent_4uA = 3U, /*!< Reference oscillator charge current is 4 µA */ + kTSI_RefOscChargeCurrent_8uA = 4U, /*!< Reference oscillator charge current is 8 µA */ + kTSI_RefOscChargeCurrent_16uA = 5U, /*!< Reference oscillator charge current is 16 µA */ + kTSI_RefOscChargeCurrent_32uA = 6U, /*!< Reference oscillator charge current is 32 µA */ + kTSI_RefOscChargeCurrent_64uA = 7U /*!< Reference oscillator charge current is 64 µA */ +} tsi_reference_osc_charge_current_t; + +/*! + * @brief TSI oscilator's voltage rails. + * + * These bits indicate the oscillator's voltage rails. + */ +typedef enum _tsi_osc_voltage_rails +{ + kTSI_OscVolRailsOption_0 = 0U, /*!< DVOLT value option 0, the value may differ on different platforms */ + kTSI_OscVolRailsOption_1 = 1U, /*!< DVOLT value option 1, the value may differ on different platforms */ + kTSI_OscVolRailsOption_2 = 2U, /*!< DVOLT value option 2, the value may differ on different platforms */ + kTSI_OscVolRailsOption_3 = 3U /*!< DVOLT value option 3, the value may differ on different platforms */ +} tsi_osc_voltage_rails_t; + +/*! + * @brief TSI External oscillator charge and discharge current select. + * + * These bits indicate the electrode oscillator charge and discharge current value + * in TSI (EXTCHRG) instance. + */ +typedef enum _tsi_external_osc_charge_current +{ + kTSI_ExtOscChargeCurrent_500nA = 0U, /*!< External oscillator charge current is 500 µA */ + kTSI_ExtOscChargeCurrent_1uA = 1U, /*!< External oscillator charge current is 1 µA */ + kTSI_ExtOscChargeCurrent_2uA = 2U, /*!< External oscillator charge current is 2 µA */ + kTSI_ExtOscChargeCurrent_4uA = 3U, /*!< External oscillator charge current is 4 µA */ + kTSI_ExtOscChargeCurrent_8uA = 4U, /*!< External oscillator charge current is 8 µA */ + kTSI_ExtOscChargeCurrent_16uA = 5U, /*!< External oscillator charge current is 16 µA */ + kTSI_ExtOscChargeCurrent_32uA = 6U, /*!< External oscillator charge current is 32 µA */ + kTSI_ExtOscChargeCurrent_64uA = 7U /*!< External oscillator charge current is 64 µA */ +} tsi_external_osc_charge_current_t; + +/*! + * @brief TSI series resistance RS value select. + * + * These bits indicate the electrode RS series resistance for the noise mode + * in TSI (EXTCHRG) instance. + */ +typedef enum _tsi_series_resistance +{ + kTSI_SeriesResistance_32k = 0U, /*!< Series Resistance is 32 kilo ohms */ + kTSI_SeriesResistance_187k = 1U /*!< Series Resistance is 18 7 kilo ohms */ +} tsi_series_resistor_t; + +/*! + * @brief TSI series filter bits select. + * + * These bits indicate the count of the filter bits + * in TSI noise mode EXTCHRG[2:1] bits + */ +typedef enum _tsi_filter_bits +{ + kTSI_FilterBits_3 = 0U, /*!< 3 filter bits, 8 peaks increments the cnt+1 */ + kTSI_FilterBits_2 = 1U, /*!< 2 filter bits, 4 peaks increments the cnt+1 */ + kTSI_FilterBits_1 = 2U, /*!< 1 filter bits, 2 peaks increments the cnt+1 */ + kTSI_FilterBits_0 = 3U /*!< no filter bits,1 peak increments the cnt+1 */ +} tsi_filter_bits_t; + +/*! @brief TSI status flags. */ +typedef enum _tsi_status_flags +{ + kTSI_EndOfScanFlag = TSI_GENCS_EOSF_MASK, /*!< End-Of-Scan flag */ + kTSI_OutOfRangeFlag = TSI_GENCS_OUTRGF_MASK /*!< Out-Of-Range flag */ +} tsi_status_flags_t; + +/*! @brief TSI feature interrupt source.*/ +typedef enum _tsi_interrupt_enable +{ + kTSI_GlobalInterruptEnable = 1U, /*!< TSI module global interrupt */ + kTSI_OutOfRangeInterruptEnable = 2U, /*!< Out-Of-Range interrupt */ + kTSI_EndOfScanInterruptEnable = 4U /*!< End-Of-Scan interrupt */ +} tsi_interrupt_enable_t; + +/*! @brief TSI calibration data storage. */ +typedef struct _tsi_calibration_data +{ + uint16_t calibratedData[FSL_FEATURE_TSI_CHANNEL_COUNT]; /*!< TSI calibration data storage buffer */ +} tsi_calibration_data_t; + +/*! + * @brief TSI configuration structure. + * + * This structure contains the settings for the most common TSI configurations including + * the TSI module charge currents, number of scans, thresholds, and so on. + */ +typedef struct _tsi_config +{ + uint16_t thresh; /*!< High threshold. */ + uint16_t thresl; /*!< Low threshold. */ + tsi_electrode_osc_prescaler_t prescaler; /*!< Prescaler */ + tsi_external_osc_charge_current_t extchrg; /*!< Electrode charge current */ + tsi_reference_osc_charge_current_t refchrg; /*!< Reference charge current */ + tsi_n_consecutive_scans_t nscn; /*!< Number of scans. */ + tsi_analog_mode_t mode; /*!< TSI mode of operation. */ + tsi_osc_voltage_rails_t dvolt; /*!< Oscillator's voltage rails. */ + tsi_series_resistor_t resistor; /*!< Series resistance value */ + tsi_filter_bits_t filter; /*!< Noise mode filter bits */ +} tsi_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * @brief Initializes hardware. + * + * @details Initializes the peripheral to the targeted state specified by parameter configuration, + * such as sets prescalers, number of scans, clocks, delta voltage + * series resistor, filter bits, reference, and electrode charge current and threshold. + * @param base TSI peripheral base address. + * @param config Pointer to TSI module configuration structure. + * @return none + */ +void TSI_Init(TSI_Type *base, const tsi_config_t *config); + +/*! + * @brief De-initializes hardware. + * + * @details De-initializes the peripheral to default state. + * + * @param base TSI peripheral base address. + * @return none + */ +void TSI_Deinit(TSI_Type *base); + +/*! + * @brief Gets the TSI normal mode user configuration structure. + * This interface sets userConfig structure to a default value. The configuration structure only + * includes the settings for the whole TSI. + * The user configure is set to these values: + * @code + userConfig->prescaler = kTSI_ElecOscPrescaler_2div; + userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA; + userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA; + userConfig->nscn = kTSI_ConsecutiveScansNumber_10time; + userConfig->mode = kTSI_AnalogModeSel_Capacitive; + userConfig->dvolt = kTSI_OscVolRailsOption_0; + userConfig->thresh = 0U; + userConfig->thresl = 0U; + @endcode + * + * @param userConfig Pointer to the TSI user configuration structure. + */ +void TSI_GetNormalModeDefaultConfig(tsi_config_t *userConfig); + +/*! + * @brief Gets the TSI low power mode default user configuration structure. + * This interface sets userConfig structure to a default value. The configuration structure only + * includes the settings for the whole TSI. + * The user configure is set to these values: + * @code + userConfig->prescaler = kTSI_ElecOscPrescaler_2div; + userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA; + userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA; + userConfig->nscn = kTSI_ConsecutiveScansNumber_10time; + userConfig->mode = kTSI_AnalogModeSel_Capacitive; + userConfig->dvolt = kTSI_OscVolRailsOption_0; + userConfig->thresh = 400U; + userConfig->thresl = 0U; + @endcode + * + * @param userConfig Pointer to the TSI user configuration structure. + */ +void TSI_GetLowPowerModeDefaultConfig(tsi_config_t *userConfig); + +/*! + * @brief Hardware calibration. + * + * @details Calibrates the peripheral to fetch the initial counter value of + * the enabled electrodes. + * This API is mostly used at initial application setup. Call + * this function after the \ref TSI_Init API and use the calibrated + * counter values to set up applications (such as to determine + * under which counter value we can confirm a touch event occurs). + * + * @param base TSI peripheral base address. + * @param calBuff Data buffer that store the calibrated counter value. + * @return none + * + */ +void TSI_Calibrate(TSI_Type *base, tsi_calibration_data_t *calBuff); + +/*! + * @brief Enables the TSI interrupt requests. + * @param base TSI peripheral base address. + * @param mask interrupt source + * The parameter can be combination of the following source if defined: + * @arg kTSI_GlobalInterruptEnable + * @arg kTSI_EndOfScanInterruptEnable + * @arg kTSI_OutOfRangeInterruptEnable + */ +void TSI_EnableInterrupts(TSI_Type *base, uint32_t mask); + +/*! + * @brief Disables the TSI interrupt requests. + * @param base TSI peripheral base address. + * @param mask interrupt source + * The parameter can be combination of the following source if defined: + * @arg kTSI_GlobalInterruptEnable + * @arg kTSI_EndOfScanInterruptEnable + * @arg kTSI_OutOfRangeInterruptEnable + */ +void TSI_DisableInterrupts(TSI_Type *base, uint32_t mask); + +/*! +* @brief Gets an interrupt flag. +* This function gets the TSI interrupt flags. +* +* @param base TSI peripheral base address. +* @return The mask of these status flags combination. +*/ +static inline uint32_t TSI_GetStatusFlags(TSI_Type *base) +{ + return (base->GENCS & (kTSI_EndOfScanFlag | kTSI_OutOfRangeFlag)); +} + +/*! + * @brief Clears the interrupt flag. + * + * This function clears the TSI interrupt flag, + * automatically cleared flags can't be cleared by this function. + * + * @param base TSI peripheral base address. + * @param mask The status flags to clear. + */ +void TSI_ClearStatusFlags(TSI_Type *base, uint32_t mask); + +/*! +* @brief Gets the TSI scan trigger mode. +* +* @param base TSI peripheral base address. +* @return Scan trigger mode. +*/ +static inline uint32_t TSI_GetScanTriggerMode(TSI_Type *base) +{ + return (base->GENCS & TSI_GENCS_STM_MASK); +} + +/*! +* @brief Gets the scan in progress flag. +* +* @param base TSI peripheral base address. +* @return True - scan is in progress. +* False - scan is not in progress. +*/ +static inline bool TSI_IsScanInProgress(TSI_Type *base) +{ + return (base->GENCS & TSI_GENCS_SCNIP_MASK); +} + +/*! +* @brief Sets the prescaler. +* +* @param base TSI peripheral base address. +* @param prescaler Prescaler value. +* @return none. +*/ +static inline void TSI_SetElectrodeOSCPrescaler(TSI_Type *base, tsi_electrode_osc_prescaler_t prescaler) +{ + base->GENCS = (base->GENCS & ~(TSI_GENCS_PS_MASK | ALL_FLAGS_MASK)) | (TSI_GENCS_PS(prescaler)); +} + +/*! +* @brief Sets the number of scans (NSCN). +* +* @param base TSI peripheral base address. +* @param number Number of scans. +* @return none. +*/ +static inline void TSI_SetNumberOfScans(TSI_Type *base, tsi_n_consecutive_scans_t number) +{ + base->GENCS = (base->GENCS & ~(TSI_GENCS_NSCN_MASK | ALL_FLAGS_MASK)) | (TSI_GENCS_NSCN(number)); +} + +/*! +* @brief Enables/disables the TSI module. +* +* @param base TSI peripheral base address. +* @param enable Choose whether to enable or disable module; +* - true Enable TSI module; +* - false Disable TSI module; +* @return none. +*/ +static inline void TSI_EnableModule(TSI_Type *base, bool enable) +{ + if (enable) + { + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) | TSI_GENCS_TSIEN_MASK; /* Enable module */ + } + else + { + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) & (~TSI_GENCS_TSIEN_MASK); /* Disable module */ + } +} + +/*! +* @brief Sets the TSI low power STOP mode as enabled or disabled. +* This enables the TSI module function in low power modes. +* +* @param base TSI peripheral base address. +* @param enable Choose to enable or disable STOP mode. +* - true Enable module in STOP mode; +* - false Disable module in STOP mode; +* @return none. +*/ +static inline void TSI_EnableLowPower(TSI_Type *base, bool enable) +{ + if (enable) + { + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) | TSI_GENCS_STPE_MASK; /* Module enabled in low power stop modes */ + } + else + { + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) & (~TSI_GENCS_STPE_MASK); /* Module disabled in low power stop modes */ + } +} + +/*! +* @brief Enables/disables the hardware trigger scan. +* +* @param base TSI peripheral base address. +* @param enable Choose to enable hardware trigger or software trigger scan. +* - true Enable hardware trigger scan; +* - false Enable software trigger scan; +* @return none. +*/ +static inline void TSI_EnableHardwareTriggerScan(TSI_Type *base, bool enable) +{ + if (enable) + { + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) | TSI_GENCS_STM_MASK; /* Enable hardware trigger scan */ + } + else + { + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) & (~TSI_GENCS_STM_MASK); /* Enable software trigger scan */ + } +} + +/*! +* @brief Starts a software trigger measurement (triggers a new measurement). +* +* @param base TSI peripheral base address. +* @return none. +*/ +static inline void TSI_StartSoftwareTrigger(TSI_Type *base) +{ + base->DATA |= TSI_DATA_SWTS_MASK; +} + +/*! +* @brief Sets the the measured channel number. +* +* @param base TSI peripheral base address. +* @param channel Channel number 0 ... 15. +* @return none. +*/ +static inline void TSI_SetMeasuredChannelNumber(TSI_Type *base, uint8_t channel) +{ + assert(channel < FSL_FEATURE_TSI_CHANNEL_COUNT); + + base->DATA = ((base->DATA) & ~TSI_DATA_TSICH_MASK) | (TSI_DATA_TSICH(channel)); +} + +/*! +* @brief Gets the current measured channel number. +* +* @param base TSI peripheral base address. +* @return uint8_t Channel number 0 ... 15. +*/ +static inline uint8_t TSI_GetMeasuredChannelNumber(TSI_Type *base) +{ + return (uint8_t)((base->DATA & TSI_DATA_TSICH_MASK) >> TSI_DATA_TSICH_SHIFT); +} + +/*! +* @brief Enables/disables the DMA transfer. +* +* @param base TSI peripheral base address. +* @param enable Choose to enable DMA transfer or not. +* - true Enable DMA transfer; +* - false Disable DMA transfer; +* @return none. +*/ +static inline void TSI_EnableDmaTransfer(TSI_Type *base, bool enable) +{ + if (enable) + { + base->DATA |= TSI_DATA_DMAEN_MASK; /* Enable DMA transfer */ + } + else + { + base->DATA &= ~TSI_DATA_DMAEN_MASK; /* Disable DMA transfer */ + } +} + +#if defined(FSL_FEATURE_TSI_HAS_END_OF_SCAN_DMA_ENABLE) && (FSL_FEATURE_TSI_HAS_END_OF_SCAN_DMA_ENABLE == 1) +/*! +* @brief Decides whether to enable end of scan DMA transfer request only. +* +* @param base TSI peripheral base address. +* @param enable Choose whether to enable End of Scan DMA transfer request only. +* - true Enable End of Scan DMA transfer request only; +* - false Both End-of-Scan and Out-of-Range can generate DMA transfer request. +* @return none. +*/ +static inline void TSI_EnableEndOfScanDmaTransferOnly(TSI_Type *base, bool enable) +{ + if (enable) + { + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) | TSI_GENCS_EOSDMEO_MASK; /* Enable End of Scan DMA transfer request only; */ + } + else + { + base->GENCS = + (base->GENCS & ~ALL_FLAGS_MASK) & (~TSI_GENCS_EOSDMEO_MASK); /* Both End-of-Scan and Out-of-Range can generate DMA transfer request. */ + } +} +#endif /* End of (FSL_FEATURE_TSI_HAS_END_OF_SCAN_DMA_ENABLE == 1)*/ + +/*! +* @brief Gets the conversion counter value. +* +* @param base TSI peripheral base address. +* @return Accumulated scan counter value ticked by the reference clock. +*/ +static inline uint16_t TSI_GetCounter(TSI_Type *base) +{ + return (uint16_t)(base->DATA & TSI_DATA_TSICNT_MASK); +} + +/*! +* @brief Sets the TSI wake-up channel low threshold. +* +* @param base TSI peripheral base address. +* @param low_threshold Low counter threshold. +* @return none. +*/ +static inline void TSI_SetLowThreshold(TSI_Type *base, uint16_t low_threshold) +{ + assert(low_threshold < 0xFFFFU); + + base->TSHD = ((base->TSHD) & ~TSI_TSHD_THRESL_MASK) | (TSI_TSHD_THRESL(low_threshold)); +} + +/*! +* @brief Sets the TSI wake-up channel high threshold. +* +* @param base TSI peripheral base address. +* @param high_threshold High counter threshold. +* @return none. +*/ +static inline void TSI_SetHighThreshold(TSI_Type *base, uint16_t high_threshold) +{ + assert(high_threshold < 0xFFFFU); + + base->TSHD = ((base->TSHD) & ~TSI_TSHD_THRESH_MASK) | (TSI_TSHD_THRESH(high_threshold)); +} + +/*! +* @brief Sets the analog mode of the TSI module. +* +* @param base TSI peripheral base address. +* @param mode Mode value. +* @return none. +*/ +static inline void TSI_SetAnalogMode(TSI_Type *base, tsi_analog_mode_t mode) +{ + base->GENCS = (base->GENCS & ~(TSI_GENCS_MODE_MASK | ALL_FLAGS_MASK)) | (TSI_GENCS_MODE(mode)); +} + +/*! +* @brief Gets the noise mode result of the TSI module. +* +* @param base TSI peripheral base address. +* @return Value of the GENCS[MODE] bit-fields. +*/ +static inline uint8_t TSI_GetNoiseModeResult(TSI_Type *base) +{ + return (base->GENCS & TSI_GENCS_MODE_MASK) >> TSI_GENCS_MODE_SHIFT; +} + +/*! +* @brief Sets the reference oscillator charge current. +* +* @param base TSI peripheral base address. +* @param current The reference oscillator charge current. +* @return none. +*/ +static inline void TSI_SetReferenceChargeCurrent(TSI_Type *base, tsi_reference_osc_charge_current_t current) +{ + base->GENCS = (base->GENCS & ~(TSI_GENCS_REFCHRG_MASK | ALL_FLAGS_MASK)) | (TSI_GENCS_REFCHRG(current)); +} + +/*! +* @brief Sets the external electrode charge current. +* +* @param base TSI peripheral base address. +* @param current External electrode charge current. +* @return none. +*/ +static inline void TSI_SetElectrodeChargeCurrent(TSI_Type *base, tsi_external_osc_charge_current_t current) +{ + base->GENCS = (base->GENCS & ~(TSI_GENCS_EXTCHRG_MASK | ALL_FLAGS_MASK)) | (TSI_GENCS_EXTCHRG(current)); +} + +/*! +* @brief Sets the oscillator's voltage rails. +* +* @param base TSI peripheral base address. +* @param dvolt The voltage rails. +* @return none. +*/ +static inline void TSI_SetOscVoltageRails(TSI_Type *base, tsi_osc_voltage_rails_t dvolt) +{ + base->GENCS = (base->GENCS & ~(TSI_GENCS_DVOLT_MASK | ALL_FLAGS_MASK)) | (TSI_GENCS_DVOLT(dvolt)); +} + +/*! +* @brief Sets the electrode series resistance value in EXTCHRG[0] bit. +* +* @param base TSI peripheral base address. +* @param resistor Series resistance. +* @return none. +*/ +static inline void TSI_SetElectrodeSeriesResistor(TSI_Type *base, tsi_series_resistor_t resistor) +{ + base->GENCS = (base->GENCS & TSI_V4_EXTCHRG_RESISTOR_BIT_CLEAR) | TSI_GENCS_EXTCHRG(resistor); +} + +/*! +* @brief Sets the electrode filter bits value in EXTCHRG[2:1] bits. +* +* @param base TSI peripheral base address. +* @param filter Series resistance. +* @return none. +*/ +static inline void TSI_SetFilterBits(TSI_Type *base, tsi_filter_bits_t filter) +{ + base->GENCS = (base->GENCS & TSI_V4_EXTCHRG_FILTER_BITS_CLEAR) | (filter << TSI_V4_EXTCHRG_FILTER_BITS_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_TSI_V4_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_vref.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_vref.c new file mode 100644 index 00000000000..20eeb4c0541 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_vref.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_vref.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Gets the instance from the base address + * + * @param base VREF peripheral base address + * + * @return The VREF instance + */ +static uint32_t VREF_GetInstance(VREF_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Pointers to VREF bases for each instance. */ +static VREF_Type *const s_vrefBases[] = VREF_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to VREF clocks for each instance. */ +static const clock_ip_name_t s_vrefClocks[] = VREF_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t VREF_GetInstance(VREF_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_VREF_COUNT; instance++) + { + if (s_vrefBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_VREF_COUNT); + + return instance; +} + +void VREF_Init(VREF_Type *base, const vref_config_t *config) +{ + assert(config != NULL); + + uint8_t reg = 0U; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate clock for VREF */ + CLOCK_EnableClock(s_vrefClocks[VREF_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/* Configure VREF to a known state */ +#if defined(FSL_FEATURE_VREF_HAS_CHOP_OSC) && FSL_FEATURE_VREF_HAS_CHOP_OSC + /* Set chop oscillator bit */ + base->TRM |= VREF_TRM_CHOPEN_MASK; +#endif /* FSL_FEATURE_VREF_HAS_CHOP_OSC */ + /* Get current SC register */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + reg = base->VREFH_SC; +#else + reg = base->SC; +#endif/* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + /* Clear old buffer mode selection bits */ + reg &= ~VREF_SC_MODE_LV_MASK; + /* Set buffer Mode selection and Regulator enable bit */ + reg |= VREF_SC_MODE_LV(config->bufferMode) | VREF_SC_REGEN(1U); +#if defined(FSL_FEATURE_VREF_HAS_COMPENSATION) && FSL_FEATURE_VREF_HAS_COMPENSATION + /* Set second order curvature compensation enable bit */ + reg |= VREF_SC_ICOMPEN(1U); +#endif /* FSL_FEATURE_VREF_HAS_COMPENSATION */ + /* Enable VREF module */ + reg |= VREF_SC_VREFEN(1U); + /* Update bit-field from value to Status and Control register */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + base->VREFH_SC = reg; +#else + base->SC = reg; +#endif/* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + reg = base->VREFL_TRM; + /* Clear old select external voltage reference and VREFL (0.4 V) reference buffer enable bits */ + reg &= ~(VREF_VREFL_TRM_VREFL_EN_MASK | VREF_VREFL_TRM_VREFL_SEL_MASK); + /* Select external voltage reference and set VREFL (0.4 V) reference buffer enable */ + reg |= VREF_VREFL_TRM_VREFL_SEL(config->enableExternalVoltRef) | VREF_VREFL_TRM_VREFL_EN(config->enableLowRef); + base->VREFL_TRM = reg; +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + +#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4 + reg = base->TRM4; + /* Clear old select internal voltage reference bit (2.1V) */ + reg &= ~VREF_TRM4_VREF2V1_EN_MASK; + /* Select internal voltage reference (2.1V) */ + reg |= VREF_TRM4_VREF2V1_EN(config->enable2V1VoltRef); + base->TRM4 = reg; +#endif /* FSL_FEATURE_VREF_HAS_TRM4 */ + + /* Wait until internal voltage stable */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + while ((base->VREFH_SC & VREF_SC_VREFST_MASK) == 0) +#else + while ((base->SC & VREF_SC_VREFST_MASK) == 0) +#endif/* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + { + } +} + +void VREF_Deinit(VREF_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate clock for VREF */ + CLOCK_DisableClock(s_vrefClocks[VREF_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void VREF_GetDefaultConfig(vref_config_t *config) +{ + assert(config); + +/* Set High power buffer mode in */ +#if defined(FSL_FEATURE_VREF_MODE_LV_TYPE) && FSL_FEATURE_VREF_MODE_LV_TYPE + config->bufferMode = kVREF_ModeHighPowerBuffer; +#else + config->bufferMode = kVREF_ModeTightRegulationBuffer; +#endif /* FSL_FEATURE_VREF_MODE_LV_TYPE */ + +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + /* Select internal voltage reference */ + config->enableExternalVoltRef = false; + /* Set VREFL (0.4 V) reference buffer disable */ + config->enableLowRef = false; +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + +#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4 + /* Disable internal voltage reference (2.1V) */ + config->enable2V1VoltRef = false; +#endif /* FSL_FEATURE_VREF_HAS_TRM4 */ +} + +void VREF_SetTrimVal(VREF_Type *base, uint8_t trimValue) +{ + uint8_t reg = 0U; + + /* Set TRIM bits value in voltage reference */ + reg = base->TRM; + reg = ((reg & ~VREF_TRM_TRIM_MASK) | VREF_TRM_TRIM(trimValue)); + base->TRM = reg; + /* Wait until internal voltage stable */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + while ((base->VREFH_SC & VREF_SC_VREFST_MASK) == 0) +#else + while ((base->SC & VREF_SC_VREFST_MASK) == 0) +#endif/* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + { + } +} + +#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4 +void VREF_SetTrim2V1Val(VREF_Type *base, uint8_t trimValue) +{ + uint8_t reg = 0U; + + /* Set TRIM bits value in voltage reference (2V1) */ + reg = base->TRM4; + reg = ((reg & ~VREF_TRM4_TRIM2V1_MASK) | VREF_TRM4_TRIM2V1(trimValue)); + base->TRM4 = reg; + /* Wait until internal voltage stable */ + while ((base->SC & VREF_SC_VREFST_MASK) == 0) + { + } +} +#endif /* FSL_FEATURE_VREF_HAS_TRM4 */ + +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE +void VREF_SetLowReferenceTrimVal(VREF_Type *base, uint8_t trimValue) +{ + /* The values 111b and 110b are NOT valid/allowed */ + assert((trimValue != 0x7U) && (trimValue != 0x6U)); + + uint8_t reg = 0U; + + /* Set TRIM bits value in low voltage reference */ + reg = base->VREFL_TRM; + reg = ((reg & ~VREF_VREFL_TRM_VREFL_TRIM_MASK) | VREF_VREFL_TRM_VREFL_TRIM(trimValue)); + base->VREFL_TRM = reg; + /* Wait until internal voltage stable */ + + while ((base->VREFH_SC & VREF_SC_VREFST_MASK) == 0) + { + } +} +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_vref.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_vref.h new file mode 100644 index 00000000000..ffdf16b9ec7 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_vref.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_VREF_H_ +#define _FSL_VREF_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup vref + * @{ + */ + + +/****************************************************************************** + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_VREF_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0. */ +/*@}*/ + +/* Those macros below defined to support SoC family which have VREFL (0.4V) reference */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE +#define VREF_SC_MODE_LV VREF_VREFH_SC_MODE_LV +#define VREF_SC_REGEN VREF_VREFH_SC_REGEN +#define VREF_SC_VREFEN VREF_VREFH_SC_VREFEN +#define VREF_SC_ICOMPEN VREF_VREFH_SC_ICOMPEN +#define VREF_SC_REGEN_MASK VREF_VREFH_SC_REGEN_MASK +#define VREF_SC_VREFST_MASK VREF_VREFH_SC_VREFST_MASK +#define VREF_SC_VREFEN_MASK VREF_VREFH_SC_VREFEN_MASK +#define VREF_SC_MODE_LV_MASK VREF_VREFH_SC_MODE_LV_MASK +#define VREF_SC_ICOMPEN_MASK VREF_VREFH_SC_ICOMPEN_MASK +#define TRM VREFH_TRM +#define VREF_TRM_TRIM VREF_VREFH_TRM_TRIM +#define VREF_TRM_CHOPEN_MASK VREF_VREFH_TRM_CHOPEN_MASK +#define VREF_TRM_TRIM_MASK VREF_VREFH_TRM_TRIM_MASK +#define VREF_TRM_CHOPEN_SHIFT VREF_VREFH_TRM_CHOPEN_SHIFT +#define VREF_TRM_TRIM_SHIFT VREF_VREFH_TRM_TRIM_SHIFT +#define VREF_SC_MODE_LV_SHIFT VREF_VREFH_SC_MODE_LV_SHIFT +#define VREF_SC_REGEN_SHIFT VREF_VREFH_SC_REGEN_SHIFT +#define VREF_SC_VREFST_SHIFT VREF_VREFH_SC_VREFST_SHIFT +#define VREF_SC_ICOMPEN_SHIFT VREF_VREFH_SC_ICOMPEN_SHIFT +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + +/*! + * @brief VREF modes. + */ +typedef enum _vref_buffer_mode +{ + kVREF_ModeBandgapOnly = 0U, /*!< Bandgap on only, for stabilization and startup */ +#if defined(FSL_FEATURE_VREF_MODE_LV_TYPE) && FSL_FEATURE_VREF_MODE_LV_TYPE + kVREF_ModeHighPowerBuffer = 1U, /*!< High-power buffer mode enabled */ + kVREF_ModeLowPowerBuffer = 2U /*!< Low-power buffer mode enabled */ +#else + kVREF_ModeTightRegulationBuffer = 2U /*!< Tight regulation buffer enabled */ +#endif /* FSL_FEATURE_VREF_MODE_LV_TYPE */ +} vref_buffer_mode_t; + +/*! + * @brief The description structure for the VREF module. + */ +typedef struct _vref_config +{ + vref_buffer_mode_t bufferMode; /*!< Buffer mode selection */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + bool enableLowRef; /*!< Set VREFL (0.4 V) reference buffer enable or disable */ + bool enableExternalVoltRef; /*!< Select external voltage reference or not (internal) */ +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ +#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4 + bool enable2V1VoltRef; /*!< Enable Internal Voltage Reference (2.1V) */ +#endif /* FSL_FEATURE_VREF_HAS_TRM4 */ +} vref_config_t; + +/****************************************************************************** + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name VREF functional operation + * @{ + */ + +/*! + * @brief Enables the clock gate and configures the VREF module according to the configuration structure. + * + * This function must be called before calling all other VREF driver functions, + * read/write registers, and configurations with user-defined settings. + * The example below shows how to set up vref_config_t parameters and + * how to call the VREF_Init function by passing in these parameters. + * This is an example. + * @code + * vref_config_t vrefConfig; + * vrefConfig.bufferMode = kVREF_ModeHighPowerBuffer; + * vrefConfig.enableExternalVoltRef = false; + * vrefConfig.enableLowRef = false; + * VREF_Init(VREF, &vrefConfig); + * @endcode + * + * @param base VREF peripheral address. + * @param config Pointer to the configuration structure. + */ +void VREF_Init(VREF_Type *base, const vref_config_t *config); + +/*! + * @brief Stops and disables the clock for the VREF module. + * + * This function should be called to shut down the module. + * This is an example. + * @code + * vref_config_t vrefUserConfig; + * VREF_Init(VREF); + * VREF_GetDefaultConfig(&vrefUserConfig); + * ... + * VREF_Deinit(VREF); + * @endcode + * + * @param base VREF peripheral address. + */ +void VREF_Deinit(VREF_Type *base); + +/*! + * @brief Initializes the VREF configuration structure. + * + * This function initializes the VREF configuration structure to default values. + * This is an example. + * @code + * vrefConfig->bufferMode = kVREF_ModeHighPowerBuffer; + * vrefConfig->enableExternalVoltRef = false; + * vrefConfig->enableLowRef = false; + * @endcode + * + * @param config Pointer to the initialization structure. + */ +void VREF_GetDefaultConfig(vref_config_t *config); + +/*! + * @brief Sets a TRIM value for the reference voltage. + * + * This function sets a TRIM value for the reference voltage. + * Note that the TRIM value maximum is 0x3F. + * + * @param base VREF peripheral address. + * @param trimValue Value of the trim register to set the output reference voltage (maximum 0x3F (6-bit)). + */ +void VREF_SetTrimVal(VREF_Type *base, uint8_t trimValue); + +/*! + * @brief Reads the value of the TRIM meaning output voltage. + * + * This function gets the TRIM value from the TRM register. + * + * @param base VREF peripheral address. + * @return Six-bit value of trim setting. + */ +static inline uint8_t VREF_GetTrimVal(VREF_Type *base) +{ + return (base->TRM & VREF_TRM_TRIM_MASK); +} + +#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4 +/*! + * @brief Sets a TRIM value for the reference voltage (2V1). + * + * This function sets a TRIM value for the reference voltage (2V1). + * Note that the TRIM value maximum is 0x3F. + * + * @param base VREF peripheral address. + * @param trimValue Value of the trim register to set the output reference voltage (maximum 0x3F (6-bit)). + */ +void VREF_SetTrim2V1Val(VREF_Type *base, uint8_t trimValue); + +/*! + * @brief Reads the value of the TRIM meaning output voltage (2V1). + * + * This function gets the TRIM value from the VREF_TRM4 register. + * + * @param base VREF peripheral address. + * @return Six-bit value of trim setting. + */ +static inline uint8_t VREF_GetTrim2V1Val(VREF_Type *base) +{ + return (base->TRM4 & VREF_TRM4_TRIM2V1_MASK); +} +#endif /* FSL_FEATURE_VREF_HAS_TRM4 */ + +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + +/*! + * @brief Sets the TRIM value for the low voltage reference. + * + * This function sets the TRIM value for low reference voltage. + * Note the following. + * - The TRIM value maximum is 0x05U + * - The values 111b and 110b are not valid/allowed. + * + * @param base VREF peripheral address. + * @param trimValue Value of the trim register to set output low reference voltage (maximum 0x05U (3-bit)). + */ +void VREF_SetLowReferenceTrimVal(VREF_Type *base, uint8_t trimValue); + +/*! + * @brief Reads the value of the TRIM meaning output voltage. + * + * This function gets the TRIM value from the VREFL_TRM register. + * + * @param base VREF peripheral address. + * @return Three-bit value of the trim setting. + */ +static inline uint8_t VREF_GetLowReferenceTrimVal(VREF_Type *base) +{ + return (base->VREFL_TRM & VREF_VREFL_TRM_VREFL_TRIM_MASK); +} +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_VREF_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_wdog.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_wdog.c new file mode 100644 index 00000000000..489798ca889 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_wdog.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_wdog.h" + +/******************************************************************************* + * Code + ******************************************************************************/ + +void WDOG_GetDefaultConfig(wdog_config_t *config) +{ + assert(config); + + config->enableWdog = true; + config->clockSource = kWDOG_LpoClockSource; + config->prescaler = kWDOG_ClockPrescalerDivide1; +#if defined(FSL_FEATURE_WDOG_HAS_WAITEN) && FSL_FEATURE_WDOG_HAS_WAITEN + config->workMode.enableWait = true; +#endif /* FSL_FEATURE_WDOG_HAS_WAITEN */ + config->workMode.enableStop = false; + config->workMode.enableDebug = false; + config->enableUpdate = true; + config->enableInterrupt = false; + config->enableWindowMode = false; + config->windowValue = 0U; + config->timeoutValue = 0xFFFFU; +} + +void WDOG_Init(WDOG_Type *base, const wdog_config_t *config) +{ + assert(config); + + uint32_t value = 0U; + uint32_t primaskValue = 0U; + + value = WDOG_STCTRLH_WDOGEN(config->enableWdog) | WDOG_STCTRLH_CLKSRC(config->clockSource) | + WDOG_STCTRLH_IRQRSTEN(config->enableInterrupt) | WDOG_STCTRLH_WINEN(config->enableWindowMode) | + WDOG_STCTRLH_ALLOWUPDATE(config->enableUpdate) | WDOG_STCTRLH_DBGEN(config->workMode.enableDebug) | + WDOG_STCTRLH_STOPEN(config->workMode.enableStop) | +#if defined(FSL_FEATURE_WDOG_HAS_WAITEN) && FSL_FEATURE_WDOG_HAS_WAITEN + WDOG_STCTRLH_WAITEN(config->workMode.enableWait) | +#endif /* FSL_FEATURE_WDOG_HAS_WAITEN */ + WDOG_STCTRLH_DISTESTWDOG(1U); + + /* Disable the global interrupts. Otherwise, an interrupt could effectively invalidate the unlock sequence + * and the WCT may expire. After the configuration finishes, re-enable the global interrupts. */ + primaskValue = DisableGlobalIRQ(); + WDOG_Unlock(base); + /* Wait one bus clock cycle */ + base->RSTCNT = 0U; + /* Set configruation */ + base->PRESC = WDOG_PRESC_PRESCVAL(config->prescaler); + base->WINH = (uint16_t)((config->windowValue >> 16U) & 0xFFFFU); + base->WINL = (uint16_t)((config->windowValue) & 0xFFFFU); + base->TOVALH = (uint16_t)((config->timeoutValue >> 16U) & 0xFFFFU); + base->TOVALL = (uint16_t)((config->timeoutValue) & 0xFFFFU); + base->STCTRLH = value; + EnableGlobalIRQ(primaskValue); +} + +void WDOG_Deinit(WDOG_Type *base) +{ + uint32_t primaskValue = 0U; + + /* Disable the global interrupts */ + primaskValue = DisableGlobalIRQ(); + WDOG_Unlock(base); + /* Wait one bus clock cycle */ + base->RSTCNT = 0U; + WDOG_Disable(base); + EnableGlobalIRQ(primaskValue); + WDOG_ClearResetCount(base); +} + +void WDOG_SetTestModeConfig(WDOG_Type *base, wdog_test_config_t *config) +{ + assert(config); + + uint32_t value = 0U; + uint32_t primaskValue = 0U; + + value = WDOG_STCTRLH_DISTESTWDOG(0U) | WDOG_STCTRLH_TESTWDOG(1U) | WDOG_STCTRLH_TESTSEL(config->testMode) | + WDOG_STCTRLH_BYTESEL(config->testedByte) | WDOG_STCTRLH_IRQRSTEN(0U) | WDOG_STCTRLH_WDOGEN(1U) | + WDOG_STCTRLH_ALLOWUPDATE(1U); + + /* Disable the global interrupts. Otherwise, an interrupt could effectively invalidate the unlock sequence + * and the WCT may expire. After the configuration finishes, re-enable the global interrupts. */ + primaskValue = DisableGlobalIRQ(); + WDOG_Unlock(base); + /* Wait one bus clock cycle */ + base->RSTCNT = 0U; + /* Set configruation */ + base->TOVALH = (uint16_t)((config->timeoutValue >> 16U) & 0xFFFFU); + base->TOVALL = (uint16_t)((config->timeoutValue) & 0xFFFFU); + base->STCTRLH = value; + EnableGlobalIRQ(primaskValue); +} + +uint32_t WDOG_GetStatusFlags(WDOG_Type *base) +{ + uint32_t status_flag = 0U; + + status_flag |= (base->STCTRLH & WDOG_STCTRLH_WDOGEN_MASK); + status_flag |= (base->STCTRLL & WDOG_STCTRLL_INTFLG_MASK); + + return status_flag; +} + +void WDOG_ClearStatusFlags(WDOG_Type *base, uint32_t mask) +{ + if (mask & kWDOG_TimeoutFlag) + { + base->STCTRLL |= WDOG_STCTRLL_INTFLG_MASK; + } +} + +void WDOG_Refresh(WDOG_Type *base) +{ + uint32_t primaskValue = 0U; + + /* Disable the global interrupt to protect refresh sequence */ + primaskValue = DisableGlobalIRQ(); + base->REFRESH = WDOG_FIRST_WORD_OF_REFRESH; + base->REFRESH = WDOG_SECOND_WORD_OF_REFRESH; + EnableGlobalIRQ(primaskValue); +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_wdog.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_wdog.h new file mode 100644 index 00000000000..39ddab0c910 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/drivers/fsl_wdog.h @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_WDOG_H_ +#define _FSL_WDOG_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup wdog + * @{ + */ + + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief Defines WDOG driver version 2.0.0. */ +#define FSL_WDOG_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! @name Unlock sequence */ +/*@{*/ +#define WDOG_FIRST_WORD_OF_UNLOCK (0xC520U) /*!< First word of unlock sequence */ +#define WDOG_SECOND_WORD_OF_UNLOCK (0xD928U) /*!< Second word of unlock sequence */ +/*@}*/ + +/*! @name Refresh sequence */ +/*@{*/ +#define WDOG_FIRST_WORD_OF_REFRESH (0xA602U) /*!< First word of refresh sequence */ +#define WDOG_SECOND_WORD_OF_REFRESH (0xB480U) /*!< Second word of refresh sequence */ +/*@}*/ + +/*! @brief Describes WDOG clock source. */ +typedef enum _wdog_clock_source +{ + kWDOG_LpoClockSource = 0U, /*!< WDOG clock sourced from LPO*/ + kWDOG_AlternateClockSource = 1U, /*!< WDOG clock sourced from alternate clock source*/ +} wdog_clock_source_t; + +/*! @brief Defines WDOG work mode. */ +typedef struct _wdog_work_mode +{ +#if defined(FSL_FEATURE_WDOG_HAS_WAITEN) && FSL_FEATURE_WDOG_HAS_WAITEN + bool enableWait; /*!< Enables or disables WDOG in wait mode */ +#endif /* FSL_FEATURE_WDOG_HAS_WAITEN */ + bool enableStop; /*!< Enables or disables WDOG in stop mode */ + bool enableDebug; /*!< Enables or disables WDOG in debug mode */ +} wdog_work_mode_t; + +/*! @brief Describes the selection of the clock prescaler. */ +typedef enum _wdog_clock_prescaler +{ + kWDOG_ClockPrescalerDivide1 = 0x0U, /*!< Divided by 1 */ + kWDOG_ClockPrescalerDivide2 = 0x1U, /*!< Divided by 2 */ + kWDOG_ClockPrescalerDivide3 = 0x2U, /*!< Divided by 3 */ + kWDOG_ClockPrescalerDivide4 = 0x3U, /*!< Divided by 4 */ + kWDOG_ClockPrescalerDivide5 = 0x4U, /*!< Divided by 5 */ + kWDOG_ClockPrescalerDivide6 = 0x5U, /*!< Divided by 6 */ + kWDOG_ClockPrescalerDivide7 = 0x6U, /*!< Divided by 7 */ + kWDOG_ClockPrescalerDivide8 = 0x7U, /*!< Divided by 8 */ +} wdog_clock_prescaler_t; + +/*! @brief Describes WDOG configuration structure. */ +typedef struct _wdog_config +{ + bool enableWdog; /*!< Enables or disables WDOG */ + wdog_clock_source_t clockSource; /*!< Clock source select */ + wdog_clock_prescaler_t prescaler; /*!< Clock prescaler value */ + wdog_work_mode_t workMode; /*!< Configures WDOG work mode in debug stop and wait mode */ + bool enableUpdate; /*!< Update write-once register enable */ + bool enableInterrupt; /*!< Enables or disables WDOG interrupt */ + bool enableWindowMode; /*!< Enables or disables WDOG window mode */ + uint32_t windowValue; /*!< Window value */ + uint32_t timeoutValue; /*!< Timeout value */ +} wdog_config_t; + +/*! @brief Describes WDOG test mode. */ +typedef enum _wdog_test_mode +{ + kWDOG_QuickTest = 0U, /*!< Selects quick test */ + kWDOG_ByteTest = 1U, /*!< Selects byte test */ +} wdog_test_mode_t; + +/*! @brief Describes WDOG tested byte selection in byte test mode. */ +typedef enum _wdog_tested_byte +{ + kWDOG_TestByte0 = 0U, /*!< Byte 0 selected in byte test mode */ + kWDOG_TestByte1 = 1U, /*!< Byte 1 selected in byte test mode */ + kWDOG_TestByte2 = 2U, /*!< Byte 2 selected in byte test mode */ + kWDOG_TestByte3 = 3U, /*!< Byte 3 selected in byte test mode */ +} wdog_tested_byte_t; + +/*! @brief Describes WDOG test mode configuration structure. */ +typedef struct _wdog_test_config +{ + wdog_test_mode_t testMode; /*!< Selects test mode */ + wdog_tested_byte_t testedByte; /*!< Selects tested byte in byte test mode */ + uint32_t timeoutValue; /*!< Timeout value */ +} wdog_test_config_t; + +/*! + * @brief WDOG interrupt configuration structure, default settings all disabled. + * + * This structure contains the settings for all of the WDOG interrupt configurations. + */ +enum _wdog_interrupt_enable_t +{ + kWDOG_InterruptEnable = WDOG_STCTRLH_IRQRSTEN_MASK, /*!< WDOG timeout generates an interrupt before reset*/ +}; + +/*! + * @brief WDOG status flags. + * + * This structure contains the WDOG status flags for use in the WDOG functions. + */ +enum _wdog_status_flags_t +{ + kWDOG_RunningFlag = WDOG_STCTRLH_WDOGEN_MASK, /*!< Running flag, set when WDOG is enabled*/ + kWDOG_TimeoutFlag = WDOG_STCTRLL_INTFLG_MASK, /*!< Interrupt flag, set when an exception occurs*/ +}; + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name WDOG Initialization and De-initialization + * @{ + */ + +/*! + * @brief Initializes the WDOG configuration sturcture. + * + * This function initializes the WDOG configuration structure to default values. The default + * values are as follows. + * @code + * wdogConfig->enableWdog = true; + * wdogConfig->clockSource = kWDOG_LpoClockSource; + * wdogConfig->prescaler = kWDOG_ClockPrescalerDivide1; + * wdogConfig->workMode.enableWait = true; + * wdogConfig->workMode.enableStop = false; + * wdogConfig->workMode.enableDebug = false; + * wdogConfig->enableUpdate = true; + * wdogConfig->enableInterrupt = false; + * wdogConfig->enableWindowMode = false; + * wdogConfig->windowValue = 0; + * wdogConfig->timeoutValue = 0xFFFFU; + * @endcode + * + * @param config Pointer to the WDOG configuration structure. + * @see wdog_config_t + */ +void WDOG_GetDefaultConfig(wdog_config_t *config); + +/*! + * @brief Initializes the WDOG. + * + * This function initializes the WDOG. When called, the WDOG runs according to the configuration. + * To reconfigure WDOG without forcing a reset first, enableUpdate must be set to true + * in the configuration. + * + * This is an example. + * @code + * wdog_config_t config; + * WDOG_GetDefaultConfig(&config); + * config.timeoutValue = 0x7ffU; + * config.enableUpdate = true; + * WDOG_Init(wdog_base,&config); + * @endcode + * + * @param base WDOG peripheral base address + * @param config The configuration of WDOG + */ +void WDOG_Init(WDOG_Type *base, const wdog_config_t *config); + +/*! + * @brief Shuts down the WDOG. + * + * This function shuts down the WDOG. + * Ensure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which indicates that the register update is enabled. + */ +void WDOG_Deinit(WDOG_Type *base); + +/*! + * @brief Configures the WDOG functional test. + * + * This function is used to configure the WDOG functional test. When called, the WDOG goes into test mode + * and runs according to the configuration. + * Ensure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which means that the register update is enabled. + * + * This is an example. + * @code + * wdog_test_config_t test_config; + * test_config.testMode = kWDOG_QuickTest; + * test_config.timeoutValue = 0xfffffu; + * WDOG_SetTestModeConfig(wdog_base, &test_config); + * @endcode + * @param base WDOG peripheral base address + * @param config The functional test configuration of WDOG + */ +void WDOG_SetTestModeConfig(WDOG_Type *base, wdog_test_config_t *config); + +/* @} */ + +/*! + * @name WDOG Functional Operation + * @{ + */ + +/*! + * @brief Enables the WDOG module. + * + * This function write value into WDOG_STCTRLH register to enable the WDOG, it is a write-once register, + * make sure that the WCT window is still open and this register has not been written in this WCT + * while this function is called. + * + * @param base WDOG peripheral base address + */ +static inline void WDOG_Enable(WDOG_Type *base) +{ + base->STCTRLH |= WDOG_STCTRLH_WDOGEN_MASK; +} + +/*! + * @brief Disables the WDOG module. + * + * This function writes a value into the WDOG_STCTRLH register to disable the WDOG. It is a write-once register. + * Ensure that the WCT window is still open and that register has not been written to in this WCT + * while the function is called. + * + * @param base WDOG peripheral base address + */ +static inline void WDOG_Disable(WDOG_Type *base) +{ + base->STCTRLH &= ~WDOG_STCTRLH_WDOGEN_MASK; +} + +/*! + * @brief Enables the WDOG interrupt. + * + * This function writes a value into the WDOG_STCTRLH register to enable the WDOG interrupt. It is a write-once register. + * Ensure that the WCT window is still open and the register has not been written to in this WCT + * while the function is called. + * + * @param base WDOG peripheral base address + * @param mask The interrupts to enable + * The parameter can be combination of the following source if defined. + * @arg kWDOG_InterruptEnable + */ +static inline void WDOG_EnableInterrupts(WDOG_Type *base, uint32_t mask) +{ + base->STCTRLH |= mask; +} + +/*! + * @brief Disables the WDOG interrupt. + * + * This function writes a value into the WDOG_STCTRLH register to disable the WDOG interrupt. It is a write-once register. + * Ensure that the WCT window is still open and the register has not been written to in this WCT + * while the function is called. + * + * @param base WDOG peripheral base address + * @param mask The interrupts to disable + * The parameter can be combination of the following source if defined. + * @arg kWDOG_InterruptEnable + */ +static inline void WDOG_DisableInterrupts(WDOG_Type *base, uint32_t mask) +{ + base->STCTRLH &= ~mask; +} + +/*! + * @brief Gets the WDOG all status flags. + * + * This function gets all status flags. + * + * This is an example for getting the Running Flag. + * @code + * uint32_t status; + * status = WDOG_GetStatusFlags (wdog_base) & kWDOG_RunningFlag; + * @endcode + * @param base WDOG peripheral base address + * @return State of the status flag: asserted (true) or not-asserted (false).@see _wdog_status_flags_t + * - true: a related status flag has been set. + * - false: a related status flag is not set. + */ +uint32_t WDOG_GetStatusFlags(WDOG_Type *base); + +/*! + * @brief Clears the WDOG flag. + * + * This function clears the WDOG status flag. + * + * This is an example for clearing the timeout (interrupt) flag. + * @code + * WDOG_ClearStatusFlags(wdog_base,kWDOG_TimeoutFlag); + * @endcode + * @param base WDOG peripheral base address + * @param mask The status flags to clear. + * The parameter could be any combination of the following values. + * kWDOG_TimeoutFlag + */ +void WDOG_ClearStatusFlags(WDOG_Type *base, uint32_t mask); + +/*! + * @brief Sets the WDOG timeout value. + * + * This function sets the timeout value. + * It should be ensured that the time-out value for the WDOG is always greater than + * 2xWCT time + 20 bus clock cycles. + * This function writes a value into WDOG_TOVALH and WDOG_TOVALL registers which are wirte-once. + * Ensure the WCT window is still open and the two registers have not been written to in this WCT + * while the function is called. + * + * @param base WDOG peripheral base address + * @param timeoutCount WDOG timeout value; count of WDOG clock tick. + */ +static inline void WDOG_SetTimeoutValue(WDOG_Type *base, uint32_t timeoutCount) +{ + base->TOVALH = (uint16_t)((timeoutCount >> 16U) & 0xFFFFU); + base->TOVALL = (uint16_t)((timeoutCount)&0xFFFFU); +} + +/*! + * @brief Sets the WDOG window value. + * + * This function sets the WDOG window value. + * This function writes a value into WDOG_WINH and WDOG_WINL registers which are wirte-once. + * Ensure the WCT window is still open and the two registers have not been written to in this WCT + * while the function is called. + * + * @param base WDOG peripheral base address + * @param windowValue WDOG window value. + */ +static inline void WDOG_SetWindowValue(WDOG_Type *base, uint32_t windowValue) +{ + base->WINH = (uint16_t)((windowValue >> 16U) & 0xFFFFU); + base->WINL = (uint16_t)((windowValue)&0xFFFFU); +} + +/*! + * @brief Unlocks the WDOG register written. + * + * This function unlocks the WDOG register written. + * Before starting the unlock sequence and following congfiguration, disable the global interrupts. + * Otherwise, an interrupt may invalidate the unlocking sequence and the WCT may expire. + * After the configuration finishes, re-enable the global interrupts. + * + * @param base WDOG peripheral base address + */ +static inline void WDOG_Unlock(WDOG_Type *base) +{ + base->UNLOCK = WDOG_FIRST_WORD_OF_UNLOCK; + base->UNLOCK = WDOG_SECOND_WORD_OF_UNLOCK; +} + +/*! + * @brief Refreshes the WDOG timer. + * + * This function feeds the WDOG. + * This function should be called before the WDOG timer is in timeout. Otherwise, a reset is asserted. + * + * @param base WDOG peripheral base address + */ +void WDOG_Refresh(WDOG_Type *base); + +/*! + * @brief Gets the WDOG reset count. + * + * This function gets the WDOG reset count value. + * + * @param base WDOG peripheral base address + * @return WDOG reset count value. + */ +static inline uint16_t WDOG_GetResetCount(WDOG_Type *base) +{ + return base->RSTCNT; +} +/*! + * @brief Clears the WDOG reset count. + * + * This function clears the WDOG reset count value. + * + * @param base WDOG peripheral base address + */ +static inline void WDOG_ClearResetCount(WDOG_Type *base) +{ + base->RSTCNT |= UINT16_MAX; +} + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_WDOG_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/peripheral_clock_defines.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/peripheral_clock_defines.h new file mode 100644 index 00000000000..e37531c2f8c --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/peripheral_clock_defines.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_PERIPHERAL_CLOCK_H_ +#define _FSL_PERIPHERAL_CLOCK_H_ + +#include "fsl_clock.h" + +/* Array for LPUART module clocks */ +#define LPUART_CLOCK_FREQS \ + { \ + kCLOCK_Osc0ErClk, kCLOCK_Osc0ErClk, kCLOCK_Osc0ErClk, kCLOCK_Osc0ErClk, kCLOCK_Osc0ErClk \ + } + +/* Array for I2C module clocks */ +#define I2C_CLOCK_FREQS \ + { \ + I2C0_CLK_SRC, I2C1_CLK_SRC, I2C2_CLK_SRC \ + } + +/* Array for DSPI module clocks */ +#define SPI_CLOCK_FREQS \ + { \ + DSPI0_CLK_SRC, DSPI1_CLK_SRC, DSPI2_CLK_SRC \ + } + +#endif /* _FSL_PERIPHERAL_CLOCK_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/pwmout_api.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/pwmout_api.c new file mode 100644 index 00000000000..216d583191a --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/pwmout_api.c @@ -0,0 +1,143 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" + +#if DEVICE_PWMOUT + +#include "cmsis.h" +#include "pinmap.h" +#include "fsl_ftm.h" +#include "PeripheralPins.h" + +static float pwm_clock_mhz; +/* Array of FTM peripheral base address. */ +static FTM_Type *const ftm_addrs[] = FTM_BASE_PTRS; + +void pwmout_init(pwmout_t* obj, PinName pin) { + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + MBED_ASSERT(pwm != (PWMName)NC); + + obj->pwm_name = pwm; + + uint32_t pwm_base_clock; + pwm_base_clock = CLOCK_GetFreq(kCLOCK_BusClk); + float clkval = (float)pwm_base_clock / 1000000.0f; + uint32_t clkdiv = 0; + while (clkval > 1) { + clkdiv++; + clkval /= 2.0f; + if (clkdiv == 7) { + break; + } + } + + pwm_clock_mhz = clkval; + uint32_t channel = pwm & 0xF; + uint32_t instance = pwm >> TPM_SHIFT; + ftm_config_t ftmInfo; + + FTM_GetDefaultConfig(&ftmInfo); + ftmInfo.prescale = (ftm_clock_prescale_t)clkdiv; + /* Initialize FTM module */ + FTM_Init(ftm_addrs[instance], &ftmInfo); + + ftm_addrs[instance]->CONF |= FTM_CONF_NUMTOF(3); + + ftm_chnl_pwm_signal_param_t config = { + .chnlNumber = (ftm_chnl_t)channel, + .level = kFTM_HighTrue, + .dutyCyclePercent = 0, + .firstEdgeDelayPercent = 0 + }; + // default to 20ms: standard for servos, and fine for e.g. brightness control + FTM_SetupPwm(ftm_addrs[instance], &config, 1, kFTM_EdgeAlignedPwm, 50, pwm_base_clock); + + FTM_StartTimer(ftm_addrs[instance], kFTM_SystemClock); + + // Wire pinout + pinmap_pinout(pin, PinMap_PWM); +} + +void pwmout_free(pwmout_t* obj) { + FTM_Deinit(ftm_addrs[obj->pwm_name >> TPM_SHIFT]); +} + +void pwmout_write(pwmout_t* obj, float value) { + if (value < 0.0f) { + value = 0.0f; + } else if (value > 1.0f) { + value = 1.0f; + } + + FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; + uint16_t mod = base->MOD & FTM_MOD_MOD_MASK; + uint32_t new_count = (uint32_t)((float)(mod) * value); + // Update of CnV register + base->CONTROLS[obj->pwm_name & 0xF].CnV = new_count; + base->CNT = 0; + /* Software trigger to update registers */ + FTM_SetSoftwareTrigger(base, true); +} + +float pwmout_read(pwmout_t* obj) { + FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; + uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & FTM_CnV_VAL_MASK; + uint16_t mod = base->MOD & FTM_MOD_MOD_MASK; + + if (mod == 0) + return 0.0; + float v = (float)(count) / (float)(mod); + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; + float dc = pwmout_read(obj); + + // Stop FTM clock to ensure instant update of MOD register + base->MOD = FTM_MOD_MOD((pwm_clock_mhz * (float)us) - 1); + pwmout_write(obj, dc); +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; + uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us); + + // Update of CnV register + base->CONTROLS[obj->pwm_name & 0xF].CnV = value; + /* Software trigger to update registers */ + FTM_SetSoftwareTrigger(base, true); +} + +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/serial_api.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/serial_api.c new file mode 100644 index 00000000000..64752bca048 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/serial_api.c @@ -0,0 +1,274 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "serial_api.h" + +#if DEVICE_SERIAL + +// math.h required for floating point operations for baud rate calculation +#include +#include "mbed_assert.h" + +#include + +#include "cmsis.h" +#include "pinmap.h" +#include "fsl_lpuart.h" +#include "peripheral_clock_defines.h" +#include "PeripheralPins.h" +#include "fsl_clock_config.h" + +static uint32_t serial_irq_ids[FSL_FEATURE_SOC_LPUART_COUNT] = {0}; +static uart_irq_handler irq_handler; +/* Array of UART peripheral base address. */ +static LPUART_Type *const uart_addrs[] = LPUART_BASE_PTRS; +/* Array of LPUART bus clock frequencies */ +static clock_name_t const uart_clocks[] = LPUART_CLOCK_FREQS; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + uint32_t uart_tx = pinmap_peripheral(tx, PinMap_UART_TX); + uint32_t uart_rx = pinmap_peripheral(rx, PinMap_UART_RX); + obj->index = pinmap_merge(uart_tx, uart_rx); + MBED_ASSERT((int)obj->index != NC); + + /* Set the LPUART clock source */ + CLOCK_SetLpuartClock(2U); + + lpuart_config_t config; + LPUART_GetDefaultConfig(&config); + config.baudRate_Bps = 9600; + config.enableTx = false; + config.enableRx = false; + + LPUART_Init(uart_addrs[obj->index], &config, CLOCK_GetFreq(uart_clocks[obj->index])); + + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + if (tx != NC) { + LPUART_EnableTx(uart_addrs[obj->index], true); + pin_mode(tx, PullUp); + } + if (rx != NC) { + LPUART_EnableRx(uart_addrs[obj->index], true); + pin_mode(rx, PullUp); + } + + if (obj->index == STDIO_UART) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + LPUART_Deinit(uart_addrs[obj->index]); + serial_irq_ids[obj->index] = 0; +} + +void serial_baud(serial_t *obj, int baudrate) { + LPUART_SetBaudRate(uart_addrs[obj->index], (uint32_t)baudrate, CLOCK_GetFreq(uart_clocks[obj->index])); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + LPUART_Type *base = uart_addrs[obj->index]; + uint8_t temp; + /* Set bit count and parity mode. */ + temp = base->CTRL & ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK); + if (parity != ParityNone) + { + /* Enable Parity */ + temp |= (LPUART_CTRL_PE_MASK | LPUART_CTRL_M_MASK); + if (parity == ParityOdd) { + temp |= LPUART_CTRL_PT_MASK; + } else if (parity == ParityEven) { + // PT=0 so nothing more to do + } else { + // Hardware does not support forced parity + MBED_ASSERT(0); + } + } + base->CTRL = temp; + +#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT + /* set stop bit per char */ + temp = base->BAUD & ~LPUART_BAUD_SBNS_MASK; + base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)--stop_bits); +#endif +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t transmit_empty, uint32_t receive_full, uint32_t index) { + LPUART_Type *base = uart_addrs[index]; + + /* If RX overrun. */ + if (LPUART_STAT_OR_MASK & base->STAT) + { + /* Read base->D, otherwise the RX does not work. */ + (void)base->DATA; + LPUART_ClearStatusFlags(base, kLPUART_RxOverrunFlag); + } + + if (serial_irq_ids[index] != 0) { + if (transmit_empty) + irq_handler(serial_irq_ids[index], TxIrq); + + if (receive_full) + irq_handler(serial_irq_ids[index], RxIrq); + } +} + +void uart0_irq() { + uint32_t status_flags = LPUART0->STAT; + uart_irq((status_flags & kLPUART_TxDataRegEmptyFlag), (status_flags & kLPUART_RxDataRegFullFlag), 0); +} + +void uart1_irq() { + uint32_t status_flags = LPUART1->STAT; + uart_irq((status_flags & kLPUART_TxDataRegEmptyFlag), (status_flags & kLPUART_RxDataRegFullFlag), 1); +} + +void uart2_irq() { + uint32_t status_flags = LPUART2->STAT; + uart_irq((status_flags & kLPUART_TxDataRegEmptyFlag), (status_flags & kLPUART_RxDataRegFullFlag), 2); +} + +void uart3_irq() { + uint32_t status_flags = LPUART3->STAT; + uart_irq((status_flags & kLPUART_TxDataRegEmptyFlag), (status_flags & kLPUART_RxDataRegFullFlag), 3); +} + +void uart4_irq() { + uint32_t status_flags = LPUART4->STAT; + uart_irq((status_flags & kLPUART_TxDataRegEmptyFlag), (status_flags & kLPUART_RxDataRegFullFlag), 4); +} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type uart_irqs[] = LPUART_RX_TX_IRQS; + uint32_t vector = 0; + + switch (obj->index) { + case 0: + vector = (uint32_t)&uart0_irq; + break; + case 1: + vector = (uint32_t)&uart1_irq; + break; + case 2: + vector = (uint32_t)&uart2_irq; + break; + case 3: + vector = (uint32_t)&uart3_irq; + break; + case 4: + vector = (uint32_t)&uart4_irq; + break; + default: + break; + } + + if (enable) { + switch (irq) { + case RxIrq: + LPUART_EnableInterrupts(uart_addrs[obj->index], kLPUART_RxDataRegFullInterruptEnable); + break; + case TxIrq: + LPUART_EnableInterrupts(uart_addrs[obj->index], kLPUART_TxDataRegEmptyInterruptEnable); + break; + default: + break; + } + NVIC_SetVector(uart_irqs[obj->index], vector); + NVIC_EnableIRQ(uart_irqs[obj->index]); + + } else { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + switch (irq) { + case RxIrq: + LPUART_DisableInterrupts(uart_addrs[obj->index], kLPUART_RxDataRegFullInterruptEnable); + break; + case TxIrq: + LPUART_DisableInterrupts(uart_addrs[obj->index], kLPUART_TxDataRegEmptyInterruptEnable); + break; + default: + break; + } + switch (other_irq) { + case RxIrq: + all_disabled = ((LPUART_GetEnabledInterrupts(uart_addrs[obj->index]) & kLPUART_RxDataRegFullInterruptEnable) == 0); + break; + case TxIrq: + all_disabled = ((LPUART_GetEnabledInterrupts(uart_addrs[obj->index]) & kLPUART_TxDataRegEmptyInterruptEnable) == 0); + break; + default: + break; + } + if (all_disabled) + NVIC_DisableIRQ(uart_irqs[obj->index]); + } +} + +int serial_getc(serial_t *obj) { + uint8_t data; + + LPUART_ReadBlocking(uart_addrs[obj->index], &data, 1); + return data; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + LPUART_WriteByte(uart_addrs[obj->index], (uint8_t)c); +} + +int serial_readable(serial_t *obj) { + uint32_t status_flags = LPUART_GetStatusFlags(uart_addrs[obj->index]); + if (status_flags & kLPUART_RxOverrunFlag) + LPUART_ClearStatusFlags(uart_addrs[obj->index], kLPUART_RxOverrunFlag); + return (status_flags & kLPUART_RxDataRegFullFlag); +} + +int serial_writable(serial_t *obj) { + uint32_t status_flags = LPUART_GetStatusFlags(uart_addrs[obj->index]); + if (status_flags & kLPUART_RxOverrunFlag) + LPUART_ClearStatusFlags(uart_addrs[obj->index], kLPUART_RxOverrunFlag); + return (status_flags & kLPUART_TxDataRegEmptyFlag); +} + +void serial_clear(serial_t *obj) { +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_set(serial_t *obj) { + uart_addrs[obj->index]->CTRL |= LPUART_CTRL_SBK_MASK; +} + +void serial_break_clear(serial_t *obj) { + uart_addrs[obj->index]->CTRL &= ~LPUART_CTRL_SBK_MASK; +} + +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/spi_api.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/spi_api.c new file mode 100644 index 00000000000..54b4d177615 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/spi_api.c @@ -0,0 +1,132 @@ +/* mbed Microcontroller Library + * Copyright (c) 2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "mbed_assert.h" + +#include "spi_api.h" + +#if DEVICE_SPI + +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" +#include "fsl_dspi.h" +#include "peripheral_clock_defines.h" +#include "PeripheralPins.h" + +/* Array of SPI peripheral base address. */ +static SPI_Type *const spi_address[] = SPI_BASE_PTRS; +/* Array of SPI bus clock frequencies */ +static clock_name_t const spi_clocks[] = SPI_CLOCK_FREQS; + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // determine the SPI to use + uint32_t spi_mosi = pinmap_peripheral(mosi, PinMap_SPI_MOSI); + uint32_t spi_miso = pinmap_peripheral(miso, PinMap_SPI_MISO); + uint32_t spi_sclk = pinmap_peripheral(sclk, PinMap_SPI_SCLK); + uint32_t spi_ssel = pinmap_peripheral(ssel, PinMap_SPI_SSEL); + uint32_t spi_data = pinmap_merge(spi_mosi, spi_miso); + uint32_t spi_cntl = pinmap_merge(spi_sclk, spi_ssel); + + obj->instance = pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT((int)obj->instance != NC); + + // pin out the spi pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } +} + +void spi_free(spi_t *obj) { + DSPI_Deinit(spi_address[obj->instance]); +} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + + dspi_master_config_t master_config; + dspi_slave_config_t slave_config; + + if (slave) { + /* Slave config */ + DSPI_SlaveGetDefaultConfig(&slave_config); + slave_config.whichCtar = kDSPI_Ctar0; + slave_config.ctarConfig.bitsPerFrame = (uint32_t)bits;; + slave_config.ctarConfig.cpol = (mode & 0x2) ? kDSPI_ClockPolarityActiveLow : kDSPI_ClockPolarityActiveHigh; + slave_config.ctarConfig.cpha = (mode & 0x1) ? kDSPI_ClockPhaseSecondEdge : kDSPI_ClockPhaseFirstEdge; + + DSPI_SlaveInit(spi_address[obj->instance], &slave_config); + } else { + /* Master config */ + DSPI_MasterGetDefaultConfig(&master_config); + master_config.ctarConfig.bitsPerFrame = (uint32_t)bits;; + master_config.ctarConfig.cpol = (mode & 0x2) ? kDSPI_ClockPolarityActiveLow : kDSPI_ClockPolarityActiveHigh; + master_config.ctarConfig.cpha = (mode & 0x1) ? kDSPI_ClockPhaseSecondEdge : kDSPI_ClockPhaseFirstEdge; + master_config.ctarConfig.direction = kDSPI_MsbFirst; + master_config.ctarConfig.pcsToSckDelayInNanoSec = 0; + + DSPI_MasterInit(spi_address[obj->instance], &master_config, CLOCK_GetFreq(spi_clocks[obj->instance])); + } +} + +void spi_frequency(spi_t *obj, int hz) { + uint32_t busClock = CLOCK_GetFreq(spi_clocks[obj->instance]); + DSPI_MasterSetBaudRate(spi_address[obj->instance], kDSPI_Ctar0, (uint32_t)hz, busClock); + //Half clock period delay after SPI transfer + DSPI_MasterSetDelayTimes(spi_address[obj->instance], kDSPI_Ctar0, kDSPI_LastSckToPcs, busClock, 500000000 / hz); +} + +static inline int spi_readable(spi_t * obj) { + return (DSPI_GetStatusFlags(spi_address[obj->instance]) & kDSPI_RxFifoDrainRequestFlag); +} + +int spi_master_write(spi_t *obj, int value) { + dspi_command_data_config_t command; + uint32_t rx_data; + DSPI_GetDefaultDataCommandConfig(&command); + command.isEndOfQueue = true; + + DSPI_MasterWriteDataBlocking(spi_address[obj->instance], &command, (uint16_t)value); + + DSPI_ClearStatusFlags(spi_address[obj->instance], kDSPI_TxFifoFillRequestFlag); + + // wait rx buffer full + while (!spi_readable(obj)); + rx_data = DSPI_ReadData(spi_address[obj->instance]); + DSPI_ClearStatusFlags(spi_address[obj->instance], kDSPI_RxFifoDrainRequestFlag | kDSPI_EndOfQueueFlag); + return rx_data & 0xffff; +} + +int spi_slave_receive(spi_t *obj) { + return spi_readable(obj); +} + +int spi_slave_read(spi_t *obj) { + uint32_t rx_data; + + while (!spi_readable(obj)); + rx_data = DSPI_ReadData(spi_address[obj->instance]); + DSPI_ClearStatusFlags(spi_address[obj->instance], kDSPI_RxFifoDrainRequestFlag); + return rx_data & 0xffff; +} + +void spi_slave_write(spi_t *obj, int value) { + DSPI_SlaveWriteDataBlocking(spi_address[obj->instance], (uint32_t)value); +} + +#endif diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/us_ticker.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/us_ticker.c new file mode 100644 index 00000000000..f7fb7b7f3ea --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K82F/us_ticker.c @@ -0,0 +1,87 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "us_ticker_api.h" +#include "PeripheralNames.h" +#include "fsl_pit.h" +#include "fsl_clock_config.h" + +static int us_ticker_inited = 0; + +void us_ticker_init(void) { + if (us_ticker_inited) { + return; + } + us_ticker_inited = 1; + //Common for ticker/timer + uint32_t busClock; + // Structure to initialize PIT + pit_config_t pitConfig; + + PIT_GetDefaultConfig(&pitConfig); + PIT_Init(PIT, &pitConfig); + + busClock = CLOCK_GetFreq(kCLOCK_BusClk); + + //Timer + PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, busClock / 1000000 - 1); + PIT_SetTimerPeriod(PIT, kPIT_Chnl_1, 0xFFFFFFFF); + PIT_SetTimerChainMode(PIT, kPIT_Chnl_1, true); + PIT_StartTimer(PIT, kPIT_Chnl_0); + PIT_StartTimer(PIT, kPIT_Chnl_1); + + //Ticker + PIT_SetTimerPeriod(PIT, kPIT_Chnl_2, busClock / 1000000 - 1); + PIT_SetTimerChainMode(PIT, kPIT_Chnl_3, true); + NVIC_SetVector(PIT3_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(PIT3_IRQn); +} + + +uint32_t us_ticker_read() { + if (!us_ticker_inited) { + us_ticker_init(); + } + + return ~(PIT_GetCurrentTimerCount(PIT, kPIT_Chnl_1)); +} + +void us_ticker_disable_interrupt(void) { + PIT_DisableInterrupts(PIT, kPIT_Chnl_3, kPIT_TimerInterruptEnable); +} + +void us_ticker_clear_interrupt(void) { + PIT_ClearStatusFlags(PIT, kPIT_Chnl_3, PIT_TFLG_TIF_MASK); +} + +void us_ticker_set_interrupt(timestamp_t timestamp) { + int delta = (int)(timestamp - us_ticker_read()); + if (delta <= 0) { + // This event was in the past. + // Set the interrupt as pending, but don't process it here. + // This prevents a recurive loop under heavy load + // which can lead to a stack overflow. + NVIC_SetPendingIRQ(PIT3_IRQn); + return; + } + + PIT_StopTimer(PIT, kPIT_Chnl_3); + PIT_StopTimer(PIT, kPIT_Chnl_2); + PIT_SetTimerPeriod(PIT, kPIT_Chnl_3, (uint32_t)delta); + PIT_EnableInterrupts(PIT, kPIT_Chnl_3, kPIT_TimerInterruptEnable); + PIT_StartTimer(PIT, kPIT_Chnl_3); + PIT_StartTimer(PIT, kPIT_Chnl_2); +} diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/api/i2c_api.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/api/i2c_api.c index 84e38993d8e..a72fb8276f8 100644 --- a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/api/i2c_api.c +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/api/i2c_api.c @@ -170,10 +170,15 @@ int i2c_byte_read(i2c_t *obj, int last) { } int i2c_byte_write(i2c_t *obj, int data) { +#if FSL_I2C_DRIVER_VERSION > MAKE_VERSION(2, 0, 1) + if (I2C_MasterWriteBlocking(i2c_addrs[obj->instance], (uint8_t *)(&data), 1, kI2C_TransferNoStopFlag) == kStatus_Success) { + return 1; + } +#else if (I2C_MasterWriteBlocking(i2c_addrs[obj->instance], (uint8_t *)(&data), 1) == kStatus_Success) { return 1; } - +#endif return 0; } @@ -184,7 +189,11 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave) { I2C_SlaveGetDefaultConfig(&slave_config); slave_config.slaveAddress = 0; slave_config.enableSlave = (bool)enable_slave; +#if FSL_I2C_DRIVER_VERSION > MAKE_VERSION(2, 0, 1) + I2C_SlaveInit(i2c_addrs[obj->instance], &slave_config, CLOCK_GetFreq(i2c_clocks[obj->instance])); +#else I2C_SlaveInit(i2c_addrs[obj->instance], &slave_config); +#endif } int i2c_slave_receive(i2c_t *obj) { diff --git a/targets/TARGET_Freescale/mbed_rtx.h b/targets/TARGET_Freescale/mbed_rtx.h index 82c22cb8dfe..7a59d79d739 100644 --- a/targets/TARGET_Freescale/mbed_rtx.h +++ b/targets/TARGET_Freescale/mbed_rtx.h @@ -217,6 +217,21 @@ #define OS_CLOCK 48000000 #endif +#elif defined(TARGET_K82F) + +#ifndef INITIAL_SP +#define INITIAL_SP (0x20030000UL) +#endif +#ifndef OS_TASKCNT +#define OS_TASKCNT 14 +#endif +#ifndef OS_MAINSTKSIZE +#define OS_MAINSTKSIZE 256 +#endif +#ifndef OS_CLOCK +#define OS_CLOCK 120000000 +#endif + #endif #endif // MBED_MBED_RTX_H diff --git a/targets/targets.json b/targets/targets.json index c7ffd80cd09..de66b8ebba4 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -531,10 +531,10 @@ "macros": ["CPU_MKL82Z128VLK7", "FSL_RTOS_MBED"], "is_disk_virtual": true, "inherits": ["Target"], - "progen": {"target": "frdm-kl82z"}, "detect_code": ["0218"], "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SEMIHOST", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], - "release_versions": ["2", "5"] + "release_versions": ["2", "5"], + "device_name": "MKL82Z128xxx7" }, "KW24D": { "supported_form_factors": ["ARDUINO"], @@ -544,10 +544,10 @@ "is_disk_virtual": true, "macros": ["CPU_MKW24D512VHA5", "FSL_RTOS_MBED"], "inherits": ["Target"], - "progen": {"target": "frdm-kw24d"}, "detect_code": ["0250"], "device_has": ["ANALOGIN", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "TRNG"], - "release_versions": ["2", "5"] + "release_versions": ["2", "5"], + "device_name": "MKW24D512xxx5" }, "K64F": { "supported_form_factors": ["ARDUINO"], @@ -600,6 +600,19 @@ "release_versions": ["2", "5"], "device_name" : "MK66FN2M0xxx18" }, + "K82F": { + "supported_form_factors": ["ARDUINO"], + "core": "Cortex-M4F", + "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], + "extra_labels": ["Freescale", "KSDK2_MCUS", "FRDM"], + "is_disk_virtual": true, + "macros": ["CPU_MK82FN256VDC15", "FSL_RTOS_MBED"], + "inherits": ["Target"], + "detect_code": ["0217"], + "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "release_versions": ["2", "5"], + "device_name" : "MK66FN256xxx15" + }, "NUCLEO_F030R8": { "supported_form_factors": ["ARDUINO", "MORPHO"], "core": "Cortex-M0", From 6582aa4e2ad7931e0af0c5bb6402a280291d791e Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Mon, 31 Oct 2016 10:15:36 +0200 Subject: [PATCH 064/107] NanostackInterface: Check input address is IPv6 For the two calls that use the address - sendto and connect, check that it actually is an IPv6 address. --- .../nanostack-interface/NanostackInterface.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp index cbadf5462f9..f6a68b34b87 100644 --- a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp +++ b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp @@ -716,6 +716,10 @@ int NanostackInterface::socket_sendto(void *handle, const SocketAddress &address return NSAPI_ERROR_NO_SOCKET; } + if (address.get_ip_version() != NSAPI_IPv6) { + return NSAPI_ERROR_UNSUPPORTED; + } + nanostack_lock(); int ret; @@ -849,6 +853,10 @@ int NanostackInterface::socket_connect(void *handle, const SocketAddress &addr) return NSAPI_ERROR_NO_SOCKET; } + if (addr.get_ip_version() != NSAPI_IPv6) { + return NSAPI_ERROR_UNSUPPORTED; + } + nanostack_lock(); int ret; From cef0a8f5610d7f838d1eebdcc47906501ad157ff Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Mon, 31 Oct 2016 10:17:29 +0200 Subject: [PATCH 065/107] NanostackInterface: Allow binding to address These days Nanostack does let you bind to an address - permit this. (Remembering to check it is an IPv6 address). --- .../nanostack-interface/NanostackInterface.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp index f6a68b34b87..89f28d10417 100644 --- a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp +++ b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp @@ -809,12 +809,23 @@ int NanostackInterface::socket_bind(void *handle, const SocketAddress &address) return NSAPI_ERROR_NO_SOCKET; } + const void *addr_field; + switch (address.get_ip_version()) { + case NSAPI_IPv6: + addr_field = address.get_ip_bytes(); + break; + case NSAPI_UNSPEC: + addr_field = &ns_in6addr_any; + break; + default: + return NSAPI_ERROR_UNSUPPORTED; + } nanostack_lock(); ns_address_t ns_address; ns_address.type = ADDRESS_IPV6; - memset(ns_address.address, 0, sizeof ns_address.address); + memcpy(ns_address.address, addr_field, sizeof ns_address.address); ns_address.identifier = address.get_port(); int ret = NSAPI_ERROR_DEVICE_ERROR; if (0 == ::socket_bind(socket->socket_id, &ns_address)) { From df07f61f58185a43679f1ebcb5eb0fd92a723feb Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Mon, 31 Oct 2016 10:18:47 +0200 Subject: [PATCH 066/107] NanostackInterface: Remove string round-trips Older versions of SocketAddress required conversion via string - this is no longer the case. --- .../nanostack-interface/NanostackInterface.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp index 89f28d10417..835a655a9eb 100644 --- a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp +++ b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp @@ -28,7 +28,6 @@ #include "mesh_system.h" // from inside mbed-mesh-api #include "socket_api.h" #include "net_interface.h" -#include "ip6string.h" // Uncomment to enable trace //#define HAVE_DEBUG #include "ns_trace.h" @@ -126,16 +125,13 @@ static void convert_mbed_addr_to_ns(ns_address_t *ns_addr, { ns_addr->type = ADDRESS_IPV6; ns_addr->identifier = s_addr->get_port(); - const char *str = s_addr->get_ip_address(); - stoip6(str, strlen(str), ns_addr->address); + memcpy(ns_addr->address, s_addr->get_ip_bytes(), 16); } static void convert_ns_addr_to_mbed(SocketAddress *s_addr, const ns_address_t *ns_addr) { - char str[40]; - ip6tos(ns_addr->address, str); s_addr->set_port(ns_addr->identifier); - s_addr->set_ip_address(str); + s_addr->set_ip_bytes(ns_addr->address, NSAPI_IPv6); } void* NanostackSocket::operator new(std::size_t sz) { From 24016a1262003ac66391d873e684b639b1fe4bfe Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Mon, 31 Oct 2016 10:45:18 +0200 Subject: [PATCH 067/107] nsapi_dns: Provide 2 IPv6-hosted default servers Replace Comodo and OpenDNS IPv4 servers with Google and DNS.WATCH IPv6 servers, so IPv6-only devices (eg 6LoWPAN) have a default. 3 IPv4 resolvers should be plenty - existing code doesn't remember which one last worked, so if early list entries were unreachable performance would be consistently bad anyway. Replacing two entries avoids increasing image size and RAM consumption. On an IPv6-only or IPv4-only system, the sendto() for the wrong type of address should fail immediately - change loop to move on to the next server for any sendto() error. --- features/netsocket/nsapi_dns.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/features/netsocket/nsapi_dns.cpp b/features/netsocket/nsapi_dns.cpp index 118a71ae8f7..2b0bd0ea119 100644 --- a/features/netsocket/nsapi_dns.cpp +++ b/features/netsocket/nsapi_dns.cpp @@ -31,11 +31,13 @@ #define DNS_SERVERS_SIZE 5 nsapi_addr_t dns_servers[DNS_SERVERS_SIZE] = { - {NSAPI_IPv4, {8, 8, 8, 8}}, - {NSAPI_IPv4, {209, 244, 0, 3}}, - {NSAPI_IPv4, {84, 200, 69, 80}}, - {NSAPI_IPv4, {8, 26, 56, 26}}, - {NSAPI_IPv4, {208, 67, 222, 222}}, + {NSAPI_IPv4, {8, 8, 8, 8}}, // Google + {NSAPI_IPv4, {209, 244, 0, 3}}, // Level 3 + {NSAPI_IPv4, {84, 200, 69, 80}}, // DNS.WATCH + {NSAPI_IPv6, {0x20,0x01, 0x48,0x60, 0x48,0x60, 0,0, // Google + 0,0, 0,0, 0,0, 0x88,0x88}}, + {NSAPI_IPv6, {0x20,0x01, 0x16,0x08, 0,0x10, 0,0x25, // DNS.WATCH + 0,0, 0,0, 0x1c,0x04, 0xb1,0x2f}}, }; // DNS server configuration @@ -226,11 +228,9 @@ static int nsapi_dns_query_multiple(NetworkStack *stack, const char *host, dns_append_question(&question, host, version); err = socket.sendto(SocketAddress(dns_servers[i], 53), packet, DNS_BUFFER_SIZE); - if (err == NSAPI_ERROR_WOULD_BLOCK) { + // send may fail for various reasons, including wrong address type - move on + if (err < 0) { continue; - } else if (err < 0) { - result = err; - break; } // recv the response From 21307015fc1e4d5879651b0e2b16a4d68b0de7f0 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Mon, 31 Oct 2016 15:39:34 -0500 Subject: [PATCH 068/107] Fixing project.py -S printing problem Printing too large of a string can fail in Windows, as detailed here: https://bugs.python.org/issue11395. This works around the problem by adding a print_large_string function that breaks up the string into smaller pieces before printing it. --- tools/project.py | 3 ++- tools/utils.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tools/project.py b/tools/project.py index 3bd4f3a3a22..ad9e5ed209f 100644 --- a/tools/project.py +++ b/tools/project.py @@ -18,6 +18,7 @@ from tools.utils import argparse_filestring_type, argparse_many, args_error from tools.utils import argparse_force_lowercase_type from tools.utils import argparse_force_uppercase_type +from tools.utils import print_large_string from tools.project_api import export_project, get_exporter_toolchain from tools.options import extract_profile @@ -189,7 +190,7 @@ def main(): # Only prints matrix of supported IDEs if options.supported_ides: - print mcu_ide_matrix() + print_large_string(mcu_ide_matrix()) exit(0) # Only prints matrix of supported IDEs diff --git a/tools/utils.py b/tools/utils.py index 734dfae0e07..6ee32716137 100644 --- a/tools/utils.py +++ b/tools/utils.py @@ -24,6 +24,7 @@ from os.path import isdir, join, exists, split, relpath, splitext, abspath from os.path import commonprefix, normpath, dirname from subprocess import Popen, PIPE, STDOUT, call +from math import ceil import json from collections import OrderedDict import logging @@ -486,3 +487,23 @@ def parse_type(not_parent): else: return not_parent return parse_type + +def print_large_string(large_string): + """ Breaks a string up into smaller pieces before print them + + This is a limitation within Windows, as detailed here: + https://bugs.python.org/issue11395 + + Positional arguments: + large_string - the large string to print + """ + string_limit = 1000 + large_string_len = len(large_string) + num_parts = int(ceil(float(large_string_len) / float(string_limit))) + for string_part in range(num_parts): + start_index = string_part * string_limit + if string_part == num_parts - 1: + print large_string[start_index:] + else: + end_index = ((string_part + 1) * string_limit) - 1 + print large_string[start_index:end_index], From fe029510c99917844b4f40d56a09a1312f164cae Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Tue, 1 Nov 2016 15:38:59 -0500 Subject: [PATCH 069/107] Adding check to Travis for exporter support matrix --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index dd96d456a11..abd787a14ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ script: - python tools/test/pylint.py - py.test tools/test/toolchains/api.py - python tools/test/memap/memap_test.py + - python tools/project.py -S - python tools/build_travis.py before_install: - sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded @@ -16,9 +17,7 @@ before_install: - arm-none-eabi-gcc --version - python --version install: - - sudo pip install colorama - - sudo pip install prettytable - - sudo pip install jinja2 + - sudo pip install -r requirements.txt - sudo pip install pytest - sudo pip install pylint - sudo pip install hypothesis From 027f2b23ccb64829df86f9ec263469f80605e24a Mon Sep 17 00:00:00 2001 From: Sarah Marsh Date: Mon, 31 Oct 2016 16:00:15 -0500 Subject: [PATCH 070/107] New export-build tests. Allows command line workflow of: mbed import mbed export Also revises exporter supported target checks --- tools/export/cmsis/__init__.py | 46 ++++++------ tools/export/exporters.py | 7 -- tools/export/iar/__init__.py | 33 +++++---- tools/export/makefile/__init__.py | 37 +++++++++- tools/export/uvision/__init__.py | 50 ++++++------- tools/project.py | 4 +- tools/project_api.py | 1 - tools/test/examples/examples.py | 106 +++++++++++++++++++++++++++- tools/test/examples/examples_lib.py | 13 ++++ tools/test/export/build_test.py | 36 +++++----- 10 files changed, 235 insertions(+), 98 deletions(-) diff --git a/tools/export/cmsis/__init__.py b/tools/export/cmsis/__init__.py index 313c5e52c6c..68aff56a66b 100644 --- a/tools/export/cmsis/__init__.py +++ b/tools/export/cmsis/__init__.py @@ -31,10 +31,25 @@ class DeviceCMSIS(): Encapsulates target information retrieved by arm-pack-manager""" def __init__(self, target): - cache = Cache(True, False) + target_info = self.check_supported(target) + if not target_info: + raise TargetNotSupportedException("Target not supported in CMSIS pack") + self.url = target_info['pdsc_file'] + self.pack_url, self.pack_id = ntpath.split(self.url) + self.dname = target_info["_cpu_name"] + self.core = target_info["_core"] + self.dfpu = target_info['processor']['fpu'] + self.debug, self.dvendor = self.vendor_debug(target_info['vendor']) + self.dendian = target_info['processor'].get('endianness','Little-endian') + self.debug_svd = target_info.get('debug', '') + self.compile_header = target_info['compile']['header'] + self.target_info = target_info + + @staticmethod + def check_supported(target): + cache = Cache(True, False) t = TARGET_MAP[target] - self.core = t.core try: cpu_name = t.device_name target_info = cache.index[cpu_name] @@ -42,26 +57,13 @@ def __init__(self, target): except: try: # Try to find the core as a generic CMSIS target - cpu_name = self.cpu_cmsis() + cpu_name = DeviceCMSIS.cpu_cmsis(t.core) target_info = cache.index[cpu_name] except: - raise TargetNotSupportedException("Target not in CMSIS packs") - - self.target_info = target_info - - self.url = target_info['pdsc_file'] - self.pack_url, self.pack_id = ntpath.split(self.url) - self.dname = cpu_name - self.dfpu = target_info['processor']['fpu'] - self.debug, self.dvendor = self.vendor_debug(target_info['vendor']) - self.dendian = target_info['processor'].get('endianness','Little-endian') - self.debug_svd = target_info.get('debug', '') - self.compile_header = target_info['compile']['header'] - - def check_version(self, filename): - with open(filename) as data_file: - data = json.load(data_file) - return data.get("version", "0") == "0.1.0" + return False + target_info["_cpu_name"] = cpu_name + target_info["_core"] = t.core + return target_info def vendor_debug(self, vendor): reg = "([\w\s]+):?\d*?" @@ -74,9 +76,9 @@ def vendor_debug(self, vendor): } return debug_map.get(vendor_match, "CMSIS-DAP"), vendor_match - def cpu_cmsis(self): + @staticmethod + def cpu_cmsis(cpu): #Cortex-M4F => ARMCM4_FP, Cortex-M0+ => ARMCM0P - cpu = self.core cpu = cpu.replace("Cortex-","ARMC") cpu = cpu.replace("+","P") cpu = cpu.replace("F","_FP") diff --git a/tools/export/exporters.py b/tools/export/exporters.py index ba31064e587..ae7ad692ebc 100644 --- a/tools/export/exporters.py +++ b/tools/export/exporters.py @@ -119,13 +119,6 @@ def get_source_paths(self): source_files.extend(getattr(self.resources, key)) return list(set([os.path.dirname(src) for src in source_files])) - def check_supported(self): - """Indicated if this combination of IDE and MCU is supported""" - if self.target not in self.TARGETS or \ - self.TOOLCHAIN not in TARGET_MAP[self.target].supported_toolchains: - raise TargetNotSupportedException() - return True - def gen_file(self, template_file, data, target_file): """Generates a project file from a template using jinja""" jinja_loader = FileSystemLoader( diff --git a/tools/export/iar/__init__.py b/tools/export/iar/__init__.py index f595a3606f4..4b065ba8745 100644 --- a/tools/export/iar/__init__.py +++ b/tools/export/iar/__init__.py @@ -2,7 +2,7 @@ from os.path import sep, join, exists from collections import namedtuple from subprocess import Popen, PIPE -from distutils.spawn import find_executable +import shutil import re import sys @@ -29,7 +29,8 @@ class IAR(Exporter): #iar_definitions.json TARGETS = [target for target, obj in TARGET_MAP.iteritems() if hasattr(obj, 'device_name') and - obj.device_name in IAR_DEFS.keys()] + obj.device_name in IAR_DEFS.keys() and "IAR" in obj.supported_toolchains + and DeviceCMSIS.check_supported(target)] SPECIAL_TEMPLATES = { 'rz_a1h' : 'iar/iar_rz_a1h.ewp.tmpl', @@ -120,22 +121,13 @@ def generate(self): self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd") self.gen_file(self.get_ewp_template(), ctx, self.project_name + ".ewp") - def build(self): + @staticmethod + def build(project_name, clean=True): """ Build IAR project """ # > IarBuild [project_path] -build [project_name] - proj_file = join(self.export_dir, self.project_name + ".ewp") - if find_executable("IarBuild"): - iar_exe = "IarBuild.exe" - else: - iar_exe = join('C:', sep, - 'Program Files (x86)', 'IAR Systems', - 'Embedded Workbench 7.5', 'common', 'bin', - 'IarBuild.exe') - if not exists(iar_exe): - raise Exception("IarBuild.exe not found. Add to path.") - - cmd = [iar_exe, proj_file, '-build', self.project_name] + proj_file = project_name + ".ewp" + cmd = ["IarBuild.exe", proj_file, '-build', project_name] # IAR does not support a '0' option to automatically use all # available CPUs, so we use Python's multiprocessing library @@ -156,7 +148,14 @@ def build(self): m = re.match(error_re, line) if m is not None: num_errors = int(m.group(1)) + + if clean: + os.remove(project_name + ".ewp") + os.remove(project_name + ".ewd") + os.remove(project_name + ".eww") + shutil.rmtree('.build') + if num_errors !=0: # Seems like something went wrong. - raise FailedBuildException("Project: %s build failed with %s erros" % ( - proj_file, num_errors)) + return -1 + return 0 diff --git a/tools/export/makefile/__init__.py b/tools/export/makefile/__init__.py index 41030f54c28..46a4d626d38 100644 --- a/tools/export/makefile/__init__.py +++ b/tools/export/makefile/__init__.py @@ -16,7 +16,10 @@ """ from os.path import splitext, basename, relpath, join, abspath, dirname,\ exists -from os import curdir, getcwd +from os import remove +import sys +from subprocess import check_output, CalledProcessError, Popen, PIPE +import shutil from jinja2.exceptions import TemplateNotFound from tools.export.exporters import Exporter from tools.utils import NotSupportedException @@ -102,6 +105,38 @@ def generate(self): else: raise NotSupportedException("This make tool is in development") + @staticmethod + def build(project_name, build_log="build_log.txt", project_loc=None, clean=True): + """ Build Make project """ + # > Make -C [project directory] -j + cmd = ["make", "-j"] + p = Popen(cmd, stdout=PIPE, stderr=PIPE) + ret = p.communicate() + out, err = ret[0], ret[1] + ret_code = p.returncode + with open(build_log, 'w+') as f: + f.write("=" * 10 + "OUT" + "=" * 10 + "\n") + f.write(out) + f.write("=" * 10 + "ERR" + "=" * 10 + "\n") + f.write(err) + if ret_code == 0: + f.write("SUCCESS") + else: + f.write("FAILURE") + with open(build_log, 'r') as f: + print "\n".join(f.readlines()) + sys.stdout.flush() + + if clean: + remove("Makefile") + remove(build_log) + if exists('.build'): + shutil.rmtree('.build') + if ret_code != 0: + # Seems like something went wrong. + return -1 + return 0 + class GccArm(Makefile): """GCC ARM specific makefile target""" diff --git a/tools/export/uvision/__init__.py b/tools/export/uvision/__init__.py index a50a5665eb2..2de2f333262 100644 --- a/tools/export/uvision/__init__.py +++ b/tools/export/uvision/__init__.py @@ -3,7 +3,7 @@ import ntpath import copy from collections import namedtuple -from distutils.spawn import find_executable +import shutil import subprocess import re @@ -117,10 +117,15 @@ class Uvision(Exporter): project file (.uvprojx). The needed information can be viewed in uvision.tmpl """ - NAME = 'cmsis' + NAME = 'uvision5' TOOLCHAIN = 'ARM' - TARGETS = [target for target, obj in TARGET_MAP.iteritems() - if "ARM" in obj.supported_toolchains] + TARGETS = [] + for target, obj in TARGET_MAP.iteritems(): + if not ("ARM" in obj.supported_toolchains and hasattr(obj, "device_name")): + continue + if not DeviceCMSIS.check_supported(target): + continue + TARGETS.append(target) #File associations within .uvprojx file file_types = {'.cpp': 8, '.c': 1, '.s': 2, '.obj': 3, '.o': 3, '.lib': 4, @@ -200,35 +205,22 @@ def generate(self): self.gen_file('uvision/uvision.tmpl', ctx, self.project_name+".uvprojx") self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx") - def build(self): - ERRORLEVEL = { - 0: 'success (0 warnings, 0 errors)', - 1: 'warnings', - 2: 'errors', - 3: 'fatal errors', - 11: 'cant write to project file', - 12: 'device error', - 13: 'error writing', - 15: 'error reading xml file', - } + @staticmethod + def build(project_name, log_name='build_log.txt', clean=True): success = 0 warn = 1 - if find_executable("UV4"): - uv_exe = "UV4.exe" - else: - uv_exe = join('C:', sep, - 'Keil_v5', 'UV4', 'UV4.exe') - if not exists(uv_exe): - raise Exception("UV4.exe not found. Add to path.") - cmd = [uv_exe, '-r', '-j0', '-o', join(self.export_dir,'build_log.txt'), join(self.export_dir,self.project_name+".uvprojx")] + cmd = ["UV4.exe", '-r', '-j0', '-o', log_name, project_name+".uvprojx"] ret_code = subprocess.call(cmd) - with open(join(self.export_dir, 'build_log.txt'), 'r') as build_log: + with open(log_name, 'r') as build_log: print build_log.read() + if clean: + os.remove(log_name) + os.remove(project_name+".uvprojx") + os.remove(project_name+".uvoptx") + shutil.rmtree(".build") + if ret_code != success and ret_code != warn: # Seems like something went wrong. - raise FailedBuildException("Project: %s build failed with the status: %s" % ( - self.project_name, ERRORLEVEL.get(ret_code, "Unknown"))) - else: - return "Project: %s build succeeded with the status: %s" % ( - self.project_name, ERRORLEVEL.get(ret_code, "Unknown")) + return -1 + return 0 diff --git a/tools/project.py b/tools/project.py index ad9e5ed209f..1e51ceccfd7 100644 --- a/tools/project.py +++ b/tools/project.py @@ -233,7 +233,9 @@ def main(): if (options.program is None) and (not options.source_dir): args_error(parser, "one of -p, -n, or --source is required") # Export to selected toolchain - _, toolchain_name = get_exporter_toolchain(options.ide) + exporter, toolchain_name = get_exporter_toolchain(options.ide) + if options.mcu not in exporter.TARGETS: + args_error(parser, "%s not supported by %s") profile = extract_profile(parser, options, toolchain_name) export(options.mcu, options.ide, build=options.build, src=options.source_dir, macros=options.macros, diff --git a/tools/project_api.py b/tools/project_api.py index d735b36ec97..dc5871f217f 100644 --- a/tools/project_api.py +++ b/tools/project_api.py @@ -86,7 +86,6 @@ def generate_project_files(resources, export_path, target, name, toolchain, ide, exporter_cls, _ = get_exporter_toolchain(ide) exporter = exporter_cls(target, export_path, name, toolchain, extra_symbols=macros, resources=resources) - exporter.check_supported() exporter.generate() files = exporter.generated_files return files, exporter diff --git a/tools/test/examples/examples.py b/tools/test/examples/examples.py index fecadef4567..a69f4a746dd 100644 --- a/tools/test/examples/examples.py +++ b/tools/test/examples/examples.py @@ -14,6 +14,62 @@ from tools.utils import argparse_force_uppercase_type import examples_lib as lib from examples_lib import SUPPORTED_TOOLCHAINS +from tools.export import EXPORTERS +from tools.build_api import get_mbed_official_release +from tools.targets import TARGET_MAP + +EXAMPLES = json.load(open(os.path.join(os.path.dirname(__file__), + "examples.json"))) + +def print_stuff(name, lst): + if lst: + print("#"*80) + print("# {} example combinations".format(name)) + print("#") + for thing in lst: + print(thing) + + +SUPPORTED_TOOLCHAINS = ["ARM", "IAR", "GCC_ARM"] +SUPPORTED_IDES = ["iar", "uvision", "make_gcc_arm", "make_iar", "make_armc5"] + + +def target_cross_toolchain(allowed_toolchains, + features=[], targets=TARGET_MAP.keys(), + toolchains=SUPPORTED_TOOLCHAINS): + """Generate pairs of target and toolchains + + Args: + allowed_toolchains - a list of all possible toolchains + + Kwargs: + features - the features that must be in the features array of a + target + targets - a list of available targets + toolchains - a list of available toolchains + """ + for release_target, release_toolchains in get_mbed_official_release("5"): + for toolchain in release_toolchains: + if (toolchain in allowed_toolchains and + toolchain in toolchains and + release_target in targets and + all(feature in TARGET_MAP[release_target].features + for feature in features)): + yield release_target, toolchain + + +def target_cross_ide(allowed_ides, + targets=TARGET_MAP.keys()): + """Generate pairs of target and ides + + Args: + allowed_ides - a list of all possible IDEs + + """ + for release_target, release_toolchains in get_mbed_official_release("5"): + for ide in allowed_ides: + if release_target in EXPORTERS[ide].TARGETS: + yield release_target, ide def main(): @@ -27,17 +83,61 @@ def main(): version_cmd.add_argument("tag") version_cmd.set_defaults(fn=do_versionning) compile_cmd = subparsers.add_parser("compile") - compile_cmd.set_defaults(fn=do_compile) + compile_cmd.set_defaults(fn=do_compile), compile_cmd.add_argument( "toolchains", nargs="*", default=SUPPORTED_TOOLCHAINS, type=argparse_force_uppercase_type(SUPPORTED_TOOLCHAINS, - "toolchain")) + "toolchain")), + export_cmd = subparsers.add_parser("export") + export_cmd.set_defaults(fn=do_export), + export_cmd.add_argument( + "ide", nargs="*", default=SUPPORTED_IDES, + type=argparse_force_uppercase_type(SUPPORTED_IDES, + "ide")) args = parser.parse_args() config = json.load(open(os.path.join(os.path.dirname(__file__), args.config))) - return args.fn(args, config) + +def do_export(args): + + def print_message(message, name): + print(message+ " %s"%name) + sys.stdout.flush() + + export_failures = [] + build_failures = [] + sucesses = [] + for example, requirements in EXAMPLES.iteritems(): + ex_name = basename(example) + if ex_name != "mbed-os-example-blinky": + continue + os.chdir(ex_name) + for target, ide in target_cross_ide(args.ide): + example_name = "{} {} {}".format(ex_name, target, + ide) + print_message("Export:",example_name) + proc = subprocess.Popen(["mbed-cli", "export", "-i", ide, + "-m", target]) + proc.wait() + if proc.returncode: + export_failures.append(example_name) + print_message("FAILURE Export:", example_name) + else: + print_message("SUCCESS Export:", example_name) + print_message("Build:", example_name) + if EXPORTERS[ide].build(ex_name): + print_message("FAILURE Build:", example_name) + build_failures.append(example_name) + else: + print_message("SUCCESS Build:", example_name) + sucesses.append(example_name) + print_stuff("Passed", sucesses) + print_stuff("Failed Export", export_failures) + print_stuff("Failed Building", build_failures) + return len(export_failures+build_failures) + def do_import(_, config): """Do the import step of this process""" diff --git a/tools/test/examples/examples_lib.py b/tools/test/examples/examples_lib.py index ec34c416df9..110216e580d 100644 --- a/tools/test/examples/examples_lib.py +++ b/tools/test/examples/examples_lib.py @@ -81,6 +81,19 @@ def target_cross_toolchain(allowed_toolchains, for feature in features)): yield target, toolchain +def target_cross_ide(allowed_ides, + targets=TARGET_MAP.keys()): + """Generate pairs of target and ides + + Args: + allowed_ides - a list of all possible IDEs + + """ + for release_target, release_toolchains in get_mbed_official_release("5"): + for ide in allowed_ides: + if release_target in EXPORTERS[ide].TARGETS: + yield release_target, ide + def get_repo_list(example): """ Returns a list of all the repos associated with the specific example in the json diff --git a/tools/test/export/build_test.py b/tools/test/export/build_test.py index f03f360d6b2..d467018a43a 100644 --- a/tools/test/export/build_test.py +++ b/tools/test/export/build_test.py @@ -22,6 +22,7 @@ ROOT = abspath(join(dirname(__file__), "..", "..", "..")) sys.path.insert(0, ROOT) import argparse +import os from argparse import ArgumentTypeError import sys from shutil import rmtree @@ -37,9 +38,8 @@ from Queue import Queue from threading import Thread, Lock from tools.project_api import print_results, get_exporter_toolchain -from tools.tests import test_name_known, test_known, Test -from tools.export.exporters import FailedBuildException, \ - TargetNotSupportedException +from tools.tests import test_name_known, test_known +from tools.export import EXPORTERS from tools.utils import argparse_force_lowercase_type, \ argparse_many, columnate, args_error, \ argparse_filestring_type @@ -125,9 +125,12 @@ def batch_tests(self, clean=False): % (test_case.mcu, test_case.ide, test_case.name)) - try: - exporter.build() - except FailedBuildException: + + cwd = os.getcwd() + os.chdir(exporter.export_dir) + res = EXPORTERS[exporter.NAME.lower()].build(exporter.project_name, clean=False) + os.chdir(cwd) + if res: self.failures.append("%s::%s\t%s" % (test_case.mcu, test_case.ide, test_case.name)) @@ -157,20 +160,19 @@ def perform_exports(self, test_case): self.display_counter("Exporting test case %s::%s\t%s" % (test_case.mcu, test_case.ide, test_case.name)) - - try: - _, toolchain = get_exporter_toolchain(test_case.ide) - profile = extract_profile(self.parser, self.options, toolchain) - exporter = export(test_case.mcu, test_case.ide, + exporter, toolchain = get_exporter_toolchain(test_case.ide) + if test_case.mcu not in exporter.TARGETS: + self.skips.append("%s::%s\t%s" % (test_case.mcu, test_case.ide, + test_case.name)) + return + profile = extract_profile(self.parser, self.options, toolchain) + exporter = export(test_case.mcu, test_case.ide, project_id=test_case.id, zip_proj=None, clean=True, src=test_case.src, export_path=join(EXPORT_DIR,name_str), silent=True, build_profile=profile) - exporter.generated_files.append(join(EXPORT_DIR,name_str,test_case.log)) - self.build_queue.put((exporter,test_case)) - except TargetNotSupportedException: - self.skips.append("%s::%s\t%s" % (test_case.mcu, test_case.ide, - test_case.name)) + exporter.generated_files.append(join(EXPORT_DIR,name_str,test_case.log)) + self.build_queue.put((exporter,test_case)) # Check if the specified name is in all_os_tests @@ -265,7 +267,7 @@ def main(): test_targets = options.mcu or targetnames if not all([t in targetnames for t in test_targets]): args_error(parser, "Only specify targets in release %s:\n%s" - %(options.release, columnate(targetnames))) + %(options.release, columnate(sorted(targetnames)))) v2_tests, v5_tests = [],[] if options.release == '5': From 5e4289aef06afa357b0cd1941837cbe4027be4ce Mon Sep 17 00:00:00 2001 From: Sarah Marsh Date: Mon, 31 Oct 2016 16:47:27 -0500 Subject: [PATCH 071/107] changing variable names and respecting requirement kwargs --- tools/export/iar/__init__.py | 4 ++-- tools/export/makefile/__init__.py | 10 +++++----- tools/export/uvision/__init__.py | 4 ++-- tools/test/examples/examples.py | 15 +++++++++++---- tools/test/export/build_test.py | 2 +- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/tools/export/iar/__init__.py b/tools/export/iar/__init__.py index 4b065ba8745..6e63016d300 100644 --- a/tools/export/iar/__init__.py +++ b/tools/export/iar/__init__.py @@ -122,7 +122,7 @@ def generate(self): self.gen_file(self.get_ewp_template(), ctx, self.project_name + ".ewp") @staticmethod - def build(project_name, clean=True): + def build(project_name, cleanup=True): """ Build IAR project """ # > IarBuild [project_path] -build [project_name] @@ -149,7 +149,7 @@ def build(project_name, clean=True): if m is not None: num_errors = int(m.group(1)) - if clean: + if cleanup: os.remove(project_name + ".ewp") os.remove(project_name + ".ewd") os.remove(project_name + ".eww") diff --git a/tools/export/makefile/__init__.py b/tools/export/makefile/__init__.py index 46a4d626d38..8c342a7b845 100644 --- a/tools/export/makefile/__init__.py +++ b/tools/export/makefile/__init__.py @@ -106,7 +106,7 @@ def generate(self): raise NotSupportedException("This make tool is in development") @staticmethod - def build(project_name, build_log="build_log.txt", project_loc=None, clean=True): + def build(project_name, log_name="build_log.txt", cleanup=True): """ Build Make project """ # > Make -C [project directory] -j cmd = ["make", "-j"] @@ -114,7 +114,7 @@ def build(project_name, build_log="build_log.txt", project_loc=None, clean=True) ret = p.communicate() out, err = ret[0], ret[1] ret_code = p.returncode - with open(build_log, 'w+') as f: + with open(log_name, 'w+') as f: f.write("=" * 10 + "OUT" + "=" * 10 + "\n") f.write(out) f.write("=" * 10 + "ERR" + "=" * 10 + "\n") @@ -123,13 +123,13 @@ def build(project_name, build_log="build_log.txt", project_loc=None, clean=True) f.write("SUCCESS") else: f.write("FAILURE") - with open(build_log, 'r') as f: + with open(log_name, 'r') as f: print "\n".join(f.readlines()) sys.stdout.flush() - if clean: + if cleanup: remove("Makefile") - remove(build_log) + remove(log_name) if exists('.build'): shutil.rmtree('.build') if ret_code != 0: diff --git a/tools/export/uvision/__init__.py b/tools/export/uvision/__init__.py index 2de2f333262..ab0cb33b5fe 100644 --- a/tools/export/uvision/__init__.py +++ b/tools/export/uvision/__init__.py @@ -206,14 +206,14 @@ def generate(self): self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx") @staticmethod - def build(project_name, log_name='build_log.txt', clean=True): + def build(project_name, log_name='build_log.txt', cleanup=True): success = 0 warn = 1 cmd = ["UV4.exe", '-r', '-j0', '-o', log_name, project_name+".uvprojx"] ret_code = subprocess.call(cmd) with open(log_name, 'r') as build_log: print build_log.read() - if clean: + if cleanup: os.remove(log_name) os.remove(project_name+".uvprojx") os.remove(project_name+".uvoptx") diff --git a/tools/test/examples/examples.py b/tools/test/examples/examples.py index a69f4a746dd..56dabfada4e 100644 --- a/tools/test/examples/examples.py +++ b/tools/test/examples/examples.py @@ -59,7 +59,9 @@ def target_cross_toolchain(allowed_toolchains, def target_cross_ide(allowed_ides, - targets=TARGET_MAP.keys()): + features=[], + ides=SUPPORTED_IDES, + toolchains=SUPPORTED_TOOLCHAINS): """Generate pairs of target and ides Args: @@ -68,7 +70,11 @@ def target_cross_ide(allowed_ides, """ for release_target, release_toolchains in get_mbed_official_release("5"): for ide in allowed_ides: - if release_target in EXPORTERS[ide].TARGETS: + if (release_target in EXPORTERS[ide].TARGETS and + EXPORTERS[ide].TOOLCHAIN in toolchains and + ide in ides and + all(feature in TARGET_MAP[release_target].features + for feature in features)): yield release_target, ide @@ -101,7 +107,7 @@ def main(): def do_export(args): - + """Do export and build step""" def print_message(message, name): print(message+ " %s"%name) sys.stdout.flush() @@ -114,7 +120,8 @@ def print_message(message, name): if ex_name != "mbed-os-example-blinky": continue os.chdir(ex_name) - for target, ide in target_cross_ide(args.ide): + for target, ide in target_cross_ide(args.ide, + **requirements): example_name = "{} {} {}".format(ex_name, target, ide) print_message("Export:",example_name) diff --git a/tools/test/export/build_test.py b/tools/test/export/build_test.py index d467018a43a..eadf0cf4a22 100644 --- a/tools/test/export/build_test.py +++ b/tools/test/export/build_test.py @@ -128,7 +128,7 @@ def batch_tests(self, clean=False): cwd = os.getcwd() os.chdir(exporter.export_dir) - res = EXPORTERS[exporter.NAME.lower()].build(exporter.project_name, clean=False) + res = EXPORTERS[exporter.NAME.lower()].build(exporter.project_name, cleanup=False) os.chdir(cwd) if res: self.failures.append("%s::%s\t%s" % (test_case.mcu, From 718d0c01856498d8d047f760bb2fd3b434fe97fb Mon Sep 17 00:00:00 2001 From: Sarah Marsh Date: Mon, 31 Oct 2016 17:42:36 -0500 Subject: [PATCH 072/107] Make ArmPackManager cache a static variable (to avoid reading index.json for each target). --- tools/export/cmsis/__init__.py | 6 +++--- tools/project.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/export/cmsis/__init__.py b/tools/export/cmsis/__init__.py index 68aff56a66b..48d526ca9ef 100644 --- a/tools/export/cmsis/__init__.py +++ b/tools/export/cmsis/__init__.py @@ -30,6 +30,7 @@ class DeviceCMSIS(): """CMSIS Device class Encapsulates target information retrieved by arm-pack-manager""" + cache = Cache(True, False) def __init__(self, target): target_info = self.check_supported(target) if not target_info: @@ -48,17 +49,16 @@ def __init__(self, target): @staticmethod def check_supported(target): - cache = Cache(True, False) t = TARGET_MAP[target] try: cpu_name = t.device_name - target_info = cache.index[cpu_name] + target_info = DeviceCMSIS.cache.index[cpu_name] # Target does not have device name or pdsc file except: try: # Try to find the core as a generic CMSIS target cpu_name = DeviceCMSIS.cpu_cmsis(t.core) - target_info = cache.index[cpu_name] + target_info = DeviceCMSIS.index[cpu_name] except: return False target_info["_cpu_name"] = cpu_name diff --git a/tools/project.py b/tools/project.py index 1e51ceccfd7..feb642b51b1 100644 --- a/tools/project.py +++ b/tools/project.py @@ -235,7 +235,7 @@ def main(): # Export to selected toolchain exporter, toolchain_name = get_exporter_toolchain(options.ide) if options.mcu not in exporter.TARGETS: - args_error(parser, "%s not supported by %s") + args_error(parser, "%s not supported by %s"%(options.mcu,options.ide)) profile = extract_profile(parser, options, toolchain_name) export(options.mcu, options.ide, build=options.build, src=options.source_dir, macros=options.macros, From 21ac2431b826b2ff946afa8dabd69e2f90269405 Mon Sep 17 00:00:00 2001 From: Sarah Marsh Date: Tue, 1 Nov 2016 11:18:40 -0500 Subject: [PATCH 073/107] Build method documentation. Removal of unused Exception classes. --- tools/export/__init__.py | 1 - tools/export/cmsis/__init__.py | 5 +++-- tools/export/exporters.py | 34 +++++++++++++++++++++---------- tools/export/iar/__init__.py | 2 +- tools/export/makefile/__init__.py | 2 +- tools/export/uvision/__init__.py | 4 +++- 6 files changed, 31 insertions(+), 17 deletions(-) diff --git a/tools/export/__init__.py b/tools/export/__init__.py index 4f7ba95dc8b..d419077451c 100644 --- a/tools/export/__init__.py +++ b/tools/export/__init__.py @@ -18,7 +18,6 @@ from tools.export import codered, ds5_5, iar, makefile from tools.export import emblocks, coide, kds, simplicityv3, atmelstudio from tools.export import sw4stm32, e2studio, zip, cmsis, uvision, cdt -from tools.export.exporters import OldLibrariesException, FailedBuildException from tools.targets import TARGET_NAMES EXPORTERS = { diff --git a/tools/export/cmsis/__init__.py b/tools/export/cmsis/__init__.py index 48d526ca9ef..b953227f5a0 100644 --- a/tools/export/cmsis/__init__.py +++ b/tools/export/cmsis/__init__.py @@ -30,7 +30,8 @@ class DeviceCMSIS(): """CMSIS Device class Encapsulates target information retrieved by arm-pack-manager""" - cache = Cache(True, False) + + CACHE = Cache(True, False) def __init__(self, target): target_info = self.check_supported(target) if not target_info: @@ -52,7 +53,7 @@ def check_supported(target): t = TARGET_MAP[target] try: cpu_name = t.device_name - target_info = DeviceCMSIS.cache.index[cpu_name] + target_info = DeviceCMSIS.CACHE.index[cpu_name] # Target does not have device name or pdsc file except: try: diff --git a/tools/export/exporters.py b/tools/export/exporters.py index ae7ad692ebc..439d4697f68 100644 --- a/tools/export/exporters.py +++ b/tools/export/exporters.py @@ -11,16 +11,6 @@ from tools.targets import TARGET_MAP -class OldLibrariesException(Exception): - """Exception that indicates an export can not complete due to an out of date - library version. - """ - pass - -class FailedBuildException(Exception): - """Exception that indicates that a build failed""" - pass - class TargetNotSupportedException(Exception): """Indicates that an IDE does not support a particular MCU""" pass @@ -146,9 +136,31 @@ def make_key(self, src): def group_project_files(self, sources): """Group the source files by their encompassing directory Positional Arguments: - sources - array of sourc locations + sources - array of source locations Returns a dictionary of {group name: list of source locations} """ data = sorted(sources, key=self.make_key) return {k: list(g) for k,g in groupby(data, self.make_key)} + + @staticmethod + def build(project_name, log_name='build_log.txt', cleanup=True): + """Invoke exporters build command within a subprocess. + This method is assumed to be executed at the same level as exporter + project files and project source code. + See uvision/__init__.py, iar/__init__.py, and makefile/__init__.py for + example implemenation. + + Positional Arguments: + project_name - the name of the project to build; often required by + exporter's build command. + + Keyword Args: + log_name - name of the build log to create. Written and printed out, + deleted if cleanup = True + cleanup - a boolean dictating whether exported project files and + build log are removed after build + + Returns -1 on failure and 0 on success + """ + raise NotImplemented("Implement in derived Exporter class.") diff --git a/tools/export/iar/__init__.py b/tools/export/iar/__init__.py index 6e63016d300..d9b92db4f3e 100644 --- a/tools/export/iar/__init__.py +++ b/tools/export/iar/__init__.py @@ -7,7 +7,7 @@ import sys from tools.targets import TARGET_MAP -from tools.export.exporters import Exporter, FailedBuildException +from tools.export.exporters import Exporter import json from tools.export.cmsis import DeviceCMSIS from multiprocessing import cpu_count diff --git a/tools/export/makefile/__init__.py b/tools/export/makefile/__init__.py index 8c342a7b845..cf67940bae5 100644 --- a/tools/export/makefile/__init__.py +++ b/tools/export/makefile/__init__.py @@ -108,7 +108,7 @@ def generate(self): @staticmethod def build(project_name, log_name="build_log.txt", cleanup=True): """ Build Make project """ - # > Make -C [project directory] -j + # > Make -j cmd = ["make", "-j"] p = Popen(cmd, stdout=PIPE, stderr=PIPE) ret = p.communicate() diff --git a/tools/export/uvision/__init__.py b/tools/export/uvision/__init__.py index ab0cb33b5fe..14eedbc637b 100644 --- a/tools/export/uvision/__init__.py +++ b/tools/export/uvision/__init__.py @@ -9,7 +9,7 @@ from tools.arm_pack_manager import Cache from tools.targets import TARGET_MAP -from tools.export.exporters import Exporter, FailedBuildException +from tools.export.exporters import Exporter from tools.export.cmsis import DeviceCMSIS cache_d = False @@ -207,6 +207,8 @@ def generate(self): @staticmethod def build(project_name, log_name='build_log.txt', cleanup=True): + """ Build Uvision project """ + # > UV4.exe -r -j0 -o [log_name] [project_name].uvprojx success = 0 warn = 1 cmd = ["UV4.exe", '-r', '-j0', '-o', log_name, project_name+".uvprojx"] From 96259cdfb60c0d7877245f6770051a3817036b52 Mon Sep 17 00:00:00 2001 From: Sarah Marsh Date: Tue, 1 Nov 2016 15:46:51 -0500 Subject: [PATCH 074/107] Add boolean 'export' to examples.json. This will determine whether the example should be exported. Additionally, relocated export logic to examples_lib.py. --- tools/test/examples/examples.json | 16 ++++ tools/test/examples/examples.py | 109 +++------------------------- tools/test/examples/examples_lib.py | 108 ++++++++++++++++++++++++--- 3 files changed, 123 insertions(+), 110 deletions(-) diff --git a/tools/test/examples/examples.json b/tools/test/examples/examples.json index 538017318a3..3787e9c8919 100644 --- a/tools/test/examples/examples.json +++ b/tools/test/examples/examples.json @@ -9,7 +9,9 @@ "features" : [], "targets" : [], "toolchains" : [], + "exporters": [], "compile" : true, + "export": true, "auto-update" : true }, { @@ -24,7 +26,9 @@ "features" : [], "targets" : ["K64F", "NUCLEO_F429ZI"], "toolchains" : ["GCC_ARM", "ARM"], + "exporters": [], "compile" : true, + "export": false, "auto-update" : true }, { @@ -36,7 +40,9 @@ "features" : ["IPV6"], "targets" : [], "toolchains" : [], + "exporters": [], "compile" : true, + "export": false, "auto-update" : true }, { @@ -57,7 +63,9 @@ "features" : ["BLE"], "targets" : ["NRF51_DK", "NRF52_DK", "K64F", "NUCLEO_F401RE"], "toolchains" : [], + "exporters": [], "compile" : true, + "export": false, "auto-update" : true }, { @@ -69,7 +77,9 @@ "features" : ["IPV6"], "targets" : [], "toolchains" : [], + "exporters": [], "compile" : true, + "export": false, "auto-update" : true }, { @@ -80,7 +90,9 @@ "features" : ["IPV6"], "targets" : [], "toolchains" : [], + "exporters": [], "compile" : true, + "export": false, "auto-update" : true }, { @@ -91,7 +103,9 @@ "features" : [], "targets" : [], "toolchains" : [], + "exporters": [], "compile" : false, + "export": false, "auto-update" : true }, { @@ -102,7 +116,9 @@ "features" : [], "targets" : ["K64F"], "toolchains" : ["GCC_ARM"], + "exporters": [], "compile" : true, + "export": false, "auto-update" : false } ] diff --git a/tools/test/examples/examples.py b/tools/test/examples/examples.py index 56dabfada4e..06c2f65999d 100644 --- a/tools/test/examples/examples.py +++ b/tools/test/examples/examples.py @@ -13,70 +13,11 @@ from tools.utils import argparse_force_uppercase_type import examples_lib as lib -from examples_lib import SUPPORTED_TOOLCHAINS -from tools.export import EXPORTERS -from tools.build_api import get_mbed_official_release -from tools.targets import TARGET_MAP +from examples_lib import SUPPORTED_TOOLCHAINS, SUPPORTED_IDES EXAMPLES = json.load(open(os.path.join(os.path.dirname(__file__), "examples.json"))) -def print_stuff(name, lst): - if lst: - print("#"*80) - print("# {} example combinations".format(name)) - print("#") - for thing in lst: - print(thing) - - -SUPPORTED_TOOLCHAINS = ["ARM", "IAR", "GCC_ARM"] -SUPPORTED_IDES = ["iar", "uvision", "make_gcc_arm", "make_iar", "make_armc5"] - - -def target_cross_toolchain(allowed_toolchains, - features=[], targets=TARGET_MAP.keys(), - toolchains=SUPPORTED_TOOLCHAINS): - """Generate pairs of target and toolchains - - Args: - allowed_toolchains - a list of all possible toolchains - - Kwargs: - features - the features that must be in the features array of a - target - targets - a list of available targets - toolchains - a list of available toolchains - """ - for release_target, release_toolchains in get_mbed_official_release("5"): - for toolchain in release_toolchains: - if (toolchain in allowed_toolchains and - toolchain in toolchains and - release_target in targets and - all(feature in TARGET_MAP[release_target].features - for feature in features)): - yield release_target, toolchain - - -def target_cross_ide(allowed_ides, - features=[], - ides=SUPPORTED_IDES, - toolchains=SUPPORTED_TOOLCHAINS): - """Generate pairs of target and ides - - Args: - allowed_ides - a list of all possible IDEs - - """ - for release_target, release_toolchains in get_mbed_official_release("5"): - for ide in allowed_ides: - if (release_target in EXPORTERS[ide].TARGETS and - EXPORTERS[ide].TOOLCHAIN in toolchains and - ide in ides and - all(feature in TARGET_MAP[release_target].features - for feature in features)): - yield release_target, ide - def main(): """Entry point""" @@ -106,57 +47,29 @@ def main(): return args.fn(args, config) -def do_export(args): +def do_export(args, config): """Do export and build step""" - def print_message(message, name): - print(message+ " %s"%name) - sys.stdout.flush() + results = {} + results = lib.export_repos(config, args.ide) + + lib.print_summary(results, export=True) + failures = lib.get_num_failures(results, export=True) + print("Number of failures = %d" % failures) + return failures - export_failures = [] - build_failures = [] - sucesses = [] - for example, requirements in EXAMPLES.iteritems(): - ex_name = basename(example) - if ex_name != "mbed-os-example-blinky": - continue - os.chdir(ex_name) - for target, ide in target_cross_ide(args.ide, - **requirements): - example_name = "{} {} {}".format(ex_name, target, - ide) - print_message("Export:",example_name) - proc = subprocess.Popen(["mbed-cli", "export", "-i", ide, - "-m", target]) - proc.wait() - if proc.returncode: - export_failures.append(example_name) - print_message("FAILURE Export:", example_name) - else: - print_message("SUCCESS Export:", example_name) - print_message("Build:", example_name) - if EXPORTERS[ide].build(ex_name): - print_message("FAILURE Build:", example_name) - build_failures.append(example_name) - else: - print_message("SUCCESS Build:", example_name) - sucesses.append(example_name) - print_stuff("Passed", sucesses) - print_stuff("Failed Export", export_failures) - print_stuff("Failed Building", build_failures) - return len(export_failures+build_failures) - def do_import(_, config): """Do the import step of this process""" lib.source_repos(config) return 0 + def do_compile(args, config): """Do the compile step""" results = {} results = lib.compile_repos(config, args.toolchains) - lib.print_compilation_summary(results) + lib.print_summary(results) failures = lib.get_num_failures(results) print("Number of failures = %d" % failures) return failures diff --git a/tools/test/examples/examples_lib.py b/tools/test/examples/examples_lib.py index 110216e580d..68b839f66d6 100644 --- a/tools/test/examples/examples_lib.py +++ b/tools/test/examples/examples_lib.py @@ -16,8 +16,10 @@ from tools.build_api import get_mbed_official_release from tools.targets import TARGET_MAP +from tools.export import EXPORTERS SUPPORTED_TOOLCHAINS = ["ARM", "IAR", "GCC_ARM"] +SUPPORTED_IDES = ["iar", "uvision", "make_gcc_arm", "make_iar", "make_armc5"] def print_list(lst): """Prints to screen the contents of a list @@ -30,13 +32,13 @@ def print_list(lst): for thing in lst: print("# %s" % thing) -def print_compilation_summary(results): - """Prints to screen the results of compiling combinations of example programs, - targets and compile chains. +def print_summary(results, export=False): + """Prints to screen the results of compiling/exporting combinations of example programs, + targets and compile toolchains/IDEs. Args: - results - results of the compilation stage. See compile_repos() for - details of the format. + results - results of the compilation stage. See compile_repos() and export_repos() + for details of the format. """ @@ -48,12 +50,23 @@ def print_compilation_summary(results): print("#") for key, val in results.iteritems(): print_list(val[2]) + + second_result = "Failed example combinations" if not export else \ + "Failed export example combinations" print("#") - print("# Failed example combinations") + print("# %s"%second_result) print("#") for key, val in results.iteritems(): print_list(val[3]) + + if export: + print("#") + print("# Failed build example combinations") + print("#") + for key, val in results.iteritems(): + print_list(val[4]) + print("#") print("#"*80) @@ -81,18 +94,30 @@ def target_cross_toolchain(allowed_toolchains, for feature in features)): yield target, toolchain + def target_cross_ide(allowed_ides, - targets=TARGET_MAP.keys()): + features=[], targets=[]): """Generate pairs of target and ides Args: allowed_ides - a list of all possible IDEs + Kwargs: + features - the features that must be in the features array of a + target + targets - a list of available targets """ - for release_target, release_toolchains in get_mbed_official_release("5"): + if len(targets) == 0: + targets=TARGET_MAP.keys() + + for target, toolchains in get_mbed_official_release("5"): for ide in allowed_ides: - if release_target in EXPORTERS[ide].TARGETS: - yield release_target, ide + if (EXPORTERS[ide].TOOLCHAIN in toolchains and + target in EXPORTERS[ide].TARGETS and + target in targets and + all(feature in TARGET_MAP[target].features + for feature in features)): + yield target, ide def get_repo_list(example): @@ -134,7 +159,7 @@ def source_repos(config): subprocess.call(["mbed-cli", "import", repo]) -def get_num_failures(results): +def get_num_failures(results, export=False): """ Returns the number of failed compilations from the results summary Args: results - results summary of the compilation stage. See compile_repos() for @@ -146,9 +171,68 @@ def get_num_failures(results): for key, val in results.iteritems(): num_failures = num_failures + len(val[3]) + if export: + num_failures += len(val[4]) return num_failures - + + +def export_repos(config, ides): + def print_message(message, name): + print(message+ " %s"%name) + sys.stdout.flush() + + results = {} + print("\nExporting example repos....\n") + for example in config['examples']: + export_failures = [] + build_failures = [] + successes = [] + exported = True + pass_status = True + if example['export']: + for repo in get_repo_list(example): + example_project_name = basename(repo) + os.chdir(example_project_name) + # Check that the target, IDE, and features combinations are valid and return a + # list of valid combinations to work through + for target, ide in target_cross_ide(ides, + example['features'], + example['targets']): + example_name = "{} {} {}".format(example_project_name, target, + ide) + def status(message): + print(message + " %s" % example_name) + sys.stdout.flush() + + status("Exporting") + proc = subprocess.Popen(["mbed-cli", "export", "-i", ide, + "-m", target]) + proc.wait() + if proc.returncode: + export_failures.append(example_name) + status("FAILURE exporting") + else: + status("SUCCESS exporting") + status("Building") + if EXPORTERS[ide].build(example_project_name): + status("FAILURE building") + build_failures.append(example_name) + else: + status("SUCCESS building") + successes.append(example_name) + os.chdir("..") + + if len(build_failures+export_failures) > 0: + pass_status= False + else: + exported = False + + results[example['name']] = [exported, pass_status, successes, export_failures, build_failures] + + return results + + def compile_repos(config, toolchains): """Compiles combinations of example programs, targets and compile chains. From 9b1c73522ff37558244eda9a4808fa1a4c256aff Mon Sep 17 00:00:00 2001 From: Marcelo Salazar Date: Tue, 25 Oct 2016 22:34:18 +0100 Subject: [PATCH 075/107] Folder re-org to fit new MCU K22F variances This is a simple re-structure of the K22F folder to allow other MCU variances to land here. Created the MCU_K22F512 device but left the 'K22F' as a target for the FRDM-K22F board. Rebased to master --- .../TARGET_MCU_K22F512}/TARGET_FRDM/PeripheralNames.h | 0 .../TARGET_MCU_K22F512}/TARGET_FRDM/PeripheralPins.c | 0 .../TARGET_MCU_K22F512}/TARGET_FRDM/PinNames.h | 0 .../TARGET_MCU_K22F512}/TARGET_FRDM/device.h | 0 .../TARGET_MCU_K22F512}/TARGET_FRDM/fsl_clock_config.c | 0 .../TARGET_MCU_K22F512}/TARGET_FRDM/fsl_clock_config.h | 0 .../TARGET_MCU_K22F512}/TARGET_FRDM/mbed_overrides.c | 0 .../TARGET_MCU_K22F512}/device/MK22F51212.h | 0 .../TARGET_MCU_K22F512}/device/MK22F51212_features.h | 0 .../device/TOOLCHAIN_ARM_STD/MK22FN512xxx12.sct | 0 .../device/TOOLCHAIN_ARM_STD/startup_MK22F51212.S | 0 .../device/TOOLCHAIN_ARM_STD/sys.cpp | 0 .../device/TOOLCHAIN_GCC_ARM/MK22FN512xxx12.ld | 0 .../device/TOOLCHAIN_GCC_ARM/startup_MK22F51212.S | 0 .../device/TOOLCHAIN_IAR/MK22F51212.icf | 0 .../device/TOOLCHAIN_IAR/startup_MK22F12.S | 0 .../TARGET_MCU_K22F512}/device/cmsis.h | 0 .../TARGET_MCU_K22F512}/device/cmsis_nvic.c | 0 .../TARGET_MCU_K22F512}/device/cmsis_nvic.h | 0 .../TARGET_MCU_K22F512}/device/fsl_device_registers.h | 0 .../TARGET_MCU_K22F512}/device/system_MK22F51212.c | 0 .../TARGET_MCU_K22F512}/device/system_MK22F51212.h | 0 .../drivers/fsl_adc16.c | 0 .../drivers/fsl_adc16.h | 0 .../drivers/fsl_clock.c | 0 .../drivers/fsl_clock.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_cmp.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_cmp.h | 0 .../drivers/fsl_common.c | 0 .../drivers/fsl_common.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_crc.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_crc.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_dac.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_dac.h | 0 .../drivers/fsl_dmamux.c | 0 .../drivers/fsl_dmamux.h | 0 .../drivers/fsl_dspi.c | 0 .../drivers/fsl_dspi.h | 0 .../drivers/fsl_dspi_edma.c | 0 .../drivers/fsl_dspi_edma.h | 0 .../drivers/fsl_edma.c | 0 .../drivers/fsl_edma.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_ewm.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_ewm.h | 0 .../drivers/fsl_flash.c | 0 .../drivers/fsl_flash.h | 0 .../drivers/fsl_flexbus.c | 0 .../drivers/fsl_flexbus.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_ftm.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_ftm.h | 0 .../drivers/fsl_gpio.c | 0 .../drivers/fsl_gpio.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_i2c.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_i2c.h | 0 .../drivers/fsl_i2c_edma.c | 0 .../drivers/fsl_i2c_edma.h | 0 .../drivers/fsl_llwu.c | 0 .../drivers/fsl_llwu.h | 0 .../drivers/fsl_lptmr.c | 0 .../drivers/fsl_lptmr.h | 0 .../drivers/fsl_lpuart.c | 0 .../drivers/fsl_lpuart.h | 0 .../drivers/fsl_lpuart_edma.c | 0 .../drivers/fsl_lpuart_edma.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_pdb.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_pdb.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_pit.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_pit.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_pmc.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_pmc.h | 0 .../drivers/fsl_port.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_rcm.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_rcm.h | 0 .../drivers/fsl_rnga.c | 0 .../drivers/fsl_rnga.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_rtc.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_rtc.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_sai.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_sai.h | 0 .../drivers/fsl_sai_edma.c | 0 .../drivers/fsl_sai_edma.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_sim.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_sim.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_smc.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_smc.h | 0 .../drivers/fsl_uart.c | 0 .../drivers/fsl_uart.h | 0 .../drivers/fsl_uart_edma.c | 0 .../drivers/fsl_uart_edma.h | 0 .../drivers/fsl_vref.c | 0 .../drivers/fsl_vref.h | 0 .../drivers/fsl_wdog.c | 0 .../drivers/fsl_wdog.h | 0 .../peripheral_clock_defines.h | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/pwmout_api.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/serial_api.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/spi_api.c | 0 .../{TARGET_K22F => TARGET_MCU_K22F}/us_ticker.c | 0 targets/TARGET_Freescale/mbed_rtx.h | 2 +- targets/targets.json | 10 +++++++--- 100 files changed, 8 insertions(+), 4 deletions(-) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/TARGET_FRDM/PeripheralNames.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/TARGET_FRDM/PeripheralPins.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/TARGET_FRDM/PinNames.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/TARGET_FRDM/device.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/TARGET_FRDM/fsl_clock_config.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/TARGET_FRDM/fsl_clock_config.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/TARGET_FRDM/mbed_overrides.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/MK22F51212.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/MK22F51212_features.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/TOOLCHAIN_ARM_STD/MK22FN512xxx12.sct (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/TOOLCHAIN_ARM_STD/startup_MK22F51212.S (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/TOOLCHAIN_ARM_STD/sys.cpp (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/TOOLCHAIN_GCC_ARM/MK22FN512xxx12.ld (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/TOOLCHAIN_GCC_ARM/startup_MK22F51212.S (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/TOOLCHAIN_IAR/MK22F51212.icf (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/TOOLCHAIN_IAR/startup_MK22F12.S (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/cmsis.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/cmsis_nvic.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/cmsis_nvic.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/fsl_device_registers.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/system_MK22F51212.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F/TARGET_MCU_K22F512}/device/system_MK22F51212.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_adc16.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_adc16.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_clock.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_clock.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_cmp.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_cmp.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_common.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_common.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_crc.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_crc.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_dac.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_dac.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_dmamux.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_dmamux.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_dspi.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_dspi.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_dspi_edma.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_dspi_edma.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_edma.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_edma.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_ewm.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_ewm.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_flash.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_flash.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_flexbus.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_flexbus.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_ftm.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_ftm.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_gpio.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_gpio.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_i2c.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_i2c.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_i2c_edma.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_i2c_edma.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_llwu.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_llwu.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_lptmr.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_lptmr.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_lpuart.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_lpuart.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_lpuart_edma.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_lpuart_edma.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_pdb.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_pdb.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_pit.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_pit.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_pmc.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_pmc.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_port.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_rcm.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_rcm.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_rnga.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_rnga.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_rtc.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_rtc.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_sai.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_sai.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_sai_edma.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_sai_edma.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_sim.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_sim.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_smc.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_smc.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_uart.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_uart.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_uart_edma.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_uart_edma.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_vref.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_vref.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_wdog.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/drivers/fsl_wdog.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/peripheral_clock_defines.h (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/pwmout_api.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/serial_api.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/spi_api.c (100%) rename targets/TARGET_Freescale/TARGET_KSDK2_MCUS/{TARGET_K22F => TARGET_MCU_K22F}/us_ticker.c (100%) diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/PeripheralNames.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/PeripheralNames.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/PeripheralNames.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/PeripheralNames.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/PeripheralPins.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/PeripheralPins.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/PeripheralPins.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/PeripheralPins.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/PinNames.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/PinNames.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/PinNames.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/PinNames.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/device.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/device.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/device.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/device.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/fsl_clock_config.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/fsl_clock_config.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/fsl_clock_config.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/fsl_clock_config.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/fsl_clock_config.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/fsl_clock_config.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/fsl_clock_config.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/fsl_clock_config.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/mbed_overrides.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/mbed_overrides.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/TARGET_FRDM/mbed_overrides.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/TARGET_FRDM/mbed_overrides.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/MK22F51212.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/MK22F51212.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/MK22F51212.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/MK22F51212.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/MK22F51212_features.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/MK22F51212_features.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/MK22F51212_features.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/MK22F51212_features.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_ARM_STD/MK22FN512xxx12.sct b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_ARM_STD/MK22FN512xxx12.sct similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_ARM_STD/MK22FN512xxx12.sct rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_ARM_STD/MK22FN512xxx12.sct diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_ARM_STD/startup_MK22F51212.S b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_ARM_STD/startup_MK22F51212.S similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_ARM_STD/startup_MK22F51212.S rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_ARM_STD/startup_MK22F51212.S diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_ARM_STD/sys.cpp b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_ARM_STD/sys.cpp similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_ARM_STD/sys.cpp rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_ARM_STD/sys.cpp diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_GCC_ARM/MK22FN512xxx12.ld b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_GCC_ARM/MK22FN512xxx12.ld similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_GCC_ARM/MK22FN512xxx12.ld rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_GCC_ARM/MK22FN512xxx12.ld diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_GCC_ARM/startup_MK22F51212.S b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_GCC_ARM/startup_MK22F51212.S similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_GCC_ARM/startup_MK22F51212.S rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_GCC_ARM/startup_MK22F51212.S diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_IAR/MK22F51212.icf b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_IAR/MK22F51212.icf similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_IAR/MK22F51212.icf rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_IAR/MK22F51212.icf diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_IAR/startup_MK22F12.S b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_IAR/startup_MK22F12.S similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/TOOLCHAIN_IAR/startup_MK22F12.S rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/TOOLCHAIN_IAR/startup_MK22F12.S diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/cmsis.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/cmsis.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/cmsis_nvic.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/cmsis_nvic.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/fsl_device_registers.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/fsl_device_registers.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/fsl_device_registers.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/fsl_device_registers.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/system_MK22F51212.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/system_MK22F51212.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/system_MK22F51212.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/system_MK22F51212.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/system_MK22F51212.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/system_MK22F51212.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/device/system_MK22F51212.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/system_MK22F51212.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_adc16.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_adc16.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_adc16.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_adc16.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_adc16.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_adc16.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_adc16.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_adc16.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_clock.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_clock.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_clock.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_clock.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_clock.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_clock.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_clock.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_clock.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_cmp.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_cmp.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_cmp.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_cmp.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_cmp.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_cmp.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_cmp.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_cmp.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_common.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_common.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_common.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_common.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_common.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_common.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_common.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_common.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_crc.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_crc.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_crc.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_crc.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_crc.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_crc.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_crc.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_crc.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dac.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dac.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dac.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dac.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dac.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dac.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dac.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dac.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dmamux.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dmamux.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dmamux.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dmamux.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dmamux.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dmamux.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dmamux.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dmamux.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dspi.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dspi.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dspi.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dspi.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dspi.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dspi.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dspi.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dspi.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dspi_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dspi_edma.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dspi_edma.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dspi_edma.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dspi_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dspi_edma.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_dspi_edma.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_dspi_edma.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_edma.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_edma.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_edma.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_edma.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_edma.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_edma.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ewm.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_ewm.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ewm.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_ewm.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ewm.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_ewm.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ewm.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_ewm.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_flash.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_flash.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_flash.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_flash.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_flash.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_flash.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_flash.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_flash.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_flexbus.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_flexbus.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_flexbus.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_flexbus.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_flexbus.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_flexbus.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_flexbus.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_flexbus.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ftm.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_ftm.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ftm.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_ftm.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ftm.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_ftm.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ftm.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_ftm.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_gpio.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_gpio.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_gpio.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_gpio.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_gpio.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_gpio.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_gpio.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_gpio.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_i2c.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_i2c.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_i2c.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_i2c.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_i2c.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_i2c.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_i2c.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_i2c.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_i2c_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_i2c_edma.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_i2c_edma.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_i2c_edma.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_i2c_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_i2c_edma.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_i2c_edma.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_i2c_edma.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_llwu.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_llwu.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_llwu.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_llwu.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_llwu.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_llwu.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_llwu.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_llwu.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_lptmr.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_lptmr.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_lptmr.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_lptmr.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_lptmr.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_lptmr.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_lptmr.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_lptmr.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_lpuart.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_lpuart.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_lpuart.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_lpuart.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_lpuart.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_lpuart.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_lpuart.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_lpuart.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_lpuart_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_lpuart_edma.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_lpuart_edma.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_lpuart_edma.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_lpuart_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_lpuart_edma.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_lpuart_edma.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_lpuart_edma.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_pdb.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_pdb.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_pdb.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_pdb.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_pdb.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_pdb.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_pdb.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_pdb.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_pit.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_pit.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_pit.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_pit.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_pit.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_pit.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_pit.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_pit.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_pmc.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_pmc.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_pmc.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_pmc.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_pmc.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_pmc.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_pmc.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_pmc.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_port.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_port.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_port.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_port.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_rcm.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_rcm.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_rcm.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_rcm.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_rcm.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_rcm.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_rcm.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_rcm.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_rnga.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_rnga.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_rnga.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_rnga.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_rnga.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_rnga.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_rnga.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_rnga.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_rtc.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_rtc.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_rtc.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_rtc.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_rtc.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_rtc.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_rtc.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_rtc.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_sai.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_sai.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_sai.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_sai.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_sai.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_sai.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_sai.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_sai.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_sai_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_sai_edma.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_sai_edma.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_sai_edma.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_sai_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_sai_edma.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_sai_edma.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_sai_edma.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_sim.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_sim.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_sim.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_sim.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_sim.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_sim.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_sim.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_sim.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_smc.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_smc.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_smc.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_smc.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_smc.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_smc.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_smc.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_smc.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_uart.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_uart.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_uart.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_uart.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_uart.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_uart.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_uart.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_uart.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_uart_edma.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_uart_edma.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_uart_edma.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_uart_edma.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_uart_edma.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_uart_edma.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_uart_edma.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_uart_edma.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_vref.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_vref.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_vref.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_vref.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_vref.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_vref.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_vref.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_vref.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_wdog.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_wdog.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_wdog.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_wdog.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_wdog.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_wdog.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_wdog.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/drivers/fsl_wdog.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/peripheral_clock_defines.h b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/peripheral_clock_defines.h similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/peripheral_clock_defines.h rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/peripheral_clock_defines.h diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/pwmout_api.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/pwmout_api.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/pwmout_api.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/pwmout_api.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/serial_api.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/serial_api.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/serial_api.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/serial_api.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/spi_api.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/spi_api.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/spi_api.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/spi_api.c diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/us_ticker.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/us_ticker.c similarity index 100% rename from targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/us_ticker.c rename to targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K22F/us_ticker.c diff --git a/targets/TARGET_Freescale/mbed_rtx.h b/targets/TARGET_Freescale/mbed_rtx.h index 7a59d79d739..e9f086068d1 100644 --- a/targets/TARGET_Freescale/mbed_rtx.h +++ b/targets/TARGET_Freescale/mbed_rtx.h @@ -47,7 +47,7 @@ #define OS_CLOCK 96000000 #endif -#elif defined(TARGET_K22F) +#elif defined(TARGET_MCU_K22F) #ifndef INITIAL_SP #define INITIAL_SP (0x20010000UL) diff --git a/targets/targets.json b/targets/targets.json index de66b8ebba4..d2d04fce742 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -482,11 +482,11 @@ "release_versions": ["2"], "device_name": "MK20DX256xxx7" }, - "K22F": { + "MCU_K22F512": { "supported_form_factors": ["ARDUINO"], "core": "Cortex-M4F", "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], - "extra_labels": ["Freescale", "KSDK2_MCUS", "FRDM", "KPSDK_MCUS", "KPSDK_CODE"], + "extra_labels": ["Freescale", "KSDK2_MCUS", "MCU_K22F", "MCU_K22F512", "FRDM", "KPSDK_MCUS", "KPSDK_CODE"], "is_disk_virtual": true, "macros": ["CPU_MK22FN512VLH12", "FSL_RTOS_MBED"], "inherits": ["Target"], @@ -495,6 +495,10 @@ "release_versions": ["2", "5"], "device_name": "MK22DN512xxx5" }, + "K22F": { + "inherits": ["MCU_K22F512"], + "extra_labels_add": ["FRDM"] + }, "KL27Z": { "inherits": ["Target"], "core": "Cortex-M0+", @@ -2404,4 +2408,4 @@ "inherits": ["SARA_NBIOT"], "extra_labels": ["ublox", "HI2110", "SARA_NBIOT"] } -} +} \ No newline at end of file From 15f3d3ff861fb0e94dec171eb55ddcea0e807e2f Mon Sep 17 00:00:00 2001 From: Ashok Rao Date: Tue, 1 Nov 2016 11:44:27 +0000 Subject: [PATCH 076/107] Incorporating Brian Daniel's review comments for PR 3136 --- targets/targets.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/targets/targets.json b/targets/targets.json index d2d04fce742..953adeb8b06 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -483,20 +483,21 @@ "device_name": "MK20DX256xxx7" }, "MCU_K22F512": { - "supported_form_factors": ["ARDUINO"], "core": "Cortex-M4F", "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], "extra_labels": ["Freescale", "KSDK2_MCUS", "MCU_K22F", "MCU_K22F512", "FRDM", "KPSDK_MCUS", "KPSDK_CODE"], "is_disk_virtual": true, + "public": false, "macros": ["CPU_MK22FN512VLH12", "FSL_RTOS_MBED"], "inherits": ["Target"], "detect_code": ["0231"], "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], - "release_versions": ["2", "5"], "device_name": "MK22DN512xxx5" }, "K22F": { + "supported_form_factors": ["ARDUINO"], "inherits": ["MCU_K22F512"], + "release_versions": ["2", "5"], "extra_labels_add": ["FRDM"] }, "KL27Z": { @@ -2408,4 +2409,4 @@ "inherits": ["SARA_NBIOT"], "extra_labels": ["ublox", "HI2110", "SARA_NBIOT"] } -} \ No newline at end of file +} From f3ec6355caa2b9cc9cc3c25dd6dd7fd12c5cb4ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janne=20Kiiskil=C3=A4?= Date: Wed, 2 Nov 2016 11:01:02 +0200 Subject: [PATCH 077/107] Remove the variable ret due to compiler warning: Compile [ 94.6%]: trng_api.c [Warning] trng_api.c@67,9: unused variable 'ret' [-Wunused-variable] Github issue #3183 --- .../TARGET_KSDK2_MCUS/TARGET_MCU_K64F/trng_api.c | 1 - 1 file changed, 1 deletion(-) diff --git a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K64F/trng_api.c b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K64F/trng_api.c index 9458af27a0e..53e5380639b 100644 --- a/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K64F/trng_api.c +++ b/targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K64F/trng_api.c @@ -64,7 +64,6 @@ int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_l { (void)obj; size_t i; - int ret; /* Set "Interrupt Mask", "High Assurance" and "Go", * unset "Clear interrupt" and "Sleep" */ From dc7f0200dc38208e52ed78094fa75c1097443310 Mon Sep 17 00:00:00 2001 From: Mahadevan Mahesh Date: Wed, 2 Nov 2016 11:08:53 -0500 Subject: [PATCH 078/107] Update tests to fix build failures. Also make the code similar to other tests Signed-off-by: Mahadevan Mahesh --- TESTS/mbed_drivers/lp_timeout/main.cpp | 4 ++-- TESTS/mbed_hal/lp_ticker/main.cpp | 4 ++-- .../FEATURE_STORAGE/TESTS/flash_journal/basicAPI/basicAPI.cpp | 2 +- .../TESTS/storage-volume-manager/basicAPI/basicAPI.cpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/TESTS/mbed_drivers/lp_timeout/main.cpp b/TESTS/mbed_drivers/lp_timeout/main.cpp index 8d4412b5010..3641275b416 100644 --- a/TESTS/mbed_drivers/lp_timeout/main.cpp +++ b/TESTS/mbed_drivers/lp_timeout/main.cpp @@ -118,7 +118,7 @@ void lp_timeout_500us(void) } -status_t greentea_failure_handler(const Case *const source, const failure_t reason) { +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { greentea_case_failure_abort_handler(source, reason); return STATUS_CONTINUE; } @@ -134,7 +134,7 @@ Case cases[] = { #endif /* DEVICE_SLEEP */ }; -status_t greentea_test_setup(const size_t number_of_cases) { +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { GREENTEA_SETUP(20, "default_auto"); return greentea_test_setup_handler(number_of_cases); } diff --git a/TESTS/mbed_hal/lp_ticker/main.cpp b/TESTS/mbed_hal/lp_ticker/main.cpp index b706087d1d6..fb93e948d65 100644 --- a/TESTS/mbed_hal/lp_ticker/main.cpp +++ b/TESTS/mbed_hal/lp_ticker/main.cpp @@ -133,7 +133,7 @@ void lp_ticker_5s(void) lp_ticker_delay_us(5000000, LONG_TIMEOUT); } -status_t greentea_failure_handler(const Case *const source, const failure_t reason) { +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { greentea_case_failure_abort_handler(source, reason); return STATUS_CONTINUE; } @@ -149,7 +149,7 @@ Case cases[] = { #endif /* DEVICE_SLEEP */ }; -status_t greentea_test_setup(const size_t number_of_cases) { +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { GREENTEA_SETUP(20, "default_auto"); lp_ticker_data->interface->init(); return greentea_test_setup_handler(number_of_cases); diff --git a/features/storage/FEATURE_STORAGE/TESTS/flash_journal/basicAPI/basicAPI.cpp b/features/storage/FEATURE_STORAGE/TESTS/flash_journal/basicAPI/basicAPI.cpp index 71a0e4effef..cf42fc78312 100644 --- a/features/storage/FEATURE_STORAGE/TESTS/flash_journal/basicAPI/basicAPI.cpp +++ b/features/storage/FEATURE_STORAGE/TESTS/flash_journal/basicAPI/basicAPI.cpp @@ -1055,7 +1055,7 @@ void test_crc32() #ifndef AVOID_GREENTEA // Custom setup handler required for proper Greentea support -status_t greentea_setup(const size_t number_of_cases) +utest::v1::status_t greentea_setup(const size_t number_of_cases) { GREENTEA_SETUP(60, "default_auto"); // Call the default reporting function diff --git a/features/storage/FEATURE_STORAGE/TESTS/storage-volume-manager/basicAPI/basicAPI.cpp b/features/storage/FEATURE_STORAGE/TESTS/storage-volume-manager/basicAPI/basicAPI.cpp index e950f17522f..8200f8565d5 100644 --- a/features/storage/FEATURE_STORAGE/TESTS/storage-volume-manager/basicAPI/basicAPI.cpp +++ b/features/storage/FEATURE_STORAGE/TESTS/storage-volume-manager/basicAPI/basicAPI.cpp @@ -56,7 +56,7 @@ static int32_t virtualVolumeCallbackStatus; #ifndef AVOID_GREENTEA // Custom setup handler required for proper Greentea support -status_t greentea_setup(const size_t number_of_cases) +utest::v1::status_t greentea_setup(const size_t number_of_cases) { GREENTEA_SETUP(30, "default_auto"); // Call the default reporting function From 06b7d5df39ed1b3dd91e54eca5f210fb8cb808e4 Mon Sep 17 00:00:00 2001 From: ccli8 Date: Thu, 13 Oct 2016 14:32:43 +0800 Subject: [PATCH 079/107] Rename SD_0/SD_1 SD_0_0/SD_0_1 to match real SD H/W --- .../PeripheralNames.h | 4 +- .../PeripheralPins.c | 50 +++++++++---------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h index 2cdc0bbc454..bff2175b2a1 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h @@ -116,8 +116,8 @@ typedef enum { } DMAName; typedef enum { - SD_0 = (int) NU_MODNAME(SD_BASE, 0), - SD_1 = (int) NU_MODNAME(SD_BASE, 1) + SD_0_0 = (int) NU_MODNAME(SD_BASE, 0), + SD_0_1 = (int) NU_MODNAME(SD_BASE, 1) } SDName; #ifdef __cplusplus diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c index 4ab4693a68b..5a53f72db40 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c @@ -451,62 +451,62 @@ const PinMap PinMap_SPI_SSEL[] = { //*** SD *** const PinMap PinMap_SD_CD[] = { - {PC_12, SD_1, SYS_GPC_MFPH_PC12MFP_SD1_CDn}, - {PD_3, SD_0, SYS_GPD_MFPL_PD3MFP_SD0_CDn}, - {PE_5, SD_0, SYS_GPE_MFPL_PE5MFP_SD0_CDn}, - {PF_6, SD_0, SYS_GPF_MFPL_PF6MFP_SD0_CDn}, + {PC_12, SD_0_1, SYS_GPC_MFPH_PC12MFP_SD1_CDn}, + {PD_3, SD_0_0, SYS_GPD_MFPL_PD3MFP_SD0_CDn}, + {PE_5, SD_0_0, SYS_GPE_MFPL_PE5MFP_SD0_CDn}, + {PF_6, SD_0_0, SYS_GPF_MFPL_PF6MFP_SD0_CDn}, {NC, NC, 0} }; const PinMap PinMap_SD_CMD[] = { - {PC_13, SD_1, SYS_GPC_MFPH_PC13MFP_SD1_CMD}, - {PD_6, SD_0, SYS_GPD_MFPL_PD6MFP_SD0_CMD}, - {PE_6, SD_0, SYS_GPE_MFPL_PE6MFP_SD0_CMD}, - {PF_7, SD_0, SYS_GPF_MFPL_PF7MFP_SD0_CMD}, + {PC_13, SD_0_1, SYS_GPC_MFPH_PC13MFP_SD1_CMD}, + {PD_6, SD_0_0, SYS_GPD_MFPL_PD6MFP_SD0_CMD}, + {PE_6, SD_0_0, SYS_GPE_MFPL_PE6MFP_SD0_CMD}, + {PF_7, SD_0_0, SYS_GPF_MFPL_PF7MFP_SD0_CMD}, {NC, NC, 0} }; const PinMap PinMap_SD_CLK[] = { - {PC_14, SD_1, SYS_GPC_MFPH_PC14MFP_SD1_CLK}, - {PD_7, SD_0, SYS_GPD_MFPL_PD7MFP_SD0_CLK}, - {PE_7, SD_0, SYS_GPE_MFPL_PE7MFP_SD0_CLK}, - {PF_8, SD_0, SYS_GPF_MFPH_PF8MFP_SD0_CLK}, + {PC_14, SD_0_1, SYS_GPC_MFPH_PC14MFP_SD1_CLK}, + {PD_7, SD_0_0, SYS_GPD_MFPL_PD7MFP_SD0_CLK}, + {PE_7, SD_0_0, SYS_GPE_MFPL_PE7MFP_SD0_CLK}, + {PF_8, SD_0_0, SYS_GPF_MFPH_PF8MFP_SD0_CLK}, {NC, NC, 0} }; const PinMap PinMap_SD_DAT0[] = { - {PC_9, SD_1, SYS_GPC_MFPH_PC9MFP_SD1_DAT0}, - {PD_2, SD_1, SYS_GPD_MFPL_PD2MFP_SD1_DAT0}, - {PE_11, SD_0, SYS_GPE_MFPH_PE11MFP_SD0_DAT0}, - {PF_5, SD_0, SYS_GPF_MFPL_PF5MFP_SD0_DAT0}, + {PC_9, SD_0_1, SYS_GPC_MFPH_PC9MFP_SD1_DAT0}, + {PD_2, SD_0_1, SYS_GPD_MFPL_PD2MFP_SD1_DAT0}, + {PE_11, SD_0_0, SYS_GPE_MFPH_PE11MFP_SD0_DAT0}, + {PF_5, SD_0_0, SYS_GPF_MFPL_PF5MFP_SD0_DAT0}, {NC, NC, 0} }; const PinMap PinMap_SD_DAT1[] = { - {PD_1, SD_1, SYS_GPD_MFPL_PD1MFP_SD1_DAT1}, - {PE_10, SD_0, SYS_GPE_MFPH_PE10MFP_SD0_DAT1}, - {PF_4, SD_0, SYS_GPF_MFPL_PF4MFP_SD0_DAT1}, + {PD_1, SD_0_1, SYS_GPD_MFPL_PD1MFP_SD1_DAT1}, + {PE_10, SD_0_0, SYS_GPE_MFPH_PE10MFP_SD0_DAT1}, + {PF_4, SD_0_0, SYS_GPF_MFPL_PF4MFP_SD0_DAT1}, {NC, NC, 0} }; const PinMap PinMap_SD_DAT2[] = { - {PD_0, SD_1, SYS_GPD_MFPL_PD0MFP_SD1_DAT2}, - {PE_9, SD_0, SYS_GPE_MFPH_PE9MFP_SD0_DAT2}, - {PF_3, SD_0, SYS_GPF_MFPL_PF3MFP_SD0_DAT2}, + {PD_0, SD_0_1, SYS_GPD_MFPL_PD0MFP_SD1_DAT2}, + {PE_9, SD_0_0, SYS_GPE_MFPH_PE9MFP_SD0_DAT2}, + {PF_3, SD_0_0, SYS_GPF_MFPL_PF3MFP_SD0_DAT2}, {NC, NC, 0} }; const PinMap PinMap_SD_DAT3[] = { - {PC_15, SD_1, SYS_GPC_MFPH_PC15MFP_SD1_DAT3}, - {PE_8, SD_0, SYS_GPE_MFPH_PE8MFP_SD0_DAT3}, - {PF_2, SD_0, SYS_GPF_MFPL_PF2MFP_SD0_DAT3}, + {PC_15, SD_0_1, SYS_GPC_MFPH_PC15MFP_SD1_DAT3}, + {PE_8, SD_0_0, SYS_GPE_MFPH_PE8MFP_SD0_DAT3}, + {PF_2, SD_0_0, SYS_GPF_MFPL_PF2MFP_SD0_DAT3}, {NC, NC, 0} }; From c4f0ce24c56646c115ecfc3024e833616ef6da9a Mon Sep 17 00:00:00 2001 From: ccli8 Date: Tue, 18 Oct 2016 10:32:41 +0800 Subject: [PATCH 080/107] Fix PWM1 clock source setting error --- .../device/StdDriver/nuc472_pwm.c | 52 +++++++++++-------- .../device/StdDriver/nuc472_pwm.h | 49 ++++++++++------- 2 files changed, 60 insertions(+), 41 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_pwm.c b/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_pwm.c index 3544caf0d99..df0cd818cbe 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_pwm.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_pwm.c @@ -1,8 +1,8 @@ /**************************************************************************//** * @file PWM.c * @version V1.00 - * $Revision: 22 $ - * $Date: 14/10/02 9:21a $ + * $Revision: 26 $ + * $Date: 15/11/18 2:34p $ * @brief NUC472/NUC442 PWM driver source file * * @note @@ -52,14 +52,14 @@ uint32_t PWM_ConfigOutputChannel (PWM_T *pwm, * @note Since every two channels, (0 & 1), (2 & 3), (4 & 5), shares a prescaler. Call this API to configure PWM frequency may affect * existing frequency of other channel. */ -uint32_t PWM_ConfigOutputChannel2(PWM_T *pwm, - uint32_t u32ChannelNum, - uint32_t u32Frequency, - uint32_t u32DutyCycle, - uint32_t u32Frequency2) +uint32_t PWM_ConfigOutputChannel2 (PWM_T *pwm, + uint32_t u32ChannelNum, + uint32_t u32Frequency, + uint32_t u32DutyCycle, + uint32_t u32Frequency2) { uint32_t i; - uint32_t u32PWM_CLock; + uint32_t u32PWM_CLock = __HIRC; uint8_t u8Divider = 1, u8Prescale = 0xFF; uint16_t u16CNR = 0xFFFF; @@ -100,15 +100,15 @@ uint32_t PWM_ConfigOutputChannel2(PWM_T *pwm, } } else if (pwm == PWM1) { if (u32ChannelNum < 2) { - if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == 0) + if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == (0 << CLK_CLKSEL2_PWM1CH01SEL_Pos)) u32PWM_CLock = __HXT; - else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == 1) + else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == (1 << CLK_CLKSEL2_PWM1CH01SEL_Pos)) u32PWM_CLock = __LXT; - else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == 2) + else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == (2 << CLK_CLKSEL2_PWM1CH01SEL_Pos)) u32PWM_CLock = SystemCoreClock; - else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == 3) + else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == (3 << CLK_CLKSEL2_PWM1CH01SEL_Pos)) u32PWM_CLock = __HIRC; - else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == 4) + else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == (4 << CLK_CLKSEL2_PWM1CH01SEL_Pos)) u32PWM_CLock = __LIRC; } else if (u32ChannelNum < 4) { if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH23SEL_Msk) == (0 << CLK_CLKSEL2_PWM1CH23SEL_Pos)) @@ -207,7 +207,7 @@ uint32_t PWM_ConfigCaptureChannel (PWM_T *pwm, uint32_t u32CaptureEdge) { uint32_t i; - uint32_t u32PWM_CLock; + uint32_t u32PWM_CLock = __HIRC; uint8_t u8Divider = 1, u8Prescale = 0xFF; uint16_t u16CNR = 0xFFFF; @@ -248,15 +248,15 @@ uint32_t PWM_ConfigCaptureChannel (PWM_T *pwm, } } else if (pwm == PWM1) { if (u32ChannelNum < 2) { - if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == 0) + if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == (0 << CLK_CLKSEL2_PWM1CH01SEL_Pos)) u32PWM_CLock = __HXT; - else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == 1) + else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == (1 << CLK_CLKSEL2_PWM1CH01SEL_Pos)) u32PWM_CLock = __LXT; - else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == 2) + else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == (2 << CLK_CLKSEL2_PWM1CH01SEL_Pos)) u32PWM_CLock = SystemCoreClock; - else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == 3) + else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == (3 << CLK_CLKSEL2_PWM1CH01SEL_Pos)) u32PWM_CLock = __HIRC; - else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == 4) + else if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH01SEL_Msk) == (4 << CLK_CLKSEL2_PWM1CH01SEL_Pos)) u32PWM_CLock = __LIRC; } else if (u32ChannelNum < 4) { if ((CLK->CLKSEL2 & CLK_CLKSEL2_PWM1CH23SEL_Msk) == (0 << CLK_CLKSEL2_PWM1CH23SEL_Pos)) @@ -451,6 +451,7 @@ uint32_t PWM_GetADCTriggerFlag (PWM_T *pwm, uint32_t u32ChannelNum) * - \ref PWM_BRK0_CPO0 * - \ref PWM_BRK0_CPO1 * - \ref PWM_BRK0_CPO2 + * - \ref PWM_BRK1_LVDBK * - \ref PWM_BK1SEL_BKP1 * - \ref PWM_BK1SEL_CPO0 * - \ref PWM_BK1SEL_CPO1 @@ -463,20 +464,29 @@ void PWM_EnableFaultBrake (PWM_T *pwm, { if ((u32BrakeSource == PWM_BRK0_BKP0)||(u32BrakeSource == PWM_BRK0_CPO0)||(u32BrakeSource == PWM_BRK0_CPO1)||(u32BrakeSource == PWM_BRK0_CPO2)) pwm->BRKCTL |= (u32BrakeSource | PWM_BRKCTL_BRK0EN_Msk); + else if (u32BrakeSource == PWM_BRK1_LVDBK) + pwm->BRKCTL |= PWM_BRKCTL_LVDBKEN_Msk; else pwm->BRKCTL = (pwm->BRKCTL & ~PWM_BRKCTL_BK1SEL_Msk) | u32BrakeSource | PWM_BRKCTL_BRK1EN_Msk; + + pwm->BRKCTL = (pwm->BRKCTL & ~PWM_BRKCTL_BKOD_Msk) | (u32LevelMask << PWM_BRKCTL_BKOD_Pos); + } /** * @brief This function clear fault brake flag * @param[in] pwm The base address of PWM module - * @param[in] u32BrakeSource This parameter is not used + * @param[in] u32BrakeSource Fault brake source 0 or 1 + * 0: brake 0, 1: brake 1 * @return None * @note After fault brake occurred, application must clear fault brake source before re-enable PWM output */ void PWM_ClearFaultBrakeFlag (PWM_T *pwm, uint32_t u32BrakeSource) { - pwm->INTSTS = PWM_INTSTS_BRKLK0_Msk; + if (u32BrakeSource == 0) + pwm->INTSTS = (PWM_INTSTS_BRKLK0_Msk | PWM_INTSTS_BRKIF0_Msk); + else + pwm->INTSTS = PWM_INTSTS_BRKIF1_Msk; } /** diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_pwm.h b/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_pwm.h index a41b58cdcc8..d9386a10093 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_pwm.h +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_pwm.h @@ -1,8 +1,8 @@ /**************************************************************************//** * @file pwm.h * @version V1.00 - * $Revision: 19 $ - * $Date: 14/10/06 1:36p $ + * $Revision: 22 $ + * $Date: 15/11/16 2:08p $ * @brief NUC472/NUC442 PWM driver header file * * @note @@ -29,14 +29,18 @@ extern "C" @{ */ #define PWM_CHANNEL_NUM (6) /*!< PWM channel number \hideinitializer */ +#define PWM_CH0 (0UL) /*!< PWM channel 0 \hideinitializer */ +#define PWM_CH1 (1UL) /*!< PWM channel 1 \hideinitializer */ +#define PWM_CH2 (2UL) /*!< PWM channel 2 \hideinitializer */ +#define PWM_CH3 (3UL) /*!< PWM channel 3 \hideinitializer */ +#define PWM_CH4 (4UL) /*!< PWM channel 4 \hideinitializer */ +#define PWM_CH5 (5UL) /*!< PWM channel 5 \hideinitializer */ #define PWM_CH_0_MASK (1UL) /*!< PWM channel 0 mask \hideinitializer */ #define PWM_CH_1_MASK (2UL) /*!< PWM channel 1 mask \hideinitializer */ #define PWM_CH_2_MASK (4UL) /*!< PWM channel 2 mask \hideinitializer */ #define PWM_CH_3_MASK (8UL) /*!< PWM channel 3 mask \hideinitializer */ #define PWM_CH_4_MASK (16UL) /*!< PWM channel 4 mask \hideinitializer */ #define PWM_CH_5_MASK (32UL) /*!< PWM channel 5 mask \hideinitializer */ -#define PWM_CH_6_MASK (64UL) /*!< PWM channel 6 mask \hideinitializer */ -#define PWM_CH_7_MASK (128UL) /*!< PWM channel 7 mask \hideinitializer */ #define PWM_CLK_DIV_1 (4UL) /*!< PWM clock divide by 1 \hideinitializer */ #define PWM_CLK_DIV_2 (0UL) /*!< PWM clock divide by 2 \hideinitializer */ #define PWM_CLK_DIV_4 (1UL) /*!< PWM clock divide by 4 \hideinitializer */ @@ -48,10 +52,11 @@ extern "C" #define PWM_TRIGGER_ADC_FALLING_EDGE_POINT (0x10000UL) /*!< PWM trigger ADC while output falling edge is detected \hideinitializer */ #define PWM_TRIGGER_ADC_CENTER_POINT (0x100UL) /*!< PWM trigger ADC while counter matches (CNR + 1) \hideinitializer */ #define PWM_TRIGGER_ADC_PERIOD_POINT (0x1UL) /*!< PWM trigger ADC while counter down count to 0 \hideinitializer */ -#define PWM_BRK0_BKP0 (0UL) /*!< Brake0 signal source from external pin BKP0 \hideinitializer */ +#define PWM_BRK0_BKP0 (PWM_BRKCTL_BRK0EN_Msk) /*!< Brake0 signal source from external pin BKP0 \hideinitializer */ #define PWM_BRK0_CPO0 (PWM_BRKCTL_CPO0BKEN_Msk) /*!< Brake0 signal source from analog comparator 0 output \hideinitializer */ #define PWM_BRK0_CPO1 (PWM_BRKCTL_CPO1BKEN_Msk) /*!< Brake0 signal source from analog comparator 1 output \hideinitializer */ #define PWM_BRK0_CPO2 (PWM_BRKCTL_CPO2BKEN_Msk) /*!< Brake0 signal source from analog comparator 2 output \hideinitializer */ +#define PWM_BRK1_LVDBK (PWM_BRKCTL_LVDBKEN_Msk) /*!< Brake1 signal source from level detect \hideinitializer */ #define PWM_BK1SEL_BKP1 (0UL << PWM_BRKCTL_BK1SEL_Pos) /*!< Brake1 signal source from external pin BKP1 \hideinitializer */ #define PWM_BK1SEL_CPO0 (1UL << PWM_BRKCTL_BK1SEL_Pos) /*!< Brake1 signal source from analog comparator 0 output \hideinitializer */ #define PWM_BK1SEL_CPO1 (2UL << PWM_BRKCTL_BK1SEL_Pos) /*!< Brake1 signal source from analog comparator 1 output \hideinitializer */ @@ -79,7 +84,7 @@ extern "C" * @return None * \hideinitializer */ -#define PWM_ENABLE_COMPLEMENTARY_MODE(pwm) (pwm->CTL = pwm->CTL | PWM_CTL_OUTMODE_Msk) +#define PWM_ENABLE_COMPLEMENTARY_MODE(pwm) ((pwm)->CTL = (pwm)->CTL | PWM_CTL_OUTMODE_Msk) /** * @brief This macro disable complementary mode, and enable independent mode. @@ -87,7 +92,7 @@ extern "C" * @return None * \hideinitializer */ -#define PWM_DISABLE_COMPLEMENTARY_MODE(pwm) (pwm->CTL = pwm->CTL & ~PWM_CTL_OUTMODE_Msk) +#define PWM_DISABLE_COMPLEMENTARY_MODE(pwm) ((pwm)->CTL = (pwm)->CTL & ~PWM_CTL_OUTMODE_Msk) /** * @brief This macro enable group mode @@ -95,7 +100,7 @@ extern "C" * @return None * \hideinitializer */ -#define PWM_ENABLE_GROUP_MODE(pwm) (pwm->CTL = pwm->CTL | PWM_CTL_GROUPEN_Msk) +#define PWM_ENABLE_GROUP_MODE(pwm) ((pwm)->CTL = (pwm)->CTL | PWM_CTL_GROUPEN_Msk) /** * @brief This macro disable group mode @@ -103,7 +108,7 @@ extern "C" * @return None * \hideinitializer */ -#define PWM_DISABLE_GROUP_MODE(pwm) (pwm->CTL = pwm->CTL & ~PWM_CTL_GROUPEN_Msk) +#define PWM_DISABLE_GROUP_MODE(pwm) ((pwm)->CTL = (pwm)->CTL & ~PWM_CTL_GROUPEN_Msk) /** * @brief This macro enable synchronous mode @@ -111,7 +116,7 @@ extern "C" * @return None * \hideinitializer */ -#define PWM_ENABLE_SYNC_MODE(pwm) (pwm->CTL = pwm->CTL | PWM_CTL_SYNCEN_Msk) +#define PWM_ENABLE_SYNC_MODE(pwm) ((pwm)->CTL = (pwm)->CTL | PWM_CTL_SYNCEN_Msk) /** * @brief This macro disable synchronous mode, and enable independent mode. @@ -119,7 +124,7 @@ extern "C" * @return None * \hideinitializer */ -#define PWM_DISABLE_SYNC_MODE(pwm) (pwm->CTL = pwm->CTL & ~PWM_CTL_SYNCEN_Msk) +#define PWM_DISABLE_SYNC_MODE(pwm) ((pwm)->CTL = (pwm)->CTL & ~PWM_CTL_SYNCEN_Msk) /** * @brief This macro enable output inverter of specified channel(s) @@ -129,7 +134,7 @@ extern "C" * @return None * \hideinitializer */ -#define PWM_ENABLE_OUTPUT_INVERTER(pwm, u32ChannelMask) (pwm->CTL |= (u32ChannelMask << PWM_CTL_PINV_Pos) +#define PWM_ENABLE_OUTPUT_INVERTER(pwm, u32ChannelMask) ((pwm)->CTL = (((pwm)->CTL & ~PWM_CTL_PINV_Msk) | ((u32ChannelMask) << PWM_CTL_PINV_Pos))) /** * @brief This macro get captured rising data @@ -138,7 +143,7 @@ extern "C" * @return None * \hideinitializer */ -#define PWM_GET_CAPTURE_RISING_DATA(pwm, u32ChannelNum) (*(__IO uint32_t *) (&pwm->RCAPDAT0 + 2 * u32ChannelNum)) +#define PWM_GET_CAPTURE_RISING_DATA(pwm, u32ChannelNum) (*(__IO uint32_t *) (&(pwm)->RCAPDAT0 + 2 * (u32ChannelNum))) /** * @brief This macro get captured falling data @@ -147,7 +152,7 @@ extern "C" * @return None * \hideinitializer */ -#define PWM_GET_CAPTURE_FALLING_DATA(pwm, u32ChannelNum) (*(__IO uint32_t *) (&pwm->FCAPDAT0 + 2 * u32ChannelNum)) +#define PWM_GET_CAPTURE_FALLING_DATA(pwm, u32ChannelNum) (*(__IO uint32_t *) (&(pwm)->FCAPDAT0 + 2 * (u32ChannelNum))) /** * @brief This macro mask output output logic to high or low @@ -158,7 +163,7 @@ extern "C" * @return None * \hideinitializer */ -#define PWM_MASK_OUTPUT(pwm, u32ChannelMask, u32LevelMask) (pwm->MSKEN |= u32ChannelMask) +#define PWM_MASK_OUTPUT(pwm, u32ChannelMask, u32LevelMask) ((pwm)->MSKEN |= (u32ChannelMask)) /** * @brief This macro set the prescaler of the selected channel @@ -171,7 +176,7 @@ extern "C" * \hideinitializer */ #define PWM_SET_PRESCALER(pwm, u32ChannelNum, u32Prescaler) \ - (pwm->CLKPSC = (pwm->CLKPSC & ~(PWM_CLKPSC_CLKPSC01_Msk << (((u32ChannelNum) >> 1) * 8))) | ((u32Prescaler) << (((u32ChannelNum) >> 1) * 8))) + (pwm->CLKPSC = ((pwm)->CLKPSC & ~(PWM_CLKPSC_CLKPSC01_Msk << (((u32ChannelNum) >> 1) * 8))) | ((u32Prescaler) << (((u32ChannelNum) >> 1) * 8))) /** * @brief This macro set the divider of the selected channel @@ -187,7 +192,7 @@ extern "C" * \hideinitializer */ #define PWM_SET_DIVIDER(pwm, u32ChannelNum, u32Divider) \ - (pwm->CLKDIV = (pwm->CLKDIV & ~(PWM_CLKDIV_CLKDIV0_Msk << ((u32ChannelNum) * 4))) | ((u32Divider) << ((u32ChannelNum) * 4))) + ((pwm)->CLKDIV = ((pwm)->CLKDIV & ~(PWM_CLKDIV_CLKDIV0_Msk << ((u32ChannelNum) * 4))) | ((u32Divider) << ((u32ChannelNum) * 4))) /** * @brief This macro set the duty of the selected channel @@ -198,7 +203,7 @@ extern "C" * @note This new setting will take effect on next PWM period * \hideinitializer */ -#define PWM_SET_CMR(pwm, u32ChannelNum, u32CMR) (pwm->CMPDAT[u32ChannelNum] = (u32CMR)) +#define PWM_SET_CMR(pwm, u32ChannelNum, u32CMR) ((pwm)->CMPDAT[(u32ChannelNum)] = (u32CMR)) /** * @brief This macro set the period of the selected channel @@ -210,7 +215,7 @@ extern "C" * @note PWM counter will stop if period length set to 0 * \hideinitializer */ -#define PWM_SET_CNR(pwm, u32ChannelNum, u32CNR) (pwm->PERIOD[u32ChannelNum] = (u32CNR)) +#define PWM_SET_CNR(pwm, u32ChannelNum, u32CNR) ((pwm)->PERIOD[(u32ChannelNum)] = (u32CNR)) /** * @brief This macro set the PWM aligned type @@ -224,7 +229,11 @@ extern "C" * \hideinitializer */ #define PWM_SET_ALIGNED_TYPE(pwm, u32ChannelMask, u32AlignedType) \ - (pwm->CTL = (pwm->CTL & ~(u32ChannelMask << PWM_CTL_CNTMODE_Pos) | (u32AlignedType << PWM_CTL_CNTMODE_Pos)) +do { \ + (pwm)->CTL = ((pwm)->CTL & ~PWM_CTL_CNTTYPE_Msk); \ + if ((u32AlignedType) == PWM_CENTER_ALIGNED) \ + (pwm)->CTL = ((pwm)->CTL | ((u32ChannelMask) << PWM_CTL_CNTTYPE_Pos)); \ +} while(0) uint32_t PWM_ConfigOutputChannel(PWM_T *pwm, From 6af9ee295fabe9b8143f1b7c073e240e19cb7b9f Mon Sep 17 00:00:00 2001 From: cyliangtw Date: Tue, 18 Oct 2016 17:04:31 +0800 Subject: [PATCH 081/107] support NUC472 CAN --- .../PeripheralNames.h | 5 + .../PeripheralPins.c | 19 + .../PeripheralPins.h | 4 + .../TARGET_NUMAKER_PFM_NUC472/device.h | 2 +- .../TARGET_NUMAKER_PFM_NUC472/objects.h | 4 + .../TARGET_NUVOTON/TARGET_NUC472/can_api.c | 352 ++++++++++++++++++ .../device/StdDriver/nuc472_can.h | 5 + 7 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h index bff2175b2a1..66621e43b07 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h @@ -120,6 +120,11 @@ typedef enum { SD_0_1 = (int) NU_MODNAME(SD_BASE, 1) } SDName; +typedef enum { + CAN_0 = (int) NU_MODNAME(CAN0_BASE, 0), + CAN_1 = (int) NU_MODNAME(CAN1_BASE, 0) +} CANName; + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c index 5a53f72db40..a609071396f 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c @@ -510,3 +510,22 @@ const PinMap PinMap_SD_DAT3[] = { {NC, NC, 0} }; + +const PinMap PinMap_CAN_TD[] = { + {PB_13, CAN_0, SYS_GPB_MFPH_PB13MFP_CAN0_TXD}, + {PA_1, CAN_1, SYS_GPA_MFPL_PA1MFP_CAN1_TXD}, + {PA_6, CAN_1, SYS_GPA_MFPL_PA6MFP_CAN1_TXD}, + {PH_1, CAN_1, SYS_GPH_MFPL_PH1MFP_CAN1_TXD}, + + {NC, NC, 0} +}; + + +const PinMap PinMap_CAN_RD[] = { + {PB_12, CAN_0, SYS_GPB_MFPH_PB12MFP_CAN0_RXD}, + {PA_0, CAN_1, SYS_GPA_MFPL_PA0MFP_CAN1_RXD}, + {PH_0, CAN_1, SYS_GPH_MFPL_PH0MFP_CAN1_RXD}, + + {NC, NC, 0} +}; + diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.h b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.h index 104d38ee4fe..53bde3dc39e 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.h +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.h @@ -64,6 +64,10 @@ extern const PinMap PinMap_SD_DAT1[]; extern const PinMap PinMap_SD_DAT2[]; extern const PinMap PinMap_SD_DAT3[]; +//*** CAN *** +extern const PinMap PinMap_CAN_TD[]; +extern const PinMap PinMap_CAN_RD[]; + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/device.h b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/device.h index 89e12ecd417..dbc69c2bf61 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/device.h +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/device.h @@ -38,7 +38,7 @@ #define DEVICE_SPI_ASYNCH 1 #define DEVICE_SPISLAVE 1 -#define DEVICE_CAN 0 +#define DEVICE_CAN 1 #define DEVICE_RTC 1 diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/objects.h b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/objects.h index dcc39b0d682..59f3d654caa 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/objects.h +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/objects.h @@ -128,6 +128,10 @@ struct trng_s { uint8_t dummy; }; +struct can_s { + CANName can; + char index; +}; #ifdef __cplusplus } #endif diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c new file mode 100644 index 00000000000..65734720a7c --- /dev/null +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c @@ -0,0 +1,352 @@ +/* mbed Microcontroller Library + * Copyright (c) 2015-2016 Nuvoton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "can_api.h" + #include "nuc472_gpio.h" + #include "nuc472_can.h" + + #if DEVICE_CAN + #include + #include "cmsis.h" + #include "pinmap.h" + #include "PeripheralPins.h" + #include "nu_modutil.h" + #include "nu_miscutil.h" + #include "nu_bitutil.h" + #include "critical.h" + + #define NU_CAN_DEBUG 0 + #define CAN_NUM 2 + + static uint32_t can_irq_ids[CAN_NUM] = {0}; + static can_irq_handler can0_irq_handler; + static can_irq_handler can1_irq_handler; + + + static const struct nu_modinit_s can_modinit_tab[] = { + {CAN_0, CAN0_MODULE, 0, 0, CAN0_RST, CAN0_IRQn, NULL}, + {CAN_1, CAN1_MODULE, 0, 0, CAN1_RST, CAN1_IRQn, NULL}, + + {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL} +}; + + + void can_init(can_t *obj, PinName rd, PinName td) + { + uint32_t can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); + uint32_t can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); + obj->can = (CANName)pinmap_merge(can_td, can_rd); + MBED_ASSERT((int)obj->can != NC); + + const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); + MBED_ASSERT(modinit != NULL); + MBED_ASSERT(modinit->modname == obj->can); + + // Reset this module + SYS_ResetModule(modinit->rsetidx); + + // Enable IP clock + CLK_EnableModuleClock(modinit->clkidx); + + if(obj->can == CAN_1) { + obj->index = 1; + } + else + obj->index = 0; + + pinmap_pinout(td, PinMap_CAN_TD); + pinmap_pinout(rd, PinMap_CAN_RD); + + /* For NCU 472 mbed Board Transmitter Setting (RS Pin) */ + GPIO_SetMode(PA, BIT2| BIT3, GPIO_MODE_OUTPUT); + PA2 = 0x00; + PA3 = 0x00; + + CAN_Open((CAN_T *)obj->can, 500000, CAN_NORMAL_MODE); + + can_filter(obj, 0, 0, CANStandard, 0); + } + + +void can_free(can_t *obj) +{ + + const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); + + MBED_ASSERT(modinit != NULL); + MBED_ASSERT(modinit->modname == obj->can); + + // Reset this module + SYS_ResetModule(modinit->rsetidx); + + CLK_DisableModuleClock(modinit->clkidx); +} + +int can_frequency(can_t *obj, int hz) +{ + CAN_SetBaudRate((CAN_T *)obj->can, hz); + + return CAN_GetCANBitRate((CAN_T *)obj->can); +} + +static void can_irq(CANName name, int id) +{ + + CAN_T *can = (CAN_T *)NU_MODBASE(name); + uint32_t u8IIDRstatus; + + u8IIDRstatus = can->IIDR; + + if(u8IIDRstatus == 0x00008000) { /* Check Status Interrupt Flag (Error status Int and Status change Int) */ + /**************************/ + /* Status Change interrupt*/ + /**************************/ + if(can->STATUS & CAN_STATUS_RXOK_Msk) { + can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/ + if(id) + can1_irq_handler(can_irq_ids[id] , IRQ_RX); + else + can0_irq_handler(can_irq_ids[id], IRQ_RX); + } + + if(can->STATUS & CAN_STATUS_TXOK_Msk) { + can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/ + if(id) + can1_irq_handler(can_irq_ids[id] , IRQ_TX); + else + can0_irq_handler(can_irq_ids[id], IRQ_TX); + + } + + /**************************/ + /* Error Status interrupt */ + /**************************/ + if(can->STATUS & CAN_STATUS_EWARN_Msk) { + if(id) + can1_irq_handler(can_irq_ids[id] , IRQ_ERROR); + else + can0_irq_handler(can_irq_ids[id], IRQ_ERROR); + } + + if(can->STATUS & CAN_STATUS_BOFF_Msk) { + if(id) + can1_irq_handler(can_irq_ids[id] , IRQ_BUS); + else + can0_irq_handler(can_irq_ids[id], IRQ_BUS); + } + } else if (u8IIDRstatus!=0) { + + //CAN_MsgInterrupt(can, u8IIDRstatus); + if(id) + can1_irq_handler(can_irq_ids[id] , IRQ_OVERRUN); + else + can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN); + + CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */ + + } else if(can->WU_STATUS == 1) { + + can->WU_STATUS = 0; /* Write '0' to clear */ + if(id) + can1_irq_handler(can_irq_ids[id] , IRQ_WAKEUP); + else + can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP); + } +} + +void CAN0_IRQHandler(void) +{ + can_irq(CAN_0, 0); +} + +void CAN1_IRQHandler(void) +{ + can_irq(CAN_1, 1); +} + +void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) +{ + if(obj->index) + can1_irq_handler = handler; + else + can0_irq_handler = handler; + can_irq_ids[obj->index] = id; + +} + +void can_irq_free(can_t *obj) +{ + CAN_DisableInt((CAN_T *)obj->can, (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk)); + + can_irq_ids[obj->index] = 0; + + if(!obj->index) + NVIC_DisableIRQ(CAN0_IRQn); + else + NVIC_DisableIRQ(CAN1_IRQn); + + +} + +void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable) +{ + + CAN_EnterInitMode((CAN_T*)obj->can); + + ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON ) | ((enable != 0 )? CAN_CON_IE_Msk :0); + + switch (irq) + { + case IRQ_ERROR: + //case IRQ_PASSIVE: + //case IRQ_ARB: + ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_EIE_Msk; + break; + + case IRQ_RX: + case IRQ_TX: + case IRQ_BUS: + case IRQ_OVERRUN: + case IRQ_WAKEUP: + ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_SIE_Msk; + break; + + default: + break; + + } + + CAN_LeaveInitMode((CAN_T*)obj->can); + + if(!obj->index) + { + NVIC_SetVector(CAN0_IRQn, (uint32_t)&CAN0_IRQHandler); + NVIC_EnableIRQ(CAN0_IRQn); + } + else + { + NVIC_SetVector(CAN1_IRQn, (uint32_t)&CAN1_IRQHandler); + NVIC_EnableIRQ(CAN1_IRQn); + } + +} + +int can_write(can_t *obj, CAN_Message msg, int cc) +{ + STR_CANMSG_T CMsg; + + CMsg.IdType = (uint32_t)msg.format; + CMsg.FrameType = (uint32_t)!msg.type; + CMsg.Id = msg.id; + CMsg.DLC = msg.len; + memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8); + + return CAN_Transmit((CAN_T *)(obj->can), cc, &CMsg); +} + +int can_read(can_t *obj, CAN_Message *msg, int handle) +{ + STR_CANMSG_T CMsg; + + if(!CAN_Receive((CAN_T *)(obj->can), handle, &CMsg)) + return 0; + + msg->format = (CANFormat)CMsg.IdType; + msg->type = (CANType)!CMsg.FrameType; + msg->id = CMsg.Id; + msg->len = CMsg.DLC; + memcpy(&msg->data[0], &CMsg.Data[0], 8); + + return 1; +} + +int can_mode(can_t *obj, CanMode mode) +{ + int success = 0; + switch (mode) + { + case MODE_RESET: + CAN_LeaveTestMode((CAN_T*)obj->can); + success = 1; + break; + + case MODE_NORMAL: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_BASIC_Msk); + success = 1; + break; + + case MODE_SILENT: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk); + success = 1; + break; + + case MODE_TEST_LOCAL: + case MODE_TEST_GLOBAL: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_LBACK_Msk); + success = 1; + break; + + case MODE_TEST_SILENT: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk | CAN_TEST_LBACK_Msk); + success = 1; + break; + + default: + success = 0; + break; + + } + + + return success; +} + +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) +{ + return CAN_SetRxMsg((CAN_T *)(obj->can), handle , (uint32_t)format, id); +} + + +void can_reset(can_t *obj) +{ + const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); + + MBED_ASSERT(modinit != NULL); + MBED_ASSERT(modinit->modname == obj->can); + + // Reset this module + SYS_ResetModule(modinit->rsetidx); + +} + +unsigned char can_rderror(can_t *obj) +{ + CAN_T *can = (CAN_T *)(obj->can); + return ((can->ERR>>8)&0xFF); +} + +unsigned char can_tderror(can_t *obj) +{ + CAN_T *can = (CAN_T *)(obj->can); + return ((can->ERR)&0xFF); +} + +void can_monitor(can_t *obj, int silent) +{ + CAN_EnterTestMode((CAN_T *)(obj->can), CAN_TEST_SILENT_Msk); +} + +#endif // DEVICE_CAN diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_can.h b/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_can.h index 4d487119751..65e63fa7474 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_can.h +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_can.h @@ -150,6 +150,11 @@ int32_t CAN_SetMultiRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32MsgCount int32_t CAN_SetRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint32_t u32ID); int32_t CAN_SetTxMsg(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg); int32_t CAN_TriggerTxMsg(CAN_T *tCAN, uint32_t u32MsgNum); +uint32_t CAN_GetCANBitRate(CAN_T *tCAN); +void CAN_EnterInitMode(CAN_T *tCAN); +void CAN_LeaveInitMode(CAN_T *tCAN); +void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask); +void CAN_LeaveTestMode(CAN_T *tCAN); /*@}*/ /* end of group NUC472_442_CAN_EXPORTED_FUNCTIONS */ From ad329f79b8b3ab4eb4d1817e34e7aa160fd4869a Mon Sep 17 00:00:00 2001 From: cyliangtw Date: Thu, 20 Oct 2016 13:44:34 +0800 Subject: [PATCH 082/107] Support CAN --- .../TARGET_NUMAKER_PFM_M453/PeripheralNames.h | 4 + .../TARGET_NUMAKER_PFM_M453/PeripheralPins.c | 16 + .../TARGET_NUMAKER_PFM_M453/PeripheralPins.h | 5 + .../TARGET_NUMAKER_PFM_M453/device.h | 2 +- .../TARGET_NUMAKER_PFM_M453/objects.h | 4 + targets/TARGET_NUVOTON/TARGET_M451/can_api.c | 306 ++++++++++++++++++ .../TARGET_M451/device/StdDriver/m451_can.h | 6 +- targets/targets.json | 4 +- 8 files changed, 343 insertions(+), 4 deletions(-) create mode 100644 targets/TARGET_NUVOTON/TARGET_M451/can_api.c diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralNames.h b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralNames.h index c08e2cef5a0..17f54002997 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralNames.h +++ b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralNames.h @@ -110,6 +110,10 @@ typedef enum { DMA_0 = (int) NU_MODNAME(PDMA_BASE, 0) } DMAName; +typedef enum { + CAN_0 = (int) NU_MODNAME(CAN0_BASE, 0) +} CANName; + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.c b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.c index 7b58a28abe9..1992ecf8762 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.c @@ -359,3 +359,19 @@ const PinMap PinMap_SPI_SSEL[] = { {NC, NC, 0} }; + +const PinMap PinMap_CAN_TD[] = { + {PC_0, CAN_0, SYS_GPC_MFPL_PC0MFP_CAN0_TXD}, + {PA_1, CAN_0, SYS_GPA_MFPL_PA1MFP_CAN0_TXD}, + {PA_12, CAN_0, SYS_GPA_MFPH_PA12MFP_CAN0_TXD}, + + {NC, NC, 0} +}; + +const PinMap PinMap_CAN_RD[] = { + {PC_1, CAN_0, SYS_GPC_MFPL_PC1MFP_CAN0_RXD}, + {PA_0, CAN_0, SYS_GPA_MFPL_PA0MFP_CAN0_RXD}, + {PA_13, CAN_0, SYS_GPA_MFPH_PA13MFP_CAN0_RXD}, + + {NC, NC, 0} +}; diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.h b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.h index 6c9a26b865e..1f2eb94dee6 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.h +++ b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.h @@ -65,6 +65,11 @@ extern const PinMap PinMap_SD_DAT1[]; extern const PinMap PinMap_SD_DAT2[]; extern const PinMap PinMap_SD_DAT3[]; +//*** CAN *** + +extern PinMap const PinMap_CAN_TD[]; +extern PinMap const PinMap_CAN_RD[]; + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/device.h b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/device.h index 89e12ecd417..7e1fc957528 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/device.h +++ b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/device.h @@ -38,7 +38,7 @@ #define DEVICE_SPI_ASYNCH 1 #define DEVICE_SPISLAVE 1 -#define DEVICE_CAN 0 +//#define DEVICE_CAN 1 #define DEVICE_RTC 1 diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/objects.h b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/objects.h index e06ff861eb7..eee0c0bf77a 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/objects.h +++ b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/objects.h @@ -123,6 +123,10 @@ struct sleep_s { int powerdown; }; +struct can_s { + CANName can; + char index; +}; #ifdef __cplusplus } #endif diff --git a/targets/TARGET_NUVOTON/TARGET_M451/can_api.c b/targets/TARGET_NUVOTON/TARGET_M451/can_api.c new file mode 100644 index 00000000000..20a56e27e83 --- /dev/null +++ b/targets/TARGET_NUVOTON/TARGET_M451/can_api.c @@ -0,0 +1,306 @@ +/* mbed Microcontroller Library + * Copyright (c) 2015-2016 Nuvoton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "can_api.h" + #include "m451_gpio.h" + #include "m451_can.h" + + #if DEVICE_CAN + #include + #include "cmsis.h" + #include "pinmap.h" + #include "PeripheralPins.h" + #include "nu_modutil.h" + #include "nu_miscutil.h" + #include "nu_bitutil.h" + #include "critical.h" + + #define NU_CAN_DEBUG 0 + #define CAN_NUM 1 + + static uint32_t can_irq_ids[CAN_NUM] = {0}; + static can_irq_handler can0_irq_handler; + + + static const struct nu_modinit_s can_modinit_tab[] = { + {CAN_0, CAN0_MODULE, 0, 0, CAN0_RST, CAN0_IRQn, NULL}, + + {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL} +}; + + + void can_init(can_t *obj, PinName rd, PinName td) + { + uint32_t can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); + uint32_t can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); + obj->can = (CANName)pinmap_merge(can_td, can_rd); + MBED_ASSERT((int)obj->can != NC); + + const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); + MBED_ASSERT(modinit != NULL); + MBED_ASSERT(modinit->modname == obj->can); + + // Reset this module + SYS_ResetModule(modinit->rsetidx); + + // Enable IP clock + CLK_EnableModuleClock(modinit->clkidx); + + obj->index = 0; + + pinmap_pinout(td, PinMap_CAN_TD); + pinmap_pinout(rd, PinMap_CAN_RD); + + /* For M453 mbed Board Transmitter Setting (RS Pin) */ + GPIO_SetMode(PA, BIT0| BIT1, GPIO_MODE_OUTPUT); + PA0 = 0x00; + PA1 = 0x00; + + CAN_Open((CAN_T *)obj->can, 500000, CAN_NORMAL_MODE); + + can_filter(obj, 0, 0, CANStandard, 0); + } + + +void can_free(can_t *obj) +{ + + const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); + + MBED_ASSERT(modinit != NULL); + MBED_ASSERT(modinit->modname == obj->can); + + // Reset this module + SYS_ResetModule(modinit->rsetidx); + + CLK_DisableModuleClock(modinit->clkidx); +} + +int can_frequency(can_t *obj, int hz) +{ + CAN_SetBaudRate((CAN_T *)obj->can, hz); + + return CAN_GetCANBitRate((CAN_T *)obj->can); +} + +static void can_irq(CANName name, int id) +{ + + CAN_T *can = (CAN_T *)NU_MODBASE(name); + uint32_t u8IIDRstatus; + + u8IIDRstatus = can->IIDR; + + if(u8IIDRstatus == 0x00008000) { /* Check Status Interrupt Flag (Error status Int and Status change Int) */ + /**************************/ + /* Status Change interrupt*/ + /**************************/ + if(can->STATUS & CAN_STATUS_RXOK_Msk) { + can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/ + can0_irq_handler(can_irq_ids[id], IRQ_RX); + } + + if(can->STATUS & CAN_STATUS_TXOK_Msk) { + can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/ + can0_irq_handler(can_irq_ids[id], IRQ_TX); + } + + /**************************/ + /* Error Status interrupt */ + /**************************/ + if(can->STATUS & CAN_STATUS_EWARN_Msk) { + can0_irq_handler(can_irq_ids[id], IRQ_ERROR); + } + + if(can->STATUS & CAN_STATUS_BOFF_Msk) { + can0_irq_handler(can_irq_ids[id], IRQ_BUS); + } + } else if (u8IIDRstatus!=0) { + + //CAN_MsgInterrupt(can, u8IIDRstatus); + + can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN); + + CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */ + + } else if(can->WU_STATUS == 1) { + + can->WU_STATUS = 0; /* Write '0' to clear */ + can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP); + } +} + +void CAN0_IRQHandler(void) +{ + can_irq(CAN_0, 0); +} + +void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) +{ + can0_irq_handler = handler; + can_irq_ids[obj->index] = id; +} + +void can_irq_free(can_t *obj) +{ + CAN_DisableInt((CAN_T *)obj->can, (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk)); + + can_irq_ids[obj->index] = 0; + + NVIC_DisableIRQ(CAN0_IRQn); +} + +void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable) +{ + + CAN_EnterInitMode((CAN_T*)obj->can, ((enable != 0 )? CAN_CON_IE_Msk :0) ); + +// ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON ) | ((enable != 0 )? CAN_CON_IE_Msk :0); + + switch (irq) + { + case IRQ_ERROR: + //case IRQ_PASSIVE: + //case IRQ_ARB: + ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_EIE_Msk; + break; + + case IRQ_RX: + case IRQ_TX: + case IRQ_BUS: + case IRQ_OVERRUN: + case IRQ_WAKEUP: + ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_SIE_Msk; + break; + + default: + break; + + } + + CAN_LeaveInitMode((CAN_T*)obj->can); + + NVIC_SetVector(CAN0_IRQn, (uint32_t)&CAN0_IRQHandler); + NVIC_EnableIRQ(CAN0_IRQn); + +} + +int can_write(can_t *obj, CAN_Message msg, int cc) +{ + STR_CANMSG_T CMsg; + + CMsg.IdType = (uint32_t)msg.format; + CMsg.FrameType = (uint32_t)!msg.type; + CMsg.Id = msg.id; + CMsg.DLC = msg.len; + memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8); + + return CAN_Transmit((CAN_T *)(obj->can), cc, &CMsg); +} + +int can_read(can_t *obj, CAN_Message *msg, int handle) +{ + STR_CANMSG_T CMsg; + + if(!CAN_Receive((CAN_T *)(obj->can), handle, &CMsg)) + return 0; + + msg->format = (CANFormat)CMsg.IdType; + msg->type = (CANType)!CMsg.FrameType; + msg->id = CMsg.Id; + msg->len = CMsg.DLC; + memcpy(&msg->data[0], &CMsg.Data[0], 8); + + return 1; +} + +int can_mode(can_t *obj, CanMode mode) +{ + int success = 0; + switch (mode) + { + case MODE_RESET: + CAN_LeaveTestMode((CAN_T*)obj->can); + success = 1; + break; + + case MODE_NORMAL: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_BASIC_Msk); + success = 1; + break; + + case MODE_SILENT: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk); + success = 1; + break; + + case MODE_TEST_LOCAL: + case MODE_TEST_GLOBAL: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_LBACK_Msk); + success = 1; + break; + + case MODE_TEST_SILENT: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk | CAN_TEST_LBACK_Msk); + success = 1; + break; + + default: + success = 0; + break; + + } + + + return success; +} + +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) +{ + return CAN_SetRxMsg((CAN_T *)(obj->can), handle , (uint32_t)format, id); +} + + +void can_reset(can_t *obj) +{ + const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); + + MBED_ASSERT(modinit != NULL); + MBED_ASSERT(modinit->modname == obj->can); + + // Reset this module + SYS_ResetModule(modinit->rsetidx); + +} + +unsigned char can_rderror(can_t *obj) +{ + CAN_T *can = (CAN_T *)(obj->can); + return ((can->ERR>>8)&0xFF); +} + +unsigned char can_tderror(can_t *obj) +{ + CAN_T *can = (CAN_T *)(obj->can); + return ((can->ERR)&0xFF); +} + +void can_monitor(can_t *obj, int silent) +{ + CAN_EnterTestMode((CAN_T *)(obj->can), CAN_TEST_SILENT_Msk); +} + +#endif // DEVICE_CAN diff --git a/targets/TARGET_NUVOTON/TARGET_M451/device/StdDriver/m451_can.h b/targets/TARGET_NUVOTON/TARGET_M451/device/StdDriver/m451_can.h index 7f661c3bb04..d2427af227b 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/device/StdDriver/m451_can.h +++ b/targets/TARGET_NUVOTON/TARGET_M451/device/StdDriver/m451_can.h @@ -158,7 +158,11 @@ int32_t CAN_SetRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint3 int32_t CAN_SetRxMsgAndMsk(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint32_t u32ID, uint32_t u32IDMask); int32_t CAN_SetTxMsg(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg); int32_t CAN_TriggerTxMsg(CAN_T *tCAN, uint32_t u32MsgNum); - +uint32_t CAN_GetCANBitRate(CAN_T *tCAN); +void CAN_EnterInitMode(CAN_T *tCAN, uint8_t u8Mask); +void CAN_LeaveInitMode(CAN_T *tCAN); +void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask); +void CAN_LeaveTestMode(CAN_T *tCAN); /*@}*/ /* end of group CAN_EXPORTED_FUNCTIONS */ diff --git a/targets/targets.json b/targets/targets.json index 953adeb8b06..2bbacc11df0 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -2355,7 +2355,7 @@ "is_disk_virtual": true, "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "inherits": ["Target"], - "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "TRNG"], + "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "TRNG", "CAN"], "features": ["LWIP"], "release_versions": ["5"], "device_name": "NUC472HI8AE" @@ -2379,7 +2379,7 @@ "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "inherits": ["Target"], "progen": {"target": "numaker-pfm-m453"}, - "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH"], + "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "CAN"], "release_versions": ["2", "5"], "device_name": "M453VG6AE" }, From b0df87c149fdf28cfdff90fa3e656022df3b5d9e Mon Sep 17 00:00:00 2001 From: cyliangtw Date: Fri, 21 Oct 2016 14:01:17 +0800 Subject: [PATCH 083/107] Fix SetBaudRate 5% inaccuracy issue --- .../device/StdDriver/nuc472_can.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_can.c b/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_can.c index c779e6ec958..cfdf751a99e 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_can.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_can.c @@ -419,6 +419,7 @@ uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate) SystemCoreClockUpdate(); +#if 0 // original implementation got 5% inaccuracy. u32Value = SystemCoreClock; if(u32BaudRate * 8 < (u32Value/2)) { @@ -428,7 +429,26 @@ uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate) u8Tseg1 = 2; u8Tseg2 = 1; } +#else + u32Value = SystemCoreClock / u32BaudRate; + /* Fix for most standard baud rates, include 125K */ + + u8Tseg1 = 3; + u8Tseg2 = 2; + while(1) + { + if(((u32Value % (u8Tseg1 + u8Tseg2 + 3)) == 0) | (u8Tseg1 >= 15)) + break; + + u8Tseg1++; + if((u32Value % (u8Tseg1 + u8Tseg2 + 3)) == 0) + break; + + if(u8Tseg2 < 7) + u8Tseg2++; + } +#endif u32Brp = SystemCoreClock/(u32BaudRate) / (u8Tseg1 + u8Tseg2 + 3) -1; u32Value = ((uint32_t)u8Tseg2 << CAN_BTIME_TSEG2_Pos) | ((uint32_t)u8Tseg1 << CAN_BTIME_TSEG1_Pos) | From 83d657b1daeaec3cce78c95a33affa85c56a6c86 Mon Sep 17 00:00:00 2001 From: cyliangtw Date: Thu, 27 Oct 2016 16:31:29 +0800 Subject: [PATCH 084/107] replace tab by 4 space char --- targets/TARGET_NUVOTON/TARGET_M451/can_api.c | 214 +++++++-------- .../TARGET_NUVOTON/TARGET_NUC472/can_api.c | 258 +++++++++--------- 2 files changed, 236 insertions(+), 236 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/can_api.c b/targets/TARGET_NUVOTON/TARGET_M451/can_api.c index 20a56e27e83..f135575809f 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/can_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/can_api.c @@ -122,24 +122,24 @@ static void can_irq(CANName name, int id) /* Error Status interrupt */ /**************************/ if(can->STATUS & CAN_STATUS_EWARN_Msk) { - can0_irq_handler(can_irq_ids[id], IRQ_ERROR); + can0_irq_handler(can_irq_ids[id], IRQ_ERROR); } if(can->STATUS & CAN_STATUS_BOFF_Msk) { - can0_irq_handler(can_irq_ids[id], IRQ_BUS); + can0_irq_handler(can_irq_ids[id], IRQ_BUS); } } else if (u8IIDRstatus!=0) { //CAN_MsgInterrupt(can, u8IIDRstatus); - can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN); - + can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN); + CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */ } else if(can->WU_STATUS == 1) { can->WU_STATUS = 0; /* Write '0' to clear */ - can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP); + can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP); } } @@ -150,157 +150,157 @@ void CAN0_IRQHandler(void) void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) { - can0_irq_handler = handler; - can_irq_ids[obj->index] = id; + can0_irq_handler = handler; + can_irq_ids[obj->index] = id; } void can_irq_free(can_t *obj) { - CAN_DisableInt((CAN_T *)obj->can, (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk)); - - can_irq_ids[obj->index] = 0; - - NVIC_DisableIRQ(CAN0_IRQn); + CAN_DisableInt((CAN_T *)obj->can, (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk)); + + can_irq_ids[obj->index] = 0; + + NVIC_DisableIRQ(CAN0_IRQn); } void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable) { - - CAN_EnterInitMode((CAN_T*)obj->can, ((enable != 0 )? CAN_CON_IE_Msk :0) ); - + + CAN_EnterInitMode((CAN_T*)obj->can, ((enable != 0 )? CAN_CON_IE_Msk :0) ); + // ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON ) | ((enable != 0 )? CAN_CON_IE_Msk :0); - - switch (irq) - { - case IRQ_ERROR: - //case IRQ_PASSIVE: - //case IRQ_ARB: - ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_EIE_Msk; - break; - - case IRQ_RX: - case IRQ_TX: - case IRQ_BUS: - case IRQ_OVERRUN: - case IRQ_WAKEUP: - ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_SIE_Msk; - break; - - default: - break; - - } + + switch (irq) + { + case IRQ_ERROR: + //case IRQ_PASSIVE: + //case IRQ_ARB: + ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_EIE_Msk; + break; + + case IRQ_RX: + case IRQ_TX: + case IRQ_BUS: + case IRQ_OVERRUN: + case IRQ_WAKEUP: + ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_SIE_Msk; + break; + + default: + break; + + } CAN_LeaveInitMode((CAN_T*)obj->can); - - NVIC_SetVector(CAN0_IRQn, (uint32_t)&CAN0_IRQHandler); - NVIC_EnableIRQ(CAN0_IRQn); - + + NVIC_SetVector(CAN0_IRQn, (uint32_t)&CAN0_IRQHandler); + NVIC_EnableIRQ(CAN0_IRQn); + } int can_write(can_t *obj, CAN_Message msg, int cc) { - STR_CANMSG_T CMsg; - - CMsg.IdType = (uint32_t)msg.format; - CMsg.FrameType = (uint32_t)!msg.type; - CMsg.Id = msg.id; - CMsg.DLC = msg.len; - memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8); + STR_CANMSG_T CMsg; + + CMsg.IdType = (uint32_t)msg.format; + CMsg.FrameType = (uint32_t)!msg.type; + CMsg.Id = msg.id; + CMsg.DLC = msg.len; + memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8); - return CAN_Transmit((CAN_T *)(obj->can), cc, &CMsg); + return CAN_Transmit((CAN_T *)(obj->can), cc, &CMsg); } int can_read(can_t *obj, CAN_Message *msg, int handle) { - STR_CANMSG_T CMsg; + STR_CANMSG_T CMsg; - if(!CAN_Receive((CAN_T *)(obj->can), handle, &CMsg)) - return 0; - - msg->format = (CANFormat)CMsg.IdType; - msg->type = (CANType)!CMsg.FrameType; - msg->id = CMsg.Id; - msg->len = CMsg.DLC; - memcpy(&msg->data[0], &CMsg.Data[0], 8); - - return 1; + if(!CAN_Receive((CAN_T *)(obj->can), handle, &CMsg)) + return 0; + + msg->format = (CANFormat)CMsg.IdType; + msg->type = (CANType)!CMsg.FrameType; + msg->id = CMsg.Id; + msg->len = CMsg.DLC; + memcpy(&msg->data[0], &CMsg.Data[0], 8); + + return 1; } int can_mode(can_t *obj, CanMode mode) { - int success = 0; - switch (mode) - { - case MODE_RESET: - CAN_LeaveTestMode((CAN_T*)obj->can); - success = 1; - break; - - case MODE_NORMAL: - CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_BASIC_Msk); - success = 1; - break; - - case MODE_SILENT: - CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk); - success = 1; - break; - - case MODE_TEST_LOCAL: - case MODE_TEST_GLOBAL: - CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_LBACK_Msk); - success = 1; - break; - - case MODE_TEST_SILENT: - CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk | CAN_TEST_LBACK_Msk); - success = 1; - break; - - default: - success = 0; - break; - - } - - - return success; + int success = 0; + switch (mode) + { + case MODE_RESET: + CAN_LeaveTestMode((CAN_T*)obj->can); + success = 1; + break; + + case MODE_NORMAL: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_BASIC_Msk); + success = 1; + break; + + case MODE_SILENT: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk); + success = 1; + break; + + case MODE_TEST_LOCAL: + case MODE_TEST_GLOBAL: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_LBACK_Msk); + success = 1; + break; + + case MODE_TEST_SILENT: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk | CAN_TEST_LBACK_Msk); + success = 1; + break; + + default: + success = 0; + break; + + } + + + return success; } int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) { - return CAN_SetRxMsg((CAN_T *)(obj->can), handle , (uint32_t)format, id); + return CAN_SetRxMsg((CAN_T *)(obj->can), handle , (uint32_t)format, id); } void can_reset(can_t *obj) { - const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); - - MBED_ASSERT(modinit != NULL); + const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); + + MBED_ASSERT(modinit != NULL); MBED_ASSERT(modinit->modname == obj->can); // Reset this module SYS_ResetModule(modinit->rsetidx); - + } unsigned char can_rderror(can_t *obj) { - CAN_T *can = (CAN_T *)(obj->can); - return ((can->ERR>>8)&0xFF); + CAN_T *can = (CAN_T *)(obj->can); + return ((can->ERR>>8)&0xFF); } unsigned char can_tderror(can_t *obj) { - CAN_T *can = (CAN_T *)(obj->can); - return ((can->ERR)&0xFF); + CAN_T *can = (CAN_T *)(obj->can); + return ((can->ERR)&0xFF); } void can_monitor(can_t *obj, int silent) { - CAN_EnterTestMode((CAN_T *)(obj->can), CAN_TEST_SILENT_Msk); + CAN_EnterTestMode((CAN_T *)(obj->can), CAN_TEST_SILENT_Msk); } -#endif // DEVICE_CAN +#endif // DEVICE_CAN diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c index 65734720a7c..923dcd6243b 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c @@ -29,7 +29,7 @@ #include "critical.h" #define NU_CAN_DEBUG 0 - #define CAN_NUM 2 + #define CAN_NUM 2 static uint32_t can_irq_ids[CAN_NUM] = {0}; static can_irq_handler can0_irq_handler; @@ -46,7 +46,7 @@ void can_init(can_t *obj, PinName rd, PinName td) { - uint32_t can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); + uint32_t can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); uint32_t can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); obj->can = (CANName)pinmap_merge(can_td, can_rd); MBED_ASSERT((int)obj->can != NC); @@ -60,22 +60,22 @@ // Enable IP clock CLK_EnableModuleClock(modinit->clkidx); - - if(obj->can == CAN_1) { + + if(obj->can == CAN_1) { obj->index = 1; } - else - obj->index = 0; - + else + obj->index = 0; + pinmap_pinout(td, PinMap_CAN_TD); pinmap_pinout(rd, PinMap_CAN_RD); - /* For NCU 472 mbed Board Transmitter Setting (RS Pin) */ + /* For NCU 472 mbed Board Transmitter Setting (RS Pin) */ GPIO_SetMode(PA, BIT2| BIT3, GPIO_MODE_OUTPUT); PA2 = 0x00; PA3 = 0x00; - CAN_Open((CAN_T *)obj->can, 500000, CAN_NORMAL_MODE); + CAN_Open((CAN_T *)obj->can, 500000, CAN_NORMAL_MODE); can_filter(obj, 0, 0, CANStandard, 0); } @@ -84,29 +84,29 @@ void can_free(can_t *obj) { - const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); - - MBED_ASSERT(modinit != NULL); + const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); + + MBED_ASSERT(modinit != NULL); MBED_ASSERT(modinit->modname == obj->can); // Reset this module SYS_ResetModule(modinit->rsetidx); - - CLK_DisableModuleClock(modinit->clkidx); + + CLK_DisableModuleClock(modinit->clkidx); } int can_frequency(can_t *obj, int hz) { - CAN_SetBaudRate((CAN_T *)obj->can, hz); - - return CAN_GetCANBitRate((CAN_T *)obj->can); + CAN_SetBaudRate((CAN_T *)obj->can, hz); + + return CAN_GetCANBitRate((CAN_T *)obj->can); } static void can_irq(CANName name, int id) { - - CAN_T *can = (CAN_T *)NU_MODBASE(name); - uint32_t u8IIDRstatus; + + CAN_T *can = (CAN_T *)NU_MODBASE(name); + uint32_t u8IIDRstatus; u8IIDRstatus = can->IIDR; @@ -116,18 +116,18 @@ static void can_irq(CANName name, int id) /**************************/ if(can->STATUS & CAN_STATUS_RXOK_Msk) { can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/ - if(id) - can1_irq_handler(can_irq_ids[id] , IRQ_RX); - else - can0_irq_handler(can_irq_ids[id], IRQ_RX); + if(id) + can1_irq_handler(can_irq_ids[id] , IRQ_RX); + else + can0_irq_handler(can_irq_ids[id], IRQ_RX); } if(can->STATUS & CAN_STATUS_TXOK_Msk) { can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/ - if(id) - can1_irq_handler(can_irq_ids[id] , IRQ_TX); - else - can0_irq_handler(can_irq_ids[id], IRQ_TX); + if(id) + can1_irq_handler(can_irq_ids[id] , IRQ_TX); + else + can0_irq_handler(can_irq_ids[id], IRQ_TX); } @@ -135,35 +135,35 @@ static void can_irq(CANName name, int id) /* Error Status interrupt */ /**************************/ if(can->STATUS & CAN_STATUS_EWARN_Msk) { - if(id) - can1_irq_handler(can_irq_ids[id] , IRQ_ERROR); - else - can0_irq_handler(can_irq_ids[id], IRQ_ERROR); + if(id) + can1_irq_handler(can_irq_ids[id] , IRQ_ERROR); + else + can0_irq_handler(can_irq_ids[id], IRQ_ERROR); } if(can->STATUS & CAN_STATUS_BOFF_Msk) { - if(id) - can1_irq_handler(can_irq_ids[id] , IRQ_BUS); - else - can0_irq_handler(can_irq_ids[id], IRQ_BUS); + if(id) + can1_irq_handler(can_irq_ids[id] , IRQ_BUS); + else + can0_irq_handler(can_irq_ids[id], IRQ_BUS); } } else if (u8IIDRstatus!=0) { //CAN_MsgInterrupt(can, u8IIDRstatus); - if(id) - can1_irq_handler(can_irq_ids[id] , IRQ_OVERRUN); - else - can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN); - + if(id) + can1_irq_handler(can_irq_ids[id] , IRQ_OVERRUN); + else + can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN); + CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */ } else if(can->WU_STATUS == 1) { can->WU_STATUS = 0; /* Write '0' to clear */ - if(id) - can1_irq_handler(can_irq_ids[id] , IRQ_WAKEUP); - else - can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP); + if(id) + can1_irq_handler(can_irq_ids[id] , IRQ_WAKEUP); + else + can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP); } } @@ -179,79 +179,79 @@ void CAN1_IRQHandler(void) void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) { - if(obj->index) - can1_irq_handler = handler; - else - can0_irq_handler = handler; - can_irq_ids[obj->index] = id; + if(obj->index) + can1_irq_handler = handler; + else + can0_irq_handler = handler; + can_irq_ids[obj->index] = id; } void can_irq_free(can_t *obj) { - CAN_DisableInt((CAN_T *)obj->can, (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk)); - - can_irq_ids[obj->index] = 0; - - if(!obj->index) - NVIC_DisableIRQ(CAN0_IRQn); - else - NVIC_DisableIRQ(CAN1_IRQn); - - + CAN_DisableInt((CAN_T *)obj->can, (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk)); + + can_irq_ids[obj->index] = 0; + + if(!obj->index) + NVIC_DisableIRQ(CAN0_IRQn); + else + NVIC_DisableIRQ(CAN1_IRQn); + + } void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable) { - - CAN_EnterInitMode((CAN_T*)obj->can); - + + CAN_EnterInitMode((CAN_T*)obj->can); + ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON ) | ((enable != 0 )? CAN_CON_IE_Msk :0); - - switch (irq) - { - case IRQ_ERROR: - //case IRQ_PASSIVE: - //case IRQ_ARB: - ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_EIE_Msk; - break; - - case IRQ_RX: - case IRQ_TX: - case IRQ_BUS: - case IRQ_OVERRUN: - case IRQ_WAKEUP: - ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_SIE_Msk; - break; - - default: - break; - - } + + switch (irq) + { + case IRQ_ERROR: + //case IRQ_PASSIVE: + //case IRQ_ARB: + ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_EIE_Msk; + break; + + case IRQ_RX: + case IRQ_TX: + case IRQ_BUS: + case IRQ_OVERRUN: + case IRQ_WAKEUP: + ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_SIE_Msk; + break; + + default: + break; + + } CAN_LeaveInitMode((CAN_T*)obj->can); - - if(!obj->index) - { - NVIC_SetVector(CAN0_IRQn, (uint32_t)&CAN0_IRQHandler); - NVIC_EnableIRQ(CAN0_IRQn); - } - else - { - NVIC_SetVector(CAN1_IRQn, (uint32_t)&CAN1_IRQHandler); - NVIC_EnableIRQ(CAN1_IRQn); - } - + + if(!obj->index) + { + NVIC_SetVector(CAN0_IRQn, (uint32_t)&CAN0_IRQHandler); + NVIC_EnableIRQ(CAN0_IRQn); + } + else + { + NVIC_SetVector(CAN1_IRQn, (uint32_t)&CAN1_IRQHandler); + NVIC_EnableIRQ(CAN1_IRQn); + } + } int can_write(can_t *obj, CAN_Message msg, int cc) { - STR_CANMSG_T CMsg; - - CMsg.IdType = (uint32_t)msg.format; - CMsg.FrameType = (uint32_t)!msg.type; - CMsg.Id = msg.id; - CMsg.DLC = msg.len; + STR_CANMSG_T CMsg; + + CMsg.IdType = (uint32_t)msg.format; + CMsg.FrameType = (uint32_t)!msg.type; + CMsg.Id = msg.id; + CMsg.DLC = msg.len; memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8); return CAN_Transmit((CAN_T *)(obj->can), cc, &CMsg); @@ -264,10 +264,10 @@ int can_read(can_t *obj, CAN_Message *msg, int handle) if(!CAN_Receive((CAN_T *)(obj->can), handle, &CMsg)) return 0; - msg->format = (CANFormat)CMsg.IdType; - msg->type = (CANType)!CMsg.FrameType; - msg->id = CMsg.Id; - msg->len = CMsg.DLC; + msg->format = (CANFormat)CMsg.IdType; + msg->type = (CANType)!CMsg.FrameType; + msg->id = CMsg.Id; + msg->len = CMsg.DLC; memcpy(&msg->data[0], &CMsg.Data[0], 8); return 1; @@ -300,53 +300,53 @@ int can_mode(can_t *obj, CanMode mode) break; case MODE_TEST_SILENT: - CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk | CAN_TEST_LBACK_Msk); - success = 1; - break; - - default: - success = 0; - break; - - } - - - return success; + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk | CAN_TEST_LBACK_Msk); + success = 1; + break; + + default: + success = 0; + break; + + } + + + return success; } int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) { - return CAN_SetRxMsg((CAN_T *)(obj->can), handle , (uint32_t)format, id); + return CAN_SetRxMsg((CAN_T *)(obj->can), handle , (uint32_t)format, id); } void can_reset(can_t *obj) { - const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); - - MBED_ASSERT(modinit != NULL); + const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); + + MBED_ASSERT(modinit != NULL); MBED_ASSERT(modinit->modname == obj->can); // Reset this module SYS_ResetModule(modinit->rsetidx); - + } unsigned char can_rderror(can_t *obj) { - CAN_T *can = (CAN_T *)(obj->can); - return ((can->ERR>>8)&0xFF); + CAN_T *can = (CAN_T *)(obj->can); + return ((can->ERR>>8)&0xFF); } unsigned char can_tderror(can_t *obj) { - CAN_T *can = (CAN_T *)(obj->can); - return ((can->ERR)&0xFF); + CAN_T *can = (CAN_T *)(obj->can); + return ((can->ERR)&0xFF); } void can_monitor(can_t *obj, int silent) { - CAN_EnterTestMode((CAN_T *)(obj->can), CAN_TEST_SILENT_Msk); + CAN_EnterTestMode((CAN_T *)(obj->can), CAN_TEST_SILENT_Msk); } -#endif // DEVICE_CAN +#endif // DEVICE_CAN From a3698abee210427cf844b1d65b617179a943ae19 Mon Sep 17 00:00:00 2001 From: cyliangtw Date: Fri, 28 Oct 2016 18:39:56 +0800 Subject: [PATCH 085/107] remove dead code in device.h of NUC472 & M453 --- .../TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/device.h | 2 -- .../TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/device.h | 1 - 2 files changed, 3 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/device.h b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/device.h index 7e1fc957528..d87271b1fbb 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/device.h +++ b/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/device.h @@ -38,8 +38,6 @@ #define DEVICE_SPI_ASYNCH 1 #define DEVICE_SPISLAVE 1 -//#define DEVICE_CAN 1 - #define DEVICE_RTC 1 #define DEVICE_ETHERNET 0 diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/device.h b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/device.h index dbc69c2bf61..530a7a41e9b 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/device.h +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/device.h @@ -38,7 +38,6 @@ #define DEVICE_SPI_ASYNCH 1 #define DEVICE_SPISLAVE 1 -#define DEVICE_CAN 1 #define DEVICE_RTC 1 From 12f3cb8dae3edc43a44569931c765fa3c58140be Mon Sep 17 00:00:00 2001 From: cyliangtw Date: Tue, 1 Nov 2016 11:29:09 +0800 Subject: [PATCH 086/107] remove dead code in can_api.c of NUC472 & M453 --- targets/TARGET_NUVOTON/TARGET_M451/can_api.c | 9 +++------ targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c | 7 +++---- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/can_api.c b/targets/TARGET_NUVOTON/TARGET_M451/can_api.c index f135575809f..d5693286757 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/can_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/can_api.c @@ -130,8 +130,6 @@ static void can_irq(CANName name, int id) } } else if (u8IIDRstatus!=0) { - //CAN_MsgInterrupt(can, u8IIDRstatus); - can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN); CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */ @@ -168,19 +166,18 @@ void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable) CAN_EnterInitMode((CAN_T*)obj->can, ((enable != 0 )? CAN_CON_IE_Msk :0) ); -// ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON ) | ((enable != 0 )? CAN_CON_IE_Msk :0); switch (irq) { case IRQ_ERROR: - //case IRQ_PASSIVE: - //case IRQ_ARB: + case IRQ_BUS: + case IRQ_PASSIVE: ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_EIE_Msk; + ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_SIE_Msk; break; case IRQ_RX: case IRQ_TX: - case IRQ_BUS: case IRQ_OVERRUN: case IRQ_WAKEUP: ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_SIE_Msk; diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c index 923dcd6243b..6d13fe09f89 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c @@ -149,7 +149,6 @@ static void can_irq(CANName name, int id) } } else if (u8IIDRstatus!=0) { - //CAN_MsgInterrupt(can, u8IIDRstatus); if(id) can1_irq_handler(can_irq_ids[id] , IRQ_OVERRUN); else @@ -211,14 +210,14 @@ void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable) switch (irq) { case IRQ_ERROR: - //case IRQ_PASSIVE: - //case IRQ_ARB: + case IRQ_BUS: + case IRQ_PASSIVE: ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_EIE_Msk; + ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_SIE_Msk; break; case IRQ_RX: case IRQ_TX: - case IRQ_BUS: case IRQ_OVERRUN: case IRQ_WAKEUP: ((CAN_T *)(obj->can))->CON = (((CAN_T *)(obj->can))->CON) |CAN_CON_SIE_Msk; From f824231bce6c1c4dea6c89bdb9e95c8f2a838973 Mon Sep 17 00:00:00 2001 From: cyliangtw Date: Tue, 1 Nov 2016 11:44:44 +0800 Subject: [PATCH 087/107] fixed misaligned lines in can_api.c of NUC472 & M453 --- targets/TARGET_NUVOTON/TARGET_M451/can_api.c | 40 ++++----- .../TARGET_NUVOTON/TARGET_NUC472/can_api.c | 86 +++++++++---------- 2 files changed, 63 insertions(+), 63 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/can_api.c b/targets/TARGET_NUVOTON/TARGET_M451/can_api.c index d5693286757..c0c6daad21c 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/can_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/can_api.c @@ -29,7 +29,7 @@ #include "critical.h" #define NU_CAN_DEBUG 0 - #define CAN_NUM 1 + #define CAN_NUM 1 static uint32_t can_irq_ids[CAN_NUM] = {0}; static can_irq_handler can0_irq_handler; @@ -44,7 +44,7 @@ void can_init(can_t *obj, PinName rd, PinName td) { - uint32_t can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); + uint32_t can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); uint32_t can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); obj->can = (CANName)pinmap_merge(can_td, can_rd); MBED_ASSERT((int)obj->can != NC); @@ -58,18 +58,18 @@ // Enable IP clock CLK_EnableModuleClock(modinit->clkidx); - - obj->index = 0; - + + obj->index = 0; + pinmap_pinout(td, PinMap_CAN_TD); pinmap_pinout(rd, PinMap_CAN_RD); - /* For M453 mbed Board Transmitter Setting (RS Pin) */ + /* For M453 mbed Board Transmitter Setting (RS Pin) */ GPIO_SetMode(PA, BIT0| BIT1, GPIO_MODE_OUTPUT); PA0 = 0x00; PA1 = 0x00; - CAN_Open((CAN_T *)obj->can, 500000, CAN_NORMAL_MODE); + CAN_Open((CAN_T *)obj->can, 500000, CAN_NORMAL_MODE); can_filter(obj, 0, 0, CANStandard, 0); } @@ -78,29 +78,29 @@ void can_free(can_t *obj) { - const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); - - MBED_ASSERT(modinit != NULL); + const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab); + + MBED_ASSERT(modinit != NULL); MBED_ASSERT(modinit->modname == obj->can); // Reset this module SYS_ResetModule(modinit->rsetidx); - - CLK_DisableModuleClock(modinit->clkidx); + + CLK_DisableModuleClock(modinit->clkidx); } int can_frequency(can_t *obj, int hz) { - CAN_SetBaudRate((CAN_T *)obj->can, hz); - - return CAN_GetCANBitRate((CAN_T *)obj->can); + CAN_SetBaudRate((CAN_T *)obj->can, hz); + + return CAN_GetCANBitRate((CAN_T *)obj->can); } static void can_irq(CANName name, int id) { - - CAN_T *can = (CAN_T *)NU_MODBASE(name); - uint32_t u8IIDRstatus; + + CAN_T *can = (CAN_T *)NU_MODBASE(name); + uint32_t u8IIDRstatus; u8IIDRstatus = can->IIDR; @@ -110,12 +110,12 @@ static void can_irq(CANName name, int id) /**************************/ if(can->STATUS & CAN_STATUS_RXOK_Msk) { can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/ - can0_irq_handler(can_irq_ids[id], IRQ_RX); + can0_irq_handler(can_irq_ids[id], IRQ_RX); } if(can->STATUS & CAN_STATUS_TXOK_Msk) { can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/ - can0_irq_handler(can_irq_ids[id], IRQ_TX); + can0_irq_handler(can_irq_ids[id], IRQ_TX); } /**************************/ diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c index 6d13fe09f89..dd410b7e41f 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c @@ -248,58 +248,58 @@ int can_write(can_t *obj, CAN_Message msg, int cc) STR_CANMSG_T CMsg; CMsg.IdType = (uint32_t)msg.format; - CMsg.FrameType = (uint32_t)!msg.type; - CMsg.Id = msg.id; - CMsg.DLC = msg.len; - memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8); + CMsg.FrameType = (uint32_t)!msg.type; + CMsg.Id = msg.id; + CMsg.DLC = msg.len; + memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8); - return CAN_Transmit((CAN_T *)(obj->can), cc, &CMsg); + return CAN_Transmit((CAN_T *)(obj->can), cc, &CMsg); } int can_read(can_t *obj, CAN_Message *msg, int handle) { - STR_CANMSG_T CMsg; - - if(!CAN_Receive((CAN_T *)(obj->can), handle, &CMsg)) - return 0; - - msg->format = (CANFormat)CMsg.IdType; - msg->type = (CANType)!CMsg.FrameType; - msg->id = CMsg.Id; - msg->len = CMsg.DLC; - memcpy(&msg->data[0], &CMsg.Data[0], 8); - - return 1; + STR_CANMSG_T CMsg; + + if(!CAN_Receive((CAN_T *)(obj->can), handle, &CMsg)) + return 0; + + msg->format = (CANFormat)CMsg.IdType; + msg->type = (CANType)!CMsg.FrameType; + msg->id = CMsg.Id; + msg->len = CMsg.DLC; + memcpy(&msg->data[0], &CMsg.Data[0], 8); + + return 1; } int can_mode(can_t *obj, CanMode mode) { - int success = 0; - switch (mode) - { - case MODE_RESET: - CAN_LeaveTestMode((CAN_T*)obj->can); - success = 1; - break; - - case MODE_NORMAL: - CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_BASIC_Msk); - success = 1; - break; - - case MODE_SILENT: - CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk); - success = 1; - break; - - case MODE_TEST_LOCAL: - case MODE_TEST_GLOBAL: - CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_LBACK_Msk); - success = 1; - break; - - case MODE_TEST_SILENT: - CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk | CAN_TEST_LBACK_Msk); + int success = 0; + switch (mode) + { + case MODE_RESET: + CAN_LeaveTestMode((CAN_T*)obj->can); + success = 1; + break; + + case MODE_NORMAL: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_BASIC_Msk); + success = 1; + break; + + case MODE_SILENT: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk); + success = 1; + break; + + case MODE_TEST_LOCAL: + case MODE_TEST_GLOBAL: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_LBACK_Msk); + success = 1; + break; + + case MODE_TEST_SILENT: + CAN_EnterTestMode((CAN_T*)(obj->can), CAN_TEST_SILENT_Msk | CAN_TEST_LBACK_Msk); success = 1; break; From 9cf3c5688ad2fc291c4e46be16f81d3f477ff4ad Mon Sep 17 00:00:00 2001 From: Sarah Marsh Date: Wed, 2 Nov 2016 17:02:38 -0500 Subject: [PATCH 088/107] Exporter documentation --- docs/exporters.md | 60 ++++++++++++++++++++++++++++++++++ docs/mbed_targets.md | 3 +- tools/export/cmsis/__init__.py | 19 +++++++++-- tools/export/exporters.py | 9 ++++- 4 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 docs/exporters.md diff --git a/docs/exporters.md b/docs/exporters.md new file mode 100644 index 00000000000..eddbbdcaa36 --- /dev/null +++ b/docs/exporters.md @@ -0,0 +1,60 @@ +# About the exporters + +The mbed exporters are used to export your code to various 3rd party tools and IDEs. Each exporter implements a `generate` function that produces an IDE specific project file. Exporters benefit from [mbed build tools](https://github.com/ARMmbed/mbed-os/blob/master/docs/BUILDING.md#build-mbed-sdk-library-from-sources). However, instead of using your source and [config data](https://github.com/ARMmbed/mbed-os/blob/master/docs/config_system.md) to create an executable, we use that information to populate an IDE project file that will be configured to build, flash, and debug your code. You can find exporter implementations [here](https://github.com/ARMmbed/mbed-os/tree/master/tools/export). + +## mbed-cli command + +`mbed export -m [target] -i [IDE]` + +# Adding export support for a target + +If you have added new target to the mbed SDK, exporting will allow users to transition from mbed source code to the offline development environment of their choice. This functionality activates the use of your device for larger number of users. + +## Eclipse and Make + +Eclipse project export utilizes a generated Makefile for building. Other than target configuration within the [config system](https://github.com/ARMmbed/mbed-os/blob/master/docs/mbed_targets.md) for mbed build system support, there is no additional work to provide Make export. + +### Available mbed-cli commands + +`mbed export -m [target] -i [make_gcc_arm, make_iar, make_armc5, eclipse_gcc_arm, eclipse_iar, eclipse_armc5]` + +## UVision and IAR + +### CMSIS Packs + +UVision and IAR both utilize [CMSIS packs](http://www.keil.com/pack/doc/CMSIS/Pack/html/index.html) to find target information necessary to create a valid project file. + +We utilize the tool [ArmPackManager](https://github.com/ARMmbed/mbed-os/tree/master/tools/arm_pack_manager) to scrape [MDK5 Software Packs](https://www.keil.com/dd2/Pack/) for target information. This is achieved by parsing [http://www.keil.com/pack/index.idx](http://sadevicepacksprod.blob.core.windows.net/idxfile/index.idx). The relevant information in the [PDSC (Pack Description)](http://www.keil.com/pack/doc/CMSIS/Pack/html/_pack_format.html) retrieved from each URL in the index is stored in [index.json](https://github.com/ARMmbed/mbed-os/blob/master/tools/arm_pack_manager/index.json). A `.pdsc` file typically describes a family of devices. Each device is uniquely identified by its [device name](https://github.com/ARMmbed/mbed-os/blob/master/docs/mbed_targets.md#device_name). Thus, this name makes a natural key to associate a device with its information in `index.json`. + +#### What's in a device name? +There is no reliable way to map an mbed alias like [NUCLEO_F030R8](https://github.com/ARMmbed/mbed-os/blob/master/targets/targets.json#L603) to its unique identifier, [STM32F030R8](https://github.com/ARMmbed/mbed-os/blob/master/targets/targets.json#L615), as it is listed in a CMSIS pack (and subsequently `index.json`). So, we added a [device name](https://github.com/ARMmbed/mbed-os/blob/master/docs/mbed_targets.md#device_name) field in `targets.json`. **This field is required for IAR or UVision exporter support**. + +#### Code Usage +http://www.keil.com/pack/Keil.Kinetis_K20_DFP.pdsc is the PDSC that contains TEENSY_31 device (MK20DX256xxx7). It has been parsed by ArmPackManager and stored in `index.json`. The device information begins on line 156: +```xml + + + + + + + + + + + + + +``` + +##### Uvision +The dname (device name) field on line 156 directly corresponds to that in the Uvision5 IDE target selection window. [`tools/export/uvision/uvision.tmpl`](https://github.com/ARMmbed/mbed-os/blob/master/tools/export/uvision/uvision.tmpl#L15), uses target information from these packs is used to generate valid Uvision5 projects. If the device name is not found, we use a generic ARM CPU target in Uvision5. + +##### IAR +[`tools/export/iar/iar_definitions.json`](https://github.com/ARMmbed/mbed-os/blob/master/tools/export/iar/iar_definitions.json) utilizes this device name to store information necessary to set the target in an IAR project. + + + + + + diff --git a/docs/mbed_targets.md b/docs/mbed_targets.md index 94ad200f566..f460dcc646c 100644 --- a/docs/mbed_targets.md +++ b/docs/mbed_targets.md @@ -164,6 +164,5 @@ The hook code can look quite different between different targets. Take a look at This property is used to pass necessary data for exporting the mbed code to various 3rd party tools and IDEs. -This is possible because the device name corresponds to a field in publicly hosted CMSIS packs. These packs hold target properties. [This](http://www.keil.com/pack/Keil.Kinetis_K20_DFP.pdsc) is the pdsc that contains TEENSY_31 device (MK20DX256xxx7). The device information begins on line 156. The dname (device name) field on line 156 directly corresponds to that in the Uvision5 IDE target selection window. Beginning on line 15 of `tools/export/uvision/uvision.tmpl`, target information from these packs is used to generate valid Uvision5 projects. If the device name is not found, we use a generic ARM CPU target in Uvision5. -`tools/export/iar/iar_definitions.json` utilizes this device name to store information necessary to set the target in an IAR project. +Please see [exporters.md](exporters.md) for information about this field. diff --git a/tools/export/cmsis/__init__.py b/tools/export/cmsis/__init__.py index b953227f5a0..4356574113f 100644 --- a/tools/export/cmsis/__init__.py +++ b/tools/export/cmsis/__init__.py @@ -36,7 +36,6 @@ def __init__(self, target): target_info = self.check_supported(target) if not target_info: raise TargetNotSupportedException("Target not supported in CMSIS pack") - self.url = target_info['pdsc_file'] self.pack_url, self.pack_id = ntpath.split(self.url) self.dname = target_info["_cpu_name"] @@ -67,6 +66,15 @@ def check_supported(target): return target_info def vendor_debug(self, vendor): + """Reads the vendor from a PDSC tag. + This tag contains some additional numeric information that is meaningless + for our purposes, so we use a regex to filter. + + Positional arguments: + Vendor - information in tag scraped from ArmPackManager + + Returns a tuple of (debugger, vendor) + """ reg = "([\w\s]+):?\d*?" m = re.search(reg, vendor) vendor_match = m.group(1) if m else None @@ -79,7 +87,13 @@ def vendor_debug(self, vendor): @staticmethod def cpu_cmsis(cpu): - #Cortex-M4F => ARMCM4_FP, Cortex-M0+ => ARMCM0P + """ + Transforms information from targets.json to the way the generic cores are named + in CMSIS PDSC files. + Ex: + Cortex-M4F => ARMCM4_FP, Cortex-M0+ => ARMCM0P + Returns formatted CPU + """ cpu = cpu.replace("Cortex-","ARMC") cpu = cpu.replace("+","P") cpu = cpu.replace("F","_FP") @@ -123,7 +137,6 @@ def group_project_files(self, sources, root_element): return root_element def generate(self): - srcs = self.resources.headers + self.resources.s_sources + \ self.resources.c_sources + self.resources.cpp_sources + \ self.resources.objects + self.resources.libraries + \ diff --git a/tools/export/exporters.py b/tools/export/exporters.py index 439d4697f68..43c659bf18c 100644 --- a/tools/export/exporters.py +++ b/tools/export/exporters.py @@ -1,6 +1,6 @@ """Just a template for subclassing""" import os -import sys +from abc import abstractmethod, ABCMeta import logging from os.path import join, dirname, relpath, basename, realpath from itertools import groupby @@ -32,12 +32,14 @@ class Exporter(object): few helper methods for implementing an exporter with either jinja2 or progen. """ + __metaclass__ = ABCMeta TEMPLATE_DIR = dirname(__file__) DOT_IN_RELATIVE_PATH = False NAME = None TARGETS = None TOOLCHAIN = None + def __init__(self, target, export_dir, project_name, toolchain, extra_symbols=None, resources=None): """Initialize an instance of class exporter @@ -164,3 +166,8 @@ def build(project_name, log_name='build_log.txt', cleanup=True): Returns -1 on failure and 0 on success """ raise NotImplemented("Implement in derived Exporter class.") + + @abstractmethod + def generate(self): + """Generate an IDE/tool specific project file""" + raise NotImplemented("Implement a generate function in Exporter child class") From 0058695e8f78d196b9beb98ab8258a4b9e9d70bb Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Wed, 2 Nov 2016 13:41:04 -0500 Subject: [PATCH 089/107] add back SPI3 pins that shouldn't have been removed --- .../TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/PeripheralPins.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/PeripheralPins.c index 24b0afcf287..6c4ed5a9d54 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/PeripheralPins.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/PeripheralPins.c @@ -108,18 +108,21 @@ const PinMap PinMap_UART_RX[] = { const PinMap PinMap_SPI_MOSI[] = { {PA_7, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {PB_15, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PC_12, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {NC, NC, 0} }; const PinMap PinMap_SPI_MISO[] = { {PA_6, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {PB_14, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PC_11, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {NC, NC, 0} }; const PinMap PinMap_SPI_SCLK[] = { {PA_5, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {PB_13, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {PC_10, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {NC, NC, 0} }; From 07cb26874c798dd59410c01fae29967ef1148acf Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Wed, 2 Nov 2016 15:42:30 -0500 Subject: [PATCH 090/107] Use internal class variable for resolving templates in makefiles This allows other exporters to inherit from make and change the name of the exporter without breaking. --- tools/export/makefile/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/export/makefile/__init__.py b/tools/export/makefile/__init__.py index cf67940bae5..816ec8785dc 100644 --- a/tools/export/makefile/__init__.py +++ b/tools/export/makefile/__init__.py @@ -91,12 +91,12 @@ def generate(self): ctx.update(self.flags) for templatefile in \ - ['makefile/%s_%s.tmpl' % (self.NAME.lower(), + ['makefile/%s_%s.tmpl' % (self.TEMPLATE, self.target.lower())] + \ - ['makefile/%s_%s.tmpl' % (self.NAME.lower(), + ['makefile/%s_%s.tmpl' % (self.TEMPLATE, label.lower()) for label in self.toolchain.target.extra_labels] +\ - ['makefile/%s.tmpl' % self.NAME.lower()]: + ['makefile/%s.tmpl' % self.TEMPLATE]: try: self.gen_file(templatefile, ctx, 'Makefile') break @@ -143,6 +143,7 @@ class GccArm(Makefile): TARGETS = [target for target, obj in TARGET_MAP.iteritems() if "GCC_ARM" in obj.supported_toolchains] NAME = 'Make-GCC-ARM' + TEMPLATE = 'make-gcc-arm' TOOLCHAIN = "GCC_ARM" LINK_SCRIPT_OPTION = "-T" USER_LIBRARY_FLAG = "-L" @@ -157,6 +158,7 @@ class Armc5(Makefile): TARGETS = [target for target, obj in TARGET_MAP.iteritems() if "ARM" in obj.supported_toolchains] NAME = 'Make-ARMc5' + TEMPLATE = 'make-armc5' TOOLCHAIN = "ARM" LINK_SCRIPT_OPTION = "--scatter" USER_LIBRARY_FLAG = "--userlibpath " @@ -171,6 +173,7 @@ class IAR(Makefile): TARGETS = [target for target, obj in TARGET_MAP.iteritems() if "IAR" in obj.supported_toolchains] NAME = 'Make-IAR' + TEMPLATE = 'make-iar' TOOLCHAIN = "IAR" LINK_SCRIPT_OPTION = "--config" USER_LIBRARY_FLAG = "-L" From 9ef6986ebe1c3613c867bb48c863ac0b3740bd18 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Thu, 3 Nov 2016 15:38:55 -0500 Subject: [PATCH 091/107] Quote the shell call in mkdir and rmdir Allows the use of bash in windows --- tools/export/makefile/Makefile.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/export/makefile/Makefile.tmpl b/tools/export/makefile/Makefile.tmpl index a22cb9c23fd..98bcd26f35b 100644 --- a/tools/export/makefile/Makefile.tmpl +++ b/tools/export/makefile/Makefile.tmpl @@ -9,8 +9,8 @@ ifeq ($(shell echo $$OS),$$OS) MAKEDIR = if not exist "$(1)" mkdir "$(1)" RM = rmdir /S /Q "$(1)" else - MAKEDIR = $(SHELL) -c "mkdir -p \"$(1)\"" - RM = $(SHELL) -c "rm -rf \"$(1)\"" + MAKEDIR = '$(SHELL)' -c "mkdir -p \"$(1)\"" + RM = '$(SHELL)' -c "rm -rf \"$(1)\"" endif # Move to the build directory From 8f138f6d16a86a05acffcdc6485d70c3bc212c04 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Fri, 4 Nov 2016 10:08:24 -0500 Subject: [PATCH 092/107] Quote make invocation too --- tools/export/makefile/Makefile.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/export/makefile/Makefile.tmpl b/tools/export/makefile/Makefile.tmpl index 98bcd26f35b..b93950099d1 100644 --- a/tools/export/makefile/Makefile.tmpl +++ b/tools/export/makefile/Makefile.tmpl @@ -18,8 +18,8 @@ ifeq (,$(filter .build,$(notdir $(CURDIR)))) .SUFFIXES: OBJDIR := .build mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) -MAKETARGET = $(MAKE) --no-print-directory -C $(OBJDIR) -f $(mkfile_path) \ - SRCDIR=$(CURDIR) $(MAKECMDGOALS) +MAKETARGET = '$(MAKE)' --no-print-directory -C $(OBJDIR) -f '$(mkfile_path)' \ + 'SRCDIR=$(CURDIR)' $(MAKECMDGOALS) .PHONY: $(OBJDIR) clean all: +@$(call MAKEDIR,$(OBJDIR)) From 93e5e235b1030864710e0456d662bd28f093928d Mon Sep 17 00:00:00 2001 From: sarahmarshy Date: Fri, 4 Nov 2016 14:09:40 -0500 Subject: [PATCH 093/107] Directory traversal error Change indentation level for directory traversal, so that we only move up at the end of exporting one project for all ide/target combinations. --- tools/test/examples/examples_lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/test/examples/examples_lib.py b/tools/test/examples/examples_lib.py index 68b839f66d6..30fb0aaff37 100644 --- a/tools/test/examples/examples_lib.py +++ b/tools/test/examples/examples_lib.py @@ -221,7 +221,7 @@ def status(message): else: status("SUCCESS building") successes.append(example_name) - os.chdir("..") + os.chdir("..") if len(build_failures+export_failures) > 0: pass_status= False From 8a379958e509a316f676ad0fd834063d6f2cf30e Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Wed, 2 Nov 2016 17:16:35 -0500 Subject: [PATCH 094/107] Force make exporter to search PATH for compilers --- tools/export/makefile/__init__.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/export/makefile/__init__.py b/tools/export/makefile/__init__.py index 816ec8785dc..465785d5175 100644 --- a/tools/export/makefile/__init__.py +++ b/tools/export/makefile/__init__.py @@ -64,14 +64,18 @@ def generate(self): == "projectfiles") else [".."]), 'cc_cmd': " ".join(["\'" + part + "\'" for part - in self.toolchain.cc]), + in ([basename(self.toolchain.cc[0])] + + self.toolchain.cc[1:])]), 'cppc_cmd': " ".join(["\'" + part + "\'" for part - in self.toolchain.cppc]), + in ([basename(self.toolchain.cppc[0])] + + self.toolchain.cppc[1:])]), 'asm_cmd': " ".join(["\'" + part + "\'" for part - in self.toolchain.asm]), + in ([basename(self.toolchain.asm[0])] + + self.toolchain.asm[1:])]), 'ld_cmd': " ".join(["\'" + part + "\'" for part - in self.toolchain.ld]), - 'elf2bin_cmd': "\'" + self.toolchain.elf2bin + "\'", + in ([basename(self.toolchain.ld[0])] + + self.toolchain.ld[1:])]), + 'elf2bin_cmd': "\'" + basename(self.toolchain.elf2bin) + "\'", 'link_script_ext': self.toolchain.LINKER_EXT, 'link_script_option': self.LINK_SCRIPT_OPTION, 'user_library_flag': self.USER_LIBRARY_FLAG, From 868dcdc21176870e1061023459d773da9be99ea3 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Thu, 3 Nov 2016 13:13:50 -0500 Subject: [PATCH 095/107] Using Popen for uvision and unifying the structure of the build function across exporters --- tools/export/iar/__init__.py | 42 ++++++++++++++++++++----------- tools/export/makefile/__init__.py | 39 +++++++++++++++++----------- tools/export/uvision/__init__.py | 33 +++++++++++++++--------- 3 files changed, 73 insertions(+), 41 deletions(-) diff --git a/tools/export/iar/__init__.py b/tools/export/iar/__init__.py index d9b92db4f3e..475f86615e5 100644 --- a/tools/export/iar/__init__.py +++ b/tools/export/iar/__init__.py @@ -122,12 +122,11 @@ def generate(self): self.gen_file(self.get_ewp_template(), ctx, self.project_name + ".ewp") @staticmethod - def build(project_name, cleanup=True): + def build(project_name, log_name="build_log.txt", cleanup=True): """ Build IAR project """ # > IarBuild [project_path] -build [project_name] - proj_file = project_name + ".ewp" - cmd = ["IarBuild.exe", proj_file, '-build', project_name] + cmd = ["IarBuild", proj_file, '-build', project_name] # IAR does not support a '0' option to automatically use all # available CPUs, so we use Python's multiprocessing library @@ -139,23 +138,38 @@ def build(project_name, cleanup=True): if jobs: cmd += ['-parallel', str(jobs)] + # Build the project p = Popen(cmd, stdout=PIPE, stderr=PIPE) - num_errors = 0 - #Parse the output for printing and errors - for line in p.stdout.readlines(): - sys.stdout.write(line) - error_re = '\s*Total number of errors:\s*(\d+)\s*' - m = re.match(error_re, line) - if m is not None: - num_errors = int(m.group(1)) + out, err = p.communicate() + ret_code = p.returncode + + out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n" + out_string += out + out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n" + out_string += err + + if ret_code == 0: + out_string += "SUCCESS" + else: + out_string += "FAILURE" + + print out_string + + if log_name: + # Write the output to the log file + with open(log_name, 'w+') as f: + f.write(out_string) + # Cleanup the exported and built files if cleanup: os.remove(project_name + ".ewp") os.remove(project_name + ".ewd") os.remove(project_name + ".eww") - shutil.rmtree('.build') + if exists('.build'): + shutil.rmtree('.build') - if num_errors !=0: + if ret_code !=0: # Seems like something went wrong. return -1 - return 0 + else: + return 0 diff --git a/tools/export/makefile/__init__.py b/tools/export/makefile/__init__.py index 465785d5175..d449a38097f 100644 --- a/tools/export/makefile/__init__.py +++ b/tools/export/makefile/__init__.py @@ -114,32 +114,41 @@ def build(project_name, log_name="build_log.txt", cleanup=True): """ Build Make project """ # > Make -j cmd = ["make", "-j"] + + # Build the project p = Popen(cmd, stdout=PIPE, stderr=PIPE) - ret = p.communicate() - out, err = ret[0], ret[1] + out, err = p.communicate() ret_code = p.returncode - with open(log_name, 'w+') as f: - f.write("=" * 10 + "OUT" + "=" * 10 + "\n") - f.write(out) - f.write("=" * 10 + "ERR" + "=" * 10 + "\n") - f.write(err) - if ret_code == 0: - f.write("SUCCESS") - else: - f.write("FAILURE") - with open(log_name, 'r') as f: - print "\n".join(f.readlines()) - sys.stdout.flush() + out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n" + out_string += out + out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n" + out_string += err + + if ret_code == 0: + out_string += "SUCCESS" + else: + out_string += "FAILURE" + + print out_string + + if log_name: + # Write the output to the log file + with open(log_name, 'w+') as f: + f.write(out_string) + + # Cleanup the exported and built files if cleanup: remove("Makefile") remove(log_name) if exists('.build'): shutil.rmtree('.build') + if ret_code != 0: # Seems like something went wrong. return -1 - return 0 + else: + return 0 class GccArm(Makefile): diff --git a/tools/export/uvision/__init__.py b/tools/export/uvision/__init__.py index 14eedbc637b..e815a00d53a 100644 --- a/tools/export/uvision/__init__.py +++ b/tools/export/uvision/__init__.py @@ -4,7 +4,7 @@ import copy from collections import namedtuple import shutil -import subprocess +from subprocess import Popen, PIPE import re from tools.arm_pack_manager import Cache @@ -208,21 +208,30 @@ def generate(self): @staticmethod def build(project_name, log_name='build_log.txt', cleanup=True): """ Build Uvision project """ - # > UV4.exe -r -j0 -o [log_name] [project_name].uvprojx - success = 0 - warn = 1 - cmd = ["UV4.exe", '-r', '-j0', '-o', log_name, project_name+".uvprojx"] - ret_code = subprocess.call(cmd) - with open(log_name, 'r') as build_log: - print build_log.read() + # > UV4 -r -j0 -o [log_name] [project_name].uvprojx + proj_file = project_name + ".uvprojx" + cmd = ['UV4', '-r', '-j0', '-o', log_name, proj_file] + + # Build the project + p = Popen(cmd, stdout=PIPE, stderr=PIPE) + out, err = p.communicate() + ret_code = p.returncode + + # Print the log file to stdout + with open(log_name, 'r') as f: + print f.read() + + # Cleanup the exported and built files if cleanup: os.remove(log_name) os.remove(project_name+".uvprojx") os.remove(project_name+".uvoptx") - shutil.rmtree(".build") - + if exists('.build'): + shutil.rmtree(".build") - if ret_code != success and ret_code != warn: + # Returns 0 upon success, 1 upon a warning, and neither upon an error + if ret_code != 0 and ret_code != 1: # Seems like something went wrong. return -1 - return 0 + else: + return 0 From 67dcb9fc4e48b387ea50a31fbc90e7e7bd2a3198 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 18 Oct 2016 14:48:46 -0500 Subject: [PATCH 096/107] nsapi - Added standardized return types for size and errors nsapi_error_t - enum of errors or 0 for NSAPI_ERROR_OK nsapi_size_t - unsigned size of data that could be sent nsapi_size_or_error_t - either a non-negative size or negative error --- features/netsocket/CellularInterface.h | 11 ++-- features/netsocket/NetworkInterface.cpp | 10 ++-- features/netsocket/NetworkInterface.h | 14 ++--- features/netsocket/NetworkStack.cpp | 52 +++++++++---------- features/netsocket/NetworkStack.h | 40 ++++++++------ features/netsocket/Socket.cpp | 26 +++++----- features/netsocket/Socket.h | 16 +++--- features/netsocket/TCPServer.cpp | 8 +-- features/netsocket/TCPServer.h | 4 +- features/netsocket/TCPSocket.cpp | 20 +++---- features/netsocket/TCPSocket.h | 8 +-- features/netsocket/UDPSocket.cpp | 16 +++--- features/netsocket/UDPSocket.h | 9 ++-- features/netsocket/WiFiInterface.h | 19 +++---- features/netsocket/nsapi_dns.cpp | 30 +++++------ features/netsocket/nsapi_dns.h | 32 ++++++------ features/netsocket/nsapi_types.h | 69 ++++++++++++++++++------- 17 files changed, 216 insertions(+), 168 deletions(-) diff --git a/features/netsocket/CellularInterface.h b/features/netsocket/CellularInterface.h index 593fbc4648c..3e4e468d196 100644 --- a/features/netsocket/CellularInterface.h +++ b/features/netsocket/CellularInterface.h @@ -39,8 +39,10 @@ class CellularInterface : public NetworkInterface * @param apn Optional name of the network to connect to * @param user Optional username for the APN * @param pass Optional password fot the APN + * @return 0 on success, negative error code on failure */ - virtual int set_credentials(const char *apn, const char *user = 0, const char *pass = 0) = 0; + virtual nsapi_error_t set_credentials(const char *apn, + const char *username = 0, const char *password = 0) = 0; /** Start the interface * @@ -49,7 +51,8 @@ class CellularInterface : public NetworkInterface * @param password Optional password for your APN * @return 0 on success, negative error code on failure */ - virtual int connect(const char *apn, const char *username = 0, const char *password = 0) = 0; + virtual nsapi_error_t connect(const char *apn, + const char *username = 0, const char *password = 0) = 0; /** Start the interface * @@ -57,13 +60,13 @@ class CellularInterface : public NetworkInterface * * @return 0 on success, negative error code on failure */ - virtual int connect() = 0; + virtual nsapi_error_t connect() = 0; /** Stop the interface * * @return 0 on success, negative error code on failure */ - virtual int disconnect() = 0; + virtual nsapi_error_t disconnect() = 0; }; diff --git a/features/netsocket/NetworkInterface.cpp b/features/netsocket/NetworkInterface.cpp index c5b68d4a5ba..5c058ea5b71 100644 --- a/features/netsocket/NetworkInterface.cpp +++ b/features/netsocket/NetworkInterface.cpp @@ -40,27 +40,27 @@ const char *NetworkInterface::get_gateway() return 0; } -int NetworkInterface::set_network(const char *ip_address, const char *netmask, const char *gateway) +nsapi_error_t NetworkInterface::set_network(const char *ip_address, const char *netmask, const char *gateway) { return NSAPI_ERROR_UNSUPPORTED; } -int NetworkInterface::set_dhcp(bool dhcp) +nsapi_error_t NetworkInterface::set_dhcp(bool dhcp) { if (!dhcp) { return NSAPI_ERROR_UNSUPPORTED; } else { - return 0; + return NSAPI_ERROR_OK; } } // DNS operations go through the underlying stack by default -int NetworkInterface::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) +nsapi_error_t NetworkInterface::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) { return get_stack()->gethostbyname(name, address, version); } -int NetworkInterface::add_dns_server(const SocketAddress &address) +nsapi_error_t NetworkInterface::add_dns_server(const SocketAddress &address) { return get_stack()->add_dns_server(address); } diff --git a/features/netsocket/NetworkInterface.h b/features/netsocket/NetworkInterface.h index dbebd6fc9d3..9b8d88564be 100644 --- a/features/netsocket/NetworkInterface.h +++ b/features/netsocket/NetworkInterface.h @@ -78,7 +78,8 @@ class NetworkInterface { * @param gateway Null-terminated representation of the local gateway * @return 0 on success, negative error code on failure */ - virtual int set_network(const char *ip_address, const char *netmask, const char *gateway); + virtual nsapi_error_t set_network( + const char *ip_address, const char *netmask, const char *gateway); /** Enable or disable DHCP on the network * @@ -89,19 +90,19 @@ class NetworkInterface { * @param dhcp True to enable DHCP * @return 0 on success, negative error code on failure */ - virtual int set_dhcp(bool dhcp); + virtual nsapi_error_t set_dhcp(bool dhcp); /** Start the interface * * @return 0 on success, negative error code on failure */ - virtual int connect() = 0; + virtual nsapi_error_t connect() = 0; /** Stop the interface * * @return 0 on success, negative error code on failure */ - virtual int disconnect() = 0; + virtual nsapi_error_t disconnect() = 0; /** Translates a hostname to an IP address with specific version * @@ -117,14 +118,15 @@ class NetworkInterface { * version is chosen by the stack (defaults to NSAPI_UNSPEC) * @return 0 on success, negative error code on failure */ - virtual int gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); + virtual nsapi_error_t gethostbyname(const char *host, + SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); /** Add a domain name server to list of servers to query * * @param addr Destination for the host address * @return 0 on success, negative error code on failure */ - virtual int add_dns_server(const SocketAddress &address); + virtual nsapi_error_t add_dns_server(const SocketAddress &address); protected: friend class Socket; diff --git a/features/netsocket/NetworkStack.cpp b/features/netsocket/NetworkStack.cpp index d59f4a9aa73..ce20014a9de 100644 --- a/features/netsocket/NetworkStack.cpp +++ b/features/netsocket/NetworkStack.cpp @@ -22,7 +22,7 @@ // Default NetworkStack operations -int NetworkStack::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) +nsapi_error_t NetworkStack::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) { // check for simple ip addresses if (address->set_ip_address(name)) { @@ -30,7 +30,7 @@ int NetworkStack::gethostbyname(const char *name, SocketAddress *address, nsapi_ return NSAPI_ERROR_DNS_FAILURE; } - return 0; + return NSAPI_ERROR_OK; } // if the version is unspecified, try to guess the version from the @@ -45,27 +45,27 @@ int NetworkStack::gethostbyname(const char *name, SocketAddress *address, nsapi_ return nsapi_dns_query(this, name, address, version); } -int NetworkStack::add_dns_server(const SocketAddress &address) +nsapi_error_t NetworkStack::add_dns_server(const SocketAddress &address) { return nsapi_dns_add_server(address); } -int NetworkStack::setstackopt(int level, int optname, const void *optval, unsigned optlen) +nsapi_error_t NetworkStack::setstackopt(int level, int optname, const void *optval, unsigned optlen) { return NSAPI_ERROR_UNSUPPORTED; } -int NetworkStack::getstackopt(int level, int optname, void *optval, unsigned *optlen) +nsapi_error_t NetworkStack::getstackopt(int level, int optname, void *optval, unsigned *optlen) { return NSAPI_ERROR_UNSUPPORTED; } -int NetworkStack::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) +nsapi_error_t NetworkStack::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) { return NSAPI_ERROR_UNSUPPORTED; } -int NetworkStack::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) +nsapi_error_t NetworkStack::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) { return NSAPI_ERROR_UNSUPPORTED; } @@ -99,19 +99,19 @@ class NetworkStackWrapper : public NetworkStack return address->get_ip_address(); } - virtual int gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) + virtual nsapi_error_t gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) { if (!_stack_api()->gethostbyname) { return NetworkStack::gethostbyname(name, address, version); } nsapi_addr_t addr = {NSAPI_UNSPEC, 0}; - int err = _stack_api()->gethostbyname(_stack(), name, &addr, version); + nsapi_error_t err = _stack_api()->gethostbyname(_stack(), name, &addr, version); address->set_addr(addr); return err; } - virtual int add_dns_server(const SocketAddress &address) + virtual nsapi_error_t add_dns_server(const SocketAddress &address) { if (!_stack_api()->add_dns_server) { return NetworkStack::add_dns_server(address); @@ -120,7 +120,7 @@ class NetworkStackWrapper : public NetworkStack return _stack_api()->add_dns_server(_stack(), address.get_addr()); } - virtual int setstackopt(int level, int optname, const void *optval, unsigned optlen) + virtual nsapi_error_t setstackopt(int level, int optname, const void *optval, unsigned optlen) { if (!_stack_api()->setstackopt) { return NSAPI_ERROR_UNSUPPORTED; @@ -129,7 +129,7 @@ class NetworkStackWrapper : public NetworkStack return _stack_api()->setstackopt(_stack(), level, optname, optval, optlen); } - virtual int getstackopt(int level, int optname, void *optval, unsigned *optlen) + virtual nsapi_error_t getstackopt(int level, int optname, void *optval, unsigned *optlen) { if (!_stack_api()->getstackopt) { return NSAPI_ERROR_UNSUPPORTED; @@ -139,7 +139,7 @@ class NetworkStackWrapper : public NetworkStack } protected: - virtual int socket_open(nsapi_socket_t *socket, nsapi_protocol_t proto) + virtual nsapi_error_t socket_open(nsapi_socket_t *socket, nsapi_protocol_t proto) { if (!_stack_api()->socket_open) { return NSAPI_ERROR_UNSUPPORTED; @@ -148,7 +148,7 @@ class NetworkStackWrapper : public NetworkStack return _stack_api()->socket_open(_stack(), socket, proto); } - virtual int socket_close(nsapi_socket_t socket) + virtual nsapi_error_t socket_close(nsapi_socket_t socket) { if (!_stack_api()->socket_close) { return NSAPI_ERROR_UNSUPPORTED; @@ -157,7 +157,7 @@ class NetworkStackWrapper : public NetworkStack return _stack_api()->socket_close(_stack(), socket); } - virtual int socket_bind(nsapi_socket_t socket, const SocketAddress &address) + virtual nsapi_error_t socket_bind(nsapi_socket_t socket, const SocketAddress &address) { if (!_stack_api()->socket_bind) { return NSAPI_ERROR_UNSUPPORTED; @@ -166,7 +166,7 @@ class NetworkStackWrapper : public NetworkStack return _stack_api()->socket_bind(_stack(), socket, address.get_addr(), address.get_port()); } - virtual int socket_listen(nsapi_socket_t socket, int backlog) + virtual nsapi_error_t socket_listen(nsapi_socket_t socket, int backlog) { if (!_stack_api()->socket_listen) { return NSAPI_ERROR_UNSUPPORTED; @@ -175,7 +175,7 @@ class NetworkStackWrapper : public NetworkStack return _stack_api()->socket_listen(_stack(), socket, backlog); } - virtual int socket_connect(nsapi_socket_t socket, const SocketAddress &address) + virtual nsapi_error_t socket_connect(nsapi_socket_t socket, const SocketAddress &address) { if (!_stack_api()->socket_connect) { return NSAPI_ERROR_UNSUPPORTED; @@ -184,7 +184,7 @@ class NetworkStackWrapper : public NetworkStack return _stack_api()->socket_connect(_stack(), socket, address.get_addr(), address.get_port()); } - virtual int socket_accept(nsapi_socket_t server, nsapi_socket_t *socket, SocketAddress *address) + virtual nsapi_error_t socket_accept(nsapi_socket_t server, nsapi_socket_t *socket, SocketAddress *address) { if (!_stack_api()->socket_accept) { return NSAPI_ERROR_UNSUPPORTED; @@ -193,7 +193,7 @@ class NetworkStackWrapper : public NetworkStack nsapi_addr_t addr = {NSAPI_IPv4, 0}; uint16_t port = 0; - int err = _stack_api()->socket_accept(_stack(), server, socket, &addr, &port); + nsapi_error_t err = _stack_api()->socket_accept(_stack(), server, socket, &addr, &port); if (address) { address->set_addr(addr); @@ -203,7 +203,7 @@ class NetworkStackWrapper : public NetworkStack return err; } - virtual int socket_send(nsapi_socket_t socket, const void *data, unsigned size) + virtual nsapi_size_or_error_t socket_send(nsapi_socket_t socket, const void *data, nsapi_size_t size) { if (!_stack_api()->socket_send) { return NSAPI_ERROR_UNSUPPORTED; @@ -212,7 +212,7 @@ class NetworkStackWrapper : public NetworkStack return _stack_api()->socket_send(_stack(), socket, data, size); } - virtual int socket_recv(nsapi_socket_t socket, void *data, unsigned size) + virtual nsapi_size_or_error_t socket_recv(nsapi_socket_t socket, void *data, nsapi_size_t size) { if (!_stack_api()->socket_recv) { return NSAPI_ERROR_UNSUPPORTED; @@ -221,7 +221,7 @@ class NetworkStackWrapper : public NetworkStack return _stack_api()->socket_recv(_stack(), socket, data, size); } - virtual int socket_sendto(nsapi_socket_t socket, const SocketAddress &address, const void *data, unsigned size) + virtual nsapi_size_or_error_t socket_sendto(nsapi_socket_t socket, const SocketAddress &address, const void *data, nsapi_size_t size) { if (!_stack_api()->socket_sendto) { return NSAPI_ERROR_UNSUPPORTED; @@ -230,7 +230,7 @@ class NetworkStackWrapper : public NetworkStack return _stack_api()->socket_sendto(_stack(), socket, address.get_addr(), address.get_port(), data, size); } - virtual int socket_recvfrom(nsapi_socket_t socket, SocketAddress *address, void *data, unsigned size) + virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t socket, SocketAddress *address, void *data, nsapi_size_t size) { if (!_stack_api()->socket_recvfrom) { return NSAPI_ERROR_UNSUPPORTED; @@ -239,7 +239,7 @@ class NetworkStackWrapper : public NetworkStack nsapi_addr_t addr = {NSAPI_IPv4, 0}; uint16_t port = 0; - int err = _stack_api()->socket_recvfrom(_stack(), socket, &addr, &port, data, size); + nsapi_size_or_error_t err = _stack_api()->socket_recvfrom(_stack(), socket, &addr, &port, data, size); if (address) { address->set_addr(addr); @@ -258,7 +258,7 @@ class NetworkStackWrapper : public NetworkStack return _stack_api()->socket_attach(_stack(), socket, callback, data); } - virtual int setsockopt(nsapi_socket_t socket, int level, int optname, const void *optval, unsigned optlen) + virtual nsapi_error_t setsockopt(nsapi_socket_t socket, int level, int optname, const void *optval, unsigned optlen) { if (!_stack_api()->setsockopt) { return NSAPI_ERROR_UNSUPPORTED; @@ -267,7 +267,7 @@ class NetworkStackWrapper : public NetworkStack return _stack_api()->setsockopt(_stack(), socket, level, optname, optval, optlen); } - virtual int getsockopt(nsapi_socket_t socket, int level, int optname, void *optval, unsigned *optlen) + virtual nsapi_error_t getsockopt(nsapi_socket_t socket, int level, int optname, void *optval, unsigned *optlen) { if (!_stack_api()->getsockopt) { return NSAPI_ERROR_UNSUPPORTED; diff --git a/features/netsocket/NetworkStack.h b/features/netsocket/NetworkStack.h index cad473a4ec2..4a927347e2e 100644 --- a/features/netsocket/NetworkStack.h +++ b/features/netsocket/NetworkStack.h @@ -58,14 +58,15 @@ class NetworkStack * version is chosen by the stack (defaults to NSAPI_UNSPEC) * @return 0 on success, negative error code on failure */ - virtual int gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); + virtual nsapi_error_t gethostbyname(const char *host, + SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); /** Add a domain name server to list of servers to query * * @param addr Destination for the host address * @return 0 on success, negative error code on failure */ - virtual int add_dns_server(const SocketAddress &address); + virtual nsapi_error_t add_dns_server(const SocketAddress &address); /* Set stack-specific stack options * @@ -79,7 +80,7 @@ class NetworkStack * @param optlen Length of the option value * @return 0 on success, negative error code on failure */ - virtual int setstackopt(int level, int optname, const void *optval, unsigned optlen); + virtual nsapi_error_t setstackopt(int level, int optname, const void *optval, unsigned optlen); /* Get stack-specific stack options * @@ -93,7 +94,7 @@ class NetworkStack * @param optlen Length of the option value * @return 0 on success, negative error code on failure */ - virtual int getstackopt(int level, int optname, void *optval, unsigned *optlen); + virtual nsapi_error_t getstackopt(int level, int optname, void *optval, unsigned *optlen); protected: friend class Socket; @@ -113,7 +114,7 @@ class NetworkStack * @param proto Protocol of socket to open, NSAPI_TCP or NSAPI_UDP * @return 0 on success, negative error code on failure */ - virtual int socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) = 0; + virtual nsapi_error_t socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) = 0; /** Close the socket * @@ -123,7 +124,7 @@ class NetworkStack * @param handle Socket handle * @return 0 on success, negative error code on failure */ - virtual int socket_close(nsapi_socket_t handle) = 0; + virtual nsapi_error_t socket_close(nsapi_socket_t handle) = 0; /** Bind a specific address to a socket * @@ -134,7 +135,7 @@ class NetworkStack * @param address Local address to bind * @return 0 on success, negative error code on failure. */ - virtual int socket_bind(nsapi_socket_t handle, const SocketAddress &address) = 0; + virtual nsapi_error_t socket_bind(nsapi_socket_t handle, const SocketAddress &address) = 0; /** Listen for connections on a TCP socket * @@ -146,7 +147,7 @@ class NetworkStack * simultaneously * @return 0 on success, negative error code on failure */ - virtual int socket_listen(nsapi_socket_t handle, int backlog) = 0; + virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog) = 0; /** Connects TCP socket to a remote host * @@ -157,7 +158,7 @@ class NetworkStack * @param address The SocketAddress of the remote host * @return 0 on success, negative error code on failure */ - virtual int socket_connect(nsapi_socket_t handle, const SocketAddress &address) = 0; + virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address) = 0; /** Accepts a connection on a TCP socket * @@ -177,7 +178,8 @@ class NetworkStack * @param address Destination for the remote address or NULL * @return 0 on success, negative error code on failure */ - virtual int socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address=0) = 0; + virtual nsapi_error_t socket_accept(nsapi_socket_t server, + nsapi_socket_t *handle, SocketAddress *address=0) = 0; /** Send data over a TCP socket * @@ -193,7 +195,8 @@ class NetworkStack * @return Number of sent bytes on success, negative error * code on failure */ - virtual int socket_send(nsapi_socket_t handle, const void *data, unsigned size) = 0; + virtual nsapi_size_or_error_t socket_send(nsapi_socket_t handle, + const void *data, nsapi_size_t size) = 0; /** Receive data over a TCP socket * @@ -209,7 +212,8 @@ class NetworkStack * @return Number of received bytes on success, negative error * code on failure */ - virtual int socket_recv(nsapi_socket_t handle, void *data, unsigned size) = 0; + virtual nsapi_size_or_error_t socket_recv(nsapi_socket_t handle, + void *data, nsapi_size_t size) = 0; /** Send a packet over a UDP socket * @@ -226,7 +230,8 @@ class NetworkStack * @return Number of sent bytes on success, negative error * code on failure */ - virtual int socket_sendto(nsapi_socket_t handle, const SocketAddress &address, const void *data, unsigned size) = 0; + virtual nsapi_size_or_error_t socket_sendto(nsapi_socket_t handle, const SocketAddress &address, + const void *data, nsapi_size_t size) = 0; /** Receive a packet over a UDP socket * @@ -243,7 +248,8 @@ class NetworkStack * @return Number of received bytes on success, negative error * code on failure */ - virtual int socket_recvfrom(nsapi_socket_t handle, SocketAddress *address, void *buffer, unsigned size) = 0; + virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, SocketAddress *address, + void *buffer, nsapi_size_t size) = 0; /** Register a callback on state change of the socket * @@ -273,7 +279,8 @@ class NetworkStack * @param optlen Length of the option value * @return 0 on success, negative error code on failure */ - virtual int setsockopt(nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen); + virtual nsapi_error_t setsockopt(nsapi_socket_t handle, int level, + int optname, const void *optval, unsigned optlen); /* Get stack-specific socket options * @@ -288,7 +295,8 @@ class NetworkStack * @param optlen Length of the option value * @return 0 on success, negative error code on failure */ - virtual int getsockopt(nsapi_socket_t handle, int level, int optname, void *optval, unsigned *optlen); + virtual nsapi_error_t getsockopt(nsapi_socket_t handle, int level, + int optname, void *optval, unsigned *optlen); }; diff --git a/features/netsocket/Socket.cpp b/features/netsocket/Socket.cpp index 7429144a39d..14ea797ec80 100644 --- a/features/netsocket/Socket.cpp +++ b/features/netsocket/Socket.cpp @@ -24,7 +24,7 @@ Socket::Socket() { } -int Socket::open(NetworkStack *stack) +nsapi_error_t Socket::open(NetworkStack *stack) { _lock.lock(); @@ -35,7 +35,7 @@ int Socket::open(NetworkStack *stack) _stack = stack; nsapi_socket_t socket; - int err = _stack->socket_open(&socket, get_proto()); + nsapi_error_t err = _stack->socket_open(&socket, get_proto()); if (err) { _lock.unlock(); return err; @@ -46,14 +46,14 @@ int Socket::open(NetworkStack *stack) _stack->socket_attach(_socket, Callback::thunk, &_event); _lock.unlock(); - return 0; + return NSAPI_ERROR_OK; } -int Socket::close() +nsapi_error_t Socket::close() { _lock.lock(); - int ret = 0; + nsapi_error_t ret = NSAPI_ERROR_OK; if (_socket) { _stack->socket_attach(_socket, 0, 0); nsapi_socket_t socket = _socket; @@ -69,24 +69,24 @@ int Socket::close() return ret; } -int Socket::bind(uint16_t port) +nsapi_error_t Socket::bind(uint16_t port) { // Underlying bind is thread safe SocketAddress addr(0, port); return bind(addr); } -int Socket::bind(const char *address, uint16_t port) +nsapi_error_t Socket::bind(const char *address, uint16_t port) { // Underlying bind is thread safe SocketAddress addr(address, port); return bind(addr); } -int Socket::bind(const SocketAddress &address) +nsapi_error_t Socket::bind(const SocketAddress &address) { _lock.lock(); - int ret; + nsapi_error_t ret; if (!_socket) { ret = NSAPI_ERROR_NO_SOCKET; @@ -117,10 +117,10 @@ void Socket::set_timeout(int timeout) _lock.unlock(); } -int Socket::setsockopt(int level, int optname, const void *optval, unsigned optlen) +nsapi_error_t Socket::setsockopt(int level, int optname, const void *optval, unsigned optlen) { _lock.lock(); - int ret; + nsapi_error_t ret; if (!_socket) { ret = NSAPI_ERROR_NO_SOCKET; @@ -132,10 +132,10 @@ int Socket::setsockopt(int level, int optname, const void *optval, unsigned optl return ret; } -int Socket::getsockopt(int level, int optname, void *optval, unsigned *optlen) +nsapi_error_t Socket::getsockopt(int level, int optname, void *optval, unsigned *optlen) { _lock.lock(); - int ret; + nsapi_error_t ret; if (!_socket) { ret = NSAPI_ERROR_NO_SOCKET; diff --git a/features/netsocket/Socket.h b/features/netsocket/Socket.h index b3cfbd6cb6b..2ca3d0a062a 100644 --- a/features/netsocket/Socket.h +++ b/features/netsocket/Socket.h @@ -46,10 +46,10 @@ class Socket { * @param stack Network stack as target for socket * @return 0 on success, negative error code on failure */ - int open(NetworkStack *stack); + nsapi_error_t open(NetworkStack *stack); template - int open(S *stack) { + nsapi_error_t open(S *stack) { return open(nsapi_create_stack(stack)); } @@ -60,7 +60,7 @@ class Socket { * * @return 0 on success, negative error code on failure */ - int close(); + nsapi_error_t close(); /** Bind a specific address to a socket * @@ -70,7 +70,7 @@ class Socket { * @param port Local port to bind * @return 0 on success, negative error code on failure. */ - int bind(uint16_t port); + nsapi_error_t bind(uint16_t port); /** Bind a specific address to a socket * @@ -81,7 +81,7 @@ class Socket { * @param port Local port to bind * @return 0 on success, negative error code on failure. */ - int bind(const char *address, uint16_t port); + nsapi_error_t bind(const char *address, uint16_t port); /** Bind a specific address to a socket * @@ -91,7 +91,7 @@ class Socket { * @param address Local address to bind * @return 0 on success, negative error code on failure. */ - int bind(const SocketAddress &address); + nsapi_error_t bind(const SocketAddress &address); /** Set blocking or non-blocking mode of the socket * @@ -132,7 +132,7 @@ class Socket { * @param optlen Length of the option value * @return 0 on success, negative error code on failure */ - int setsockopt(int level, int optname, const void *optval, unsigned optlen); + nsapi_error_t setsockopt(int level, int optname, const void *optval, unsigned optlen); /* Get stack-specific socket options * @@ -146,7 +146,7 @@ class Socket { * @param optlen Length of the option value * @return 0 on success, negative error code on failure */ - int getsockopt(int level, int optname, void *optval, unsigned *optlen); + nsapi_error_t getsockopt(int level, int optname, void *optval, unsigned *optlen); /** Register a callback on state change of the socket * diff --git a/features/netsocket/TCPServer.cpp b/features/netsocket/TCPServer.cpp index 2ddfb9288e8..85f3249341c 100644 --- a/features/netsocket/TCPServer.cpp +++ b/features/netsocket/TCPServer.cpp @@ -32,10 +32,10 @@ nsapi_protocol_t TCPServer::get_proto() return NSAPI_TCP; } -int TCPServer::listen(int backlog) +nsapi_error_t TCPServer::listen(int backlog) { _lock.lock(); - int ret; + nsapi_error_t ret; if (!_socket) { ret = NSAPI_ERROR_NO_SOCKET; @@ -47,10 +47,10 @@ int TCPServer::listen(int backlog) return ret; } -int TCPServer::accept(TCPSocket *connection, SocketAddress *address) +nsapi_error_t TCPServer::accept(TCPSocket *connection, SocketAddress *address) { _lock.lock(); - int ret; + nsapi_error_t ret; while (true) { if (!_socket) { diff --git a/features/netsocket/TCPServer.h b/features/netsocket/TCPServer.h index db2d6dd0f6f..6c26e2c7075 100644 --- a/features/netsocket/TCPServer.h +++ b/features/netsocket/TCPServer.h @@ -66,7 +66,7 @@ class TCPServer : public Socket { * simultaneously, defaults to 1 * @return 0 on success, negative error code on failure */ - int listen(int backlog = 1); + nsapi_error_t listen(int backlog = 1); /** Accepts a connection on a TCP socket * @@ -82,7 +82,7 @@ class TCPServer : public Socket { * @param address Destination for the remote address or NULL * @return 0 on success, negative error code on failure */ - int accept(TCPSocket *connection, SocketAddress *address = NULL); + nsapi_error_t accept(TCPSocket *connection, SocketAddress *address = NULL); protected: virtual nsapi_protocol_t get_proto(); diff --git a/features/netsocket/TCPSocket.cpp b/features/netsocket/TCPSocket.cpp index 2c0f18d65c5..010dd7d039c 100644 --- a/features/netsocket/TCPSocket.cpp +++ b/features/netsocket/TCPSocket.cpp @@ -34,10 +34,10 @@ nsapi_protocol_t TCPSocket::get_proto() return NSAPI_TCP; } -int TCPSocket::connect(const SocketAddress &address) +nsapi_error_t TCPSocket::connect(const SocketAddress &address) { _lock.lock(); - int ret; + nsapi_error_t ret; if (!_socket) { ret = NSAPI_ERROR_NO_SOCKET; @@ -49,10 +49,10 @@ int TCPSocket::connect(const SocketAddress &address) return ret; } -int TCPSocket::connect(const char *host, uint16_t port) +nsapi_error_t TCPSocket::connect(const char *host, uint16_t port) { SocketAddress address; - int err = _stack->gethostbyname(host, &address); + nsapi_error_t err = _stack->gethostbyname(host, &address); if (err) { return NSAPI_ERROR_DNS_FAILURE; } @@ -63,10 +63,10 @@ int TCPSocket::connect(const char *host, uint16_t port) return connect(address); } -int TCPSocket::send(const void *data, unsigned size) +nsapi_size_or_error_t TCPSocket::send(const void *data, nsapi_size_t size) { _lock.lock(); - int ret; + nsapi_size_or_error_t ret; // If this assert is hit then there are two threads // performing a send at the same time which is undefined @@ -81,7 +81,7 @@ int TCPSocket::send(const void *data, unsigned size) } _pending = 0; - int sent = _stack->socket_send(_socket, data, size); + nsapi_size_or_error_t sent = _stack->socket_send(_socket, data, size); if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) { ret = sent; break; @@ -107,10 +107,10 @@ int TCPSocket::send(const void *data, unsigned size) return ret; } -int TCPSocket::recv(void *data, unsigned size) +nsapi_size_or_error_t TCPSocket::recv(void *data, nsapi_size_t size) { _lock.lock(); - int ret; + nsapi_size_or_error_t ret; // If this assert is hit then there are two threads // performing a recv at the same time which is undefined @@ -125,7 +125,7 @@ int TCPSocket::recv(void *data, unsigned size) } _pending = 0; - int recv = _stack->socket_recv(_socket, data, size); + nsapi_size_or_error_t recv = _stack->socket_recv(_socket, data, size); if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) { ret = recv; break; diff --git a/features/netsocket/TCPSocket.h b/features/netsocket/TCPSocket.h index 31a2e9ec37d..b8a41eea71c 100644 --- a/features/netsocket/TCPSocket.h +++ b/features/netsocket/TCPSocket.h @@ -66,7 +66,7 @@ class TCPSocket : public Socket { * @param port Port of the remote host * @return 0 on success, negative error code on failure */ - int connect(const char *host, uint16_t port); + nsapi_error_t connect(const char *host, uint16_t port); /** Connects TCP socket to a remote host * @@ -76,7 +76,7 @@ class TCPSocket : public Socket { * @param address The SocketAddress of the remote host * @return 0 on success, negative error code on failure */ - int connect(const SocketAddress &address); + nsapi_error_t connect(const SocketAddress &address); /** Send data over a TCP socket * @@ -92,7 +92,7 @@ class TCPSocket : public Socket { * @return Number of sent bytes on success, negative error * code on failure */ - int send(const void *data, unsigned size); + nsapi_size_or_error_t send(const void *data, nsapi_size_t size); /** Receive data over a TCP socket * @@ -108,7 +108,7 @@ class TCPSocket : public Socket { * @return Number of received bytes on success, negative error * code on failure */ - int recv(void *data, unsigned size); + nsapi_size_or_error_t recv(void *data, nsapi_size_t size); protected: friend class TCPServer; diff --git a/features/netsocket/UDPSocket.cpp b/features/netsocket/UDPSocket.cpp index fdfa4ce998f..0243a4b831c 100644 --- a/features/netsocket/UDPSocket.cpp +++ b/features/netsocket/UDPSocket.cpp @@ -34,10 +34,10 @@ nsapi_protocol_t UDPSocket::get_proto() return NSAPI_UDP; } -int UDPSocket::sendto(const char *host, uint16_t port, const void *data, unsigned size) +nsapi_size_or_error_t UDPSocket::sendto(const char *host, uint16_t port, const void *data, nsapi_size_t size) { SocketAddress address; - int err = _stack->gethostbyname(host, &address); + nsapi_size_or_error_t err = _stack->gethostbyname(host, &address); if (err) { return NSAPI_ERROR_DNS_FAILURE; } @@ -48,10 +48,10 @@ int UDPSocket::sendto(const char *host, uint16_t port, const void *data, unsigne return sendto(address, data, size); } -int UDPSocket::sendto(const SocketAddress &address, const void *data, unsigned size) +nsapi_size_or_error_t UDPSocket::sendto(const SocketAddress &address, const void *data, nsapi_size_t size) { _lock.lock(); - int ret; + nsapi_size_or_error_t ret; // If this assert is hit then there are two threads // performing a send at the same time which is undefined @@ -66,7 +66,7 @@ int UDPSocket::sendto(const SocketAddress &address, const void *data, unsigned s } _pending = 0; - int sent = _stack->socket_sendto(_socket, address, data, size); + nsapi_size_or_error_t sent = _stack->socket_sendto(_socket, address, data, size); if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) { ret = sent; break; @@ -92,10 +92,10 @@ int UDPSocket::sendto(const SocketAddress &address, const void *data, unsigned s return ret; } -int UDPSocket::recvfrom(SocketAddress *address, void *buffer, unsigned size) +nsapi_size_or_error_t UDPSocket::recvfrom(SocketAddress *address, void *buffer, nsapi_size_t size) { _lock.lock(); - int ret; + nsapi_size_or_error_t ret; // If this assert is hit then there are two threads // performing a recv at the same time which is undefined @@ -110,7 +110,7 @@ int UDPSocket::recvfrom(SocketAddress *address, void *buffer, unsigned size) } _pending = 0; - int recv = _stack->socket_recvfrom(_socket, address, buffer, size); + nsapi_size_or_error_t recv = _stack->socket_recvfrom(_socket, address, buffer, size); if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) { ret = recv; break; diff --git a/features/netsocket/UDPSocket.h b/features/netsocket/UDPSocket.h index 719e7f29ac0..58584b9d83b 100644 --- a/features/netsocket/UDPSocket.h +++ b/features/netsocket/UDPSocket.h @@ -74,7 +74,8 @@ class UDPSocket : public Socket { * @return Number of sent bytes on success, negative error * code on failure */ - int sendto(const char *host, uint16_t port, const void *data, unsigned size); + nsapi_size_or_error_t sendto(const char *host, uint16_t port, + const void *data, nsapi_size_t size); /** Send a packet over a UDP socket * @@ -91,7 +92,8 @@ class UDPSocket : public Socket { * @return Number of sent bytes on success, negative error * code on failure */ - int sendto(const SocketAddress &address, const void *data, unsigned size); + nsapi_size_or_error_t sendto(const SocketAddress &address, + const void *data, nsapi_size_t size); /** Receive a packet over a UDP socket * @@ -108,7 +110,8 @@ class UDPSocket : public Socket { * @return Number of received bytes on success, negative error * code on failure */ - int recvfrom(SocketAddress *address, void *data, unsigned size); + nsapi_size_or_error_t recvfrom(SocketAddress *address, + void *data, nsapi_size_t size); protected: virtual nsapi_protocol_t get_proto(); diff --git a/features/netsocket/WiFiInterface.h b/features/netsocket/WiFiInterface.h index 65ffc51148e..3078655b856 100644 --- a/features/netsocket/WiFiInterface.h +++ b/features/netsocket/WiFiInterface.h @@ -44,14 +44,15 @@ class WiFiInterface: public NetworkInterface * (defaults to NSAPI_SECURITY_NONE) * @return 0 on success, or error code on failure */ - virtual int set_credentials(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE) = 0; + virtual nsapi_error_t set_credentials(const char *ssid, const char *pass, + nsapi_security_t security = NSAPI_SECURITY_NONE) = 0; /** Set the WiFi network channel * * @param channel Channel on which the connection is to be made, or 0 for any (Default: 0) * @return 0 on success, or error code on failure */ - virtual int set_channel(uint8_t channel) = 0; + virtual nsapi_error_t set_channel(uint8_t channel) = 0; /** Gets the current radio signal strength for active connection * @@ -70,9 +71,8 @@ class WiFiInterface: public NetworkInterface * @param channel Channel on which the connection is to be made, or 0 for any (Default: 0) * @return 0 on success, or error code on failure */ - virtual int connect(const char *ssid, const char *pass, - nsapi_security_t security = NSAPI_SECURITY_NONE, - uint8_t channel = 0) = 0; + virtual nsapi_error_t connect(const char *ssid, const char *pass, + nsapi_security_t security = NSAPI_SECURITY_NONE, uint8_t channel = 0) = 0; /** Start the interface * @@ -81,13 +81,13 @@ class WiFiInterface: public NetworkInterface * * @return 0 on success, negative error code on failure */ - virtual int connect() = 0; + virtual nsapi_error_t connect() = 0; /** Stop the interface * * @return 0 on success, or error code on failure */ - virtual int disconnect() = 0; + virtual nsapi_error_t disconnect() = 0; /** Scan for available networks * @@ -99,10 +99,11 @@ class WiFiInterface: public NetworkInterface * @param ap Pointer to allocated array to store discovered AP * @param count Size of allocated @a res array, or 0 to only count available AP * @param timeout Timeout in milliseconds; 0 for no timeout (Default: 0) - * @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error + * @return Number of entries in @a, or if @a count was 0 number of available networks, + * negative on error * see @a nsapi_error */ - virtual int scan(WiFiAccessPoint *res, unsigned count) = 0; + virtual nsapi_size_or_error_t scan(WiFiAccessPoint *res, nsapi_size_t count) = 0; }; #endif diff --git a/features/netsocket/nsapi_dns.cpp b/features/netsocket/nsapi_dns.cpp index 2b0bd0ea119..4e1970a266d 100644 --- a/features/netsocket/nsapi_dns.cpp +++ b/features/netsocket/nsapi_dns.cpp @@ -41,13 +41,13 @@ nsapi_addr_t dns_servers[DNS_SERVERS_SIZE] = { }; // DNS server configuration -extern "C" int nsapi_dns_add_server(nsapi_addr_t addr) +extern "C" nsapi_error_t nsapi_dns_add_server(nsapi_addr_t addr) { memmove(&dns_servers[1], &dns_servers[0], (DNS_SERVERS_SIZE-1)*sizeof(nsapi_addr_t)); dns_servers[0] = addr; - return 0; + return NSAPI_ERROR_OK; } @@ -195,7 +195,7 @@ static int dns_scan_response(const uint8_t **p, nsapi_addr_t *addr, unsigned add } // core query function -static int nsapi_dns_query_multiple(NetworkStack *stack, const char *host, +static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char *host, nsapi_addr_t *addr, unsigned addr_count, nsapi_version_t version) { // check for valid host name @@ -219,7 +219,7 @@ static int nsapi_dns_query_multiple(NetworkStack *stack, const char *host, return NSAPI_ERROR_NO_MEMORY; } - int result = NSAPI_ERROR_DNS_FAILURE; + nsapi_size_or_error_t result = NSAPI_ERROR_DNS_FAILURE; // check against each dns server for (unsigned i = 0; i < DNS_SERVERS_SIZE; i++) { @@ -265,18 +265,18 @@ static int nsapi_dns_query_multiple(NetworkStack *stack, const char *host, } // convenience functions for other forms of queries -extern "C" int nsapi_dns_query_multiple(nsapi_stack_t *stack, const char *host, - nsapi_addr_t *addr, unsigned addr_count, nsapi_version_t version) +extern "C" nsapi_size_or_error_t nsapi_dns_query_multiple(nsapi_stack_t *stack, const char *host, + nsapi_addr_t *addr, nsapi_size_t addr_count, nsapi_version_t version) { NetworkStack *nstack = nsapi_create_stack(stack); return nsapi_dns_query_multiple(nstack, host, addr, addr_count, version); } -int nsapi_dns_query_multiple(NetworkStack *stack, const char *host, - SocketAddress *addresses, unsigned addr_count, nsapi_version_t version) +nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char *host, + SocketAddress *addresses, nsapi_size_t addr_count, nsapi_version_t version) { nsapi_addr_t *addrs = new nsapi_addr_t[addr_count]; - int result = nsapi_dns_query_multiple(stack, host, addrs, addr_count, version); + nsapi_size_or_error_t result = nsapi_dns_query_multiple(stack, host, addrs, addr_count, version); if (result > 0) { for (int i = 0; i < result; i++) { @@ -288,19 +288,19 @@ int nsapi_dns_query_multiple(NetworkStack *stack, const char *host, return result; } -extern "C" int nsapi_dns_query(nsapi_stack_t *stack, const char *host, +extern "C" nsapi_error_t nsapi_dns_query(nsapi_stack_t *stack, const char *host, nsapi_addr_t *addr, nsapi_version_t version) { NetworkStack *nstack = nsapi_create_stack(stack); - int result = nsapi_dns_query_multiple(nstack, host, addr, 1, version); - return (result > 0) ? 0 : result; + nsapi_size_or_error_t result = nsapi_dns_query_multiple(nstack, host, addr, 1, version); + return (nsapi_error_t)((result > 0) ? 0 : result); } -int nsapi_dns_query(NetworkStack *stack, const char *host, +nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host, SocketAddress *address, nsapi_version_t version) { nsapi_addr_t addr; - int result = nsapi_dns_query_multiple(stack, host, &addr, 1, version); + nsapi_size_or_error_t result = nsapi_dns_query_multiple(stack, host, &addr, 1, version); address->set_addr(addr); - return (result > 0) ? 0 : result; + return (nsapi_error_t)((result > 0) ? 0 : result); } diff --git a/features/netsocket/nsapi_dns.h b/features/netsocket/nsapi_dns.h index 93a55ef21ef..0575ae35f94 100644 --- a/features/netsocket/nsapi_dns.h +++ b/features/netsocket/nsapi_dns.h @@ -37,7 +37,7 @@ * @return 0 on success, negative error code on failure * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ -int nsapi_dns_query(nsapi_stack_t *stack, const char *host, +nsapi_error_t nsapi_dns_query(nsapi_stack_t *stack, const char *host, nsapi_addr_t *addr, nsapi_version_t version); /** Query a domain name server for multiple IP address of a given hostname @@ -50,15 +50,15 @@ int nsapi_dns_query(nsapi_stack_t *stack, const char *host, * @return Number of addresses found on success, negative error code on failure * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ -int nsapi_dns_query_multiple(nsapi_stack_t *stack, const char *host, - nsapi_addr_t *addr, unsigned addr_count, nsapi_version_t version); +nsapi_size_or_error_t nsapi_dns_query_multiple(nsapi_stack_t *stack, const char *host, + nsapi_addr_t *addr, nsapi_size_t addr_count, nsapi_version_t version); /** Add a domain name server to list of servers to query * * @param addr Destination for the host address * @return 0 on success, negative error code on failure */ -int nsapi_dns_add_server(nsapi_addr_t addr); +nsapi_error_t nsapi_dns_add_server(nsapi_addr_t addr); #else @@ -73,7 +73,7 @@ int nsapi_dns_add_server(nsapi_addr_t addr); * @return 0 on success, negative error code on failure * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ -int nsapi_dns_query(NetworkStack *stack, const char *host, +nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host, SocketAddress *addr, nsapi_version_t version = NSAPI_IPv4); /** Query a domain name server for an IP address of a given hostname @@ -85,7 +85,7 @@ int nsapi_dns_query(NetworkStack *stack, const char *host, * @return 0 on success, negative error code on failure * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ -extern "C" int nsapi_dns_query(nsapi_stack_t *stack, const char *host, +extern "C" nsapi_error_t nsapi_dns_query(nsapi_stack_t *stack, const char *host, nsapi_addr_t *addr, nsapi_version_t version = NSAPI_IPv4); /** Query a domain name server for an IP address of a given hostname @@ -98,7 +98,7 @@ extern "C" int nsapi_dns_query(nsapi_stack_t *stack, const char *host, * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ template -int nsapi_dns_query(S *stack, const char *host, +nsapi_error_t nsapi_dns_query(S *stack, const char *host, SocketAddress *addr, nsapi_version_t version = NSAPI_IPv4) { return nsapi_dns_query(nsapi_create_stack(stack), host, addr, version); @@ -114,8 +114,8 @@ int nsapi_dns_query(S *stack, const char *host, * @return Number of addresses found on success, negative error code on failure * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ -int nsapi_dns_query_multiple(NetworkStack *stack, const char *host, - SocketAddress *addr, unsigned addr_count, nsapi_version_t version = NSAPI_IPv4); +nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char *host, + SocketAddress *addr, nsapi_size_t addr_count, nsapi_version_t version = NSAPI_IPv4); /** Query a domain name server for multiple IP address of a given hostname * @@ -127,8 +127,8 @@ int nsapi_dns_query_multiple(NetworkStack *stack, const char *host, * @return Number of addresses found on success, negative error code on failure * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ -extern "C" int nsapi_dns_query_multiple(nsapi_stack_t *stack, const char *host, - nsapi_addr_t *addr, unsigned addr_count, nsapi_version_t version = NSAPI_IPv4); +extern "C" nsapi_size_or_error_t nsapi_dns_query_multiple(nsapi_stack_t *stack, const char *host, + nsapi_addr_t *addr, nsapi_size_t addr_count, nsapi_version_t version = NSAPI_IPv4); /** Query a domain name server for multiple IP address of a given hostname * @@ -141,8 +141,8 @@ extern "C" int nsapi_dns_query_multiple(nsapi_stack_t *stack, const char *host, * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ template -int nsapi_dns_query_multiple(S *stack, const char *host, - SocketAddress *addr, unsigned addr_count, nsapi_version_t version = NSAPI_IPv4) +nsapi_size_or_error_t nsapi_dns_query_multiple(S *stack, const char *host, + SocketAddress *addr, nsapi_size_t addr_count, nsapi_version_t version = NSAPI_IPv4) { return nsapi_dns_query_multiple(nsapi_create_stack(stack), host, addr, addr_count, version); @@ -153,14 +153,14 @@ int nsapi_dns_query_multiple(S *stack, const char *host, * @param addr Destination for the host address * @return 0 on success, negative error code on failure */ -extern "C" int nsapi_dns_add_server(nsapi_addr_t addr); +extern "C" nsapi_error_t nsapi_dns_add_server(nsapi_addr_t addr); /** Add a domain name server to list of servers to query * * @param addr Destination for the host address * @return 0 on success, negative error code on failure */ -static inline int nsapi_dns_add_server(const SocketAddress &address) +static inline nsapi_error_t nsapi_dns_add_server(const SocketAddress &address) { return nsapi_dns_add_server(address.get_addr()); } @@ -170,7 +170,7 @@ static inline int nsapi_dns_add_server(const SocketAddress &address) * @param addr Destination for the host address * @return 0 on success, negative error code on failure */ -static inline int nsapi_dns_add_server(const char *address) +static inline nsapi_error_t nsapi_dns_add_server(const char *address) { return nsapi_dns_add_server(SocketAddress(address)); } diff --git a/features/netsocket/nsapi_types.h b/features/netsocket/nsapi_types.h index 04df2c21c15..95f86b3c047 100644 --- a/features/netsocket/nsapi_types.h +++ b/features/netsocket/nsapi_types.h @@ -34,7 +34,7 @@ extern "C" { * * @enum nsapi_error_t */ -typedef enum nsapi_error { +enum nsapi_error { NSAPI_ERROR_OK = 0, /*!< no error */ NSAPI_ERROR_WOULD_BLOCK = -3001, /*!< no data is not available but call is non-blocking */ NSAPI_ERROR_UNSUPPORTED = -3002, /*!< unsupported functionality */ @@ -48,7 +48,25 @@ typedef enum nsapi_error { NSAPI_ERROR_DHCP_FAILURE = -3010, /*!< DHCP failed to complete successfully */ NSAPI_ERROR_AUTH_FAILURE = -3011, /*!< connection to access point failed */ NSAPI_ERROR_DEVICE_ERROR = -3012, /*!< failure interfacing with the network processor */ -} nsapi_error_t; +}; + +/** Type used to represent error codes + * + * This is a separate type from enum nsapi_error to avoid breaking + * compatibility in type-sensitive overloads + */ +typedef signed int nsapi_error_t; + +/** Type used to represent the size of data passed through sockets + */ +typedef unsigned int nsapi_size_t; + +/** Type used to represent either a size or error pased through sockets + * + * A valid nsapi_size_or_error_t is either a non-negative size or a + * negative error code from the nsapi_error_t + */ +typedef signed int nsapi_size_or_error_t; /** Enum of encryption types * @@ -233,14 +251,14 @@ typedef struct nsapi_stack_api * @param version Address family * @return 0 on success, negative error code on failure */ - int (*gethostbyname)(nsapi_stack_t *stack, const char *host, nsapi_addr_t *addr, nsapi_version_t version); + nsapi_error_t (*gethostbyname)(nsapi_stack_t *stack, const char *host, nsapi_addr_t *addr, nsapi_version_t version); /** Add a domain name server to list of servers to query * * @param addr Destination for the host address * @return 0 on success, negative error code on failure */ - int (*add_dns_server)(nsapi_stack_t *stack, nsapi_addr_t addr); + nsapi_error_t (*add_dns_server)(nsapi_stack_t *stack, nsapi_addr_t addr); /* Set stack-specific stack options * @@ -255,7 +273,8 @@ typedef struct nsapi_stack_api * @param optlen Length of the option value * @return 0 on success, negative error code on failure */ - int (*setstackopt)(nsapi_stack_t *stack, int level, int optname, const void *optval, unsigned optlen); + nsapi_error_t (*setstackopt)(nsapi_stack_t *stack, int level, + int optname, const void *optval, unsigned optlen); /* Get stack-specific stack options * @@ -270,7 +289,8 @@ typedef struct nsapi_stack_api * @param optlen Length of the option value * @return 0 on success, negative error code on failure */ - int (*getstackopt)(nsapi_stack_t *stack, int level, int optname, void *optval, unsigned *optlen); + nsapi_error_t (*getstackopt)(nsapi_stack_t *stack, int level, + int optname, void *optval, unsigned *optlen); /** Opens a socket * @@ -285,7 +305,8 @@ typedef struct nsapi_stack_api * @param proto Protocol of socket to open, NSAPI_TCP or NSAPI_UDP * @return 0 on success, negative error code on failure */ - int (*socket_open)(nsapi_stack_t *stack, nsapi_socket_t *socket, nsapi_protocol_t proto); + nsapi_error_t (*socket_open)(nsapi_stack_t *stack, nsapi_socket_t *socket, + nsapi_protocol_t proto); /** Close the socket * @@ -296,7 +317,7 @@ typedef struct nsapi_stack_api * @param socket Socket handle * @return 0 on success, negative error code on failure */ - int (*socket_close)(nsapi_stack_t *stack, nsapi_socket_t socket); + nsapi_error_t (*socket_close)(nsapi_stack_t *stack, nsapi_socket_t socket); /** Bind a specific address to a socket * @@ -309,7 +330,8 @@ typedef struct nsapi_stack_api * @param port Local port to bind * @return 0 on success, negative error code on failure. */ - int (*socket_bind)(nsapi_stack_t *stack, nsapi_socket_t socket, nsapi_addr_t addr, uint16_t port); + nsapi_error_t (*socket_bind)(nsapi_stack_t *stack, nsapi_socket_t socket, + nsapi_addr_t addr, uint16_t port); /** Listen for connections on a TCP socket * @@ -322,7 +344,7 @@ typedef struct nsapi_stack_api * simultaneously * @return 0 on success, negative error code on failure */ - int (*socket_listen)(nsapi_stack_t *stack, nsapi_socket_t socket, int backlog); + nsapi_error_t (*socket_listen)(nsapi_stack_t *stack, nsapi_socket_t socket, int backlog); /** Connects TCP socket to a remote host * @@ -335,7 +357,8 @@ typedef struct nsapi_stack_api * @param port The port of the remote host * @return 0 on success, negative error code on failure */ - int (*socket_connect)(nsapi_stack_t *stack, nsapi_socket_t socket, nsapi_addr_t addr, uint16_t port); + nsapi_error_t (*socket_connect)(nsapi_stack_t *stack, nsapi_socket_t socket, + nsapi_addr_t addr, uint16_t port); /** Accepts a connection on a TCP socket * @@ -357,7 +380,8 @@ typedef struct nsapi_stack_api * @param port Destination for the port of the remote host * @return 0 on success, negative error code on failure */ - int (*socket_accept)(nsapi_stack_t *stack, nsapi_socket_t server, nsapi_socket_t *socket, nsapi_addr_t *addr, uint16_t *port); + nsapi_error_t (*socket_accept)(nsapi_stack_t *stack, nsapi_socket_t server, + nsapi_socket_t *socket, nsapi_addr_t *addr, uint16_t *port); /** Send data over a TCP socket * @@ -374,7 +398,8 @@ typedef struct nsapi_stack_api * @return Number of sent bytes on success, negative error * code on failure */ - int (*socket_send)(nsapi_stack_t *stack, nsapi_socket_t socket, const void *data, unsigned size); + nsapi_size_or_error_t (*socket_send)(nsapi_stack_t *stack, nsapi_socket_t socket, + const void *data, nsapi_size_t size); /** Receive data over a TCP socket * @@ -391,7 +416,8 @@ typedef struct nsapi_stack_api * @return Number of received bytes on success, negative error * code on failure */ - int (*socket_recv)(nsapi_stack_t *stack, nsapi_socket_t socket, void *data, unsigned size); + nsapi_size_or_error_t (*socket_recv)(nsapi_stack_t *stack, nsapi_socket_t socket, + void *data, nsapi_size_t size); /** Send a packet over a UDP socket * @@ -410,7 +436,8 @@ typedef struct nsapi_stack_api * @return Number of sent bytes on success, negative error * code on failure */ - int (*socket_sendto)(nsapi_stack_t *stack, nsapi_socket_t socket, nsapi_addr_t addr, uint16_t port, const void *data, unsigned size); + nsapi_size_or_error_t (*socket_sendto)(nsapi_stack_t *stack, nsapi_socket_t socket, + nsapi_addr_t addr, uint16_t port, const void *data, nsapi_size_t size); /** Receive a packet over a UDP socket * @@ -429,7 +456,8 @@ typedef struct nsapi_stack_api * @return Number of received bytes on success, negative error * code on failure */ - int (*socket_recvfrom)(nsapi_stack_t *stack, nsapi_socket_t socket, nsapi_addr_t *addr, uint16_t *port, void *buffer, unsigned size); + nsapi_size_or_error_t (*socket_recvfrom)(nsapi_stack_t *stack, nsapi_socket_t socket, + nsapi_addr_t *addr, uint16_t *port, void *buffer, nsapi_size_t size); /** Register a callback on state change of the socket * @@ -445,7 +473,8 @@ typedef struct nsapi_stack_api * @param callback Function to call on state change * @param data Argument to pass to callback */ - void (*socket_attach)(nsapi_stack_t *stack, nsapi_socket_t socket, void (*callback)(void *), void *data); + void (*socket_attach)(nsapi_stack_t *stack, nsapi_socket_t socket, + void (*callback)(void *), void *data); /* Set stack-specific socket options * @@ -461,7 +490,8 @@ typedef struct nsapi_stack_api * @param optlen Length of the option value * @return 0 on success, negative error code on failure */ - int (*setsockopt)(nsapi_stack_t *stack, nsapi_socket_t socket, int level, int optname, const void *optval, unsigned optlen); + nsapi_error_t (*setsockopt)(nsapi_stack_t *stack, nsapi_socket_t socket, int level, + int optname, const void *optval, unsigned optlen); /* Get stack-specific socket options * @@ -477,7 +507,8 @@ typedef struct nsapi_stack_api * @param optlen Length of the option value * @return 0 on success, negative error code on failure */ - int (*getsockopt)(nsapi_stack_t *stack, nsapi_socket_t socket, int level, int optname, void *optval, unsigned *optlen); + nsapi_error_t (*getsockopt)(nsapi_stack_t *stack, nsapi_socket_t socket, int level, + int optname, void *optval, unsigned *optlen); } nsapi_stack_api_t; From e769c79ccc10be20b5890434a8c83d57ccc00987 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 18 Oct 2016 16:48:49 -0500 Subject: [PATCH 097/107] nsapi - Adopted standardized return types in lwip --- .../lwip-interface/EthernetInterface.cpp | 14 +++---- .../lwip-interface/EthernetInterface.h | 9 +++-- .../FEATURE_LWIP/lwip-interface/lwip_stack.c | 40 +++++++++---------- .../FEATURE_LWIP/lwip-interface/lwip_stack.h | 6 +-- 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/features/FEATURE_LWIP/lwip-interface/EthernetInterface.cpp b/features/FEATURE_LWIP/lwip-interface/EthernetInterface.cpp index ae672a55ee2..9a05a981302 100644 --- a/features/FEATURE_LWIP/lwip-interface/EthernetInterface.cpp +++ b/features/FEATURE_LWIP/lwip-interface/EthernetInterface.cpp @@ -24,22 +24,22 @@ EthernetInterface::EthernetInterface() { } -int EthernetInterface::set_network(const char *ip_address, const char *netmask, const char *gateway) +nsapi_error_t EthernetInterface::set_network(const char *ip_address, const char *netmask, const char *gateway) { _dhcp = false; strncpy(_ip_address, ip_address ? ip_address : "", sizeof(_ip_address)); strncpy(_netmask, netmask ? netmask : "", sizeof(_netmask)); strncpy(_gateway, gateway ? gateway : "", sizeof(_gateway)); - return 0; + return NSAPI_ERROR_OK; } -int EthernetInterface::set_dhcp(bool dhcp) +nsapi_error_t EthernetInterface::set_dhcp(bool dhcp) { _dhcp = dhcp; - return 0; + return NSAPI_ERROR_OK; } -int EthernetInterface::connect() +nsapi_error_t EthernetInterface::connect() { return mbed_lwip_bringup(_dhcp, _ip_address[0] ? _ip_address : 0, @@ -47,7 +47,7 @@ int EthernetInterface::connect() _gateway[0] ? _gateway : 0); } -int EthernetInterface::disconnect() +nsapi_error_t EthernetInterface::disconnect() { return mbed_lwip_bringdown(); } @@ -63,7 +63,7 @@ const char *EthernetInterface::get_ip_address() return _ip_address; } - return 0; + return NULL; } const char *EthernetInterface::get_netmask() diff --git a/features/FEATURE_LWIP/lwip-interface/EthernetInterface.h b/features/FEATURE_LWIP/lwip-interface/EthernetInterface.h index dfb01950d39..f92f70e4ebf 100644 --- a/features/FEATURE_LWIP/lwip-interface/EthernetInterface.h +++ b/features/FEATURE_LWIP/lwip-interface/EthernetInterface.h @@ -46,7 +46,8 @@ class EthernetInterface : public EthInterface * @param gateway Null-terminated representation of the local gateway * @return 0 on success, negative error code on failure */ - virtual int set_network(const char *ip_address, const char *netmask, const char *gateway); + virtual nsapi_error_t set_network( + const char *ip_address, const char *netmask, const char *gateway); /** Enable or disable DHCP on the network * @@ -55,17 +56,17 @@ class EthernetInterface : public EthInterface * @param dhcp False to disable dhcp (defaults to enabled) * @return 0 on success, negative error code on failure */ - virtual int set_dhcp(bool dhcp); + virtual nsapi_error_t set_dhcp(bool dhcp); /** Start the interface * @return 0 on success, negative on failure */ - virtual int connect(); + virtual nsapi_error_t connect(); /** Stop the interface * @return 0 on success, negative on failure */ - virtual int disconnect(); + virtual nsapi_error_t disconnect(); /** Get the local MAC address * diff --git a/features/FEATURE_LWIP/lwip-interface/lwip_stack.c b/features/FEATURE_LWIP/lwip-interface/lwip_stack.c index f8099386f42..ecffd0aa3d3 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip_stack.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip_stack.c @@ -326,7 +326,7 @@ const char *mbed_lwip_get_mac_address(void) return lwip_mac_address[0] ? lwip_mac_address : 0; } -char *mbed_lwip_get_ip_address(char *buf, int buflen) +char *mbed_lwip_get_ip_address(char *buf, nsapi_size_t buflen) { const ip_addr_t *addr = mbed_lwip_get_ip_addr(true, &lwip_netif); if (!addr) { @@ -345,7 +345,7 @@ char *mbed_lwip_get_ip_address(char *buf, int buflen) return NULL; } -const char *mbed_lwip_get_netmask(char *buf, int buflen) +const char *mbed_lwip_get_netmask(char *buf, nsapi_size_t buflen) { #if LWIP_IPV4 const ip4_addr_t *addr = netif_ip4_netmask(&lwip_netif); @@ -359,7 +359,7 @@ const char *mbed_lwip_get_netmask(char *buf, int buflen) #endif } -char *mbed_lwip_get_gateway(char *buf, int buflen) +char *mbed_lwip_get_gateway(char *buf, nsapi_size_t buflen) { #if LWIP_IPV4 const ip4_addr_t *addr = netif_ip4_gw(&lwip_netif); @@ -373,7 +373,7 @@ char *mbed_lwip_get_gateway(char *buf, int buflen) #endif } -int mbed_lwip_init(emac_interface_t *emac) +nsapi_error_t mbed_lwip_init(emac_interface_t *emac) { // Check if we've already brought up lwip if (!mbed_lwip_get_mac_address()) { @@ -409,7 +409,7 @@ int mbed_lwip_init(emac_interface_t *emac) return NSAPI_ERROR_OK; } -int mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw) +nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw) { // Check if we've already connected if (lwip_connected) { @@ -509,7 +509,7 @@ int mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char return 0; } -int mbed_lwip_bringdown(void) +nsapi_error_t mbed_lwip_bringdown(void) { // Check if we've connected if (!lwip_connected) { @@ -533,7 +533,7 @@ int mbed_lwip_bringdown(void) } /* LWIP error remapping */ -static int mbed_lwip_err_remap(err_t err) { +static nsapi_error_t mbed_lwip_err_remap(err_t err) { switch (err) { case ERR_OK: case ERR_CLSD: @@ -559,7 +559,7 @@ static int mbed_lwip_err_remap(err_t err) { } /* LWIP network stack implementation */ -static int mbed_lwip_gethostbyname(nsapi_stack_t *stack, const char *host, nsapi_addr_t *addr, nsapi_version_t version) +static nsapi_error_t mbed_lwip_gethostbyname(nsapi_stack_t *stack, const char *host, nsapi_addr_t *addr, nsapi_version_t version) { ip_addr_t lwip_addr; @@ -600,7 +600,7 @@ static int mbed_lwip_gethostbyname(nsapi_stack_t *stack, const char *host, nsapi return 0; } -static int mbed_lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t *handle, nsapi_protocol_t proto) +static nsapi_error_t mbed_lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t *handle, nsapi_protocol_t proto) { // check if network is connected if (!lwip_connected) { @@ -643,7 +643,7 @@ static int mbed_lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t *handle, n return 0; } -static int mbed_lwip_socket_close(nsapi_stack_t *stack, nsapi_socket_t handle) +static nsapi_error_t mbed_lwip_socket_close(nsapi_stack_t *stack, nsapi_socket_t handle) { struct lwip_socket *s = (struct lwip_socket *)handle; @@ -652,7 +652,7 @@ static int mbed_lwip_socket_close(nsapi_stack_t *stack, nsapi_socket_t handle) return mbed_lwip_err_remap(err); } -static int mbed_lwip_socket_bind(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port) +static nsapi_error_t mbed_lwip_socket_bind(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port) { struct lwip_socket *s = (struct lwip_socket *)handle; ip_addr_t ip_addr; @@ -670,7 +670,7 @@ static int mbed_lwip_socket_bind(nsapi_stack_t *stack, nsapi_socket_t handle, ns return mbed_lwip_err_remap(err); } -static int mbed_lwip_socket_listen(nsapi_stack_t *stack, nsapi_socket_t handle, int backlog) +static nsapi_error_t mbed_lwip_socket_listen(nsapi_stack_t *stack, nsapi_socket_t handle, int backlog) { struct lwip_socket *s = (struct lwip_socket *)handle; @@ -678,7 +678,7 @@ static int mbed_lwip_socket_listen(nsapi_stack_t *stack, nsapi_socket_t handle, return mbed_lwip_err_remap(err); } -static int mbed_lwip_socket_connect(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port) +static nsapi_error_t mbed_lwip_socket_connect(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port) { struct lwip_socket *s = (struct lwip_socket *)handle; ip_addr_t ip_addr; @@ -694,7 +694,7 @@ static int mbed_lwip_socket_connect(nsapi_stack_t *stack, nsapi_socket_t handle, return mbed_lwip_err_remap(err); } -static int mbed_lwip_socket_accept(nsapi_stack_t *stack, nsapi_socket_t server, nsapi_socket_t *handle, nsapi_addr_t *addr, uint16_t *port) +static nsapi_error_t mbed_lwip_socket_accept(nsapi_stack_t *stack, nsapi_socket_t server, nsapi_socket_t *handle, nsapi_addr_t *addr, uint16_t *port) { struct lwip_socket *s = (struct lwip_socket *)server; struct lwip_socket *ns = mbed_lwip_arena_alloc(); @@ -718,7 +718,7 @@ static int mbed_lwip_socket_accept(nsapi_stack_t *stack, nsapi_socket_t server, return 0; } -static int mbed_lwip_socket_send(nsapi_stack_t *stack, nsapi_socket_t handle, const void *data, unsigned size) +static nsapi_size_or_error_t mbed_lwip_socket_send(nsapi_stack_t *stack, nsapi_socket_t handle, const void *data, nsapi_size_t size) { struct lwip_socket *s = (struct lwip_socket *)handle; size_t bytes_written = 0; @@ -728,10 +728,10 @@ static int mbed_lwip_socket_send(nsapi_stack_t *stack, nsapi_socket_t handle, co return mbed_lwip_err_remap(err); } - return (int)bytes_written; + return (nsapi_size_or_error_t)bytes_written; } -static int mbed_lwip_socket_recv(nsapi_stack_t *stack, nsapi_socket_t handle, void *data, unsigned size) +static nsapi_size_or_error_t mbed_lwip_socket_recv(nsapi_stack_t *stack, nsapi_socket_t handle, void *data, nsapi_size_t size) { struct lwip_socket *s = (struct lwip_socket *)handle; @@ -755,7 +755,7 @@ static int mbed_lwip_socket_recv(nsapi_stack_t *stack, nsapi_socket_t handle, vo return recv; } -static int mbed_lwip_socket_sendto(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port, const void *data, unsigned size) +static nsapi_size_or_error_t mbed_lwip_socket_sendto(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port, const void *data, nsapi_size_t size) { struct lwip_socket *s = (struct lwip_socket *)handle; ip_addr_t ip_addr; @@ -780,7 +780,7 @@ static int mbed_lwip_socket_sendto(nsapi_stack_t *stack, nsapi_socket_t handle, return size; } -static int mbed_lwip_socket_recvfrom(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t *addr, uint16_t *port, void *data, unsigned size) +static nsapi_size_or_error_t mbed_lwip_socket_recvfrom(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t *addr, uint16_t *port, void *data, nsapi_size_t size) { struct lwip_socket *s = (struct lwip_socket *)handle; struct netbuf *buf; @@ -799,7 +799,7 @@ static int mbed_lwip_socket_recvfrom(nsapi_stack_t *stack, nsapi_socket_t handle return recv; } -static int mbed_lwip_setsockopt(nsapi_stack_t *stack, nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen) +static nsapi_error_t mbed_lwip_setsockopt(nsapi_stack_t *stack, nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen) { struct lwip_socket *s = (struct lwip_socket *)handle; diff --git a/features/FEATURE_LWIP/lwip-interface/lwip_stack.h b/features/FEATURE_LWIP/lwip-interface/lwip_stack.h index 89161f61f4a..afbb8d2f5b0 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip_stack.h +++ b/features/FEATURE_LWIP/lwip-interface/lwip_stack.h @@ -25,9 +25,9 @@ extern "C" { #endif // Access to lwip through the nsapi -int mbed_lwip_init(emac_interface_t *emac); -int mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw); -int mbed_lwip_bringdown(void); +nsapi_error_t mbed_lwip_init(emac_interface_t *emac); +nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw); +nsapi_error_t mbed_lwip_bringdown(void); const char *mbed_lwip_get_mac_address(void); char *mbed_lwip_get_ip_address(char *buf, int buflen); From 33b600ef03dc2b615f2ad0e39612e2c648524040 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Wed, 2 Nov 2016 15:37:34 -0500 Subject: [PATCH 098/107] nsapi - Adopted standardized return types in the Odin wifi interface --- .../ublox-odin-w2-drivers/OdinWiFiInterface.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/ublox-odin-w2-drivers/OdinWiFiInterface.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/ublox-odin-w2-drivers/OdinWiFiInterface.h index 091609c402b..0e5226b24ee 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/ublox-odin-w2-drivers/OdinWiFiInterface.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/ublox-odin-w2-drivers/OdinWiFiInterface.h @@ -54,14 +54,14 @@ class OdinWiFiInterface : public WiFiInterface * (defaults to NSAPI_SECURITY_NONE) * @return 0 on success, or error code on failure */ - virtual int set_credentials(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE); + virtual nsapi_error_t set_credentials(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE); /** Set the WiFi network channel * * @param channel Channel on which the connection is to be made, or 0 for any (Default: 0) * @return 0 on success, or error code on failure */ - virtual int set_channel(uint8_t channel); + virtual nsapi_error_t set_channel(uint8_t channel); /** Start the interface * @@ -73,7 +73,7 @@ class OdinWiFiInterface : public WiFiInterface * @param channel Channel on which the connection is to be made, or 0 for any (Default: 0) * @return 0 on success, or error code on failure */ - virtual int connect(const char *ssid, + virtual nsapi_error_t connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE, uint8_t channel = 0); @@ -85,13 +85,13 @@ class OdinWiFiInterface : public WiFiInterface * * @return 0 on success, negative error code on failure */ - virtual int connect(); + virtual nsapi_error_t connect(); /** Stop the interface * * @return 0 on success, or error code on failure */ - virtual int disconnect(); + virtual nsapi_error_t disconnect(); /** Get the local MAC address * @@ -136,7 +136,7 @@ class OdinWiFiInterface : public WiFiInterface * @param gateway Null-terminated representation of the local gateway * @return 0 on success, negative error code on failure */ - virtual int set_network(const char *ip_address, const char *netmask, const char *gateway); + virtual nsapi_error_t set_network(const char *ip_address, const char *netmask, const char *gateway); /** Enable or disable DHCP on the network * @@ -147,7 +147,7 @@ class OdinWiFiInterface : public WiFiInterface * @param dhcp True to enable DHCP * @return 0 on success, negative error code on failure */ - virtual int set_dhcp(bool dhcp); + virtual nsapi_error_t set_dhcp(bool dhcp); /** Gets the current radio signal strength for active connection * @@ -168,7 +168,7 @@ class OdinWiFiInterface : public WiFiInterface * @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error * see @a nsapi_error */ - virtual int scan(WiFiAccessPoint *res, unsigned count); + virtual nsapi_size_or_error_t scan(WiFiAccessPoint *res, nsapi_size_t count); /** Sets timeout for connection setup. Note that the time for DHCP retrieval is not included. * @@ -184,7 +184,7 @@ class OdinWiFiInterface : public WiFiInterface private: - int connect_async(const char *ssid, + nsapi_error_t connect_async(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE, uint8_t channel = 0, From a49783c34fe133f71e491ebe639ed1265d325b9f Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Wed, 2 Nov 2016 15:52:54 -0500 Subject: [PATCH 099/107] nsapi - Adopted standardized return types in the Nanostack interfaces --- .../NanostackInterface.cpp | 58 +++++++++---------- .../nanostack-interface/NanostackInterface.h | 38 ++++++------ 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp index 835a655a9eb..3c5dcb72995 100644 --- a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp +++ b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp @@ -109,7 +109,7 @@ class NanostackSocket { static NanostackSocket * socket_tbl[NS_INTERFACE_SOCKETS_MAX]; -static int map_mesh_error(mesh_error_t err) +static nsapi_error_t map_mesh_error(mesh_error_t err) { switch (err) { case MESH_ERROR_NONE: return 0; @@ -163,7 +163,7 @@ NanostackSocket::~NanostackSocket() close(); } if (socket_id >= 0) { - int ret = socket_free(socket_id); + nsapi_error_t ret = socket_free(socket_id); MBED_ASSERT(0 == ret); MBED_ASSERT(socket_tbl[socket_id] == this); socket_tbl[socket_id] = NULL; @@ -205,7 +205,7 @@ void NanostackSocket::close() MBED_ASSERT(mode != SOCKET_MODE_CLOSED); if (socket_id >= 0) { - int ret = socket_close(socket_id, (addr_valid ? &ns_address : NULL)); + nsapi_error_t ret = socket_close(socket_id, (addr_valid ? &ns_address : NULL)); MBED_ASSERT(0 == ret); } else { MBED_ASSERT(SOCKET_MODE_UNOPENED == mode); @@ -462,7 +462,7 @@ MeshInterfaceNanostack::MeshInterfaceNanostack(NanostackRfPhy *phy) // Nothing to do } -int MeshInterfaceNanostack::initialize(NanostackRfPhy *phy) +nsapi_error_t MeshInterfaceNanostack::initialize(NanostackRfPhy *phy) { if (this->phy != NULL) { error("Phy already set"); @@ -482,7 +482,7 @@ void MeshInterfaceNanostack::mesh_network_handler(mesh_connection_status_t statu nanostack_unlock(); } -int MeshInterfaceNanostack::register_rf() +nsapi_error_t MeshInterfaceNanostack::register_rf() { nanostack_lock(); @@ -500,7 +500,7 @@ int MeshInterfaceNanostack::register_rf() return 0; } -int MeshInterfaceNanostack::actual_connect() +nsapi_error_t MeshInterfaceNanostack::actual_connect() { nanostack_assert_locked(); @@ -528,7 +528,7 @@ NetworkStack * MeshInterfaceNanostack::get_stack() return NanostackInterface::get_stack(); } -int MeshInterfaceNanostack::disconnect() +nsapi_error_t MeshInterfaceNanostack::disconnect() { nanostack_lock(); @@ -558,7 +558,7 @@ const char *MeshInterfaceNanostack::get_mac_address() return mac_addr_str; } -int ThreadInterface::connect() +nsapi_error_t ThreadInterface::connect() { // initialize mesh networking resources, memory, timers, etc... mesh_system_init(); @@ -582,14 +582,14 @@ int ThreadInterface::connect() nanostack_unlock(); return map_mesh_error(status); } - int ret = this->actual_connect(); + nsapi_error_t ret = this->actual_connect(); nanostack_unlock(); return ret; } -int LoWPANNDInterface::connect() +nsapi_error_t LoWPANNDInterface::connect() { // initialize mesh networking resources, memory, timers, etc... mesh_system_init(); @@ -613,7 +613,7 @@ int LoWPANNDInterface::connect() nanostack_unlock(); return map_mesh_error(status); } - int ret = this->actual_connect(); + nsapi_error_t ret = this->actual_connect(); nanostack_unlock(); @@ -642,7 +642,7 @@ const char * NanostackInterface::get_ip_address() return NULL; } -int NanostackInterface::socket_open(void **handle, nsapi_protocol_t protocol) +nsapi_error_t NanostackInterface::socket_open(void **handle, nsapi_protocol_t protocol) { // Validate parameters if (NULL == handle) { @@ -683,7 +683,7 @@ int NanostackInterface::socket_open(void **handle, nsapi_protocol_t protocol) return 0; } -int NanostackInterface::socket_close(void *handle) +nsapi_error_t NanostackInterface::socket_close(void *handle) { // Validate parameters NanostackSocket * socket = static_cast(handle); @@ -703,7 +703,7 @@ int NanostackInterface::socket_close(void *handle) } -int NanostackInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned int size) +nsapi_size_or_error_t NanostackInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, nsapi_size_t size) { // Validate parameters NanostackSocket * socket = static_cast(handle); @@ -718,7 +718,7 @@ int NanostackInterface::socket_sendto(void *handle, const SocketAddress &address nanostack_lock(); - int ret; + nsapi_size_or_error_t ret; if (socket->closed()) { ret = NSAPI_ERROR_NO_CONNECTION; } else if (NANOSTACK_SOCKET_TCP == socket->proto) { @@ -758,7 +758,7 @@ int NanostackInterface::socket_sendto(void *handle, const SocketAddress &address return ret; } -int NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size) +nsapi_size_or_error_t NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, nsapi_size_t size) { // Validate parameters NanostackSocket * socket = static_cast(handle); @@ -777,7 +777,7 @@ int NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, vo nanostack_lock(); - int ret; + nsapi_size_or_error_t ret; if (socket->closed()) { ret = NSAPI_ERROR_NO_CONNECTION; } else if (NANOSTACK_SOCKET_TCP == socket->proto) { @@ -796,7 +796,7 @@ int NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, vo return ret; } -int NanostackInterface::socket_bind(void *handle, const SocketAddress &address) +nsapi_error_t NanostackInterface::socket_bind(void *handle, const SocketAddress &address) { // Validate parameters NanostackSocket * socket = static_cast(handle); @@ -823,7 +823,7 @@ int NanostackInterface::socket_bind(void *handle, const SocketAddress &address) ns_address.type = ADDRESS_IPV6; memcpy(ns_address.address, addr_field, sizeof ns_address.address); ns_address.identifier = address.get_port(); - int ret = NSAPI_ERROR_DEVICE_ERROR; + nsapi_error_t ret = NSAPI_ERROR_DEVICE_ERROR; if (0 == ::socket_bind(socket->socket_id, &ns_address)) { socket->set_bound(); ret = 0; @@ -836,22 +836,22 @@ int NanostackInterface::socket_bind(void *handle, const SocketAddress &address) return ret; } -int NanostackInterface::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) +nsapi_error_t NanostackInterface::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) { return NSAPI_ERROR_UNSUPPORTED; } -int NanostackInterface::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) +nsapi_error_t NanostackInterface::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) { return NSAPI_ERROR_UNSUPPORTED; } -int NanostackInterface::socket_listen(void *handle, int backlog) +nsapi_error_t NanostackInterface::socket_listen(void *handle, int backlog) { return NSAPI_ERROR_UNSUPPORTED; } -int NanostackInterface::socket_connect(void *handle, const SocketAddress &addr) +nsapi_error_t NanostackInterface::socket_connect(void *handle, const SocketAddress &addr) { // Validate parameters NanostackSocket * socket = static_cast(handle); @@ -866,7 +866,7 @@ int NanostackInterface::socket_connect(void *handle, const SocketAddress &addr) nanostack_lock(); - int ret; + nsapi_error_t ret; ns_address_t ns_addr; int random_port = socket->is_bound() ? 0 : 1; convert_mbed_addr_to_ns(&ns_addr, &addr); @@ -884,12 +884,12 @@ int NanostackInterface::socket_connect(void *handle, const SocketAddress &addr) return ret; } -int NanostackInterface::socket_accept(void *server, void **handle, SocketAddress *address) +nsapi_error_t NanostackInterface::socket_accept(void *server, void **handle, SocketAddress *address) { return NSAPI_ERROR_UNSUPPORTED; } -int NanostackInterface::socket_send(void *handle, const void *p, unsigned size) +nsapi_size_or_error_t NanostackInterface::socket_send(void *handle, const void *p, nsapi_size_t size) { // Validate parameters NanostackSocket * socket = static_cast(handle); @@ -900,7 +900,7 @@ int NanostackInterface::socket_send(void *handle, const void *p, unsigned size) nanostack_lock(); - int ret; + nsapi_size_or_error_t ret; if (socket->closed()) { ret = NSAPI_ERROR_NO_CONNECTION; } else if (socket->is_connecting()) { @@ -933,7 +933,7 @@ int NanostackInterface::socket_send(void *handle, const void *p, unsigned size) return ret; } -int NanostackInterface::socket_recv(void *handle, void *data, unsigned size) +nsapi_size_or_error_t NanostackInterface::socket_recv(void *handle, void *data, nsapi_size_t size) { // Validate parameters NanostackSocket * socket = static_cast(handle); @@ -944,7 +944,7 @@ int NanostackInterface::socket_recv(void *handle, void *data, unsigned size) nanostack_lock(); - int ret; + nsapi_size_or_error_t ret; if (socket->closed()) { ret = NSAPI_ERROR_NO_CONNECTION; } else if (socket->data_available()) { diff --git a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.h b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.h index 3d61503b9ee..2582c6f3333 100644 --- a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.h +++ b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.h @@ -37,7 +37,7 @@ class NanostackInterface : public NetworkStack { * @param proto Protocol of socket to open, NSAPI_TCP or NSAPI_UDP * @return 0 on success, negative error code on failure */ - virtual int socket_open(void **handle, nsapi_protocol_t proto); + virtual nsapi_error_t socket_open(void **handle, nsapi_protocol_t proto); /** Close the socket * @@ -47,7 +47,7 @@ class NanostackInterface : public NetworkStack { * @param handle Socket handle * @return 0 on success, negative error code on failure */ - virtual int socket_close(void *handle); + virtual nsapi_error_t socket_close(void *handle); /** Bind a specific address to a socket * @@ -58,7 +58,7 @@ class NanostackInterface : public NetworkStack { * @param address Local address to bind * @return 0 on success, negative error code on failure. */ - virtual int socket_bind(void *handle, const SocketAddress &address); + virtual nsapi_error_t socket_bind(void *handle, const SocketAddress &address); /** Listen for connections on a TCP socket * @@ -70,7 +70,7 @@ class NanostackInterface : public NetworkStack { * simultaneously * @return 0 on success, negative error code on failure */ - virtual int socket_listen(void *handle, int backlog); + virtual nsapi_error_t socket_listen(void *handle, int backlog); /** Connects TCP socket to a remote host * @@ -81,7 +81,7 @@ class NanostackInterface : public NetworkStack { * @param address The SocketAddress of the remote host * @return 0 on success, negative error code on failure */ - virtual int socket_connect(void *handle, const SocketAddress &address); + virtual nsapi_error_t socket_connect(void *handle, const SocketAddress &address); /** Accepts a connection on a TCP socket * @@ -101,7 +101,7 @@ class NanostackInterface : public NetworkStack { * @param address Destination for the remote address or NULL * @return 0 on success, negative error code on failure */ - virtual int socket_accept(void *handle, void **server, SocketAddress *address); + virtual nsapi_error_t socket_accept(void *handle, void **server, SocketAddress *address); /** Send data over a TCP socket * @@ -117,7 +117,7 @@ class NanostackInterface : public NetworkStack { * @return Number of sent bytes on success, negative error * code on failure */ - virtual int socket_send(void *handle, const void *data, unsigned size); + virtual nsapi_size_or_error_t socket_send(void *handle, const void *data, nsapi_size_t size); /** Receive data over a TCP socket * @@ -133,7 +133,7 @@ class NanostackInterface : public NetworkStack { * @return Number of received bytes on success, negative error * code on failure */ - virtual int socket_recv(void *handle, void *data, unsigned size); + virtual nsapi_size_or_error_t socket_recv(void *handle, void *data, nsapi_size_t size); /** Send a packet over a UDP socket * @@ -150,7 +150,7 @@ class NanostackInterface : public NetworkStack { * @return Number of sent bytes on success, negative error * code on failure */ - virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size); + virtual nsapi_size_or_error_t socket_sendto(void *handle, const SocketAddress &address, const void *data, nsapi_size_t size); /** Receive a packet over a UDP socket * @@ -167,7 +167,7 @@ class NanostackInterface : public NetworkStack { * @return Number of received bytes on success, negative error * code on failure */ - virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size); + virtual nsapi_size_or_error_t socket_recvfrom(void *handle, SocketAddress *address, void *buffer, nsapi_size_t size); /** Register a callback on state change of the socket * @@ -197,7 +197,7 @@ class NanostackInterface : public NetworkStack { * @param optlen Length of the option value * @return 0 on success, negative error code on failure */ - virtual int setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen); + virtual nsapi_error_t setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen); /* Get stack-specific socket options * @@ -212,7 +212,7 @@ class NanostackInterface : public NetworkStack { * @param optlen Length of the option value * @return 0 on success, negative error code on failure */ - virtual int getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen); + virtual nsapi_error_t getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen); private: static NanostackInterface * _ns_interface; @@ -228,19 +228,19 @@ class MeshInterfaceNanostack : public MeshInterface { * * @return 0 on success, negative on failure */ - virtual int initialize(NanostackRfPhy *phy); + virtual nsapi_error_t initialize(NanostackRfPhy *phy); /** Start the interface * * @return 0 on success, negative on failure */ - virtual int connect() = 0; + virtual nsapi_error_t connect() = 0; /** Stop the interface * * @return 0 on success, negative on failure */ - virtual int disconnect(); + virtual nsapi_error_t disconnect(); /** Get the internally stored IP address /return IP address of the interface or null if not yet connected @@ -255,8 +255,8 @@ class MeshInterfaceNanostack : public MeshInterface { protected: MeshInterfaceNanostack(); MeshInterfaceNanostack(NanostackRfPhy *phy); - int register_rf(); - int actual_connect(); + nsapi_error_t register_rf(); + nsapi_error_t actual_connect(); virtual NetworkStack * get_stack(void); void mesh_network_handler(mesh_connection_status_t status); @@ -287,7 +287,7 @@ class LoWPANNDInterface : public MeshInterfaceNanostack { } - int connect(); + nsapi_error_t connect(); protected: Mesh6LoWPAN_ND *get_mesh_api() const { return static_cast(mesh_api); } private: @@ -312,7 +312,7 @@ class ThreadInterface : public MeshInterfaceNanostack { } - int connect(); + nsapi_error_t connect(); protected: MeshThread *get_mesh_api() const { return static_cast(mesh_api); } private: From 10cfea3bd80409eb575dd8b74729ef60ac87562e Mon Sep 17 00:00:00 2001 From: "andreas.larsson" Date: Thu, 27 Oct 2016 13:51:32 +0200 Subject: [PATCH 100/107] Added emac_stack_mem_copy. Needed by the u-blox ODIN-W2 driver. --- features/FEATURE_LWIP/lwip-interface/emac_stack_lwip.cpp | 5 +++++ features/netsocket/emac_stack_mem.h | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/features/FEATURE_LWIP/lwip-interface/emac_stack_lwip.cpp b/features/FEATURE_LWIP/lwip-interface/emac_stack_lwip.cpp index 44de56e6ae2..42ec7ff82a8 100644 --- a/features/FEATURE_LWIP/lwip-interface/emac_stack_lwip.cpp +++ b/features/FEATURE_LWIP/lwip-interface/emac_stack_lwip.cpp @@ -47,6 +47,11 @@ void emac_stack_mem_free(emac_stack_t* stack, emac_stack_mem_t *mem) pbuf_free((struct pbuf*)mem); } +void emac_stack_mem_copy(emac_stack_t* stack, emac_stack_mem_t *to, emac_stack_mem_t *from) +{ + pbuf_copy((struct pbuf*)to, (struct pbuf*)from); +} + void *emac_stack_mem_ptr(emac_stack_t* stack, emac_stack_mem_t *mem) { return ((struct pbuf*)mem)->payload; diff --git a/features/netsocket/emac_stack_mem.h b/features/netsocket/emac_stack_mem.h index 1a88bde94d3..dc81317b5d9 100644 --- a/features/netsocket/emac_stack_mem.h +++ b/features/netsocket/emac_stack_mem.h @@ -49,6 +49,15 @@ emac_stack_mem_t *emac_stack_mem_alloc(emac_stack_t* stack, uint32_t size, uint3 */ void emac_stack_mem_free(emac_stack_t* stack, emac_stack_mem_t *mem); +/** + * Copy memory + * + * @param stack Emac stack context + * @param to Memory to copy to + * @param from Memory to copy from + */ +void emac_stack_mem_copy(emac_stack_t* stack, emac_stack_mem_t *to, emac_stack_mem_t *from); + /** * Return pointer to the payload * From 2c1c84502afd37163c9712e1346e24c4c79a8c17 Mon Sep 17 00:00:00 2001 From: "andreas.larsson" Date: Thu, 27 Oct 2016 13:54:11 +0200 Subject: [PATCH 101/107] Added copying of the wifi_link_out buffer since the buffer might change after call chain has ended. --- .../sdk/wifi_emac/wifi_emac_api.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp index 9e816d5791a..1d42b024749 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp @@ -265,9 +265,11 @@ static void send_packet(emac_interface_t *emac, void *buf) static bool wifi_link_out(emac_interface_t *emac, emac_stack_mem_t *buf) { (void)emac; - // Break call chain to avoid the driver affecting stack usage for the IP stack thread too much - emac_stack_mem_ref(emac,buf); - cbMAIN_getEventQueue()->call(send_packet,emac,buf); + // Break call chain to avoid the driver affecting stack usage for the IP stack thread too much + emac_stack_mem_t *new_buf = emac_stack_mem_alloc(emac, emac_stack_mem_chain_len(emac,buf),0); + emac_stack_mem_copy(emac,new_buf,buf); + cbMAIN_getEventQueue()->call(send_packet,emac,new_buf); + cbMAIN_dispatchEventQueue(); return true; } From 9ddfed274fa33881cb4237a2abe523d43e6700f4 Mon Sep 17 00:00:00 2001 From: "andreas.larsson" Date: Mon, 31 Oct 2016 14:52:27 +0100 Subject: [PATCH 102/107] Added missing checks for wifi_link_out when allocating packets --- .../sdk/wifi_emac/wifi_emac_api.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp index 1d42b024749..d1148ade4e8 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp @@ -267,9 +267,16 @@ static bool wifi_link_out(emac_interface_t *emac, emac_stack_mem_t *buf) (void)emac; // Break call chain to avoid the driver affecting stack usage for the IP stack thread too much emac_stack_mem_t *new_buf = emac_stack_mem_alloc(emac, emac_stack_mem_chain_len(emac,buf),0); - emac_stack_mem_copy(emac,new_buf,buf); - cbMAIN_getEventQueue()->call(send_packet,emac,new_buf); - cbMAIN_dispatchEventQueue(); + if (new_buf != NULL) { + emac_stack_mem_copy(emac, new_buf, buf); + int id = cbMAIN_getEventQueue()->call(send_packet, emac, new_buf); + if (id != 0) { + cbMAIN_dispatchEventQueue(); + } + else { + emac_stack_mem_free(emac, new_buf); + } + } return true; } From d255de6d830b26809314d5e29b8752ea3aa9f095 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Mon, 7 Nov 2016 00:15:02 +0100 Subject: [PATCH 103/107] Added cbMAIN_dispatchEventQueue --- .../sdk/ublox-odin-w2-drivers/cb_main.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/ublox-odin-w2-drivers/cb_main.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/ublox-odin-w2-drivers/cb_main.h index b0b30a9294b..cec7cf63c88 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/ublox-odin-w2-drivers/cb_main.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/ublox-odin-w2-drivers/cb_main.h @@ -110,6 +110,7 @@ extern void cbMAIN_startOS(void); /** * Get event queue. Used for running a function in the same thread context as the driver. * Can not be called before cbMAIN_initOS/cbMAIN_initBt/cbMAIN_initWlan. +* Use cbMAIN_dispatchEventQueue to trigger the driver to call the queued up functions. * @return EventQueue Pointer to the event queue where function calls can be enqueued. */ extern EventQueue* cbMAIN_getEventQueue(void); @@ -128,4 +129,11 @@ extern void cbMAIN_driverLock(void); */ extern void cbMAIN_driverUnlock(void); +/** +* Dispatch event queue. Should be called to trigger calls that have been queued up in the driver context +* +* @return void +*/ +extern void cbMAIN_dispatchEventQueue(void); + #endif /*_CB_MAIN_H_*/ From 3fccdea27bc00d95bd59691094f4ecd797f44ed9 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Mon, 7 Nov 2016 00:16:11 +0100 Subject: [PATCH 104/107] Fixed dynamic message queue for scan results --- .../sdk/ublox-odin-w2-drivers/OdinWiFiInterface.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/ublox-odin-w2-drivers/OdinWiFiInterface.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/ublox-odin-w2-drivers/OdinWiFiInterface.h index 0e5226b24ee..eef737b63ba 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/ublox-odin-w2-drivers/OdinWiFiInterface.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/ublox-odin-w2-drivers/OdinWiFiInterface.h @@ -22,6 +22,7 @@ #include "mbed_events.h" #include "rtos.h" +#include "cmsis_os.h" #include "emac_api.h" #include "nsapi_types.h" #include "lwip/netif.h" @@ -211,8 +212,9 @@ class OdinWiFiInterface : public WiFiInterface int32_t target_id; // Event queue for sending start up and connection events from driver to this class MsgQueue _event_queue; - // Event queue for sending scan events from driver to this class - MsgQueue _scan_event_queue; + // Message queue for sending scan events from driver to this class + osMessageQId _scan_msg_queue_id; + osMessageQDef_t _queue_def; }; #endif From 4736cab5431928f1b2fc9b8ff2c597dc13172afb Mon Sep 17 00:00:00 2001 From: "andreas.larsson" Date: Mon, 7 Nov 2016 19:11:39 +0100 Subject: [PATCH 105/107] Updated ublox ODIN-W2 binaries --- .../sdk/TOOLCHAIN_ARM/ublox-odin-w2-driver.ar | Bin 3774356 -> 4867904 bytes .../libublox-odin-w2-driver.a | Bin 1863404 -> 1866890 bytes .../sdk/TOOLCHAIN_IAR/ublox-odin-w2-driver.a | Bin 4064460 -> 4999816 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/TOOLCHAIN_ARM/ublox-odin-w2-driver.ar b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/TOOLCHAIN_ARM/ublox-odin-w2-driver.ar index 296ec9f0c137baac0fa26f70f419a459a285e20e..509b80db9a2aa5b91fb5ec668f8a5695dfd8686e 100644 GIT binary patch literal 4867904 zcmeFa31A$@c_vyj00HoZs9T~W5Q1b#7Kwx4C0jNJgBfB>93#wtq;1-x!At{aX)rUI zg9L3QCS@Iz<2c%llPAZHBPZTGC7Z)iY_FBrk@Dg=isS5xNp{!CI%_zW9m_9I)>E>4 z?>VdY{eM+;SNHUQvIvk#mP0nW|D*n@`s=U1&aU3})@&s=|F(5~UEW{60m^6dZ&%mQ zp24BL%yZ8=A==+0#BbHS*AKoR#Ot_1zq}|``wCzGVe!BE)$;Kt#f7?B@2`o~xYm5U zNBmINEBnQoAM$GZ$n)a7uU9`I+RpQ8|G*bS;Psy$5bfu2b$nt;G+f`F7ai(a+jmxY zt`GjHSo_cHT6gdp;$mIvkH0Jeum5sdtiN>qtJJ~9&7Tn~emzzb8~+tuoAxe>Rl9y? zOl(@^Yx5r+5vzH1{_GFL`CON^_KNeme&R`S*>cxk5MX#@ZQC!*Ny6WvOi>B9S$HZ03Tvu=TsAzhXzAUa@?)p#j;_6kp zuKBgkil)~O_KIt8UAuqujbEQSDXulI?!pE|{jZ{WJ=!42YkuC8@o z7t3Dn>=Ir70Kd^v==#GAVjHgR&EIjacP2&ma@SwID!MPgb@O|_C!Fiw z^^2R$>wAAKZfz3YvXnMW>NpVZF>uVk2mN#(Sni~~Ouiw8z z+`2;7n~pvp-pJK^`}f4_zD|Ew^qSWn-ywR>aozTo&xn65*X;wnqT%|{E^+(0F0|XX zzk%z`yB`wgydL|Ec=PMIzIj@_`G>gf*#D#mygu}@xZ{VtzWohx2d?dJ{aQQaQ(;^#n45(c3pdi_!o8k!4JePb?qKLEiUNw zxAS7p!0KOnf2t(0;@gn5m8{%himT(N6L#p}8%NfGm3fAFe^ z`K|*;#)NbITv8nP>mLMOqeCx>^SXZh(_-|Mv~wjMcvV1~d9>g@|Z(yzll?;$gN(K~f$pE1>%lR6MWwQBvv|g>17RZFsrAYpm zL5UZ#b5%cbtdz?ZsH!Ya(E65fjAx7W*=(*>uUHj-II?d$X9Xodk*4c*eqeBKlYmU! z-9RKeB|A$LYkpdKF911p-{>JR<$WQPHC^#N@mRgD#!LUVsWCWMx%Dh z(j=m+n}!V%vRb)ss#?~X%?Ag~+ZA{QUu0I^K4t`+g^Tf}aLy`Pm2ANm4wV?yyF|%J zA;HOPCA&bbh%*J^a6XdHlT*JNr{adWH$lW znabpBqy}F*Q?FTOGLsc+)~ZyjJSDFo6I0egsixhw&d5|rIU<<@!@3$HR>UfdYZ>D1 z0GhTglo+ZwYz#)6Ei^KkrskvCd8=5XQZUNbag|8C?J*j=I%ZLOqKm97y@(Ok#lSIX zHtkXUu*b6^GR>z8{6sSb?LZpou5)I2)l%UYY&Bo8s?`K#RksJAR#p2jVOe=gI&{Vs zNS(6U%0`k46>f|CzG;I%jc|35mH}p>j+gSX4Ps$|#*2Urjho~?Xq`ajWg{Umj;GVg zL*NNCS+a@;M7WH#BB*JY0JS0w;nPLw1Da>5maWuc#a!h?*=boQt%Oe1N@Y|>t5S0+ zP`#Yb*4PP3GnEx+%DP|2*@OYE3N2PVxQ_tJ0iO~js<9Q4c&81Lpp$Qa3F`jfKBc-o zO0{Ocz@X}oj_EN?nw@-9;iX7lf55{*t&>C;eE~waJplLGm$<(Dg?q!W~#J*{vFi?5O|} zSB0Ci7P5${I5%9Mm1!z1*qL$-Rc@-x{rzF;@8@UcrtR_Bsvz0Xc`J9{)S}K9qddbU zg^3qR$2ov>90;jBhsp`@LB~2D3giwQKf8HQAd1;!Ms;XNKXJMliOxsz3wAL=eMM9h zWKClzhbU=k&kS_jrV)#Q;G|20jZTe!49p=rD@U42peFISlcP`=H;$14YL_<- zjdJ5KF^D5-s}%e2X52nf0{LE)sd6Yzsx-!vDzqW6Q3_JdOwHo95UW&5mDn+~z=Vs= zvUCTC}zM~v8rZCrCr=!c}DXp5128sgy!r=@`AlOM_| zKq@<5?#noAtYOsYRn+gYn4Elwgx*zg^)q2WqRZ~#C?y7 zoh>9wXw>D{h=w=;)VMuciq2;%O~|S`EyE!@&`HaxkPB{L^iNqJcSv0>&<}yo=!qn< z(HBYlL}Ry~Be3P9h>T6UDkuAXHw9T9M@6t(&9zE_GOD`92D+=6;dEv?ofu2O3zwa7 zl8Y>#Xhb6Gi6RC7cD|8jSDTU$zn7LyjAvvu8?Vj@g3v-%YU-&}7BqG&&X%B!k=UV3 zVj@0CYH!q}LsiOjU`L;kbQ(puP|j8?wjUonD13;We#DSM6sgZiA_j*~pqo%bZ()H+ z7`T;qa6^);#oTM(psH&AE@B^O2pHR~`Yk1UtXz$w02c-7$(=@Vt^P_|Ha zSp8^&I{~d}iNwaRq9b9LzGF$z;w&e`K*6{9Q4^&aqgc6=Zo4{M8_rf;O_nPbY1Wew z4^Bl5W#xwpr5T+x2R7*^4pd6@GUe98W}rRXjf{*jc*g66nq4k<#5p*F&y0?`NR(Bo zGc?3j&yMX>(Lc2EoMAXaCLgC_^Z;5QQ%GWN<^TyoPf58tjmZ^kj2U&`)L_k9+Jw;t zN12NTJS@gTlg>AQhSEcs%4$YaATp?$$swU|shF#>Di{vhxe=?HtJvjQsp5)i##^17 z^<^XPvL-9`Lbh^3F$4)iZfTs`oX0C-_=Ix&oB?Unxk4R15PuvrZRE$H4%j(8LCF%7 ztKjEisb_^QShHCebYQV+TUnN< zt;}ZXzlMyD@;g!UhO_+=O-N`|SkfaZF0D-m^{(=^hG6>B^f z$tjhM7^VO)u{%oLGim7(jaCCVxxPUYQ>H0794?tVXHhx7VhD#6mnT^%mC+Q~JcHMa zsWF}kreV>&qsF5uWD$(!Z1Nj4I;>ZzOK6~ZA~1KKRU@Ycb3vQpV`@b@2}expD2Z#f@PZ$$E>Nvv{m(q9kU1*E9Ski0UgAQ zIflFI=u6ZnN*af{Nujv}mzFG<3PU$5RVdYhR6-MDLHJ~L&Z6nzDXUB@UOnDjN~Nq? zomPf?sW2(tG=Or*E*03VP`l}-d@7YnG-O91y)sCpk=c1lZ_z4@X9E%t$kHf9mr=Ex zHfH=OKaIRR*(W=1n6PZjGez0R(5oL>4Js$82l1wMmvuA7L4<&UTcw^b%W+L z4N0a6cDeWv6qu?0(li1#CYd0rx$3Es)5UAYTnXdIX;enbdY<96{&5Z za?Z_+MiUtfv7q=VD`#P{zCy+7At+zx#Z|J!>VjQEugc4xgF#p@2P&Fum6kVD3?Rs? zTBD_E4Vf)tJnWLyyxak5fJ&GUqXDd<<_aa6Enq>AA{}26lTNbDa4DXa!bQgx?OLj6 z&(5m#1WFL(C~xBO>2^V{H!HroOI7xpF5{HfpP2;5wJUvzS|d@KOxv*Pnq91y z>eVUgzXagZ9{k8u5<@9Z!qWB_`o1-?Ix0`O24c!mma*uK0YQ?vg|SkpOxqJ=4KPE2 zj>b+e{FxMriFW`X&M|rvRT|r@W)I&E_iEGpzC2h zSeu$PwN5Z%&D3esK>4y*PgB{vT{@ga^P4Ye3OeJ`cGOY;ajP*MJ)(0?Q;hVeM>e#Q z#uN z`n^<1l~G56Gv+dQq|E1R7Aa$c%c+zK1q*hC)yXo(BHTJT$pQD6kvd8nCJnH2Bv+7g z)zr`k2aW#80y-8ePc87HKXIQaCISaAv$8jzj@8R$~>0mVBs0bpUcf6ZM4|3tL8X*H0-| zCJ0hc>uJEIgE$Sc66tn$H3u@uWgNE)aNT|^_e)e*a8e4ewuOBuT+cLt>#GygY2Xx@ zbm6x3LC6TrXx3yYA`cuO01jYF%~Q|FkjaQ)BEXKo? zXdSzDinT;GHBc2mHnU( zJk6UOOj3oGtz8C#q!w)r%ox^;u^wZU3({<)bOXzsXD3=(y*5IVMIEzbI%zT`D5bC* zxjloNgb~)ktDcFQH*J-U{mDcr6O7Jt6YP~FSJkO6jNy)#M9oZ46oiKxFJtka_u!eK zeA`Xjr0MRZ?#{auuK#16K06W7pY`m!Q8;QSXg`Glq2wSg?8Bs2b=b*RK{Le zur6KjBjmH;RJ~3_V|gt{lDGs%j0GX&W<+k9;U`!E%v-fqhBP@iR+dlWVu_&m4Txr@ z+4;J-c%fdMcfm=t?6dH{E{0}7WJF%vnB~W&7bEC4BW|_ofu64OG-i>qod&f`?USP| zYH$;?KG4%#mp$4oM;Bb?=)xGLKUAltOdWr>D*#Zb#N<$QMR#OelH!GDsfx04XBhI9 zDqQg~0@e+8%v(S)rxE;v(be^B6aj~9meS#!VQQ{fW>hHxUlT5u`DWAakP&rB1@! zY;j_+OGb~|C3(uaS2cAGooAeBidJ5}369A{vo)!JyuHG(i(oVo zsDsP>7^az`^8Gqcoq$-ez4x@QGmh5~+$wm9-D2685l z#vDjIx=M32DGh+Ow8mK=#uM>G*2>& z&7i8^p;mtslIF`;TQothaNbuIC}=Kl5>!!KWvlRVf&rab(y&UOpM>`{5_*+cHHtEo zGO$cJ)&pm4q_0lX4isAeF_~S4m@3l-fhHkoArbrby$ofoEfl)$1xpD)xb2(j2RjsW z#;8w+281T^vA>KXMG#FGi@7*C*i{odlsNDqtMsx(!7&_#SJSctDLbOaimJ)Fsgd&z z9B0MZya?Bcev(Xyi*=Rh;#?iNI9GKhPHV@-spVLis{2)Grz|=MR1RknG?^Djc8V3! zJOMp%dnjgX&K@mfNiHpLEDqYpm4k!iAl6iwm&#N+9d3%vWk(eq##W(PsZ^WSlPtXD zN97N6UD{qVFbIwr0M}p!!JFx6#~=njl#W7yJEL6MGc`aX=n3JaI_1W3BBo;WJg z4WSO&lwiojehoCC4kxeh8x03rHY3%vzf5D}n-#j)V9aT`0l<+-A!$;`o%_XdbVK*788z_Ry}eZ@~9;1@m40V@Kz`vS^V zH=Wdo%9&l(paM)kWP4no?lJQ+7)q{UzAxy3wMD?MW0KDA$0W9?-)chEg+$~=zXh!J zKMe&RL^Gu6aGt`}VH%5BQ5p(Z;Twz2Aee;)wBw-oxw(UCLN@ZCYB}Bf+0dlGoG4;Y zW)vwfKL)KKO95`kO~3XfhJncUrC}zn?Gk?-{rQCks|H0afO200FLAnk&vDvI8|<_K z2u2Eg4hhUn91>F&Rpxmniz^P$ZrvnmkOem3Fv`%&;V(vm8d#DpJ*Y5UYG8SK$*M?a zYTWNgCo`Cwp|^9elV88Rrhr)*fJ?k~Dqz9V7WNrRJPwCIQv)AtzCHyxz`G#;H0#4N zCwjze95c15mBZ>EiB64Y^1L$1V_d!mZ4rQ=*$*r1Hf zH^fe>X;MD*w+aQhI%W#eQGjlu-B8O0p*3i#1}?jv%+l>PQm=J`N39u}>Y~1`jvY#& z*p-+{wd}lGDN_#&=KlkcG~*9DHIGyveaaB#a)2YLd5A`KR0m%kfoaHNEHi7oW;dMT z_g$vsd^qPRmcbkwrX6Tym(qbZxaHIVJ*vfbdPHrYIdtTwT3?V&6R^i=!y1Ph^F=g9 z25Ck#=8I^|jcCk`Xe=9i81 zGY_dXd!$mHp_sTBd7}+U^x=6kj32LtS#o#I*g;i?5Qp;&lb4{15riTy5R+fQ;u6^( zaHMwkNv_34=tThD84U(q0%HfU&L*oW^E;4^2nZ)CJgdlRZ0H==i3(IMZOl{VD`sSh zAXgozauI_wk-|b`axhAyM2tmgDpfi1287cC^73(up-`S#9)%!IV;2pf z4#1`4+-VIziu$$Dc}IyVfUmcs0=diIGB${&6u1*wicig%C`cQdXCoWY{8L|q3!dmA z3aXIO9-2X?304%(P@ZtQc=71>W=d7?5YUT95Kw3~+*sJ|Ac5VBv-xm5awHRpj%CIY z69-em17S%UD^1QI$0?drIubpYDVx1xq(Wg`e${aXX?ScpmY$qUk7ml1QjS)FH9J~5 zy@?X9WYMV=SeW6x-(bO#4ZWv@&5s%f4DHI`eR!BM#e4;v8?6drjgFU9HBoKSLk)I< z#N?(?>|>u%^U*$%o-;dSTR4ox4H%~>5wzdRHiz-1l1oIy1yZ}S*CTj)pA(hgJ{(*M zw%{g`-%qlxZuXG3D)09Ixi=_G?Bml_Nt1B~C7IOrw~Fv-LbQ z$IIS&jnUn}1kFb=Uqmach_I3F5cD9(2#SW8muNU(BRyd*$IfN4GcujDW@~90Pht_m z73(2ICnr)F!Oxerd8#FmEOl(}kPCDH)Of8tSuQWbz^P?H zn2=qDPsx^3$ASZRP?-Ht*kz-u%US*4h~ULyQ-=~!YM$xzr3Ch%2j$G*YnFMJWp)`2 zxLmgE%IWya&2-_0sLC}brI03g(uzT9rW%)JS^cC&e0%7C;PS&gSW`^k^+Bw`2??dL z`l0GP&{R4twkVEjR#fvi`M|RPYhrlm(}SRamxF~AMP?Fu%3 z89cyI%{Ea=E*-H^Q5%}7d3W(tH#*Kbyd>U_OzWqr`=qn&kQ5izBI(^`Qpe16(OSg* z#2UtPa1`-U9i8b3TA3{1K#u7;)=$7inUM!vNf-%_6)bumWw=x-5QmEyMMo9wp$A91 z-o~urTy5Tqr$bpVgz)gDNh2Q2bWy&X>%*$FA!e$n@a58Ns5LA|XvjwDKD(^a4YS4T z>9Hx@#o%?K>Bv;tgJ|f9$mJxbe`0zxCLK;r`b6+~jZ^WMSMGE=Jvre)O{Svp1G48< zDAC~~Vy2Ll=P!=LhNll?#wHb+-ksNoigF-&u!?NCM6@E|< z3=Cv)GZ{MPB$F$bGrM>19^AQS=Ppp*wI`FAiX9r*eedgMPL0~HhZ*9hrj9^vzCy3v zq;Sqk89P6bs&@_S%*~8P5^{=SxRxB)r{G}>aBQ@EboyH|e(YGx&peqrMyMgh&;3J% z+hxc+3{^7YZj+I)c5-k~;RxjBS9OaacaI{;BxBy{K9-`BC(+YI>g^F>uwU`dsSUYz z*R8t66rGy9T`kkLciwE`l66G7Jh^^KORgZ}cJg5E-WUoOhIA-0hBN$Rx71=WF5Z%7 zkf2_=IHVG8=_$&1?t=*}&&pcr&c(XQJ!>g+vENiz(2+SU$yW|z-m_Cv) z9*OE6jXJcH>I4XGx8Gs6Wn<;Qy31e$tSlZtwWl;9Qw}31n+FI6DviA0eR%+fy^Z4)(+cona~Sww!t)$lMXR=emj;*Nf(y^&FfWI_ zZ?XBNF%lPK9WPbxi@{T*1~T}+EO!n2<4SmG37$JR7durx(PEq^=9JWdp<*>#ww?12 z=aa|a&w~XFks9nWt?pxg5nM?##$Cj?kj=dgPSyrqmV{Tr0YlX$scI6@P!&sdvE;xm zGCbNySgj^YaD>frFhnk`X|i{*GmOnNiENKH6ImP$iaS@ZX4=|I%Bo3gGMhNykikq#nKJDo}QXV5GS z%T6sSybC~G&L$;ER*k!2cAIvE&sm$T2NHR$y z26~GWf_M(;oVwQPI!2|Fko8t_q zeDkxK(RZHJ?s6539HSPYR}m&tvez>XH;H#XK?bI=5P-}`DRpPMnTdcvKml05Ln8EN*@NOKnZQs*miI{^hf9F(P?csC9*uiQ`*9hPVgkH z;!Wah=u$pb$d;=(azuNs@gtd$@rayY!!v~LlmI;LVW$eyqpZU4t%(X9z3igc|Ijef zi`86u<=+h_F}`35>4qX>tl*Ot+~(=Gw! zD&Yo34|A1AMgSzE!|oVVqEaWSaV+=C;9#L5Aw*s6vy@zfC0_zaRTMn&dMUbAb!Spq za_9;K(G)I`nsN$)CGZ~nDJxs$uX?Z`RO!Rn`>Z-Tp{SrzOdzf_i%mMx<04>HCO%PB zXO7526b{SvVOlrwCr#PT&P=eK=!!8gq-sV5+XPArs35cb`*zLl8lZV2Uj;cQuTfFX z!AljU!dpZ}(Ev}3;IL9?g%-*sBySgf`(|eMHA!9| zlRtR@Ov)n-Ktp56NmTqAeB@Y}&UheLC6pd{$OB4jp(=a!zM z<0F~lSsU9xWX-%Yf&|XcOq>B%`7}=h!3?}U zr6QCZ5|bK9OlA^OckAXC?r{(Ym?GW%|03N-K7)M&R$!ajQo8OZioNbb_Kqi060+^7p*pYOi z-_#2s;0@508_Hs&A2H}hc=Ss_hWs4+GP_I^IjsXplov5)3|~sP$XHriB7xcx=~*d~ z9+j=?M|zpsCr9a*IACdbja%)7g!&05b&ka?*bPu@KG8&k%#Dvia8YbuUR;XU+)ycL zf+|Qn5uY^a1bY~CmN-u7{NiemsAa+dYE%@fI@EwLx6%MVD;4mw$}B(2oM}5B7$hHA z#l(*^gu&hW_UxJo>KL7a)3B>$IbmE>zNuuw*Tqqogj&r6-BAQRQ)^5tI*WMJImBZP z4ObP%USMqne-*2Pq_Zk?hPnDwkF(R=vv=RFnf}2h)hCe2$YwK1T(MJ!C$R*CDJbt=@>BGmVx*9Km)(K z3I84wPt}80D|w;Faa#`BJ2GHSpt#;RJosQix!}%ZIQX;|k3#h%6|l!!Pp7bI>d7Qy zJlWtbE=9n?g8P{!PqV&gZicgxoxzDQ+8;88+jVnxh_Tu^FyJ1p?5InLU#BS0fb>xo2=9nR?qTb1|BHm%}FKB>Z_q`xUF^Qg}TRXZ>ns2bs39g@LwF zvP_@%-|5s})C=l|&h8zu`e*Y24(S}MMn%T@llBS$QrRt0T1JMQMQ;uA6o~dMQp|C6 zkQfp-vup3rKt4CrEOE_Q8xq%ym0XQ|JWuL6Jc3av&2Ldl?f~*xSq89W9LFVb7@O6s z1$1Kh=)vLXINC3~tO_DM!@3+3W}}gop-2qH4M&LSSVbX+k#tb@-5@<-2CzqK~?2j4Pjr{V{ z&O!aOdx)MU(vzc-N>7qXPfVqaGC4iVg+VO9JhnFJL&OQz3o4LhY^$M1EJV^i1(TV( zXo^!$<7oG)hl)~;rs{roFcqiZo0Gy6s}6WLTcJ-6dBfF8=pU;1>$aJ)mitwblY(qj&DjtswW%5F`N`a4m!PTCGI&+X2WC6HsGs8mUxxp+aIttQMWObMLumqhxv4UM!r4Y)(HB_Cd z7pXWAr9!DTon`=mj7+CTV-x8_G?Jd2%8c8&S*&i=S-D|z8+X)N&SA_lp*O=L8J{?*HXNm0%GppO8EPQM z2qUuT!7fsLCM@AZaw=XF`eSfM@FhGfKH)%(p-dIqCj}npl7L@>WTvHx{F0kb zx0vQ@Za{Q~9_rbglBt8V-z#}|#Diw_kHn^;vLE8|Yl0D7mR^LZaFx+A z6zXs?0{JG=-L|Ik8l#0eI7VLO6OP={klKgJV*J06l<5#6NeK(2;0hWe-c z+NOHJTzPL!2WSCU?GWjk<#s7oW8X@EZt!IBxP|ObgysuQqFT7-1b7NtVSw^eGqB$4ZAkS@fu4mE}J4lfNBb4i5Yk*1dKfJ1sfCT zRJ{Q4Tm*r5{~l7eP^D~HbLBISBdEs7FBe#%2KSVRsqN>J)0jK7bCpsRt7C$oSlOP# z_Dz0{O7}ts>M)$Z=8V1lg99RouQ|o0CeZ0L&gUAbpd;Xr(gzbs2RJ+)%fQ>}U<6|J zr-&iPcs3_yDy3{5y(YW>L>o+WMH$8dntbz+H})BnDfsm&K3uD+lBU?z38J_lx_LMo zXkG``yMi%dV=e`|{S$?N4PfcCj<;szf#NROT>(`%RdXH4b&v|>*@5feXb9@;%XP4* zNjyL^5M1vRtgEC0nnd(@sIR1G=GI*g$`eFw<#j{pEx;pFhYn!}&v@h=lT#3?!Ni0K zqA;VQ8Cnl>+@dp9e$*5S|_K&IB0v$lRe@3_l1Xj1f@&OONV_+m32ui7&I3Umzsuma#Y5z}; zx`=9yMltkJ1)>ZuH5pH1^LhroFQ<0{dq%1ZitM1XF*MM0ga*5cSYxQSp&D(x-8+Wu zWrlRextq8E6Vk$Fu+c&LRwGDL`HtOb0j}{m7^8_XMDo6hDQj+|r1nQ?ewb2FKfxe- zi`pOriK8hgsw?t+Z~2OWk&H67G|(`DU-;+Irz$aJY+5>j0g53*jA3w9!3Ju#v#3S* ztyR!@VNO{=Gq7>5>G$7r) zNyPly3|@f3XIFyg6KIeE3CR>b($j<_CEjm@8<|Yw)gev}w~3=^oP(R4vGJ`hd^HX2 zAY7`;f|moKTPsi1(N9}GWKakwZ+6zsxm`tkS&OBn#;0lPxcf|7JR|glOuH5#*E?n1 z&xfIq%@A)R9cOu{7dsjlP}7>xWDC%gsw$01XU$EeCY-do2$cW4o((}FnScR-my;1b zPMUJz7YiL$!gzo~C3`*Hd zHVr{q3B|=EuN|0yOf@kp#$qGhXq^pCWG_C!rtZ|NO9~EPxP;H$Njs=;f83EM!6wW!}ldV>@@z83;!*!?AQsfAz&cXDemwkCvZez&;I^e}*ftq(m{Hg@iPr^2ZRp zWK?~;zaJlumT<%Yw-82HNgPLxc$L#oM1(xn+{tRx1MBlI*% z+tXR`&6Jd&$vSmvvFxsRQ*clhxY}pwr6ys5LB(22rkW98Bnwz1YtRPGucRiXA}~Dc zF+XhCbMyQ{pEp9qr6$E1g&Y}AjZBZ(SSf-vHIm^Q#>_9g z8f4S=DjSgLBXIe16d6y`HkX^uR!}>6Fw39F@Ef9g5TjQgv?+9&&Zfwt+2sj6FC9DL zkZ1YvJzwfD7CvCX8K~1hno-GB_%vC=cr&2bY3|l*3~E$H-B4G&7ecN*uY;=O(CX~cCX~8+PqQZcn6}%%h`$_#tYOw zPA14%dV@bdTUBxT6+$_n_ZEVaEvI2h^uC}s9<)czb0Qn7Mor!&wdppxBzG@Mm>Xucx#J+nyfYC1?C(-j3qiaIb-@#4-Ar{@8q##J};H! z!}Iz-cT=$@f!b_LJ0Zsn%=j{-9tt&*@!Cyb9OeM3F%&heYKG!m@mJN@*_SNeaF%kc zR+yWOtB8espQ5WdJ8yoMNi~hxc=m*ce!eUbaeQu}aWF@bzTV7Aqw`Cq>{BOQu0*Oa zB8w#oSy503J?v|smC8+oxkE*N7;~5i8YWJ#8gMMCC;k+C0B_yN&H;@Ds5YQvhfmM| zT6i#U!;qrtmGa#5MsnJ1ni}Z!Vk3tN>Pd@%bJK$zgjh$`$;Gof+W-J2Atw&dOxJYd zCh^0x?ODGVKb5Iu@f}F+oPn$WUiOwC?|E@xml01UmL_52HqOuDWRdgm#>-R8lE{xb zECcD18?-PuT*rn69E`-03WH9GAU%b_5ob>egHVSrJB2|vH-$k?JtW2HH5?@s&(Mxi z006Y%6d9hN%)Eg8flRT>6ANf>ix%l(v|xRF0fKU~qhO;fWSH50xd}*a)=^wQa{kqJ zW`#xUo;*nbluErB!c82f*h#8h;=wC1qnH@ShYL+k6p9PVTw<1kKHBJ_IXM7%ejUqs z9!VOR8p~vJbow#{G>{b>YAWBF)JS9{O)Dh^AI@dQTk!K0bok#V_j=JH7NXLLH+boN zdBtg9>qV25Pl-`Q=s7Y*;C-(w<~dUf2up9TDo2XJ5B15gJ7r$3))GyX7ajwMN;>h` zMOs|O_5dw)a?H1u4KCo^AOLt?jL?wHbJUVYp`Dqs@sVAbh5Rn0Ry~d2)9(q6&_NyI zm+puqn!&gnTNF^vG$D%~6FyXl@0g6@{XiF@X)OAjo8S+5BHI&~-cu;zoJc1zD~i(& z@S-HbO{5(;4x5h!EsMLhESqXNu}D>?Mw+TRL4@P*sK|;zLR#D%1qR-nxc3F&tr|3> zz$k(DbTnP(hA~D9HrULSE>H9hM-nXolqF}njdXy)v+ctmsS-CZ?$Vz(lYtvSjBu!@ zF=ugFc7fgDr4IKF>H)}vDoHAZght@rtFAxGGr+(9;8=~B>S3|OMza z3$OT;BP|W}^>ulE{RSkT&A(k;y9Wjo$35$?Pi_W#?lIIyhKoB&eF}pa7@VGwDOfHF z(`R%Bhi1Z#koz+Cq0_CHa8M%T@ONM{coz|qiFg|Xo24+DNHU0Q0bdIuB7XJN1G)54 zFJ}&q4eZt7YV=YDWi>N8BwrHHR3!g6PGrhdW-YwpuF}dF*$nWeK0-Gf8l!kI&dpYM zOH0|RC|uU9b0v+F5vXIS%y{JSP6|Wo$Z)?IIANZDuln$H><`hn((%I1U5gnS^&$@g zdlwfKvm%f#OIq0q=gFqRIm+<{chDJ}C09~3r4$3hy21;_q+P`Xzmr+0=H|2IL4{es zJ{mMKC(1P~sESY37vPjooby(}Rh@x%@=6wk$(t&=myid`8yMQNch}C{cxk4q%e2ga z{(hV?2Kw&ZLwngm?^*YO*jPLi3JLuSiC*DCLcH*HrmPv_Td(L4Yxs$lM{t5uv36%y zWNN&NKpbvX>DslUe|MLxz+D4fy*!1E3UOOk8fVnq*_Ev<!>pIqtY%2bd-v8(=>g^1ckXgMufTnj+U+Hn*msmyUw?xwin0&K7+#EM@%`-!?PfW<6mOqhK6ariohS0$ z7enK!({~Z0z8H-i>s@7?Zyh%qp=fzVU<*)#rL5FTkR-Tekh=eVdW(kvqkK)#Qu{NRtlPCtR~`xh832JJvy|< za%H4q*>=SQ^{uEdl}&u~3$JQtc{YD#QmX60%1EOR53HP|zDjLzWu@tfkSM-p6FZVw zp~)l4HKo-rUBgpp?5G$Y%8c(>-P|v?2opxgfVf#jJ$sl&{!) zUZY$iij|wBJ7+XH)>WE$d*ku<<$3?>ikgJZEK1RMByDT3K@BPyUOUaC(jyl=Vb%N! zHG$_*Mo2^7aqLFO&<3dsrID2|jFlJ}Nf~`uG`1Fa$HxkEOM+!mACQ)F&ricmWUrno z)TpX&rf8k#+|RN}$71X%Dy9#616EmlVKobu(vLkatC9WR|hFb7AM;%1i9Swxl|} zOSuZ7SGYGrnw4tk(~|{iSK2D1-4_G({`&Xr-nG4dHOgQW%!PN5uBcvEqGK-SIqde< z!Hkr>8ulV3udIS;-|tGPmSpvLHchXdF*MdCprmQ;(AgiUqG?tZZI*fAcDcTpa`F)N0Xv^nS=HCcO_|iCGQt>g}6V6silddA@qc3FO(D4m#Kcd3^%2Y2n-ffe=kQDH%#P?%KarEly@P^Ur$HTtjZaapQUVP$GqI8%$5A$T+pCWKo=n z$QVmhn8XAQU!IyyLf0PjVAKRD(Yh#fz`k{%vgLLe#!1>GR zQDgwcvmKujt=Tg;U?hXLk}Gf}+h-~^zImLtvvah=3da=!S1e&rLT|y+*KP3zHr`Cm z;{19d;pICVsE7J>9`DD>VZ<`8;pW7eFr5Q{Q$NJ69fLdiw^wpFExfy4yswC3TR`_ z#{s=!2QBhpvR3TC+trz4vz96+A;#>Po*o>;T1RR1^nhBhXOu$qyUr=ZRh&D($J(%a zQ|~}ayk=hD^UEi&*IZ*18$RAx%g$9#EcEo$@tJEe%!lSW8R+RrkB;MHn8>lAo>)(^ zXQby~&u~wwXHRUr=TJOp@9e>cL`Md86Oh86@kmcH))TpNY;bUTY-nJ5Y;d6G$em*Y z13f8VQoy8up>yN$_i)d2DwaC5yXQw!>4VXOBNE&LaCEF^GL=N->WK|U_V$po+1nF~ z3@32P8MLJpx4O0)8AE|)EgaM3uLxfq zx;AuO==#vs(2Z@~p`OrX5CGc{p|yC}6xw214lv97=yiURo8IehHTd=OZXe%X!1cGf zj9SK<6(5-^{eBfZRKN63^W6-D<{{eG!1p5VZMZscQM{eFuEj-lM*lu>mk^U0z+KBD z4VZi{f$v8((cmK#_{zBP&xQits{!0~5X{}v)&zNgf_a7l&Pxb7Lt$uWXi(zMeTKr( zk8*_0848~gpA_ZKwZ%8ad*iSDkN^2vYkbG3n15)v{ZGVm`(Jr@>dl|(V!U{+^`$S1 zHz(H4Uv{=jJbz*rfQKmFKskh9JXZF~H{wk7c#{UiG2-tb+7+r;6wiH+bRcpcy^XSa#{ul(Fp z>!&Cl8NU1_sYtE6oT=A%=%wEgtsJsTgnGr9@&VEHgKrZ{DA92bApVs<*9tv|Tj#fu z+|j4!x1M@N=6>tbUGs!%i}%ONU)uh6FGt$qp*Qs_ja_AEY;MaH9*teDG`7C?@-vkF z&7M52iQo0?I?m@>l~3^|!5Y~c|I&9}J|)xT&r>JTDbv;YrOwa&po>zrANdeH_ELzY z-KC^$WN4p?bF@79kFS*}6}uGX^eMp{0}6iO)czZZzFol`SxLW5!*!zGqPepKb!*x~ zuel}u(n)dhYr|sMr>|=hVqiS37WZBF$hqeGCmNqO= z&F;vCInIs5g<3fIvRE5hqV%^e<+q|-;5j}4&(X$Dp)*7oB};C9&)F;fKb`mOe|I+8 z9zPwwG9J41wLWp?gG-`IJbo&^SJkJtb7<*-{%*@%PJOy9KF=Jd;^GO>JNM%4@ko4B zhB5TEzBffRO$@4h?qA&4+xFt7-d!(l?%ncYXYbB4olCc){)mrJ4%^~ydv+7&=~k8V z(eeP-K$5Xd$#~xGdV2EJ(EZmbTOqw%_YU!d@^@4Z#8rxS%|qhW&ZU-HHz|+RspT&2 zf9107wT90MEro6+?{(GF;t6Sk{m|9f50akzw)Q{ZqeHi7k8`7=p~+X*SFU$7MCrI5 z=^!87*4x8+xLTzv#O2+=<-HE&Ew)J?vL+sTww*PwL6xewrEO^qV>&d3HPRdZpIpcM zX)Awj4N6kCA8y+AzcSU`ENwTlH@sTu=Cn=upM3eXe$uS;252X;(!#a15sm!6+s24n zrMD!nEUn9*HmYT7;v3>!i{j-Ew0-n!=w$2n!)rUfA8x1m{xG+5ldnEL)A1>pe(~I` z&n8q`Xn5jB{bfRJz)7?gSH*9Ni=I))IvJA|d)ZX%Q~TK}#dB-Ezd=yWI-eC??9aRQ zp6sWTi2kR;y`3+%^zMAIwfDX=@g=RjJD$EhKA^n&T_-b3T0(35dryn5uJXWWX#UG* zL!Bp2fBNhi(ecs?Vuvi>&^=q<0ZMz<+Q&Y9c75l)H{QQ>LqEk$684_FbLpuY2x^T# zz;bT#$RX|}rayJV-jh8JuZ;7*oDB)YDL#)Fb*!C%v3~ca@82L}B{@=mUGY=j4lWzQ zhT@`Y&25{|mk7PQrlo!DdJ*dCSlZmxw$#$qy0o?{j7!QXAL#sC7{2ngez9#mdEA!v zv7Y(Xmp<6?@yC90ICQ2X-nx|7+5#{9vEly8dD17FlgBuK=+1L;K@xj;A z4@8?YNq%7R<<<`IrjI*yfB!3gGWdj3_t(7id*TVDkx*~t#c=QaFRtkgzqr1)c;@ex z?pcgK6W-B#Cfxma;z{l!c03y*>+JeqJly?ZA5J_T?tUcE#kETFodVy3KHP)xcQ3U< zYHRlcJ_#R;w{|c3aN_aS?n>fGpVZdwq7V0Aynm^4$M!Rw-L_A{2jiXHmcn%*{Vhwy zrNYuDxee~@eovzH`&-y&xoPg~erE&r!MIooz3H`Q@saGsj^6N@-}-)N^V%1afY$bQ zoDolide@wJ7Pv6_0HR~#(zD+eo7bHAP5dQHxTBSN4IR{XXzBO@us57(>w@+}dsT~r z=az4t{nO{aaaKIP0d@RZTVlTKV4iqv7wY=E<{v+>VJV_Kc6)r!vmGplTXXbK-pZCp zlBu66M-JPDwvM<6k?3-#Z!-#T5#aE zktFWLbKm#oPQs%#{|Q+a{q2&(HvdcQ3yntZcIxirtFx6!Pu-nRmfF($BWLCpMepG= zPvLKxTh;@CE$gtxX4iAS`)#c4uFj1N-O1FGBEtQ~Jx;y78GYKT&Ui-(l=D{AgP=Z? z^Z>dqI!Y2+Zk>Gld^?vNK{qStiO05~-2NQp*0&_bh+9=EsD0OCh0{ESB#bjw(0zmf zV1+D!lj2mC`liIU9#ZA#axGFWN0+kY&?Bj!G9W#-$2Xxb`h?T}+|4?l{bP!U{2}$G z!o8Dc{)qeF{Yo!iQDdh&luo5aD9oEweq{gZ;b+8ix4>I|^X_if>xFn+Ok-ir)lKgZ z+lF81EOQHuyg2=$?Bz?ZeOva-sUJ>#Zp!OsC$E=rUT=#(en5Lh>a$5Z|39bN49}^x z(A*wL7c>)aHF`ASxy^m#tN;Do11i;`XM*%BDF399P;cyvPVbwQ4mz^3-zYV}X%#(6 zUyq!k(7HAFJ*7P^dm35P1>4{?EQv;sH+ND_uTYYup0@b(#63gOVwT1q)T4W7_*c;O zV+4n%@EKW?Dd$0DPnyu>ug4y*a>xpo{VOV`;-`l<&VNv^M=85ilR z-tWjf_AFW2aaE@}>^h`<$QGEL+PJiF>5F9bp^`%_GL`18ej9CzoMD-FWKrJoPHNoz zW|-roXw2_Bom9H{O?%`el{{*nWPZn-7|i^}9Z5m?eY;2ITMU`+U>$0I|GfS3Z%{6F za*j`m@P`TNQ_%0&y0l_y+^pw@M$1>QrfzXGbu;4lkWIdcG7R? zeomZOgBb%oDwFNHo|_|?H2&4&x7*o&OtOStC1EXkkn4JPpJ`u`o}6dQ;K|>zw1F*N z&XG!QNuzh!7ukeRn|s^NP#YFfeG=K8h1etTC|S;|hBvX!9}IWeG={%y{fFn=c!Q?uzC%Ara$8qf z9^AiEEo-N;-qVk5M*7#;t=mFNmoKeddi=oVCCN?gE9J2r>DvFwE!j5RKBB+p)vBpe z-L{IJjnL>LYJUBvhu3{d&gqa<^}gr#*WPxmgu6x_dPem9!*CEP&FyW#tfshSAJX=y%ITMf_k2p$GVvVG z#fUY%@8$H})Y7%BTM+J~=z2E0RdQX1m_nE*;Tep0_F9SU9eMbf(Ds(U(D2)kI{HWR zkW#{vPX~oN6@TibH7&pJ(%NwD+Lo8rhVHqR;8Xn)jp`>HV+#%(mNUo_m8?GPJTDsar`evImc__6f2KGs0VmMTlZ~@pMSco`RAeN2ZvdFR)&GKmp}de4PnfHg?d@?r@y~mJo?Nn zEQ39TC*FHhxE6%_`I~;}1{vm_n;v~;!;+K;ZvYC(le1|=qx9&0=nIeCi4U!iZAsnH z3^fA?;o=QrV^a?|7Z7anWveq%OI>5TqsJb&Ii zJ3t>xPpi_jDMqeNW3SDHJ&FFDNxF0p4gL!o_qkj_JL0CjCV@j$a?M)OY~X1vWP-e?E1+d5Sb8U`y`>J;r$Zr8DVY_ZMQE zmg4nzIC(txr8DW@;MaKGpsw|S_~&^bit0JNuBOZ_=oNWe?7X7B7>(VfGwJDbJ02}K z$H8CVb|*Lym(HXQ{*YUvi)nsT{0bLj^N22;N#Fd-d&?FWpA)|#?|L?PV578TESJut z$Mfzsdc2!*P@1Um5O2IC0{y| zekDf4IFJ6)ne=buyQofW(&xOdOvTaC^hAh$xqEe`>)6bf{8z%dn&qZ3KJQuIE0bGw z#`cN|(<$fI-&aCKDv^d<I<(SC`JDf1_WwUXhWJdoG)~ zhJV75dVd^vmn#(wX#m z9LYknFw5)7Ir#q4ne@f&$D7OqFR#K&XVUk*{xwopm6y(>cTSF9k(EKOW-pydf9}f6 zXZK$^lRo3>K{XaD)n%vSM^{qTr8DVqc$l;M(`ecGoLA?3_Z3ySBXy<6T;4RVg5_O0 zlfLMD8ROEK^w`nP7T0*>{iQSM3IgkRJuCuepMW;QofvJ zUyWk*9OS<05nMWx-fkSq918d^5Q%dy;w)}j?S1zwLZFP%w$ z=}h`dXVT;7^h;;b;}Zs#&ZJ+JGwIDG$-q~0`S9b*aGZOmI4Q)*%*Tgt_UdI<66P`- z^zOl4MVQzBy9cbV;n#vA+jF@$i|_-Rwrs?y^6jDaaC=KfYsZ?7wvP6Wj*hh*>pIrA zZ|K<6elpyCD%}2Hxc!6S_J_jl4~N?y3AaBQ?l>Lpcr4uUp>W5Kg*!eR?)dR=$49~) zKY@d}uP~Cc0f%BoF8|So!XF8V3laA0PVU9?Fl?~x;Wdx6KH75nLe&FL z9lXH#H{;%Pf#dE%eEQdgN`4v(bm%~kG)ZU_`~}qGaVm7TBtlOMmo$oc^c`6ARTKSZhfTX z(F>;w(JytkAFmhE_59=Z8FJvxbW>nk5dprybpc1 z;meObwD#eSN7^54JH6(y)(^G(*u|+IvW{N7`a%7ui`90RcJVe&$A!0xi_woY^S$FD z)rT&lK2U%5VzpOhAL>H)UroRG73kn%`o(W>8C-b#znJ%rguFP{IuY@s@M;mhBw z18;>dy3lpNjQ{f&xeorYZBR$xJkt5irI0@E!4*7r)e&BeINK1P|2Iru$x}c24&>Vn zScs5#E8w?k2EargHejNYPnADO*ARWxj_7XLhdI1UZ(+Kdt`;A?)d#O(ewu@jzcoI3 zn-6YhewwqBzjhzJ!w0Wr{=J%Ato6~?F`eeY-5ntW4hZ{x{T>tG`oOu?uJO^Y zWjc*z}m%p3CyZVuIx4ucb8~$bvPjdtEce5{jJxq7&V~>x13)A8D)bAD_ z{Z^*aJdpg|Dh7~V`i_Gl@oKxy z4du5}eBA?ICVtlgZxO%hfiD+Nc;G9U?54=_UcMp7n_^JoKQGDJ5-y}ZafxEFpX9$?+z6PSHM|8dnFy&p1W94QoB3J7uY%D{-|gbhD4_a<#6j`f z9(YXrf(ITKk9pwjqUeDqM9KqCioG5B!;J1j6dEmE- z4|w3agyn(XCJuVww~GM}ykA`Hfg|Fd9N$Ul85V!#furK99{3LN84o-ne%b@a!~-5U zE@nLN0Ws=Al!W+b03O>#Bjp9}XKf>@P ze2x|m>bC`D@|p&4C;0#N!GGq1|G)=-(FgyM5B@nH{L?=8Q6GHV2jAy|-{XT5K6uCn z-{ymF@WIr!=pW_ZP><*a4E2e1za>N$-TzjIDZ2lK5dT))e^cRKzj_&VL8Y_?xy zj_iP7l0)=$xUc&g*`}@guL2ee__GTCtbhgL8S%vFj(7^VQ@97{4moXvMIc)-v80rJ={ zAROtHHM|k9e`pA@zx6=I?Atva)Bm_i@bzc<%K{?+4 zNq6v3de{AiN+0C(Q#v8HgXoagrT7lf{cBPV#rFi@Aifde`=$`b=ng$nye2>8kK)}+ z_up6fhP*C?zn$(VCob>565<|$mt=XY1N@5$M$rj^|5U+XVVLwy{G1QS-B0;JB1Y(r ze6e0}XT5^{!@{G8hvbaW9pPE;e=9_q;{O97@^nYJenQ>9N_Wt|tM0nII#hbP6rS_@ z9U*23#{GTj{tPL3h9p z;7r#r$^d%ErmLcEvme<(ze?$9TqVtK5O|1QK5 z!N|wUxKsLHr90%blANbuze?UU#E0-)FQB|n5{&qNneLFo_JedmMI8QnbVqnCcOCKl zrVvNzj&MjC=jRc~r}F+D-I2dz$Uni~pgUmduTg!g(H-^cvvfy#|5V-o8h1+fcj%6E ze~<3S{{|Hwr}qWeFJR)MdPRI~iatyC|3l^DZ)LiOkL-i^o~JwHwGkiEe-GWk|0La! z56(C4R8L4h+-@U0*B6B6`hxIViT`hO6nd+Gia<*$JMw+d!E`j*oF=Y@a>vFW|{!Y3hpPyED($l(csCx8u)owrzmp|lm5gp<0p!;W4dSN7-Ufhom9)5h0 z?toEM`2JyqXFEfBIUdlztnhzKci>@q9RBYWO!i9Y>B61#r2X&^!KYol^%6hw0~F`y zKdSq8>5lM1h3}+0^1o|F@YeeEascZHazJCs0j!|zq_FDdvQ1*0-EJ*!|8Hp2@F{z(PTDEOla zzE{CNrQo9q{%HljN5TJ_f-?$!Lc#A>@W&MVZUz60f^!P~xPpH~!B7ULFR$RARj{St zpHuMr6#S%uA5ie86kJsB&nvjB;9pR1Nx`31FpP}#`R^1wtKeT$@NotI?+OMp^FO8F zIR*c+f=?*;-zylIV*X!I@DT<7s)A9Onf_}EwiW#A3cg>#pHVP6kIesL3a%>n!wN>{ zfayQ3;JSi;Lcui!Kd#_+D)`?hn4HCq$kh0bY^_$YXX-eZRqUwNDz)qk?(_PoVik7e zt(p2;TdW~PR-QumsDrueh+WOebjFV9L=-&u zXmM6cBRmr4;{?XbgIFlzUN(hvIp?#*e8Dm`WtWORWi{b3H6~e9##|-MS+(h+4MxiL zC`YAo0ZJktuap+1?O=QqB8yfbq4n(qXf7&}EBIs;txC3L9kA$Lh}Gt;3Qjy%DX^NB zNN#3$B9_cls^tl5PH9X9a!J8>>wd!=G_!So6XrR)TC*xCt8&b$_#&_*&5JF~&Q_iD zE9rL8);Us`*@~sjTw!txdDp_cBC~};Dd$1K7RIxSV|MXA)IL-#dxw;gs7mF=UGXz0 z)wI1}RVGR`d-en>>4^odta+|HI6rFvNB@W&*u0-PHfv?(tt{S95cUofrmhg9j7yfP zb`6$?9)~^C(=%nUarN{dWWk;h3)Vtzp^UHD;Uy2NQYlpijc55dQ=gr+Dv@JZyO5nJ zSU`@(BFW4GXE0UE*6f@Yry*8XCX=8s?`6mrf=Fr)E## z$qc6KYDyVwM%lZsDP?z4%Fd>g{-%^>ggtwjQihsR2AWZJH&xE=rpnpfR5`nvDrZ+y z1 zIv5yenuLLYrfC=$Xr73sN*(BLp1%I(3G5#b3)#hqnabp>^ttfI*@A2nrb=*R3=iic z`Fur?!_9zPm?6herlwF(KcVb6lVY|!UAObdwt7OjY24smQO*|Yimo5QpdSaoF*-04j%O07$g!cGSWmKNq~~DIa8IgdPi(yBP&{ex?1>#oj|}W4Aca5Uk)C9% zCvxZ5;NbMw(7^QA;6TrjJI4kFdQ!lofJp(9h{a;~d$?yh6-yo3-SeZV^ug%C5ee=A zI6BrdnMy{Yv7Xp)WN*(@?C!li$*EXsZ%-^ToH#a!Hl%3}FNh@jDw4u2w0wkf*1bA= zhtqpg3=XWg5NETV94MaN8g;t-IO=mL9K655L2ZFUQ_Y1-RtU*~KG8D0HG4-By3V~M zdomr=L*w?@*E=(CZqLj>8oe?D>-NYP*`&=UT5wOz-VxMG(>)Sj56wg?twG_c3sg}( zGZPWOpvK-{HpAaC!>L378%Nub&5(kz}Hm%XE*x21bodgRlS z7doZ5|Gw1riq<*;*2h_ZdcRnK%7_M=zNrXo57#-Zv zzgx6MOO=|nxP5$R$81@waUjvQv3-1PcwO6Np)KJn!dHi`30)hyE_8ipYv{(d?odyN zR*BJ>5utWG&~)eP{{2deTxV!gA%<{YGD5ei=b!ZP(HzRw0KWJ8_-M{%LjWJG?NT~* zyfoL=Yw(5D^SF7;M4N{%Ewm*AI%f#pXU2RAKz2p`+;V{UGsh3$M^c`30pvtNmv7d&SaS+nm|kfBBGN?G9eSP4A}?>8k8mA7Ol0^t%qpkOJl-NOZV5jzG)=S)Bug*G`^ooe9g%Bg%#RU zY90wu9VE3i*EHceWHu4_rOEpNm#4W%0rHL4m@w4%=HR`~3{ZxA+jV>zP3Aj^eC>na z+korZxRmO@`jgj#e1l21V1wu{{mFY5`357e>;`q;L{qR|dB`^?dAQFo7`~Ip*P$hf zVSnjX;=V!qAo$)zzQM?=EgKx)hsd{U5b3r#2dAG8`39q3d->q_OcjGmw*&bGlaH86 zb-zi=a)0G<0QuTACJg)In~eK0gUN3f@(o76nb#*f==-4kF)R{MlSR zIJaQwp|2+%kfhgAM64UK0-bPfKI&l8^s|L&IfJjh4! z#7F69d|M>GHXR?5{Ct%XUpw+)*U#jUEKOd%#CHJsk~tp^x&3@gCB757baBY-=bI(* zy@q^NF3+gr8z=FZb_DWE`PTIN7&EW8Uo7%z`Ji}>?{^YkvW^djs(!v7N_G;M=d-gxM zU_IaSIzAjC`}O;g#P^zx4~NKpz9SOfo5*KHI^_e0zJ9*DCBDhGsN-?sBfrt?vPt4Q zjeJ(56CVzJ{d{XBzU20RA6%m2vq^ky$Y(`5$-|+qU!Fzcd%hjO!}$_)d{ZU9nJKpQ{JB)mt7)N|F@lWF`m-wu=sq;7D zo2BE+lK481Ps_(_9p55}?*#H`cAl%_n<4R?L%vvyqjWDDfR8#$jc@({e6c#dlmYn6 zI=<8a_|kNImI3&zIzGyGIQ~&PE$6pL$Co|;Uzv_?!2o<79pAzM_}X=RR94~m*Oz{s zI=;mN@OA0;d>X zb$mGk@OA0<>;v!}*74;Iz;{B&mp1@kkB%>Y06wpd@2Ua#&guBB9)J(_1pKdH0KQlq zU*Q0JW*y(E0r=8%e5(iGv+DSYbbK^c2*W?^DndR(xP}7r+Hn}A=euS zn{gA(Owe8HYBVp#JvnoW2X_ix=5%v%Ic@Hnm!!`%mo_xiE;qBUs+zA~RJm}mv+@Q| zVMj z+u$8DA54uj1uyEjhud$OwuZ7r>C;s)$&qkXOH(6`yN0z^Qj$YIrR{S!1}xc%hQ{G; zX8q|}+@97&BVlXGG$p=dBoYtG`9c3$Ve_O}bsNE~v-B+<9F>iv68OU;ch!h1VDWfx z+A{pjjpho>3Z#U^(@=}QuxqLv32j1A7VNi*GzkoL&lM1C*@!>Q!nvk1rJ~l2H$gUC z{|Sv;!ofJ6?4rg?m(dpdb=}s`*^!A4%7L?=nF&j%vqEb+A+!{U551*WD)htSU}uHO zr@1!Rb)QSMxN-FlU%PJ%vi<$y>w`T8)k$V6KA|&>r`FkA)zDZMBGYK%>8R9DClUOq zfL08_mt60xZ)j@9U#SJzDA+YOHB@YJ1-pJWH8(UmHwJ0$QSA)UumuHKf+~z>)8Q<~ zuPHd$%6@PPNUI0Ik=EGU5TvG(Bv~4p+k&STNz)cWvQ`(D=B#rRhE}?kS}~n*Sh&bh zxOBMFvy`r0U67S$%U?x5I1f(h>M_khDrPQBvsBR5^DdUFOCorSbf1}wmTHJr-v0IU zEtRfTcd(YmhpdL^r;d`+?4bIpRto4|x?6Gs4PI0}c({C!y1*eA2X(M)aaXzVXPwR< zjZ!{an_xIbFs66fS<&K;T8HKreaoaVU~Nm~5C;+c$PS$;_^ir8zb_7nS+pDtaSX1B z5erh&9zQk{Qso=!YC~DD7W!CDLwzW-KozpSsv(p~Y{V~jg;IWXg*%ku*{3u@nLwSh z9w!+?oTd+44`?AElvyD8mTL>rGlnG*OG(kf)P=*B)DX8|KD%g`=~%9oq^5^5Urm)k zYs~AM?w~bHjm<+{(ht~}WCgp=Wir(yf>k;s($Umhw{Su5C0g*cq!#+fS_ni3c{CF+ zgGE~`;BTdcKzAtx3%)a$wrt7bl(bNkK?vNXrP)2y#bU9ZIG9Agy9{yK-KXqO_=~D_ za1Fer))}o*3~Fn*~a zF-kysC=3$Rfj%olb?y)nQv|zzVft!9hyIpPpdk_kSGCj*aS6UZ$xT}vm98fD#^5#~ zevA0UTN<|1E@&I#y7gyff>K$yILN86_nU)S-7A^M&^Wjt8kg(bL7O3~E-A_P1Z@VZ z7vI!S)jZ_2J=t4S&AI4M8ed&Z428$2l0)a^79jykmAkQSi*u;2F!o&zVoK_ce@IN` zs-w|!&=$Lxn+ADo$Yjz=M9{{u0g1T3*HoKQQBL!PpxU>o#e=`7s&EExvc{AShz&^< z)rnXAGN?9b#-E`DsSMc)j5neAhZbg!Sh$GUQ?=nSifDJO|nZ1N*pD5wsZ$69N1BAD6hfa z7zX5Xr7^ePSXx(z%Ixfn=ev8PSL@9+uEBOy+7c5?!iaYGtC2NW(Uyh8l z1?lP84qL&sw(Cd@Zkxc~zh>Gj+bVtjnVmGQMS%wkb@yx5=9jE4cC1;&6Jy%)lEvc8 zw-qpnJSKltX-;wRnj*Bd5WOHv4@qgQD6|I`WR(=y*5)uav?_mXffUgaE6vVd?I_GC zDY50|lyE+K(HaMRbvb91P_TA8z6FrI1`9m!yy^k$Ic}fgoPr!%NlqZ&Y*XG}h_>Ra zMXVG9r7Gg=oDxRo3YHeH%GHbayY~8gOoBUaz+KRD0?L&X1oh zYjRdDScFcb`Vl$~GrAo=MeQg-6Oj!4yAbLgv)_tE`2jm~#ciu>1*>z#5-Ym4P%9xp z8cN6aD;$Nk(mc!n7EelDOKr2ed~37IQBjTWLt{*NquW*GsB}9w(i>K8`c+~|eFIKP z=(n&A{FzF#tB#+vKqUO}9Ui8F^=k;fl2sdi`r&O~-v##nB)0;}@Yl$FA9-(7jA5p5 zQ-mqfWHgyfQKo3qC}WIijImuY?o^DoD#qIs<1WRxTQTlYjC&PRhho~NnD#5C+ZEFt zis??pbeCefTM<9GNS|}E#oxS3xyvx@Y15~l{*!j-%iD~0)~=a&lNsN-%e33LCvtB@ zNBF+5{liuEl(u#y<4tCK^RB4frai{JksT5H!uN;WPMWAkvJGb)7;ZnDtQi4A`b?26 ze*3QQ-C=u%s~rBXr%#_&)2@*$d(vaL%l_Xb?<3*&BboRAq^*AH@jv~2===MT^tJ!% zeTzQ-R1U-4z7LeX*5~=dwe%5LeucyNPfK)|zGNk0MZ#ec4wrC*gd-(vl(0#{Q4)@p z@F)q#NO-h_$4GdrgkvQ>`2Edq{$Isr$+8Uc?2tAJzRG69cOTM=}m-8fqxQM1UwlM zgy*L~udaOJu-`Yj`>#_$)h|!%OdZT)#RdhASZXVVkjp%q* z0J1`KEsw9`VLcBU)HA@MJse{u%*2mpW3%U*c-YL-Y2mn)^Kao{8xObga2w~li9ffU z$K$u&ncn!#awZ?YHIAx-lF84&#>5%M51OLNpd@mPA1G!xiDUc_F~j&lamJ4y9A+3R zE5jKa&*m6EAk64!WJbpi1v5N{WBed6!^s@uhkqHK$1#53m*E*4&sQ#t%y~dLGA9InL)8 zKNQXAS8+U@WBdRu(>IOd0*>j!>;K{z273a z6N}M>PId}(t+Ult)PNhr@?-f8SxyfgPK;mU6i9eJ^_nJEW0A9|X_Koj3Z8FBFC^g6 z$9S-^E=~1d>;9j`Q?H3Q@Z)xOo2#b0}QS-CaxBe%7}qa#(>F{^?G>OqiPYqV=$T*8suSoCsHtT+!kP^%h6ir^PW|wz$1- zU+Cw=@O}@3{?Do0u9^LwiT$5bxm`2=wNttO-#KRbqCP#)&HHO+AnM}U8K4O@lt)W_ zxEL!mb^(&qK3+uV|1p0%C_JMzhk?jG_+%!b-PE2G+Rlq2dHZ=$JUas!n?5|EnYE*S zhJM;oiOx0Cx2K%Le<(8w->7R>IT@qm62z!}OAu*&m0&-8ZYU38*1d4??{Wz9(>TeZ z`5Db^=%Tq@47*eRp*a{`2P8f##?ky-yEMKwiLVqH`jY3A_{#d>yGr7tu|KU7XqT4m za)}S8ZET(<^U)bu`uy%ehQ9QpvzhgL_x8hgO5%H@AHE+-d`}=BtOQiu>UsJLvgt?1%3KiLa&~zDFg#R^;o;F62i@^5uAVD!5>dvNl8hnUrYC4 ziEo3BZ-S2RR*A1t$4C1rn!Iv}uU5x5NymrF<$`|AIzD=7LzA~i;@hs{qw~=;z8MnV zF65(fpn9G#0N;H&K3wYWSKdJ#A8r}+%lC|q54Q&T<$FcPXC8p>S317L0r=k4@g)tw z_o0rDY}TLs!b=18n>hgAcpcxY0r+O>_+}5lw@AlFW4ZqH%hvHF55QNdQ}#AI==Y>@ZG25!>z1-6O2>y= zWBtl|SI4(t0KN}(d@4nZ znSXi{jwjna$H*oDJzx$TkL;d#)cVmrXG|A6Y4Lbj+pFiN8#*$hPm+d3ljqsfnU-a3 z$y(Y=Gg#W}j6Jkp1DF zquTSL66ID^^P;y~@>JDs(@&oE+iap=F8Rlp(gkst!-Qz`lc=e(&HB?_^+lLd);2nM z+R1U;?^3&se%ayPi}jC9n(HqOK{D6>9PCnC|W6&;4ec<%(?IM0o3&m}~jwZ*7U zE%uEoTN-y`+ef;%{Dem{&%EtudnDnb8(I^t$i7jnBWdUG?9nhgm`mHH%%6HPV%FNW z`x3skCT@0VTV=u*6H?cdwjE5kY|XT|(zbUQnmKjunlXqfr>3r1gS?eDR3^;NF6GiZ zC{6Y9Xup@oKAUK!dJ~SRlzGhdSgc_wXM9=esiFta^FLh*$7gk0KYGtLhu1JTJ{$3A z+YF9pV%=@u5!+3*%6FS#zPZ<6o}M37z0;QhQ<2u`n-7NM_}<+8JIK43+Az0!e}lbE_qaMd?K|ITtd<~d*+20VAAGf*iXEtug}y@ z#6Al%#MvBbvBsBSixu1JttOesk>)LnNDMz8#k9-3FhLo#YLaQB1#O6i%)F<;JYS_&wyyRrwCsPx;K9%yyi+x!c@!Vp@j} zpsVfoZRkzrZ{YpRsVmCZ^Lw@DjrI=v1p74hd?xlOCjNXWK5w0t<~f)E=6(3&eEuBq zL~)*MKaYX)eDEHa&%S3w3z5a5nO*J&b34_8!@dJ(p$K;OfZu8l!DO@=wGgZi#iCu~0S;}w(>D!HoryH4R;hi#_{3cM>W@D4sCbOOh9qH1 z?K=(~g&F32tKIkj(Ymyj>~6UFsFHV`Ryc{k<(@(&A@2qvE2U5{7I8R z{zSZrUx&oDylHT@XY)&c$u*?+=@(&~x3XL2)%@cOrt==9!~OdJ^YA$STy3}Js~PR) ztBcZk7_fVwHcxehVzGk zs7?8%vd!377t?ldI25veWMF<(O3G2bQTW4_6;$9xl+ zlw-bWv1Q271aotoMLo0AriM2IqW9Rd4 z&SO>t^BneE2h76oQQsXf1H+xZyC9L_`+<7xN3rftW#I#GDGMJ0>JK2%>braT&i0*~ z!8`%uO|6PK9>dpK!_4C_>}U;VeRf`}!OZ&CEnpsn@p)Se<|v|XQOri--{N`k2H*IP zc}43Z(6`{*sZXqi&Ms_G!l4UWlt^q*fVC(Q_R-x2^LExw~MPw zO5A>o6y4ZL-qLdcy=G|op&T6aU8pkVew#c);`XKL5V`P`e>r?J-gVxy8x;W*8dPN#=+ZK-_^FIQW1eS1ew2l#(4 z@MnJ}|8E5TUH$N5yV6Jhp|;5V_aHbD#T?Xc)<&Y)FR&5L4ztv=oa~PFxBf6=`XKuh z>b)-Y{;HdLl1aVesFZFFqj{(qy!b25N2+b%R3B6+M4<91gh^1hGCSWW}Sl&GyC*>DO+ zF1a*vp;YlgWU$kypQCS${P4!S+ z!!Z$F`aDpds_AslG{L#oC#QQN-z6VWqjjt9xnu5?M(jzT8SR z?L0Q>>+)TN;}cAKubj4GC+of3N>(zoYF1L~0LjVTLUIgSXzcj%7UH@M+ctF^WUy20 z310`c^x7CP_E~BV1J+ZuBpY?2tqjQ#y})K0WW#XutO#yJ@+C#J5|*1PpXwpysLOZ1 zm2~Oy9f&1uyL=CrNs}($LuneXTFyKD<*d&3;J6`$%J$cr13qS$Z+JUwe)uWtM{jJ_ z`&dpZ<#ZR>pbsCTv4B=a6NMa7KVYh$8l&bgyjMvagNSmduwH8N>|(pzI6jjeKVdSE20_|r6)clmH_nzgiV*|e4x zj)OUawalW=f9jw8WypB(cDn8P}0RM6$~6xmpc)#xwR^wOxHeaGpehC~_@ zwELQ372T-dYCDbol5u=&jbZK4jCuA2`MDR;iU?V-Y+kEc>!mp&)h9E0AI%X-N?0Pb zpX%5m+I;`V=g#dqqDh1MG+ERAvJ#lAG#qGgcQ{h%)r|4f~a@0^9 zx7$D2h;gEwS})4UVV?)OGQ)dp7Zw?`o&igM=|S!2VnY)588|)-V>^A-5RUDg?ZOhn zrJOSL1tpQnU$q6zcsqTKv5;hD+L31;_HBbZPrn4@*N1&=X;hyN`&!NF%&9q6<&5@H zEv07-{8=>~%>TTo{7uiQUX_AnJf&BgL#rz#7Vt+3@_?SEkG4l@hAWGVd$t06hFca{(r(Vi&abZpm@*zS&(+Pk+J8o^9u zt{Zo>(kL*1^IEObsND<1yoNP8Mu^FCt|+6{ET9MV1={%KTR49Ci1%CS_`pBIIWqz0 zmj$>2@@bk8XP6Oej5nE$@h-vfU<99G-tmG-m|?~|J>>w^$3Xpr8I$r&55yfHpY@iV zIx{Ku^)q2lzJ4YmcKm_M?2u%$zkUYXN@s?;5{12fESqUMilZM@TLP2!)A!(b**5D( zmBkUv_u;rvm_LfX8i8xd37BWqv&e?8)l=%2mvrjmUaF$rm1+XThTA{sHg_D#oYLcM zGbG3Kn)m;H-(&kwr$nW5#=dtt9_=u95MPwHY+oY9$NqQ6V;zsSsj;fBsh&n-4jj9( ze5kGG>JK+<4&(lAFqbvTZG1egmrdjAT7i{#^v53R!2;#lk>F-hGrFlI50quXF|8y| zVoCmul_co^GZVa2g94m@IULtZH7F2g-DXHO_J|Taeu=;JOVq}uWCg7CZ(1+prfX~e zREK1VqQ7Z%LtjSJzOc1IudI=hZ0r>^iuG%B+OHAy(WC57c0blVeV*Yrv3BrIH(RH@ zd<1)WZ(hRW4OA=F;dFD|219m!!abQE;>sU+x&dc%+L%Gz2N~rRwI!QCk71T(*FV20 z?}1FR9}vpe`cYGQ1TSN1HQH-zo4OJ@a;culdG=x1(4K>vONg}ZoNwyE@j@!~fUk~I zxE!A}79gFeT*ug{{i44?Hqg}pj?X*UX{cq>wJX-4{eJ{s-p}F=Sxby6XbCbM=q-*SX%>Qu>*i2rC zb4&9%&$I0xwlCfJxG%c>aUalpfY)kux5SL|mKzcSPv1aRnIZGOxe5*dw`2&JtfPk_RFg7Th_T}jrNFddVWeZpc7XMCVOafco^>> zZkwJaLP zi6e07;Y`zSRLiMPQ5<;F>>2GedNZ2Xt|1>4X!=pV-RZj@^`n0KFy4`V>TKlz9PrS( zKdop&+?yVC6#f8A-mLc94-oHWHHQzufz4_U`w;PNHtBLmeQ6}FziOjVk}k{+?YNK0 zMt#pGYON8CP@{XP(>@(E+?PaU06WAK~sWb7s zhlA8xdJDQ|wR@|r2_4<)euHP4w``O*@`?CwXstc~@0)~}y##x)Qr7q{7C{3BVaLoe^Rj+avwYCJw^R=#qG%5t2ai*^uThr-uY zp;OghKFc4D;{1G6GEjpxtJ`p>3s?1z`HJ9MxL)|MuNdz1DZpCpnjRmVNXHaUor#;_ z&5iO#p&aaKFYL-R@}8FLW~7nf*uWZ653bMZ>jAY-Xu&L6pYE{V!*hUr;B1=V)1EP{ zgS?eEkGF4^F)JuIB4q6b&L+n7mfhTT)N}|s*(kCm>`B8D#&7iaVo!7>cyo>Rhka%+ zw;C*?d#TlEznPw;c7r@344*X}9Xs3Xr92Z&jft2&iS>fS6NfzQOg{Nzd!O>*XvFL^ zJ6o5&P0Szpizk=K;Ud{c4m zA3YCaGkU2U54}MD-pX3DTXRx>aRqyZ#-qtNOIVKRuDg z?Xla}6`OYTrPWXS9!bN|Nc!t%6lMNZan(nBPsGk+;UU~9GCe`*XWDTu=+IxGC?X>^xt`Sci6Y8>_;pt@|e6YzVici zpI7z@3$OCLj3Lc)73{lV)^UceL+elMeUaU-fR3ZM>m4=5`#k5wH79&iBhvc}Vr#9b zTfx>XY*u9AVZ^FUzQs6GW1qyZI1O-idgtjdMQagN3*1xwHNOQOW&HC&wZJ2OIidv) za0^&3JXC%^x4@cr?&Z%$Bq#Jfbkvx5m;Y&l-+uGGSH83Ioy*@@_Ri9G4*Wj<_p?|T zJXyZWufa}1gB^Yuq6S<18a!9t!ZjHGP9uNTn4H^t-wX8&tw0No>y1j>A3v%MqtmtL(+P?8(5baNTs3Rw3-4!bMBvPCQ5y(;HQ7P|;0zpxVT zG%3@);cV?eJDQwC^f~*3r1E8#-bk7^Q*Drv3A8_EsJBJ zTFb6SyNp2&N-H{f3EFU!pPzbVRkI1b+6vqXptU@x*;!52TH(beLFiWq-^ZS#GMV3d z54$gfyLma>$)0|RJw4UCpHVe0-h+r+%aMM(Z}G3(lLXG`I?nlCdJBSN#^XC9qY@|kIjKMI z^i@Lq)zC>j-i_vQtmoShI~Kz)uy-OTU9uhR5UAz42ldTMRBadG4flq56|cdojsUgZ zoji-?R2^*0x9aJyVgEBaV>0WV`O4>ouWpXz;}tL)I+f0_&hXCP<4zaEnzzvi>R0#| z+4(EnA2W7BQaambk7VyisA-uF%kzEpJs)~^;eg%rFs)|p$_(oztKpo^N^>Wgh0$IJ z9H*M8t;T;TF_CLBEf2m(H73ix9N)6*@r^%WwtI6^y<{_bRzdH@aU*+{-dOocVjO>x z#^jy8ChQ-%zafU2betKQab~D^)!4{B<j6prIMi%>qqL$!?RRT$Q*a9xWYJ|9kn&zy`k z#(N~XHk#FyzS{GtUe#-~HZ{ba2jnAqMikX#?o3jOR| z&W3{u8kL@{FN(8}rD1TAnXXf-$OQpt-?xi&zinn%yncivG zNn;T+rJU}a!f1s+JDoI&icX|-dfta;v{eLs zJ*9N^A8u#sdsa5nz;)P^%%19Presr36wX&;lEZo?;QEBZ+BvN8*iTQft8ZYYuok?% z2HY7>D_=_JHdlvrmQ{y$M&XQ@bZ)PScrxq>h0TZ$;fy#EXT&ohxz&(r>czXXh$oKu zOtI>FSP@>5yv(k)=xW;%O>GNX`Jg%1ZtV5;;q2TvXZ5*QlQxgWPt(n&@!biwH%(;& zxW7HMm(r)WF!nxY_$}DG%^Zz!)>~dbV`#(G{O~Bo0iCp}^U}==aaCWnT9`M2zxT@8 zHr9t=`nmggukmI7>JF`4!SVUnew=KqdQ@HWAE2lP>@m^$3>uB8TDr+s< z7L$BE_9l_ZQ9Y*Q7PN6=?~UGgX63*4?m#Qw`Ly+dA$E6WO3$-@-FeHr9xyA+qD4$< zz@oIqaI5{h=M7^g;SA1TD%%!`BYC60Hidh~`|s&3Ok2L~LI-<4sH+@~KaaEfiM{kp zRBvGYg?gZJcPF;@VYmWC8l&CJ2A<0<3>{xr4b?8Hv0dd_n&bPS%UY=86w-f8FZq9aO?!1-H!*f( z)=$Z|=>7V8?B713ts83I?SHGpUbfActn`e>J~75?@|Qv^<~p!yIKex?PoZ_o0L7%X zs26_LsO?3OpK2=_a@+F>uF;OcHClWJ^-RqAJk~CRqXx0bsXAZz?a^xXs|%xj98 zJ7H~WXcPf#6k+JR+^&uyzzjHwP4!m(;p&mAm|-aS+2r%jM{bT7t1jSa`%894S?yU)ERIs6`6fgch9KNdz;=HV=nSTb-YWS zYOXPNYhGq9k4+ido5%E7*KKDZwGA{oB@HvH$sVm*|9G5MLDV)daX+n%w%4d_U{p#R z+oysWPxm4&B@cfMK`kN8PXn@wm@H#TM6bS`{4_CxwawJB0_7|Zyz{(tPukEJCLqDW zB#f6N07{_LXod$>S34E1ShM*>gBsym#>LG?xDAfF6ysIA8*7wr{Ntuc7;T{8Yh z<9VtF?Y>1;_I4QiH3hZ%?A@mdZKRHGJN3jMAC1SO&<_;-FF5=wAraW}g&`Loec}F< zT1x@48tOa^_4qx%16~pRlZ;Z${$rQ56`svA)He(lCVMqu4oX z8=CPTs-_JWoxHUHb>A?!1E%Qre5j9l($&g;4}~gGp$bpS$}BvL($$tyxG1&CgHcXT zMbk=meY2}^OGD!(bINKwlx}siyADs)Oz||j-1QZ;EtRg&=Ao|KRq3c;$0DXyqWLfWP@pv&c>j#&+rF3U#r#738= zfo`f>$}N2!gqXrISV_mPJ8Lx|mWsM2caTKk$;`o$#Lm+Vk}y{*W;v*`EUwKhu9hJl z`^rnvQsr_sx8Tup!6{BnnnizTWe7!EYPYyODXjWdIV*x}5+M^(N(>HP#?;hZ&D1&s zq1N?TOnv1r1(UQm8!JXET}$A6(~-)$P6gd9o!0vAr;(=MMVtBR*vjzE$l;i{IV zMjU$$YptXtEl$r6&!?ArfX{61Sh5ujLp?P8Ur*QK_OuRnrSoT+5??YB139{+>PiW*4Ru>FHm(dpd9RJo3i?<9*CM==O z3a#se&{8Bm^p;|&w1gllG%RVZ4R+nEhx)7O06K}yDEYwK^e=49AL+~ZnJL?;onw=H6<{8w{1a{3$4HcVQ!ES1rnj0FO z8-ujOQ|%1WumuHKf+~z>)8Q;{YHoD0)&1ZUkX8?ZBdxJHSS!FJ$WIic43QI0_dz3YQLddY01Fs|&L7Z27Akw8a#ZD&6dC#G^EV)FX0X znx#rggR7)YuI@H?i*y&OFD0YF5UsrZ>*-r6U9Ik5EsYOZ4be{>C8gOx^;NAD(7klG ziq$Gz_u$+E5lO>0j4SAIdCH zg{-f_Hz$TNARoAhH#(b#I4~bres#qVcO?cEU%Q~f8PY0H=d8y`#t^6J1LuJj0zz5D zB;RsvL3+lpBw{HkT9~?U_>vmp7R+ZC4Kp3f)socoQ0A+tGH9M$=X3|HVQOq1>XLrI z#w07)eJ+!!CK0UCA(1%fs9U%o_!2GnT2c$0dq=ElT}!fU*aH1NY`W(W-n$U z@=9`Wi_cbEx~9lcnqQbh=`T)8OGDOc3v8<#Ijd}$1v$6{n4OjB$jZwva?rZvx^-NX zgZ&4Q`vj-oIwrEZZu5 z{+XRLu0??d3w8Hv*5;S2E_SS0#S>%N@{+~k%(oRVi99BMRcTIf@tPvEwGh1^OAkqD ztthky7i5(b*w*GSHnb{#ZGjZg5-ZKlU+pN&DJik#=9F+gd(j$4QE^U5&MKi`?RI<% zAbSlKc;I=}1K4xiKE*i&Iku9VK)%_gyuT1_#aWA3DF#Ya#MwC|jLsD-EnbzY7tg(9 z;j;Dlm;`s;fV-gQ1e7Z&$jQOt4XAR_HZ79Ko7UP2*5s^Qun3(<^&@l~W^}s^t6B+~ zh-B#Bg;4jH{Z=f>57?P2Zd+w5Se+}DSkbkGS_ui#P&&R};V86~=3xe~cv9+GYMb5V zTbo^uifVix8e_^E-L5J}rQ5lY-mr4huM$)08*ozMan)Bk@Ru>ot~y7x%US7S?D*rm z=0-QxuOa+SR&DqU+dNprJ{}>6Nz6o!{0$G;{YaO$bY1a-v?0Rv>z=~hzGVZ zK3!a2e1<{th4;ZX9J=V#|NrML9jvRnSef<}hdgEY_bFas?C0c{fwFx}+-NX@(O^`J zVWx0XgelTwG?`3MrfAbBV~lBxv0X9lRE)PO#@iI*F2%T8G44@}dlgfMV%n#e_A92_ z71JGx=}yITmtwjbKd%v^(A4z)jx z_oog}#M2*%v@==SH}4v*wDoqM&+|Q;cGst$HUjDE%ROV5ZJ&VYY1eajlNrBlSLE)9 zJ>h%9I!2=WlTe3|tam1s{_y$!OwITh{uuu<PGn_hYK2S0r6M?e0_ z@aU)SZ?XFw_BMGUrfG{GKHt!{3uVKcw%#v&n097->#nHXrai{JksT5H!uN;WPOZc6 zl!3mDTE}!5{x%Ay4gPB;W;`>#@#1=_+!f!7TxIwd>al{}CX}WvzHL{;?(jWfdq<{R zc439gL>-2^@6fkd8wPB%>XpYwpv{_$WuslOcr)C6o8C`$VfrJ{zw7IcI>y*?aa&@G zuUFQ_Zz)3^LtS_D?JD`taJK1sTja5JqHqb(e8>W7SdZxmTN)O>6?H4azfg}K%$SCDmE(CyOG8cPg|9{Tcmk&S6C(t}2KZw=R&Mn89@vgpHKnzy323`ZI1 zZL^>0(&yN>QLzrs*jHbd7ok2n-yIfv=+n;_;q*r$|9am%$oxTA%do|Jl*0IJ!_$7~ z%VH#K@qa!2kr>11ZJs&;^=~BdJQ8W@>v=t^=dBm77h-%F{)Kv+pr41%#`J9QH;w38 zVf6^U$#D05`f{Mx7HqiJHr#8rdK=`8fDO!;rgpuEH#BAy#_||fhJV9ZC)P7P zgnoEfbkMgEKVv#vJg-s8co6oZz7plBR zqaJ1WH=On!D9vEnTVKc2vFz~GG5y$O7c1-GA3y4Ks2U+1^y7v~)Pd$yVY`R#9TYRB zsa?>$8>D$9q%ohJ@d-(asJNmZhE|&Jlt}%_&oL+B-wag!ezh5w8y4v-5$05P2 zn|fQcqCz7vzt^`9YMmI~y=%P<{vG=0I4p9J)^HMKGqK7eho<@c+i5@QD2nk0@*eGF>grg)JE#XlTj*;+a36Ej= zlh3Nx7>PcX(WyMuYpg_%W%Oc=46zb@oP^^TKdmjQSDZwTm+*KAPmu6L2~T43FVV!q zB#Ay*!c!PO?eVDB6p4O`M88C$Un=1Q2~U;qGzm{<@&o=gU80*Ao%TJ|%Pi3o8Qr9j zAyJ|yNqB~YXG(aMgl9{5j)aq0`t-hsdL>Krxe}fy;mg?bG)7ae%Ov`IMyK(Udd-*U zDU43Mo-enkT21%V)P~dj*E4#xpMJeW-@xeW{qzkI{RT!~ z=cnJm=mB{uoxaziUMgKf05?kV98BKN{0t6>UM69ugv%vd!Q|0z+10B;qE|BdWQ`1! zj2>vORC;W<#-P$?>M)Hb>34tXrP4J7;9~Lv{h3Qjzlzac^gmD~(Kj+WeLF(EHcIqr z3A-8pM2#KX61|4eclqfx5`B~O{3eNBE8#i`*GsrT!X8P!N1|_*aHGWEDAAiF+|2j` z^}Si5w@CCBiQdZS0sFK{^ev3u61|+ZjDWBg1xyzJt*N_SqrPZ)WtH{me zOb7oJ2GQ_q0gr;C0*-;N3V1Z!CEzj8AmFjEPQbB{E8uaED&RPnB;a_66!3UB9~iu& z{U*R$0-gxp74RhZx_~Fc-2$EhtpdITZV>RLuuQ-SkSO4(5Fy}c@IO=i=0yFb!_Ne4 zhGPOwghvFN1h)uy1~>&g6P5^g7EBZ{_T&Pd0~d6QQDOL@)^`Lv7kUId4_*}TW$-lt z&xbDvI0d!}I2G0k*aC|LoCY%loDN|EUI1q=)!T0&^a^+pyeQzsa6rII;1&Tdg(?AO zK(T0!j%GE1t|hv4buc% z1irvv3GI0e{9M4r@O1%~z#RfEh0Ow915N?2g=GT17Ul|g9gGt2b@0I?y*<~%PXv5D zd`rL^;64H00NVt7BWw_`0~QIm3`Pss38w>tEwo2D{6xSN@GSvX!kq$kL7jlBph&eIh9d&L z1v&-X4s8P72`&NO3Z(+R4RQs%3(^F<8>R|)53~jrk5JL`pE^0d1Cas8BdZb9eI>^$ z5TC<)E5~Vw({SvP&G9V6&4@ENjzRoQ#3qjahMypRMu*=;Oyf&38>M#=F0{$l4F5qv$W&z&`YX$smxLm+bfmy(ZAwt02@W)t6S-lK!1b!~yr{Ng^ zKLcMD@Uw8UfS-d30e=Vb1$-Bz3ix@57w}Q=jn%Xvdwds83HSwgS->yC*9CkG?hx?z zV6%Xa!&(8KfXfB^5+n-vZip1{%W!s#Ucc`{kAPo+X9fH!JRsm7z%2s)Ayf+ZHOLq6 zk04dRKZbY#{{;R%TCYzh{8qp}h3^aabvPv8pTV61{y8)XxCgEka4)P7@Gl@yz`uk@ z0sjil#_09?HS`Mj9(Yc`Z@_~B{x4`3@SETg@LO<|fPVuP0ly971$+|zK1#38Dfq2` ze+%Ci@bBOo0=^gS60jGV1pIqgC*XHrrGWn%k_7xN7zO-4@P4#jzdt~)fZv1X1biAE z6!00?Dc~UR}1(oqzU+am>}Q};2%+Xef|W$6Y!tm6#<`vZwUB2+$G=(&?Ml$ zz;yz?53UgKhcH9He+83(KY|aa;pLYB{szAgun)c?;J?E|0{#c=6!6DTCE!osY61T* zqzm|qFj2t&gpZAyHq?H73SI$&;Z*?}3{MDHG2AWSFhjF|!wuI7IKps+fFlhv1Z*@! z3HW~alYecE^fMWLDc~r>^8$`GJS^Z*hFb+3W7sI*(S`y6k1?bRc&uTffMX4xMCk4H zC3r``2jDdUe;J+<@a^zL0Y3mY3HU*93iu(&74XB5BH%|LUcg_0zf(ueF9USJ?*#lP zyeit>G(B0Z(yEYwik;g74U*eQ7IK(kdgAj+q zogCLP903g+w=x_F*KoX+VIwT!xQbzXpNC_r4{=Hq{FS#icQG6d|HbhthDX5*9INTa zz}Eyk8ag?Cp7D=?&BF6zVLivij2;X59MiBd4$qTH^M<6sKM%NdRblfXY7{(|eD zRDSC76X0!*$=-3wM0k;7G%Mms@C}Y>*)L9+4EJyx&F~ax6YwSA;5eDlFNMoFwlbUm zGdL!Hj8mq9kz+OeY49GdhmwA2j6NNDIDUg+GaTob+P63*5xO|GGMofEInHKy22^lN z?OB{M6EZkf?K2A|bFAt+8&D;dKD8Hd${hF*Gfw)@J2G)fGQ7*NYQMSg3y#(2=fU?l zzKT768GN1NOor#f7db9xI0bIv7|nq4Q(>KeEwDtuX)uf9-!T4kh~QZDw*~M4u7{Go zs=qCSUvjM4cM*J#V^#mf@BqiVn7k#hljB;3mqInis=N#+<=D*V%is!*$1uDcrgNOf z@a6C+Iuhxl+Ghp)iDNbWmGBnFS1|r7;AxK4`gSEez;PL)TcMrfN``H41IP5vMx2rf z%Q;r-Qx<$zH{OWDHs+9oACT~V2{%c2orG6Pc$S1mN%$|QgLaWVzn1V}2_KMfyM!Bb zcpTnW=rGB@R>F1(uaxit3D1%6WC=$~_-|C${G#;#N5Vgr@N*J=T*6bZ7N`k5NQkTCVj z+C_Ml1~4Q{?TmI2rg4XM5!PiFk`QC}57E&IBvCj@VePWA#X!dxLi7;@7Esuwu>K_a zp9UcP2(RbiavoB9Nbyw9_59Q>ML(qgR$C@-9uLbXv?{oxjp3aNJjU_2DeO?-6%0ua zGvQ|xmT%&>5=MFvhI%^nC(&0bY+W>ZkD|^u@OkQolzSDx;Uz?WL1FC_(xZ!3V!GNYS_->BM$_^I8akop(0E7@NkGJ9b>$tAv2 zqGKgvc2g8!cEo(#Nbyf|`|MY6r4}*j{RoARa=nr7dxW1*;7trk-bo4L!e*kgcZ3bAow_CWcRKJkARW_qB$R^%tW$Umd8+^Ih#|81lY%e|9A zEcfs7_}3_W1nq?(rNhd1fx^ZCBqxdJ7_xj|m`C_w1vYSgDld92hKJLLj(n^>V*T31 z<25 zkUhVEx96xAtN&>K`9%L3mvgHEHH2}%;h_-QyEY6-57v%i`LO3OzwEiMa=W8`MVv2_ zp3`CW9Afe#vXjQgp2zqM{+x-zdwKoDc%oCfW9T_dSF^K~$H!3ox`6*LAdL3R<8+n} z%;z%{kM@6&LM%@&g;<{NQ;7QbFzhRT*3XDf=5(glv%LJDQ-Gd}M$F0uL$V{uujXMi z(J?=%6k__!KheLn`pWF9wQE>DD~J!vnUyP+b0=Zse}uwEFYXU|C?5G(`-|m2pZhEA zB~rhj*>g7WVfrUAB>h3J+s&98b@u@z6>kj&}+uyj_8tIlhlVw9jJ{ zBL5QdW^?ELtzJwM>zf?4?p7Z zCR`sTelriRpb+J4pb+!t;kcPXKs$2$Z3^)@TF)l_pK|&Ijz8i!AyTDhQ;6-)1`6>x zwmygX*p8U;!P@PpK)qvrK7;!y`co^FGlm@$Vj(d<#gOVB*@M*=^e@f-%ZLyCoazbr z?O~2ja7_M5bXH%HPVW>FrgsU6-%cUwS&bpdXY~u6fcZJbPp0QF-_)K^xmqd2a$3*h zD=EbC*iIqpy$eHJKb=a{u$ zNZ&>n^TG7YbIGyFs$muvK z-9vN?@8jV?&R0$N%Y2;jfNC$2A4~E0{A>zQ&lMD6I; z`On~b*(t>KwV2~Fjy)7&{@O7ld8{5_Ix{IA^=1Br{R@-RrMBnPf3kXj^iJZ#{2ibW z`3_QueBYxG^}K|KX&91xR*%r$?G%sprt+qEt^d&YS$X2~j1S9|l^fdU+w|Py3VcK% z`pqX4MqoQcc0;|$ZiH$5i|m`MsNoU{(XKcoV(HySp@G+Xfmtpx*IFI*7b5*}lW@CM#_*rT{qgYTM!l_s;6k=w}D4c`!ioz7$e#}?>Ofh47 zMDd9Vd*?<$qqGsmMV0LoF2j6Ln1SsDg-ca`RK{aD5nhb;qc9!IgTgc{cM9Xw{!PJ7 ztBddo^aBbLuwSKcs>0ssQO05YAsmb27YZk1KSSZAI6tOv3?Db2<@1wGe0=c{$5>gY zzA86yT*L7mj+bzJ5625Qeu(3Aj=#?FLXMAcyp-c(9G?L-J#?yCN*4=_rTxkzZ{!#&3!`7n@otU_IL1XlMt5=C!7(;kOx`|@ogDAyxSHeJIj-dR4vs50 zzLVoCIlhZyYz&zEyE)##aVN*ub9^tyD>?oG$N3!J$MHsvzsPYe$MsCz_$wS|ag2=+vo{W+SpFa7csa+9ah$>N zS2>=+@j;Hqa{M)p$8-ER$CEfd#PLLqzrpbYj-TK-g5xJSPUQHT9RHK&|63eKa{9M9 zHgfzF$1^!T%(02%ZjPsM{4~b~j-TNeIDVGnB#xiscq+%=;dnO3&vTs2@llTd%Ju&) z$N$Um3mjj{`CsJtADsR@j{nB-agP7a@d=Kx(`V)R636E`ewkzJd>Q@w9RG>qS2%v3 z<5xNUfa4!P$74A5a_r;$zvp-sr@zDTB^>`Z$8$J-m*aUH{}0FGIQ|32 zQ#gK)V>1piQfP83iGi8~>?mXmw>Z)YrQzn%xccJi6LhUs>xa zsdcuxik$97cm2lv`bvRT>}qPLZFSiyD;r%+P5G6s`et|Y)~xy}iOX4;RqbqaRy4aB z-A&Ezip;HRTHKWv^VwROt4T(Mlhi16*SQ*6ngv-!&ZeeKuC1~nJUXXU=4NW!-SzIK zYFDL9E_61bM*ZZipm~#=N`Y&Q2d&90Ra(~|C|2O=OWgvMw~vhEH(n&3*^g`~r<+&d zE^rlBUR&*Mb`_ujOWfOBXuMUfje-iCt)#`{DQQMEoBHR;sxEYT`X{UIkyTyVR@AV? z)rgEm4Vts4UcuA4n6Xc#vfWMSisW5#5imL2^RgQ1JhlBYXr}L+himU7ZYl1yF*foeOGkRg#kMiP`-+Q}ptn5lUgk^qS!21Jdt z+O)MTT5WObcBy^YM5QaOme}f+c5OG)m*3i|yJOd_xVSC4)MmH-^!GgHo-^~@leyRV zF9Cl4&;Ngw+U40L*+q5JxR+fkDbnoYOf^y>q0YF%)5 zxFfhpw)b$URyl<5L?S^@(bJ*z2$HDp4DVJmU)Mj~CF5DptUv7%nL|-IO2gMT`WpgW zyMmxWv~F-JT?LuKg4_`t*wo(F%q^1$+87v25-OYudM!_9cUbmmpaCOzkhib58}btz zOsLYuHSqq=AQIcDh}zy41GOCNlP=rS(}*1@wn=eGXSfd*x!LzJ)64 z2n9QChJLYEf!pggHr4xg#rq?z=hob1bALqYG{u5D^_ao%(4i^evGqM2eM1p4NXW?G zz!s=lELE^mWHr#<72Md{Da)K7rT;6b2M0Fyc1@?TDFplaG_|_+kkGiP7up=}Ug@=0k*1QkctdaqIw;v)B*Ghe>jIHLd$QzUyksEw7 zF+_+$C8G3~g!`Ldyz5c&81B1ynuEgtuhd@{CnMNMr?Jolh;gkcxI5T|y#Vz3`jmm; z^B&<;Fd1pY2E99Aj6*E+#r@^gh6*K7QS$-FI+(E;A=8@(AnuBlZHF35^6h1Kbt5N_Jf}c4#0d)b$T_^955UcZm*| z2lDA(ps(A%dwb9yf@xQrlu3-Ow!vP-L6>ev+ z4bamO8Nzc{u!nWDw>EC9-|W}AoVXa+4ucp-%`JYIQT6s!kk9b3q2A;3ck`}Bt51EH zl(2V&&+9#{t^U5CoL1nvXnLqNlhMpNExL}ch7uPg-zJdp9lEs>cDy1F2|GcEx6#|| z5BER^Fd(Jv!GVs@jp2b1UxDaCrJ&8dL8@)_Z)t68YVmh;N5tR*fgAl$yU=Tbi-CJ~ zbq6BM?+*lFZs_k0c7xrk6j>*B^;NN!jXr-r?!J%-G=>?>=P)WUE5c^04-q2Y-2h7@ z02#u8t^qzi;iY2I#6RL(iGQF|Bn*(FBYu{H+eXh;zo)Lr-_*EiLyNzuo;6j}dHj$j zIx}w~T5A#E!JP)-nwuz**tlwO653GL2)g}s-Qe*9II2Tm5rNICARoe~#fnvcE*z={ z>fAU+(Nq^-ZD}hfk_FLBVbUjxhUq}o(1mbF@$~SKg_P|QxiZu4YN@FLiH1@(ulR7cUMy0VoRTwtY$_itDsxbDa z3S)mV&PBOlTdgcN_NQ{=cIPtoU6*lnxeRkyvBuC&6>ALbRI$d;P8Dkm?POdf6*Y!- zs;DuvQ$>xTohnuv+Nol-p`9vL8{4Vc*iO~PcB(eEQ?;?3jP?wEm#fm)PL;-XGQOz7*iIG3cB(M8Q@OF7%8l(*Zfqx)v7KDTc5)dP z*=1}e!?wF+i8`tomLs!X_c{^s*LSaWo)M^V>?wD+sU}ZmBx0eG`Y&yP8G&>sxY=w zg|VH=jqOx!Y^QQ#JCz&T$+%c9V>=no$IEd(4i9GFy~-W18HQUwaO+*JkhLIfJ0%|2 zRnZZMXe&v+@Qp|GcgH`5I>PbKs6^XzAwdzb$y5hBqJ4obNL+^a;Bk#e2(|*dSnaNG z7r!yBZEZOmtqmLfjV+$tRgQXx&#}(2!BOjIajdT2=(xe_3s*Yox3;b;uSTH-{%rI( zeDw~`+NO$%ElpMBTbe4$9b4Bnm6tnOAfyFCS|FsczP=v*-ssrUQr~hzwPRmP>xQ}w z>ojpShz(7S<`$o)uHI2!>#1>UuD`y<;oDr_Qsb!i)Hd#}fSonI$wD7-`5*4-PJ1Rs zZZoRS!^m)LcT?_^(q~~3MDh(Tx?Q?CnEV+SsY5*If;ZxoAbfBl5j5?&7a29}nHL!$ zo_C3h%CjzsaQU1|A_O-~)KKw!i-dH~w#Y!S9iGCDxr!v&$ksjfLU*&1ZMrA9{$g*s zi)_mM_#`>hcDU51auj1uho)&tY)Mg{;pvO5ujIEJFjCtQGm4+~1dc9qaFzb)8(plH z@x+riGBSRjf#3PQa5p2g{#QP#KpWh8=tYy;5M$6v)9k||bo z^nmg{4CYA_b=9je`bB~SGvjZHk!lO!5%JSEEp zf0Bptu>#TdShw7vca~S1M_e2l9Sh|MZ?Gs(-v~Y1FmFh_H1P_VE z#}B68EvHZQ#9?{QG9ECk3r+qcPn?%GIuilfKp>vrNdzZ-dM6%DpWI0V(x-M3q0^t( zp>c8dO!bKX-NodA0r{v;l6b81=}#L_ub3Vi?=X23KHftW>tl6M?fU@W`(=I69eQfYq(tRtL|TZrc$afSc-(Ui=W+)xK?4dspvZNpEMkr({n> zNoOBCy3yBP($U+qoj)NM4s>nn@7>kc5!}|%?hkgi``ZWbMt#T4@!)QZ>FDkXmUb}D zCiqGvzwys3>)>NuMJep(rPsmJ;=#d^ja8-FBP=5>!Hcl7HqNqUXXaVv!}n1yu@qP? zwJf$=W+}8R$t<=wEcjk=xZTMt_<~;eqDqR#)$o38gzbB356$0Vc%Q_5Nw`Uc!}s5zqsT+1 zi|-+)`tZHI_}z7RNbbMkec+U{K?Nk^URAh4;7&?qaF+G<1BH7HB9hhb*A%V>-bb-5 zi9US)InCewz(LXChb+fVg*yV=**KNR-wg_PKREVU!byD|h5I>h$}Rtjw;#S=US}8JlJ!IQ-g(Nofx~wb$V1u%U%Ws$ z7rYOi`hnzLfpE%Q1F~BxgR`{D_Y`g~$m^1DhZSxDAD)P7RmAHn|Aen$aHmcM^exJlrszsPi-RyZe& zPd-v!$$een27wz)!i^~08Q@$=xPZdh=O*Vqq;Nh1Zn?q@1DDKCtqK=`_R^Llf4_(J zMeU5^NkJ0sfYRPhfh=u?xU9FIDf-?7j{1wd=C2j*UEuCdlJ1DYje@ehNw}L8E(d;R zCRsUJ6wU#hBZ3fBPKf+XA`h1&*PQxfiN=(nkzj{>(c3HOS^{R+5b_Ipm@@OOTE zN%TFaa8)pvcO~I&Q@A6*MUrrSh0BHabq^%rY837uaPazo_#youPvM>hBcF^@2_O4! z7{96g4#IoZ8E``g5-#54>NxELe&P~A85Kh{8v7+xF zaL`4^4_V$Ug&PGfnO$Ci3#cF9@9C|JYfIQ~OySZO>+>hmU80oZ8sKE!QLX&^Sw){4 zxMc0TPvJfd9K2>Ce#mt3cQZ z!sPu>ro#DvOV-X~u#TYldk(l{{mTy&&IRvbPsTl>a1R0JPGY~86}!9)FO-wEK;y{I zw=4Q$z{TR$OW65IMc)LxS6}L&`tDV@9~y8Wg?r9``-GCelfX44DepB3x1flzVdy*M z0oBEi0)@N(%H;j{StuN>w{$0CFGyu@mim6FaFf7wCCMMW5=^J>nyd8Vmb4|ja!VTBtk(XWpr*R60d;EpEI=To?mQfO~UxN?QFl`#gdqlq6f zU3fK%&Mq&);MNeQ66Jtb&geLMd2&1d3tWrI$S$B0xX~o~{!Zb}0{3DP?z0N_LIq>) zB-}2A%c)GB?k5!PA>iP3lJP^@1%LmKmIEFsi`OZ_@{(bNgGcw1a$$wL#(-N7x@o#@ z;5y^EOX&Wn&?loFRrJYn_!RCaaQBjl6Q+d+&XMr5ELTmx_S@tbhlkX6ozMr}IX_%r zco~NQ@-uYrTpx$vPZe-c*-^19j%q*OZ@^=upy(w_GI8TM! z3tTGczMCSqcPO=Vr+_<{LOJ%{l4AaVOQpPnw`#vDE0Z>|b2=zHA|W^%agPF*ieDAn zmRkPqPm#;rms&X<0xlIh+i%zRS4QO>11=SPRl})qPXTuX>?;qWbhqwL%@1A#E|vUk zJCIs=-vlldzY5)vn!YLEQt_8AC`2k;EJd#M&eZJkB58TY%P`%>dhrO1UolUg~>0+&ku2B6YX;m)SW4ZuV+6+b-% zTq@~?K9`!lms8|?pHIzxF9UZlh5Bu~KQ-<(;8H1X=ND4bcM7;v^o72dT6;SKTq@-q z_)=>2!xyBd;s*o3rIPLxaH;h70}rH_zXwyZ-!O2gr2B4)+~Ai}({~oQRO}aeC^hco z6gl6+spanl;8N-Dw|ynG{7t6Ft@~-Pso2kbBsK0y;8O7e*CVO<^OGrZHGh?w zpFRZ~OcCOT(fH>6T8iaOk#jzpnjbs`+;BX1#^YtpU#Hf7p93zH`fz_ewfcB2MXup* zQq%VWaH-Ts>(SKoy$D%E^w)&yZ6b|(wzb>6@7!pQmcJP`~3(jhDt{#^;&ECj@H=3lk@rtr#hzQ=`}4gTdT z+!SzlJ#wIq>qG88bM*RbuO+xN!o8?)1;F9;s1MVW=^j@&JK-`2_a%jM5-yW)yA;kv zxGci8DqIcWFrVr056>=za}y5jD!E*RYakp%#kqH8>+Rid;l_Y-3J&Wz9sXf?4=LP>z+pJ1n@6~Ag^K~_65M>kZC1G4e@p1g zC)~9PS3tN0gmWmIop1{YXHhsO;VvQEzh~>~!$r6P!u?#~Y6u69Uc~J;u5fO`EhgOk z3fDk5cw`~2uS?;4gexSRPvN!#C)@Akgj=a_A)@aJ!sRJk1h_VcM?bI=?p&!R+1@M)cZBF$LAcY<2my^BM+tWo;eM%bW5A&wW4c!p?kR;kNw}4S z`zwWu0p}C?N(gsQ;asmL>aCP;A6Gax;mQcNTH$u zzNl~!;AFq?5yA~A+%RxXh(|wg6YgUQcN94EJLEist5UcZfol_7E#c-UT+JKWa}TJm zj&S(w zdm`ON!tGNy7jUv1*AXtDa1BJ?2Ex@V+*YEmiEt|wE<*HeB-|o}8wSn>@mStw!lfzP z2+@cAjO>Sg10SfJ50m^|Pq=R>+!)cfnQ-?i+yvoT3D=`=lfX$o-9osV6po!v)W;2k z^D0~c;kFXap>QtXr2RfhIIF_d0Oy2wwDV1bdpS*Szc!-pV}$#j!i9jd3w_%N_pri^ z0M{nCj}z`zg*yeD^ix0KZc;e>0bbcYItW*za5cc4fwE$GI|;Wy;hcX+q#GpM8LQqd zZs4T-wiE6j6)pr^8^mL}I|w(Xa3_J2^%f!={FJHApC<_yCfp|!?nU6FT|P-T_{mqD zzT7`1(!H5*@ROc8u7Ge6!kvY3(e`F1Tp!`!C&zT06F6DF1B5%NaBjlwA{_jro=)FZ z;2Izv?Yx_ChZXJ!aMCV&2)9?^UIflA^bHa&tZ-AnNk14O96mFvv&)%8d2bGZkYO3dqS zC)~XXHw;`ZgkgOQ6KN`NVI)$^pov4qy2v?^~Fb_>>7ZLAXzwaFc{Xo5^}p(~S}CJ`?T?;XY%+;g?NieTG~p%)_bn4{l5pQP z;bMgQjtO^$aDQvU;SbKs{%_2L%O%{n31=tV<0hPoa8Hg5 z2;u(Dgc~N@QzqOf;f|YdM+o;l6K;%f-#6hV2=}xJH%Yi>Ot=`~eqh3#A>0WQj{P~| ze-kELF5#Xv;p~L_p$X?A+>cB+H{qT$;e3R9-h^u-+~1pU5yJi0gc~N@NfU0Aa6d8O zju7srCfpd|{=tNsAlwTk+$7hMb#lu%t5Ne1wCkuOZh) zIGCasauLG8P-4gp6AqfZAva1ms2W4=2;tzPAvZ?2znE|ngnQS7nkkHdPDcHBF5xUDoSkr16V63A{4TFix^BXyn{YnDWtebngv&JHB81B_ z;f4u^@2@Z_$0*@unQ%u4muXZ5 zag`&}%7CDyTZ9emUwbT3lpWk~w-P=~!FmADDG~N?_?(}n3%jq9l_D?NiY`M!D z!DS)vncf`lLN7b9{CM-(-v;I#!Ry!wcEWMo{dP1kJ1#E+`4@pKA!jwX_qrmP4HJ9q zk@N<3n=``fs1eHB!LtK@a*w5hUexouK)SdNSh#}Oa}C*NDLa^q#WLoAX3UXgXLdY? zn38p8rjRom+=EWY+c4Lm<}Grpq5(@QF z=6BwYIHe4B92sVI2a(aP_J(1!vxS|0mMv+_4oysD+7FG??!RZq($ALV#Gq!%FVPq) zJN-lEbh)RN<%SCDAGeg8d8w^%-Q#l`*x_m3!vM373|Q|h zOUgCRwb-+Cwq416cCRk)C2zdzPxsFCUgACMedUdu2b<5Z*_yxo{`y>zKRe{_2+!XU zUH&q>p+fiZI`3LRs66m3B(lGCz zTADK}nqHa_#XRKjJfy{FuBGlonKb)cspLO9N&aO$G@t!>Jnxv!T*1;lMY8U<+jXp# zCw-mm#eQnJmXB`*<{sgeJ7MNI&T&k)gr|!>^M19Y25W?5;OwCZA6 zJa%?0edR2;PSTdR25m%2w3B?^x2FB_ouc_iv^r)dEG20#{kcfi`CQWHILohx9vwOC zwX>%6+FH*m%Z_Ee9s0;6@o|?q_f0bUy;IrDV(*Z8VH{~AV}#`a7$I_>nX=`2_CGw8 zoongeN@DMX5vEmMi6c%wEAo+iJloIgO(ebn;u}c({@w4}*OB;>yTQ67-m{0DdE$MB0B~E|G?(R^~GMETU`wR4H>Wq4OSFhuxb#CdW&tQx{wj%Z6(v zPET0#rYdqR$1`G{!iL8)VKy*Q`_@bBL^}Uui6SjM7Uq4&w5yw9I6uIvab9)L(8E*A z{@L1(M33{1EJ{*f!R*1nD!`6tyXINwY2GJ96jql0NHGbSxprA?+?Wtq&lDlMAUlzw`D zdTbl^(At6hPX_cqqu#%JyhgMccA~A&4s*Eu*IyBDpG&k_<})gG^U>P$N%z|auD?XY zV;Rs^a&BwuVD|Y^hPF13Ts=BfVxLW9-&E!m?6dBWWi+EXD)}=)BX%|dgj>O zW0+4lpVso&e0J^5O(GAQh|bZemCWLt7tJrycvfngv=-HC1o!#jsgm4VW8Xavy%Y)c z^jmZ-@npZHcm<3H`EKlgI%2CJhs^1pti*GeId7VDkyH~UxfNM%M)9l zlU6Io+tzyoNXDcpg*cPtC6ywI!q!s_x*2|Is^lw#sm zi!&U(@B5Y#7#B)PqpbK25^LEvtVwC?^pDuYp?gndv0Jr}9CrEzcE_PXBGn!mAd+RT zmIGPB(%Ad2TZ+3hLi56XA+6MDmeW77{N&Kj-mqBNXFG_FI}WuGsrJw|BB}bBeG9Q6 z)O(31YSH!b`}>Jx(&XIYfl*VC&a>j=U2xk()6kL6xNa&X6?8Y0ymT16z8yN|}0 zy^LrX>A#w!fO%+uJYYX3Ti(ftrMQ?dY~K}Htjkhfb=fn9bZ(T_1MVNhV<4D__*c_hvY)l=P zS#VA;ZH4af*(I5i%$_F813gwEPZ^LWOMER=GcLwL?t^y@XU5o4Clc|M)ZjR?=SWS^ zrg1&0^&*A57s-mT6U}Fj^`$=|`lb^yE!iH?UT9%l8;y<6gWPT%#}W*OYR0h)#ojwa z`R2s38mxQ6&_ikKjEvZvVwAL5yVQ&8^hD2zI}w*pv+Jx$G2-)bjY4f&oG_b9^y0iE zrEGBw#(SvA9Qez^hsR;95i0ju!%pw$`W(oOJJc|q0e@N8Ii3b*87IekT)!srB75=0 zJ9miQg%$14@+Nxe(%kr*4RT=PJtB@aA14;JwckV}t^Wh2yp?G3bV%=PE36r3MH^)t z%r~$`+;87n?2Xrmm)OUByTy51)I&lvPuv35p|iIAFy^omtHC>m!**Dg7457LWvb9! zTf)wamy-P2cz?~HmtPU@uW5_6by)1hk_XRR9iwA0j;5kD^O{SHK?@-#vXxvOgE?C$ zG@c88Cqm9~tiy8e4?|dM%$^NxBqxTgqG23s5DBb9N$geHGq%-|H{SOw^j_i3{z{_7 z%6Y>+kK79a?}+ci{Qd4sB4zA(=G6Q9^_uV zh9ewHckGBk4RhJz2*jAfAG?<5n%L(aU!#*zLsk5W2Dri-!?}P=ePUm_(>A$M7n0%3 zja~_5s2N`#Py1>}dqu3ED8yU5W%<$=_IU{{R?vd=n+QpB=0#boAhwWeg5H|vI?a&@ zrAsH8K5;y!;lN(c-lbkmcUnB|eS0SO6KLe~<&(SB`knXWd&lNJ{K^|P(d(6hCo$&@ zP#QSHtmpd4w!+90DErE?oOZlu{4OK;|VN(r;r z>D&=V5__zz@GyF7JO!))=yQl{aayA`s7v3t^$W1;WP$P3k`6iahHXdZog7>L-qRnS zS^&G%uN`@70|klj9&?VS!j5i&I=P)*dbP4 zLHp}r=#R>xw6|va=)6#yX$aeidDa}Q1YD{;G>b@|K{VRZ(1MAgjr6eWo&(hH{%H$duYu~+&*@E0dF^RqA+uTmOLv8t4x;e%!p=w zL+;$=$E@GTJc=`dxv@kjAIEgHc5;s`zOK$cmcx6?Ij|cz5gHtamIA)E6=q#uoGWO%c7^dd*n;>R40_=cIl$vu@O95@(Fr5m>HMN2r3C$1=l z@jIXAv-#}d_&y&yF&DzL+&}A?CDNM(VLon+3783@HLmjhNX(|*Q^q-*hp`iRz@P;l z@FecZpjC!>=!5aGE{ki%HS92GPJ?q|o~Btv+9dxNJCO_VsP!(QbvA^#dFb8o{9+Dq zMujmrqnZfSirUj^OzJFo<4p5CV|RG5hkF2OaQ+Q&hhlWAZbjdG_N#$!3Oj6ir>$7d zh>mLB&Bsyq?StQcl*m~Fj}Ym|)coOxb@GDI2Z;RqfiDm#6ME9m>Uxz~W6zvA^BGvl zmDr+m9XSef#IqZC*j$DJIf(7$Ac;ah8t({-f#R(R`-i7nG( zsKdhlvJO>+-ZOPm2|6@Hx%eUd0JaJtyn*3t8Vk zWNS`Hw;akK(weQxg5FwbWlc(W3Z*X7K>GFYPj@B-SHXX+m>79Mqk6=kKEvRL_O1--;;}LPE3+_a- z6Vft?d|;ju_p_EjE)LeF{qoHsX&Y^4|38Xko~WG?JNvj>mEY*%y%p}R%35)jd!XI2 z6SIl^G2hFWyRhK+TSf9tskXYLzJmF}1Ah*@w+DXqd959O?a_{6xGUIaUj;uNY1e*^ z*5bPi5-?pW;sd=lv{)P?y=5>vm{5Mu? zgS^Lo6w~;(GT|8q$Vz80671=`_M+#d6Y|m#*>!FFH#y-KIw2?!>FB>U+%pjD+tb^3 zv%RF*1^))Z-9d5kG6+&w9_Z!4}_Tecw>?(*+m zRR-3^e|2@+L~gbf7Xt+Z{?2Kc{GC($0Kaou_QAh%dQKOYVQx!$!O_kk2U1B{M|XdC zhE#R-cFdF}?YCiPri8)W(A;MzW16nA;LcsaUErWIQ32b7fq`A{>)|u2t;}2RY2C89 z-rsa%qwhSbF6-J8j+F4`yFJh`!zR%cLP?2>7p`Dh>cIi*9scL-KHlnNrGH=vOCZUz zKwrm2OSi1mvw3}etG}gndhvzb{8JgVToW3!T;eq4U|JBx{T%kmSX1 z)w2FRm~mauR*6ZL1tQ^#k!(kA--YgGd2un_vT$Vgg>H1Z#H%lc#l@uWA|`z?20Lzd zQFNYuSp;Tf7t;tm!GZAhi=Kh9NCcKG7rwiZRl%)*nJA0&b_M$S`@1eiZq7$tZ0`$n z2XPTN(<4_xaoLW(Agl(0fs&4{FnpL{(-|jp@e=Ou-PJea6LV6~T|MD}q4Q@)uDYWi=?V;N@9pb8Po|OT%U}dM-$~5;Qb1P2%xmrm^z`-*1Ug{Pb4F(qFf{k~cHA7C z>8_@KptmouV}{lqp}-7HTR>6Sj4Bhw^atAe2l@hhPk&}ANVbES(bhLGQ#-(@sjP2c zaOU!b+T=z^UGwJF`mO#M+B}kZRkcfbb8B;pe`A$@clPdjh_^YqI)gS*2sH3L8AZ0P+I zwsqH?FZYra0-lC$AjN6*Q`X-(Lqp&>7zgrDwkNzj><@MaW@wi3!MT|U$C!zgk*1@p zLw_gv-25WBPMibc?cDRC`}~_xMti@MZT6y7;I>%cuA6zxubi7p6rRC?dT>YIh=E>cG z@Qig#eFNvZrJt}d>YC{>m+RD$n5o)9mHz&L?#hap*H{LRCGF}y=e>TtO|{IP56cS8 za`tnChG)OL*=V_* zSp)Cs3d~q{hPuiEy9Pqg1j8Kx*hHKuXP&NkrW<6E6lUJgWgX#2DA*V7*)gMriEBMC zMoDNt9|oDxi9WAHZS8PgOfl2r3(v1qdhSmdB|0L#;_bV-&T$LgNOS)le`l~iyklm& zkhn$S>dSifbX5$VzE<9r^WX&ZN{pb2z zom!=u`u^VS1LwTAXR7*q8eiK?JRcsTX+D2mUZzW+YJAD7{9LtyV3s?4%b?fSH zXsoOE*KhRHf#mmlT3YHixB54>tOqgiy#~BHRS93@lYEP>@mkn;T1US^!vp;OjkWcl zhYRZUI1!Obn;JLNb2g#W2lv4nH#Ki*r5DrN)$34qYg3EArNL9~#|$U#DEGF1624uS z&@XPOL4e<1x3Q(M#gCdmlsY!9Tg6p0wA8~bKF{XXEk1v1HRmEcqm=T#+>$=8f|Hk^3 z7SH*`y0yvShd=1uFVdf_FNYi??UB!u%O+yy)*k-3(p`g*9|L{_HVriCc< zrW-s>Tk5Z^r~)U_{0JO}8{O-Hrq%)`LLKy32<;wo+={-&gq=mkJ)1mD&Fl3w=DTsD ztRbB?&<@X6_&0i58=wGCJtf_{x(34SLjys7M+lyWhLHBYaB#c7GaT4~PgsTVTZtt- zy|5_3FT(oaYbpc5Zht5k=nQfkzI->(7l!tA4quVgI{t0SE!6mTbi21D`!cfjmE@WG zi|-_dfBfC#@UaavzYj+m|GM(k%({2({5dR(Wm&SUS!uR(TZS#umSwZqX4$fBv$Jw+ zbF+r6S^KS72dr6lShEgVv+lHJ-DS!YB z$^9+xxiR$sO!e@|^b zd+zza|MAJ6{PZ6@voA>fP#>v+N~r}OxzK$f%|pRO$^-Qi>>E5VCR|8Ar8am7(!Ut> zKyC0{-e24z`-=yfAj)_=(s66)n*K z(})YwH_&-h1<%LcgBNP93~xD)A1`QWL)qmpeqV;QJ^xl5w%Z`?eES6LBX79~eYDOe zp}e*EyD#{Bf%-y&Rv#D47pVQ4c-j|so;5}D?F-)@QTx|k1pCu9 zBy`Car0=6;#@}7O(0c{c=g^o=OWxG3TB=eq( zL+PJNyI|{RJESiU?Dw$Wx80d_SLWRrBkA{~9lB6sG4%&+j(*|#Kk5(5!3Gz)9sb{x z{s=FBd@gvw`@zgn68wxsuL zY{ORDeyi<()pm!~cF=0O(`viRYBRfML+4%D(DvKl-}zo^QJ-JJ`;0uf#$U3wgN$=z z?XWO?yp_kJPico$iBIG4*v7OYO^Hue;?tG*3?7eV(2fixK9k4e+DSVymG~?kpBQJd zlz5vGZ&TuD@pzmQX~!%jKAXqm99}!JmH62_9_O>#F+?eEAfk!_{(^Fo4lM| zroxt2g%WS)@d^9dmG~kapIDz3 zDe=WT{-L=3VkLelkH@`r?O3YBJ9s?qd25G5iHBcDhssI#*D@u3Igh_jUJgIVtnZJm z(;+;G`QGTZqzkzU(MsaGMZhj#INM>xWB6% zE0y>X9{+-jW+h5|sUnwg9`EmJN0|~2Ki&%V#CxyW;Zowuc|7j_Ye%^fU%}&XUtT*Z zl=w;>Un`?or4nDo>P~M zjx-ow|3xQT+4DL%jXkN8)7jT_at3=qCug!Dot(u!rju=KlTMz+KCF|onNugvW(#$4 z4zudyIqdBmSsE;PSf@^2$TsNYMQpWB zzJwL)+vc?K=h^@DiVpe*rR%_vu3Z z0m$3nbFPrTh8KzhpHLjp$pO}_liOK~POfD&I=O>gu9G{NRVN48>zOh&%T=C)crDo!rg-ltJ^;!+xuid)Wz{9AS^@MknuLm+R!+EKMh`W2dm<#9?83*w1wGAbVUV53w)l{Xq-f&Ew~H?eQ)K? zIeT2lI7hd_{QO}dKh5PU*quVYj>~q|Cu9egi&(ReAL4Q`yGF=3r-s!vvkMvL&{pPP z=|V2%{4#bL`eV%BeOzA7el6tfT)vW>5VDrOlYLFdck%cY?2wRgj%#ICv0fp2dHmI^ zRmeDpwZhK8M}+(Wk1t`D2^r09Wu@$0=#Mc!I7hXzGWJ^`_dMoX)7W=) zayt8KA>*FLd}{{#vXFnusaSvj?HJe=}Wb}vm zFj=@n$Y`JWR`}IDA>;E`^IJ0K97A%$Xa^y z*#kN`pWP?qMT$&{%ZlN8w0riH)*h@+f=-k@7QTkZ zGqz(q^ZpXzu^v%&!Wns0#(5FO+r`-pXXJ1g%r3KN>0M)C1t@>S!d}4m?=m)t=f7j@ zS9t!gg}sPpxb9^S$Z$h~SM=(vF zw42nU=0}w!e--M1@~*`*=vBk7!Enfz8ZP+-7!Ua>6?!=TA&tj!=0G?-qd#TCU|<*L zDsld>IBybX^cUpX;EdPHbg;fKJ)TaT@GGeAPQhhj{5y;t1xLl}P(PlrzR)k87V?CU z(T*7J6SDLN?w?NyznNk>f5h}371v4sF9aFGxn1lQHjHw$g+W$WHslkA3YJ}KVTU(A&*wRCJug4#<>iHT)`J|h-&^nu@?kh*IxB@-C1iP>tbepK zaxz?&uT)&uis%0VKN9i)p23cX#Q7;W1N;TgU^KL!HBIZs ztaG*YV4b72BP$q_+kLjy&s(#=p2*uQ{N9ZUkUk-LjJap&j|TjLVioghlTvMkiRM9 z{}l3LLOw3!zZUZMgnXNjzc1u{LViZbw+s0PLLLntQz73c2^@W#$$p_}_7b)i5{Pq53=(GiRc)c5rz#e$y1Tk_zS zq?0jC`1)O)vc{fHT^1TT!dv=-eZD|{|INW6^Vs^``s|Bq>+n4xecb{4IqM_}THwVx zT|r+UjIXT2AJFbfqGvPyL~j3pFPuz+h}@7gf188dy#vAe!2z%K!?<-l+cyPwsAWt- zsmP|_9!Mcc-Wq%B0+B#_7=E=onSp3@lB?H+`@t`I;C&pXk;$_Sro}6hSXIO%(J5j~ z71jlMI)Yt*s763v*%7So>F65*$D3Z?=yGbX-VMQ9dli3O9~=kB0H`C2x9l8~rW8 zftFy$u0E(xse}h&E(7gdL0#a+0KEU9uca%nJLv0$w+-npp|zj544N=$Rnx+uxbYUF ziv-U#x=uuyU5W+(7gjZT!-K(2Xjy8wa1>o|G8IX$pMG(0XTsHq&frdgLK96Ethr*c z7+qLxZ@lAz3fvsr5$3fbYOyZR)zuC^jYKce2$48+P1Bi1_$j)?72sLZodN=MwOv%KDyvLC*h^1th61y9bUrW-@QF3-aEp= zrCR%dK6f*`iA1zeC>B(BOZb)`wq@27Zg)6DZ|QJ=hOTfs>uAR}`E2&XYqFrt$Hl;Q z@M@6Y2XKPeWGl#L_}EbI@%g*Kti2sDjKND$*hbG*zo)Lr-_*EiLknxFsPp*MkxGOn zshnD@oQAqayo7qV2m+K9m0(@O(LP1IA6yh|buDkQb@Ia^~1g|mk^mNw3J6^a( z8cqXLpte)=HAyax$4Ldm*)czmhHMfb*2g_m?||Q*CIRYD43!GBnOAL*uM6G|nnR z;}~YG%FsAfhQ_HfG)|?VaViaSP-$qK3Pa;m7#gR-&^Q%_#wlNIm{9p@!<5Qb8zxo0 z+9WL_$11Njtcvn#!@4N1Hmr>DRfe@uzRIvV%2yfIM|qX8ovMuORAp?ZDq}ktm$=f{ zPL(EC8QZDC*iIG3cB(M8Q@OF7%8l(*ZfvJ=V>=la%VlgQm$98(4`5~9gfz9jsC_K&+aNmy~F2N z=h)z=b+kBE*Kc&(;Pr(o9rasV*OgbJ&;oxpdK|ubhi7e5Ma7n;s`4#O73GetYn#f; z9W4;j0wFCB(pX<#4}WiTY-y=)xuM#zucdWE-G+6VxEjQUCP#CN4_@!)sIT?ZI5yW` zU*o`c-qkqjJ++OyD_|~@bY(23IEhuU3{mG9WJMfD3|7N3KKV*m#!g=aCy&9Uj}ij| ze0(mC>ogLbeC103{i=6*gjn(FB9g9l%?X+(!^tC2kyr_nKswt}%1NUX3ngYrh7n?+ zN|F+DCM6XSs^}4+hDs7EU7CQp$|Z4fg)4(hR=0dLs$bdiAe^Tvt6E*ST+!-Rv*A+x zN*3g#t5^uvuV7_Be4!!(rY}-t46QNn4qQ>`=jAkvdUzaGR;rRuwn`;&at2R=;;Ty% zCMq?an0nc?YxEcBR-&3(-6~WG5-U(8R3skU$yc5t(qPr8ixqjHD^4EISDXA3U1`by zedQ%xVM=s*RkQRuSd|3_ zOEy-OZjZ2xxWqE&WNn;f&CblT%(pJEUScV*TxwZtxy({%S&~_7aaiVo3Ro~POBQ^9 z+de5DEt%SLGjQSu-q&%7&v;4~pVul}CxmYkad?tkp~6i-+)4z*A-ODtdlTZ5ac^hn z^N05#*GXk?mik^(IJ^%XOTtYk+%;D19+yO=zON`;rvZ1b!hISzxV;oVq`o1Av!`i$ z>JpTkU*Sf8OJBe2QHZ(*c8rZz@3F~ zs&5$NHZ3Xs7es!%qHr;glcoE-!sS9flG)`u3U`eGcb~$Afb)qw;R&Mo(XVh%0oN+x z@Fck#6fOr0nM~h@6>b}F$@DE#xG~@sBuO_*;hqC7HwpJP_y?_zUm0+(DBNqnbtcjG ztim-w#}i7z;d8q*-7(<4g#qG#?DONx3b$<*ngI$u8_bq66)Glx4K>lQ7B;|-IoEv(2XFSzJ zd7o6c5OB%*p$8T2UEl_i=o?nJ2sl+Te{NH_3E)1RL?1riOv~Gp$Jogvc5x`&g8bz5 zmZ5MV;6{?@dlSNFx@VvfO(x0T7r@UcH?a_&M9B%!C7+u2A=_qj~~9p$?NS$3il{*uSw$)eeei{PT$Doj71{lE){+5&eXVx6ghV=wfsGoBG<4zwfvm~ZX^Z!`F5n1zh42DioR{3 z)cpBH;OMw&RKK0!)XMuBa0gQ;Z|IY$Pb#|qe?rXr&d5)3& zwsxnc??vGDreMF;p47NW;8L-luQxS6cp11<{I3%R)l|w611^>Pwe3uei>1i5^`)o} zxKzrqtv@w=F9Vl~zOCR?src#3z@=ipZM#zAUQUtQwmUVyp9C(I@;2>BP2U7?sg&0Z z6S!2`<&(grl0O$b+n7qaV+LF=%){i|ioxN6XCZwH82eB7jL-0=!#NlJH3J7r&-gKX zpB4^}Uh=UQIUD?|R=82%>=2F|rX#rmg&QOKaPBC%G=-ZW95Ryo1ME}K{7nK^0P&bE zM8&z7!kq%nEjUOj&ONPg&d(&un?<+>6|RPGXb+h`{Jt~IUjuMXkuHWyZkNJEfRp8b zC3u|sn8J;abYTe|=hi9QVc_f#k9Nr+T#3Rx1svudxjBTpRN*E_x^oGau5gotn@6}a zP;hFO7;w@q=y%dCzfm~bXrew~X&vXDRk#Ae;Xa_$_n5*t2?tB-ICn_lYJijV0nH@N z^(vf?aIj>KbDI?|L^xP7$GNo%H%z!o2v?+Vhk=vzhWUhOZ9S%NM+gT?+&K3KXneFj zjuH-*u5s=+3O5E^4aB3rTt>KO6z&vovVIE*_YH;1{cNIsVTl`0_e%-l za}f@fnsKgO;oO9?6K;dT`3P4;IETWu0f&0fF2#hKqj1B(wFz!1;r;_UO8>E$ zM-=WTaI(Bt5zek~?DL6sc{SlI3ReJ}^wX7uJ7v+^*+=x15bk+}3jt?`c&y(t!hKcY zMhNF3+yR9<3Y@faIpKl|Hwm1qw+h0!6)px`0mNheDhYSF!c76^7F-qK-iOcB|7z|} z=vzg&R~61jxN5?kP`D6qJ_y77ttQ-;749jb59?3*)quiH5^fFQV7o>o?)tgc~s7e1zL&!nF}@w+R;^+#VBdm~ew8+$iCOOt>S2gRQ5yA6yEb z)8L;x#(+DH8#Lm8=_^0-;4kIEM;N;sHzLF#IXnZ0RnCty-+^}?NCD20>+g<~_LkY> zhxoDb)iu?2yNicvf6HC2>S_pEU0q&P!^7LMZ?A9i^50Dsdhu;JQZEK=dy7Y8;M@^s z`8zC~mIzFCBFECbY}uj)c%Wp+;k-2Zt?~TES)u6EL%F%dCqqTv_y7Ff`*R_7c+lcZ zi>|bzoDsW{pDi(zvSaK-CR}41a=-njiu6Y?jGe&$oZiSYm>QM~`wK0tLY~$YPDhlT zxD-B5PCdlz$K7wQ@+>-{U7IgL4-V&DH$U`?sfX-&p}FuWcLd{eFs+d}*J*iEb8t;< zMv@#P@__lle9ZAK^3H>F+(VPXvcI8RJH>Yl~VM|~MuDf!<_D5d-DAA8b7 z9+_QVwp`GO*Sm*&$MJg5=gyjT{XdcGbEny6ju$QM9*P{#(KPt7;XE-l=C(}J^pGcA z$w{J&dwKcT@&#};8(QjI6kTu}?Ue2<3bD^VGV<-I^xQ{=?w!ia)oi)K`^p<^DH5tR zf1#^Smv^s{=L~OUHU^QX8F@y5xm~jXlpBNV1w-RFs|zUbl1+SAs-mC0`mjZ zl~9AvPT4HW8!$ApXc<2j^Rm9?)5^*mg|W+lJ5_Euot}$a^O^U{(O*uv7=-L^L!Z?? zKikHN<|m|`orTtwv6q-5JJ$Tp`w=W-bjp^Oe)^!bXlg#|EX;)5xeE{0{_&-B_=LLC zc#aM;txnNL+?_?PEl=4~JGeG1Np`!}lx9eX-A*KO4>+8Nd7Z93Jt{vox6`=g%VKsOn=GyIrl@ZJ1xzVb%iJXZs&c19ccH^@b{N+o!@d}Ukv?=FI}r~ zI~%o(T1V4Hi@XaV=1CXUIQGV)Q%|ycr{=I+{`nYup3AV;9G&_ue4fX$!J?Mp=+qbs zb3148`gFg2jPz3JW3qKg+oJ!cga2Q`y?-g_V?!3_@+jsqefSFai+(jrad68?sElX=zp0UM+dojS}g#hT;kLeg55WtklB&_5p-JHT7^m%Wz9 zGQQ#C>7~Clk3D+{JDs<4UfvbQEmvZjpB;Pkl5_}}mG|grOJ3gb<}((XC5ACiy~XC) zCWn^f7F+*fX`2IDFxC07N4(^U`4GP}4dQ3<*g20`zA@`4a%@>zjM*1{qhU*TVQ$HP zy~LJf#d7WJFByTn#};y;yKr#H(b}^w=RG#(8(N6wg=xik-++EG^nG6Ymy$N&I%f6e zqvzT)ViRv=WCTBcd24;)(Z@5Le}2gYBLkFs{Rp(nL*9knCD1PO?#cZsv!{<{jAo8z zjb;^>d((N!S;Z^7bKbgyTk-HzCV0>i_7sdqS1=a$z?zU{^eGsrZ0yA;#(p-H&7PV{ zXWs_DOMmQoZv(fdwYX8#GPZ(;PtDEEaUFrbxy41^Gzcl=C9q)$?$+7>w!4MiBOx{# z1N}!s*3na;v{7qu*z4jNZ+|BDSO$7k2yF->j?02l8?+=iBF8ekbDm(1{8%1@Y9o`@ zzc!5Hh^>uA!y$K}Z5-zZorRW_Z@dJf4a{+vMGO7U*Ddz9UT5|{@>Yp$*y^3_%^fKm zIZ|thTCmO9--Wo`W0(UUTst~-KeIUZMK|)#0cIb+j(-ZVt;ZYqCs=zrZ<(y;pJBb_ z9GJv$1IG(?2IhdyuE`H`8Pe8fAKG;*qK=i*W9@G=*hSL_=o>^^Yp*Jaq4yU9_Sbzbd77;wOQ`k-?0-@BK#dV zk50i{7VPLd{x%N{9Y4cE!SWF58o!+9OlwPpzhm|{q($1;iQfx7uj%x}gr0xa=~+Vb zOufoZ{FAu$*Sc$?JoL!%eWS;Z@SLbN zFAQ^CJA|(5L02BwtwZ`g*sV?I{e+_TCLSI+zE!6;GrEkF`!tjhdx_z}n(+(|1Bj~uteuz$x~QLR^T zt!p7aOT_h@OamHcWX~n-oI6i2^?R-AD5XNOWe{&78GsCc|E)wIK zEha~}V(;w65FhL8f|2uCWVCtERbH!LZs+5k)ys+!Jpuxf+VUYctvpN-beilSX* z7&~3Zh6^L>8w+9V9o%30`0w>)`Ig;s zCOu=}@ih3mY}|VKK!$bGs&&qfM+AiouH*T9eq@nu?b3X9e*`TgS)6NTdPiW^y)afI za-DJdPK#?QkB!x4M{%WC!E_x>nbLP&=E#^mF@%;P+3)vE0gIJ5Y|F~b^%F2?9xl7}+4g3V9L^xif%}CO{ z3u1f6j|}>b#KqN z>=fJr;`YBRrma7)JPTu5i@KlXj-#9vFK6@F1H5+9V{?nNyt5N!F>Fn2D8pGanfbES zISW#nKbh_9*Ae>DYf<86C& zWdCs6AkHRH<}tUGkmJQM1ASyw z6m!6a<~c8gQqFQZc(1W^-qNMHdC*m`yqa0g#XJmqkxSvoWs6A}68(oZr)(R<8r%;p zPPV7EL9Oj2yc7nwW1kwsy`{Y(7emoo;1jmx-O)WfKLyVAXm0V&!U2%3;r7YoWoP!Z zQEkoE4Kb5bqwpf*d#4K6C#95gFMKg+J4j;~mwoTlV%7oDC`k8CT?WJG?3kakHp~BE z@7)99s?N3XHJjUnkVr^OqQ*FoF%k_75R#B+lmTV}1_A=P=%Ee+Ou|GilK~Q<(UKS= zre4t6Hf?Q-*0yQuX@kbrwDlxCwXMf$3)a)xs_pdD)2h9kX#G4K^;f^=U3;yWwRf0t zeun}2$G4TN{jB%d?^^3!_jm8v8$LHa!X7JQW67bmC0Nn)li!VUx{aSFzf}A7-@IFf zdEYoi|E9UqzFHf(USoeM!@Tm`>nxz%TUD9V-nvR_Zz{61Us0IEcayWjql(_HQnK~k zJ=SZXJ@7+Z0bOk0B2iiz`&aVPN}q=;Z4pmXmKNi_UUptu8v7%q)z>nS(k|oNvrCH> z5H2m+0M3(NDt+sRyU#O~R`+-F>%*nB>}ErAl+v#J(9)7kXCFT!=0=7??tA{u#|pB; zKtIdfJ+=;KWQb(I#!NR9nff>-CjE0bkTzt#U9*uU^ngjQU~<0 zI)$$vjtY<8@ILRpoPDUDY;EZG{SWnf`?JBNnab5(;6Ao-UFdw?u2zRVF>@Zv9|-lg z@3z1b)4cDs-Oc^41#J6{?H=yW-95Z7H>lTN=%gN|$QeR!o!NRV&k51mBXwY6DLeId zVF!KQ&v4UdMx_soZo(PO<2Q)WEF<^kF*o9d#_wj?`v%K)y-XHxB8Du`8n(a&&S__t zqxaoA?#;B8(*F4Xc7toU#LsB=eD8P*B(#z^fOY2Y`&;@QwO6%&3Vzx=9)5(8_7wMD zPSVO)_vvmwseAmG&5rB7kA9^0bbBbtRCay6usCGNvy3L?WsGHVo6zc$?0o?C9^5!9 zloMJI((+Qq&f!vBS9&Pbq)YGZG@gkW*kE63O>!kcbKYDx^$4=y)=}yW)PAzZs0=9s zyZfm}44{m9jV1H;5#V!vI@e0RJid0xndiRMpX)xlQ43wbCHeZSk8v`0RQJ>+yT3Pb z@j#%zdADX84(Kz-(2+TxrOWDVRO`{z%* z7Qzn46^**~Q4a`66OF_$>DCh_w#t9_WQOYK7GyVvs*bXY_wJvM+oFv2sSwU_X)w zbKD&E10Xra&1I*6^cnpeX61Un%Tqduf3M&xp>LyfTIe^Su~2GgC7+MmdE3kg9p}ts z!+uPkZGRN{D)iDQ;vA)1ei`T%UXJZbE{72t$>rxH;<@}ZP$ZY11TyCGUgS#6&1Ipx zqUPqp&|!Z4E>=0Bulo*iu5Qh_p>uh;DW9~8((`Gt?E{Bay3HX=s3znL^>H1|wjLht zWCzQVe@z~tq48#x6rwfM(D+Vv`pry>K8E=bL+h|i+_91Sb^UH%3r~HSo53GVHHqGa zv_ArVHMbE~PtZl)V2#hxT1da{0z z@9(+@u~_M%C%%_`ffyaxsk~59-m)>8`35i(X`>oO@_8YBuA@qfv}z!bKR-S5eCSwvpPmv%Q5v z6U~sc;!ho=)e;-TsJ45sY^CrQSl}s~oonU$SUYl5U8tvq+B;~lm;E*{uZ$WO`=-ij*<+}OKy$3t@Aog*) z$L5BzuwIy-`#)pu(1j)Gx$S&}eD|%LJKsFBbLW5k^-Ptm{rG!tzGZnYD}|k+5t2%N zx}Ea4tnhV_$N%L0;#K@RHvVenGwmzfLmO#~#9h(4-yl5uo~hmr`hWLJNVD6Wt={$n ztywneQ@Z4a-;L^$Hb~m^b%!pw9)8})4(P{V$&qL=A0av7dxE4;)$jI)?hI}C-IHL+ zG3k8v9Uy&7!d~d&xuI`y9af9|i^}r^UHhm2! z^?YmsJ+u$GP0=HFUC)SqdJ9Su8FNm-9zCJD(Av<_P)aD`33?1InD&`;H;3wWUtv&` zuS>*I*(}Z8c4sr?=Ck0pEBspucL;uq!ao51_c{Mo@S7C=t%cVK{#Fq?V99j6Ux7J^TshP1)Q z3+1?xr||VOSBNyn+LwpZBwre}blq#LuS#j;s(pLC_ac!pJN46$CI7~;^S~{|xR^Ye zl3Nb1N^mTQ`brzJ4$T@$=TAvw58B30T=Zc7fdGw?bbp_n`6w$rQ_An<9{{HPm44rU z1tahD&^X=qzm$>BobLN$q{dNNc20PoN%*eu%f#-*jh3N56OhL5P4Ck0G!#&Od~ncm z`<3Bzui|?uN>iO%^tKt9Tjq)uSAgqilt{XP>=v0})`!-I93k=%4TRI6xrNG5dge6C zL4GI=8f)eJrLSzrKcmlIGL1!up)|^GSb(!g8t~L&RD7xMn{U0%s149c_uNoYemb6I zBgw0fWM)c<&VHlln{V0YNiV0|p=ZK(O;_x=My@V1!+VF!$LYRE>Aob?Un+c{*4%=z zi$v)uuavV}cTpWja(0Q3>%IiC4tWG4@ETU=j$!z_b5jhF2DYa;VPT{KT*8)E2@V-vYCbVZ{_VYv33e-F0r6XlXSHDw!dLPSWucU`)jS-GHsliWV zS@|Cr5y?9dxu;$-vP$Zjr{ABa6^6JD_uNZHE(^<_=J)SuS1R?EF8ThW)bjwd@?*tk8m{wp9DvjK++nCFL273z~jEt8^*L{oAiI@jOEk?h9pvhRU>G zFKNnXOr^820eeOx?s?(g(j}R>XI{#DatVLl0Bv&RhSA~v=98`alFnGP&t}dZu`I*h zciDMv+aQ(T($Fy0t_#PS@w`S73*p}s7V5ui+`@)&p3H3cS7Wvt@pK`UbNV_q6W3_D zY5bZL#9H`xkP>P+VjE0;bC!kl>T8o^{=^mq=@ZL*oMrQsGkjHid_$hHkjH^>e`Y2R+cRlaAphTi zfdji~%pgw~os->Y2CEy<(|AB12W@mulAa~W6n?kN$J0p@>|`6EJn21_?p>u+ZG5Ys zj&iI%TSJ!Cy##aI)Vp-gSnf%EcG|%PGBZaqPFidzi7l1yj_6q|>!2*@Wq8i-9Dg?M zh>_+<{po92dDn|%fhWhgKZ{xq_GmWh+q6TYeH&Rp-?yD3Vrk!|kKOaK_5E$KJJn_j zWa4Qi-S2XldtOeejeVMQ(;u^q3mbg&@q^q4KP%h9J=MwXS-5gXAo;7hSLHJIEL>?( zu1v)GRm#5awJu%BBNNpVc-8tBmWQ22=hID*^-1OmqHD{eW#IIcC zo_$t6&1ogYkrv&v(tB%~TN5d!x>IZgfxf^pw-!!A_<~>!b1KOnnhLdr@mhVabresM zWqkdW@!X-baQQ6Uj$a8>y)no_fkWfT!-vLGj?XG%D~65-Sm__p7BR(tyInj#d+TA?|Tj)CqsA! zn94~$flhGg?&}R`gY?Yl&11UHVBoQ|a7!W!9D*P0>NjqO1?C>L?LOyd^X^PoATv+H z^Q6rI7V-r)@v=u+*fwY!7{B}Y7KBDCW!R{scjA7@X5R9f*>>0dmm=wDQPcAUGV^Gb zYCbD9@)%Gm5g$7F!+$&eq8Qga7}uT^=el1!)%}N)-6!?uUYU*Na~3KOMLgn#p(NNR zDZ7%70J^7uW$RvuWmx&nAIr>37hdrtNS#(n2ihy)6<-iiz2S30T0T7J`LhI#cf@{jHew>r z81nJ48BbO6df&xpl|UXQegCA7s0Dl;PYGo-o!it=x}>pU$?&6@{JBeAk{nvnGzXFe zd`2JV&tp=K==)~fUHFR6dYiMp#zxTJ;S1VU;}yuZz5qTB=d%^sa$D#{{kAoQD{PJ3 z-5u*~_*748tL>kP+g7diwta-@FfXrl-8x%dUQYmD9`p3zJ79RHbdN2s6>&Se`fPdK zlX#VL*_Nv6iY9#BuD7RYOIda8c8_c8CQofe)n?DOq9)|Msi(US-z#crZSnXzTRbhu zK`%by6OQg|BHMQ(FKxbnud8jt%x9(znQ0C5Z3w?x8gH6LlsC}Yv%%km&mHaU4&GqP zt1ZA^FFwZySs>{1ceQr(wfUwt|D7$qHVq-XwCG%81z{r$4=CL&==^YllHzAM_)@vcYj`Yo4+e>Z&6-b(7(qQ?8)Qm z+tBv>-i}FK?4aD{b)%_GA_r25qqVcgpCDCj-K~kzq}wbpCG_oq(G!$0U6+GChuDV( znurS6p??@LK^c_V9B!AhaZA0+Q@yRKF0mOksCIPh^#}5J_ub)bO|VH~rNk4SzJlrH z#P<2zFP1@6))t-G*Iii@l zy$+G&Of*$TPY`RaL=MFtI_^-C4sXCe6UnxA2d8_O<;A6R9saF#uf#MjJ(#l@m; z29utN$&TAy6rHE<2w+t+?M|ZGuicBNbJ1~PybrOl+3dm|myyh-%S2uUsCfF#LntQriZ}260 zsOjnL4tjScXz$UUASb8;is&yfHY8=Dm>zFSPjAr6z50n!F8e`Zv;}(;q$8xfw!YD|-IE~ak<6=EyTtX4wGEz{Vo%N5sV&Xf={Xu}YpcsEow!3ox0VvJ zLFn}cccL>VRGG|q!u)w6lZsyDG;vP44^2jp=cH zySt{a>F|-dYX_d1n9OJtyApPKdndUtkFCGGb&_`_Vyo{cYV}TO7wGhMVUsb*ZF=l7 zkRxC!tC;jVwpACFOiLn;hPqYxtEMlhN#26_@T%daS;?@OYZdg6E-jf zdnfDCkJy-WC3?=~I`t$HRXd~-53qHvDoVUY2Odl6>zuT&-)K`kvr}PNp;%8+W(FOgjUN{jG)tJxLoahcYK?;dCw4>D@X!iyET{{zMn6TCUR`rctmOp)mMh38i)o%~Zqk%7plct>ByB)#U*H23WFwE24cI}K$vI>D*%=bIDS-Sx-Jr>24P+)CAO*ZC8+L)M$5N&jS@t20-ruD+*x zNAIM4dofi@3r$76>dwTe(>!&p+@WV(B;eTL4|eYLPWBPTiR;0bl77d3N=)YKq}6l6 zoL#&ZBzSGeb&@9{Ve8n4M%>@)>Bwtsq5VQa?c38Az^|!Vy_0<~%hWs~YNw=&D(dxw z6Ka!Q`~)pQb;y6aAnJ@sBmqqDtCEYHO_J% zkH^{2;Hq!*)HG}ajQp;F?oO@3Px&Ojp{{BJ98VSMPiT0A$5T`0f*uac*V95oDy^>C zYbhJT zHj#V((zNBy&1(6%og}L`a$${fzGZ7wLv6ih%Vv=n&#kCgRA-g5nrjp>Rht`K_4Qlo zU~5BkQMn2!)3Pe$g+=8J)y}OhPJ>m&V+)iKnOI{*RjsGS)zIMF=xPu=cik3GUA?Qp zwb@XyZa1C+sMvxEk6f>}0DhgYPra+!F;c5WT;Xcqa*@Ht z`pp|v^`e!mT6bL)k`RqI(p=DTBAIKbcDYc!k*u6`n-(H!Oi2|T{ z@;duEdi^c?dVQYOc03P_n3ka5x5Lxs_wJ-8to-z=#JsL^C z@ViWif_QE+=tuvW#BXHvf&W8(j@zpLD%!#<^qD)0rX?|rM`@Zxoau}N{(E~YUCj`F zfFp_jq#5rj+CMjI4ohQcmNYFb$(n3Uv8GzntXAtRYr1uIT84FQ+JKgJKubHQrQNEf z9n#Wn)6x!WX}4?ELCt!HW<8==Kc-pl)U0=D*1I+9Jt$s=k^w8urz6b;N}AO;ch0}% zkao9aTGF10^3Ft>ixnHcz-_$$Q1Wd_ho{TVb|roKUT@j_J%?u9W<8vCd+K1y9mz+M zK1Mm2p7ypx$qRiuvuys2hf;4#Ih=fZ(%^L2L#>Zo%=Etko`)M}G!NAOW?~Fb>*9eK z%7Z%hX7ak2zPVRT`+lDG{%M={)wJn*#?!gxP}8RIU^>%Q+Z>I5GtutVF_3IAlVkAm z8AxBP|CKXX|IhHWr+@rc>)(z=-*nf%+6Ric4W@toQEjkv2HK#y9)AXPP&U8!Q2K4N z4qI>d zlfE~ZnKi+q$a{jqWeY@p6b`dW2n=Hi9C>@$-#*#L9#w5>aXl8#_?j9sZ#HNSs)+Jp^xkjJ~cK5mNm%_%4E&cCS{gsECfCAVW!JJ6Kf*1{%0b6b!<-l2N;_vKQq|}$(N|?*QaHEr2B^Q_!>@7etM)J z?83Y|MRTW@&A;iXAO7gaPnXSS&e_v5MyqY(ugKR--(R7=;+#L3dDA+eSr2H|gPQeL z&3Z_)-lka(Yt~rL5UG0>nnS14kEW)rx6A3r3rAc4mnVM%*)%Nrj>T@R7KKj0Ndi%CIt{&m#pT2QbO`FdD_jCLI z|8<4APa%23@mnQx$?VM!URE$Y!fnJF`xWHPVGWu|p2X$k``3>olRTNrY5$=g$tHOU zmlsPhOEJk)xt#p!`jKjqr*S#0BlIK9B)4+;3sTIiCiyHbr+bO|G0P-R=W@EYpdaZb z`D`w~UW(allRSgV>HfHWWSHc0xSZ}^>&G0Ed@h$q)+}>P@^iSH{QmlJj!B-$;kSovcI{&l>QPfkF?h% zCi#V2ennW}g(mq@Q~sBl@u#O{FwT2nJN91 zT>g#}vy~=!9+#7ETtD(m@_a5oEyXO~BzJIm#J&!bynxFi?Y+PxFXZy8!}<%ke5-<~ zy^w!MKXkc7j1}?g$#rMGzZ<1fm<)z{4FX!@zJ$1P?JRa%t$oM6$$KFOibh$)~ zUBUH7#)~UV>2Kh2T0iN>29x|sE|1JlSDNHkaXCG|s2^9E0m?{Th?J-h>-WxRGCP4d=hnB;R6^Z!yWY zn&ewe@@-sB&tmGwHj{iimsd+M+isFyYr@yDpNhsmh-;GAN7&N>Qodejy z9yVZ&ebRuFSdRfGvug}Eg%uibDqCv6X>7g$TUn|B&tm^GKU_HEC!M`!z_Zy42Asiu zV8ChkYoVX%w#|Tx*i{C+id|yB#cZ|#uV(*sj%u$pY}A0)vJnF=VV^eOb?lG< zuV>u`d^y`}z*n$51Kz+g4fsm-f99(Bxr)7Nz@===fSv5e23*FzV!-8Wzfo;0dHdeX28|#+Xh_29x~v~>}~_DW%~`dj@@9u z*RX31xSm~YzzwX#fE(Fz1Kz?G81Pn>WWd|lYl;IS3FG%~4ES31f&pL0@)XSA&p1!u z^I$d$#`6zwPm9*4G$#@MD=@9sX^%zt55NOBm-62L(?R3E1>^q@1g1C(`zSkRzys_q z13tid4A{%I8}LE4!GLdNIR<=)r5W&T?9b_xvVK_DVK!#Kx3g~<@F4rF0pGy}4EPB1 z8Suy0CIfC^1qOU4JJ*2kV(-q9xgmSp&3482 zEM&lsvL71oW9;h&yn_uH@Cnvuz>l-*4ES5@Dg*vDvm5XeEZu;2vNJR=h{M9#*)I&( z&%S5CyVyepd;=Ra;11Shz@2Q10ejfx2HeH64Y-@78E}C8CA^m<`|V~wH{c*UX}~?~ z3kKZFZZqIMc7p-$Vb>V&URGkj&1|Uw_p@XJ-pAh1r1dC&H?mO!zKMOyfcLWp4ESbt z(134YyRm+x?LaR6G&Yaz5cqkHv)Hu)lg~?I^VueWAK-Wa+aR!=<8xWAz~qzE*g}>m z@Mew|vH!yQkJ2NbgT@xK-v~@TM~$7wo)(yVgc|&b-w>GQAPxS(!vfR%qp=IwUV&+u zq_L&!dVy)#ud$2RCV}<*+gP!{%eg$8Efx5$9Op2Lz~uAL;BWgA)`OJaw>Y-5p9xGp zDGmO#5rHc?Ud}#ckYB=X5}15s8m!zTF!{tZwt`(LF!``F_`7TZlg~QVS)AZ*0bFL)BR+P zUC!zR*6Z^M<`DP@zkUPD5?F7)SF-=c`j7HMJ`;^y#r`1hO3p83KbLZjo$RXu-_LP5 zJ18*uJTz9p{z>3xICimefyt+#F*nN-Sl7RiEfsh(msc{2zRsvucC9fvp$V%H@qL z*MPUMg$BHpy@B;1<-eNqx3iGIdVjf={X$^9|6j-Up-X&+%-zySrHfMG}< zwVy1!^XSV0H*>79qXO^YIEnQMOzk^MOJ)rM7jvA#RtbD1$EnOFa1+OA>|B9g;MmHn z0#kiuX|vdSV!WbzR#{p)dqZHV?<{RL`-Q-6jx*Q~1uo-w4jU1e+GCbBm)$S$VUEvX zw+Q?I$C>N_G2ZC;Tf+WLv={yQGS(^Ve;wyv!%_q$A5NCGjcq2wi6aZ=SD5fh6JBb< z87BM=RfeMP6%+oc2|s4SpEltk6TZ!aTTS>H6E0QoJmj@d!BpOC6V5W>|4$YMA@N@` z;b%?wUrcz!gg&3r(2DQF)MDF$c>5 zwn3Qwl7-QDkiOT#Xda`G`b&Dhh1FB|NBzB6+I$PkA^e(!l~MR53#+5>n1wY`2!1<- z;P)dW{virc371m*H$^&QLO=9W3LfQ?=OO86The+YLF{<($q zQus3qyPv|ZS=eVNL_Qv-@L>x(PT{D9eM`ij7V)DLLeD!CLjFF5xGohHP1h}<5b4wS zMd@?<{F{Z3*A(9jKE*Gj>yR$DKdz_s8(q)a19-BYxShvDJ3zX;o)A_DJ(+YJu3s#! z&lT}D!l+-KJ_ZqP-=ETo74fLYLBS(FmFEfyU)R%3f5^hNiuh&<9}(^BKP_xO;Vuii zlS1V40fbbZVG2KEVHiGH`tOC^|HGoMYa!?5_>rjZ$1H3Q@qTP!0~7*3B*GIS{0@c3 zE$nFuk?$7}QaapD&x&@9u!H1}3Vq<+M;QG}=8M-q;;j__hHj^@{a=o>6OH63cQb`3 zXAadP+SR2Zq;Zh!Rw?S0x3_OtaEDLlwNnV(MIq{ow;$kd3H)avr*$Xs?i1lr3c-I~ zU^ID-mm@>O3ySa=5z>Bx_~}>=l01__U>k+V?^Y52kO*HEA>C7>au*?_>pDb8`#HMq zK7o%?ID&Nmg=mi_5Qgmq-V&69Ft_XH^!iOl$nAi7ETeJ)SBsFhBg8k+btm+8M%R}T zMq$&57eYA*Bc8XP-|6jzFtux~Pw(&AIXW->C!+r#pEkN4`J{GC{6WHq=k4H&7Iu^{ z$~!FLzeXXIi^7{M?AH{&s*fv#&j6F2w<$#ac)NK(wBG@dUtnHNq*F)NL*I4^kq(tJ z{qv$-?h)e*c(({1&mZ#7+XdpE67kQ9>qo`)zn~D;|A9jAd47;DDkrsX-v0Xa@q+Su z1;qnbA|xD*NAh&^8(u%)Q@)9xPw~)uC50%*)f9eR%rh9Lt|N^6wor)jex5?`zd<4R zyuX4^{gmSWD#E`D`C@9?FUjc>CcLhSq2Tuq3I_Nscdntr`03pc>2t)rG z3c)*0A^Ih^C*~t=uiYYjT>lQqaXrrm(p^gF;d(oTxE@u-uLp(CXD?8Q>oGL&^k1bA z!aq}p>)%I6`Je?ewGVDLj2qmZ`^5a+8!5*@khp|FcQ!3bX^4=h5I|9%RQ z?gJDe-7kyyM@0My5q}yXr7PPvZwDBc%x@zE|8i;(ky*9*+s*`S5B5xzr=+b@WD zg5d1cj)t(-cDZJcZz43CGj_gTQZ7 zNc|Q4CH+?zFDV4CnZlo2Sb##v2PnjNHz?#o6hi;!DWvuw;=e{AI_xvT;c4Pb%@h?&cecaE2dN^O$zn;RM2|FX-ygh)& z+bh~LZwJu(uf*%Ju%C+SUPeguDeIB9fAD0ze4cpF$FCm~?FaZ@C?1%%8{iiO-a&T6 z^=NARx8rk1rAb(`n^%$XGKWi!kzUqY(O5ig=#Co5g;k2knI94@TC@>4dSq;_VylsE9E7 zHy>aBU92C_D7RAlFU5R_{Img6K6pKVw}j*YF`k1*=~KSBe#m)0gr4O>&!s{xug@V2 zdA^YIe8h3RmH3#qc=?fz)X&rZ?1!hnn6Afl^&;ISglf6$BA(h!JmsPM(Dmk!mj~(W z5c>Eyg7O_9EbAHa7liyp3aR|m4zVua<2-nm62`bvLgCjiPEv?*!A&8?g{>5V*CE0n zh2S3)_yG!W9aQt{zC$7U6->|b&CC0SXeZE9jeJmfsD8CO_4cLRrMGi>;}qFNyG69O zPl*07B>WHe=+_;^RIF>UUg!1lQGNfa z{gb|~)Y1gTpxQzCm@V)kfvp1P2s}&RJb}N=pPufm;NAU*J}O(HPswu5ALpE3i*s43=EJQ{cA*ZWmY+J%P^?_(uYtFYw<5zChsb z2)sn##|6GnU?%dvRA4wsdHydF_*(+o1b$NBY=KV-yiDMK71%EDw*|gf;3ouLF7QtT zzC_^X1;%8>%bz6jw?bfxz?TaAf#6>zaH^266!>pKo-c4nV28jj3tS*@hPb{^;2#Tl zk-)zZc$L7f2wW^M20d=S)dIgH@EU=CE$~`_et@Z|#kUf?SPep=uS z0{^GL7*x6a{$1d!1fCHDA#kn0zZAGm;9m%QjlgFFt{3>f1a1)c z1O|(Id_yE3Ut$mXTl#u^JuDwz0O|F%AZ(XsL0?CHo3EvBr)Njd+v#KZ6w%t<)zjPN z?e%i#&+pmm?`>@_s%q=-IlJ1*JAB@tv#rzLCB>ZqPo39K-}bEU3CKuaZ$mG>9@c;_ zBtl?{t;5&qysi7pvAU9QY*!myU4?Jet5LqzzM#K%U%hX)5-Zc6Fw)!Ab~e@R#V462 zh%cw_M+G~T3u?UhluEFw4WD*ZVmUVDjmJ6L+JdHdS66FrU!d0%Ti&&!vD+C4z@~M< z?p9w<&t_l0nuH{XROt&Y-e7Mzz8i`XHTpY!!HC4yD-!W{chz}Om#A*kr62zUe5i*u zXD_}76X@-!LSB5{9v{En)!_~FgsotvR`{Y)@kuMna2-B1gW7F~)JY#QDN^?LRQq7f zu1e&#LvLFCe0%_oCtq*Mmbj*!bJ22wy`oB8dtmp*PT2%>Lbb2K*IN&6cPE(}If1R} zx@DPTkT&~dTa+YHGvU=jaP}3|y*HrsQAu5UWMQQ?Q413)jL6Q`Nrpnr20G4CS=8zc zxc&XUwsNG=c)1jZyW+%R zUU{+f8#?HOI*eV_NIARH8s+BhJAu^Hk&TSAyRy)ZrWS z7-b^$rASaa-5q;;Vrbz_1v8F92zYyXU=mDsk)BK{Bk=~ZoEyz#8LyB#Ft&s{7OC_H z%@JLG*#x+p<|WFh@iJL?^}HzF7EImxK&hk^=J38q)3v`fI%{)xS1e_|Hvb-D7Fv5m z)_eAK@@0pq7t0-A=us>#96@GMl%e~I($2N zd)oawdOh7;z82WPpRaehYM(wJqaAhZgNeo18$(R>FrhfsrI6{@p#TAI(BIRI0b9;) zyls_xJ33mRxTTG(*s#|d0H8XeDNkPtd3*bUK0IpVZ?W6O9AdY_5FP#&*6HhP?F_Ki z7W#%^y+?2VVd&j~MF>!BgU1&Pb_a`;bDUPXoOPZ~WT3lMuSjE@L>PE{ICodMYd!uR zH@=P?MqNF=V6Q|wd|2_(@Uhj~(HFjg$4ZJ`D4?=N&z8n2eABVVhb7J)Z->9Fj9WmJ zwFdT05ZM_JksgoN=WX$O$OeIZOobi6ViRUH&g~v&d9|myYV)QBPqm9x7nM6buqVxp ze6Ex+J2C3`g6i~1l~m?!y+LO<$zZIqyvoC?i%zOtp7PE%z64PQ2Ss99dGM?Ci)h85 zKx4Cqe<38HO`u-##s~9IIE)?XLVHLtd44&)lrQTHEYFDjZ+-eIK@$ovnr}_Rz=Oh zs;I^(ifWvqwb3tH6aA_+QEghZCaO`3)&` z+oIy=c3KtPPOGAqYgKeRt%`1^=ob}5w^LDcI~7H@Q(<&F6-KvHVRSncM7L8xbUPJ9 zFLFV2J4KZgu8V4?!gW#YRJbmxoeE2$+NrQ4s+|f;qS~o&ZB#oIu8nG^!nINDRJb;} zHKH41O$g{Xg3&QqRKVOxF z7i1k~mrhs`&^@5~hQ7v&4Rb#$>+^Sz_fB|m?e@mX8c$V&b5F6|Wv{bW*f-hB><#v{ zt{VGRcb$Kg-L<{3qHqm?2K-awwAZ=p&h^zrMO&(i3%67k723D2uP!XKHz1|~F%5{R za=Bdicbk1ngR5cd8v88`jho6hRp@XnU}d$vwxJGRzqY%|oF(>p*EJ<}`XqRX-Q_H+ z+Eav`&P3a{sIFspm5pv=M3`L0kr?SNR$_#!m|_$+v4DyLOOH`}QpN~cup458*U1ov zZ60?C>yfHwNso#6k`zo^K<;AGiEBE4j(-NFL?qr=PI64ZbEbQf!pR8ec32ed-VhorGFcx#-6UrL>%tTkZV^KP{hI? zs(6H@FtWi{FHzi~(4iNdi}Vc z_#qCniQT}s@N5?_MMm7e3WDp`-4CEi zlXesDVZ;wg5<#Qb|(u{WnUkmg6))^#nY6SB1)>-&(d$ zz#B91dck{j0^Vs8Z+jBs&zDK6EXOxZJbKm`kBWs4$@`3n_h$$uvhzU`Z#$l8Z47IR z*tyfhdj!1733yvfytlzyIRUTO#IvE{+&=;Dd=u{kc#llLn`PoP15cFhySQGhw>!bZ zBR=6n+HbF^J-4C#EDf_FZTmHozC+**D?F+17bcz^`t1r&_Kzn`yh`wvC_Jg}K@+bH zyou^#BbHFkjfBByIf}CwS!kZ0dJ0p zcOr_uzd*5S=QH3nO`z`?6R#STRyslZJ7(hDc`oC>PmwBRIS!k6nP~Lt@8KnHr-`>@ zG2_3xHS4Q1@fPDHT6lymd`Nw{CSDUBGJh(}irCp|;@K{k*v`Ml_^#To13dc#`u@el z8v+lHK86n@$B!?Xcn_e_p9r%e`Mcf3tHY1cZ4>b59XM+K0^t1_aq^Jqt~ZTCP1%t# zl(@1zFE#P5kHY%^oDZx@Z%O+dGVxY| z*FJ&14ioQw@YX0isSl6+8_N3(ctsQN@c6KS_da;*C*a|+ZUb)(empagzIi5IJ9w)7 zWd7bm8lZ;v6%Rzw_XiVi6uf4{$wSufC?ZsS1rD@(NkS;o#bfaXUNd+TmE$WW-u>WZ zDEef&_nLUaQFu3*c#lNk?J)740PjUAm^fs*8-dmG4iz%~yK*z{q^Vzqz{AuPKBQf~ zY2v*L9;VFjA$eaAJSkWJQ?aq_Hv@#XK%IC+_S;?sA3oV>+*<7-#<$H~j= zk5Av7aq_JD;w$f+;KfsK88^nqyA!;4`kNI4=b<>-{hi>&l|LjJkG>)B;?b9RbA0{s z0q}<6D96fM;!F3DIC(4aa;tdkd@N3$9Y%>q-!ORiKYTZ*a`e4BQ6tvd%&AT1aVlutNRa50@L1MCiKlw zc-NSC+rg9R&Q*8?CSE{E_Z)?{(8N0mUY$sn+LN?Pii!7{lI}c(_YNviZCCVCr%ItO zOX0n0;#GoIAb1ND-t#72KX_EH)K1S;cqdJ~0q`jQ#9OHF=o<)X{)QCZB84|-;tebL zJ5S+tnRuh%oq?RvJzwF~nRuu1o(`G63l!dZ6K@ne*)NwUJh~sPmcx2FqVGb5H^;R}VF{dA=LU=| zBLk|P2NfQT3o?H{GVzAN8-$$7u|nZJY~tnqYsAjD)ezQq(8Q|*Z%F9Ft%fkK)x>)d zynex3sqiXHyt*Gm@(0&@SfAa*dl5XTFJIv$n|O6kMatn&c)!Kuq}ne4o@{>w3hz56 zUO#xpASe43Dm?mzhN{o@!$|!WDZE=vyaMoKx~ml4P7|*Lync(GZn47KWa1tFQDmH4 zr|{^Va%%p@!ISB(S9s@{cJ$#Jbh z;nCtqwR1aoHpnS|E`|3hY^w4G!IR~6E4*h+yrYV~jSBDECf*a^$^2C+yib~Vqe{9} z3U9!~3xP-dg358V!fQA2GM|Z*cay@SXKZEx%cDTyRU=Z?2VVbU;MFO-8ij|~G8uRQ zg|}JZ;k7{q-jKqpRe1l6b2Wd*6<(df`wtUu6g+9?YZTtICf;ibuU_GiJ=JvCPa^hf zPOk8B~^sX2eA6<%u$ z-l)QBi@^&iJYNjn8HKka29G@#vER-ZyiA4H9)o97c>Wl?0)@9L2Cr1%-4KIUr|>#r z@R}7~XAE9I;dRB}4Jf?s7`!2c7l^?dR(QK(@Qy3IU<}@Ah1U~&V@WAH)>uP+Ag zjKbR!gGVp*mHn5-o@o6jQ{nZ;;Mo-3z8Jg$g?D2NUa7*nDF&}j;q8yXYgTwS$KVAN z-YqeB0}Ah>F?d4?Zy*M5Sm7Or!8@+-4#wb}R(Q9@;EgK0Los+Eg?C#F-Wi2=I0ldX zEYkjNkHO1Scr-6XYo|7acSj6ffx~jPjlnyv@a~JjJFW2GdXHLfqYCf-7`%|egR4BMzB39BF7T*4dI(RB zf1irM%T#zrWAJPW@6$1O1qu%?=BW8ARd}C`!K+hv55(X#E4B* z9oItB3h$8^yk>>>&oOubh4+mZya9#x%^18Pg?Bs# zZ&=}t#NZuQc#p>5omO~{#o&!9yc02aA%*vN4Bi=q_pKN_`WQnd-x-e;7JB)0kdn1_E=-gjQYFa6FHLIjdWA$S2PdG8Fvm%by1j_%&;O zx5K6%g~e-2Ry6n`Fll!xi#dVafZGduN&Se`fPdKllakW*_Nv6iYC0_xwofjOIda8c8_c8CQofe)n?DOq9)`${QKD`KdbHT zq+i_fhK>BR;eDK4Z5#eEGSr3)wFde&gn!J7pY|fk8))s>;P1k_{q}YTZ?NUn7T~WJ zuSA9{5cJ_K!ySEXzNsxkXN#{5M#Ha{cjmX-@~U!dO*!T39h-dq4$q#|4%nUk%FCNX zZklp(zygDQ9PN-lj;0g*INI^yKaQT%#SY4CUN@TDByu2?I9fY<{0UOk*4>&YP5KYY z6H`JTy>>c58Pjz+=#|lZXrPIxfE{?DDBdKRpbScF4!6tMxTW6Zsoqvqm)MLNR69EM z`U82q`|j|zCfFpgQsN0uU%~Wp;_b{ckfg&KY@M-m9gWWVjjl#dLu1WM6 zUHp%iBbmXoChzIaYR|r@98pZ&UWZ6>CYq|FCy2FIB8TD+9d{^6hd1D#iDX;5gVR0C z^5Rmu4u4?Jbay&K;%jEY;$qP^gGtZCWXJ6;iq6w_1h6WbNh5Umdi^_QJOhqE0Na-7 zA8uq-a4S$I9D(i*Z?LDQVNSbbNb*Px1K?yQ+Q(**DZo*mu6&M7jDRPVqHHq}Waek&lWA@Q2Kyj|V= zornoG3Z~|s?$#T8iSD00z1>0Y&IIi}+Pw){wm^|1p~^%tJ>C|4<;u&w`-!O_*$)z< zE!dkV4=`zR1bh1vmoL&L9UE`#5!pWNVjvRMEBI0LhPy>EnU7z`hKFAMMh6@4KCFf zD^lhjPX$b&-5pThF_jfd33PUMO=S_NL*g6NQ<=n0e8qbz_2UyYQ>mVR@MbC#zz4Ch z$(ZCeJ$64JN5E7Tf%H4JRTq{_OCpYjx>fnBrZ1^U-h%n?s^O;NrCO6;IF;qPaN3c1R_@57D`*DDfH{cr2-pK2tmesuR4LiI~A5 zodx2lv?<8DDFs^n6|7scIR<|*OJA>lvd&^-Kk;yl;pQ^QZTEz_r=q>+xlXKs z_jY&_Hk^?zhqte{9bM4h>V*?AQH}X*&50iBCP*RihIX|21MR*bK8>DG!-Ta?iBTfj zr@|l!UFh>l)b|ckVv0o1FFe0e>Exd>iVQ?X#XIoD_=GmNaF%=adfI$F_^{j*t9Nwo z?I`M>q~AK4dBTODR93A{a4P)y=ERzZtDKq!Zcq((oj+kaWW7n6^iTG=I&+ok>U+9( z^iJBh7gP0A8eexNPDP8+HBVhDcNh|I(C1h8dMEn`GoY#kfXi2Hjz9eJ%Sv|mW54SMfQ;FoxlEZ>AbxU%I{RJgWQmAgEy8fQ5W zzHHvm;Hq!*)HG}ajQp;F?oO@3Px>Ukp{{BJ98VSMPiT0A$5T`0f*uac*V95oDy^>C zs$IARSW#Z) zDX*-m^N`L>HB-kTNZ+LS9%@-caq_>f$t5RXnyp8Ig%KR#eq`YFrHs&W)}H!E@Jb@zBT9 zU7HOR>vrQQfQl`s@W}Og3*grY`_#LtUCstqq}=?be7F*w_2tF979+K4#1*avE*BYW ztlzv*RWDk}s&&^@AqmlVBh3XZCz82_YL^Su8_CL9w`n1w*0j}Gy~VWwKZWK8BGGWT z(cSo>yr%&sA|2|p5c)mluodg7B6b!TcW!o8*KRb{SlzZ7SwjYG(2nOTJT=b7N)!Oq zlh@hT(d%#7*X#4Nw&Qtd#Iywcz8#)6zjr4+VdbY^CFXT?V^c!EhV|fQD!sl=PrJ|C zhL6@lM4x33`q958@jF?4;E(#X+sMyy`ERl{{3f{>e;?pT;y)|CjA{GlX3b$~EX|Up zr6pODttr-2Yns(+on=k8&Q8m)&P^N8(hg{82eq_YwX{Q8+HG3eVJ+=;%{r)A@6fDA zH0#GS>z$hQF3ozkW~KKjE%HvX;l+C~KQ0i?dhm&tl8l0{?s5YSYGdSl@uMK88eYFnqXQ&R;{zv(l&i<#C zpUx-W2CV~{^?+tQs9A5-tcNt~ZJPD4W{oxeWFTF6EXPSR{-$%x%R+k6<~TJRhm#^O znZ5Y|y}vhdSeOxOYyfg9gMMfxc@mdXJJXLOlRTNrBXyE&lBbw(D(BPKr5~v#c^a3~ z*rFe4Cb`vwXPI!i3D0IXit^KYfs)u<)~47a32!%{_Yun@2`|H??}*AH30EvN;AA$> zfK%AJH0g;W3136}qXDO}UmCELJ!QbN7`;bW9!V^n-DkkF*`Fe>V*%~W55^R1Ve=Th zM^_#emc>42!1LLy2E2gz4ftGEYrqTHY6D)xE->K5OnE&FtaqN_TdWp#4#Vrk!iNQK z&^av-*?*okm+gT4NF~jkS(=5_2uy7-OVe11z|`ilv?OK|nA%vDmdxf0O!I!0mcrhL zy+|LmsVps(y)H1dp)4(p{Yqf{dMo>pz%+McX|vdI15Ri63ru}1OPkH;T}<-Gf{flZ zCJ(~*Nq~?rz3WgOgu^fFK_uZeDHM2%374DjWhR_s!V67UsVK z&lebtjbD$6jLR<(_(CYn$2vS8PcsGmE%b9BmXB3*ueSwZyF3f}I`Z3mEqyyZ{FiYo z9})ii)|T?x8oW8Dw;m5$`nz!BtE_KFga1aKK_2W0Z1(Le@9yft*4HeVFxt1f!rSXL zQhmE8rtb7(6A*0h1^4)ZhAWUCV`_K;yT;q^4thI%XXO#Hi3R$*Wbj&#@}RHH-wWd? zC2#F)tMK=LqL-{^Une&k-a>@T(~ToV&Qf?>{k7@U{ z-ca8!4N$+`Q(o_?sA|NPwYG-A8G~Ki&S1c!HV}JBG{NdqHaMbWM)S{GHaCaPpr zR7pWJN#WY4lH#b6LRLnvp>l>hmfhZ12}?IP_Y~V*_BwloeUrV+-e6zrscT>M17aEw(}0*Nm&=8Jx7oKe zxEi*uvES0rxT$;E zIw!4WmX@A6&yuAr&=y%1Th6nbZ@Iv-#IiIs$6~jf0~P3P%#wzaEOp)kj(HS;OnjOf z>7e)7(RxH4G#Aowu8BvPruk4F$>QXFgsMK8^D!lc56KH5M&&&MoEv88@2(_BYbcfX z0x->|@{svEfe4is0;W95L#F#VM5sJF0H*rzA$jy(V3pSdfGIY7$aI4y9)0J7)&ug8 zyzPik_0e}ZCgM?ERNhelT5rfh>hmC;c=C7zK<1s|O*XN`*)rb%KW_B|l2B zZjm}DLY`xJU`V$Dy#4$N{U52%%sU+??+UEL2IA27J@5|2!7D9|Pv7Y{d8N+y(tQfN zc2^P&0rCW)L(Uj{?fM-Lc79o!I2UNe*9`nIdUd_o~*rZ=Q+wvcjWuBySw&s=imjqjX3gwKd6m*~EKW(MKG~`-zG7zQRjUc*jk=z~jtLZ){CS+W!MkeZ6<3U;*qRUI+}OJ7y#AwikjB81^fbqx%zT`%{7bH+v!v`K9@6`K(PYX|UN+(qu%Gi+9=e24FMEjdni?K>X?NH4vy*M73}txr1h z#9MO%scf!o?sKCdpL~;@Q!y&9ti&62|9;Q#U~+EBSRgfZuB|`w zr27o&HB{iX?X`V$nVaRT<7uWKjf;`SBhCdP4U4V)z_Gytk7ixH@vVY7%ExQX!`zCc z7hUx3z`M-$;7!^J%cv!rg;@4;ud@fWq04T}?jIJmvV>~SSY{yyf28))E(}8UNOhm% z9zxy9TDWth`R4YM!~V*XW$tyNZc^Myd8uRU;^dI!Vhw*Rq+OgV-VZ#EI@XrUTF!Wk zooc=#IX8K<^sVQebLD%5QR^4<&pv5chTJVX&)vF9Zvh!LTi@CB%J8n_@h4?IsSQQ+ zzdRDr|E6>Hhv;wFb?+Uv8_8OvGZ5B^a(mF8?GL)yB@em3$Zb9V8!QO7?~ak*?JvIC zwkxasn)7pxSl-jvfr`+6mTP$>{Y^_cwQ`s1wU@qw`n_g!vrGHcm;W>?6=hrgt@qx2 zhh4lRtmlytx+?1x+pdBNTT5tv_L0i+>|KLpv!4Im{+uJWU6%KNzCEMv^^ z%Q3ur`U`rct9>$K#C8Nd)%N}$`FpH4Qd>CJeboKRxNWEqZ-5rqBs-sWAD9&&oStoum&yf8dU92!|Yl2OUpOP9>9vNrqnU=%n~y2N%c(pu9( z>{RXBNx|d?^)}5;>2Kb~JFrFDhu)0??mO@vYrUtYxC5DWCy(v3Q=Zp__FW1%+Md`C*IHkOL(lS0jRSaR8zs!8h6 zuT66^N9CBsc5Jr`TzU1}F|sIYCo5l@y;NBAA=q$U`{2ffTt@KAs(GP7XzwWc`SpsKrnn44_>|OZ8`- zK6z}=lDl9m_oGhHLW)Q9JjocHiyoH0mzS{@R*bZ!PFTt!?ByLJi=HPedh8@w)B$^v z^;n2(DX)y^tl>JZ=GIttmNi!HwoPaaqaNFL7aMG_3~feQ{#5okCd(VIEilvT zxc&6^#x?fBc<$+z_Ls-41xGjPy;;ugR4*%q#Z~_bac@{nB>5r4H#~=|uyN zCJiMWJ?OH$^2&I|@U`LAS@9T+NQ=kx7MgM#TJL#yJac%3JNYQ}x)k@Ek<6nQ>ACGK z{p;PjMki)n+mYv9w_L-92G3Y5mt!v1CB-4q$i`m$V}B-TNOk9*T<>;@>z@1LFJ8A~ zmAI2XOR{A5QzK`mHr$Kv0Ssjy$vldA{anqYKRFc9#!h|dk9n_uPOBj5B0Mw>Er1~2T(&Sr_!Cltv-j>GP)}DIX*8eQbxOD810gC z(?*jq7OfA@3;s}Uzbu=@yu#{9)>l|1Ua2GVJtg!JiI={TDY9n!gAaX zWWL77{oXOMgdFLy8eVzBsLtUl(f?sK3#~uz#rpH3EBdt@U3RTu9<3ie@jvN|=75yk zO=Gh|cZzjj^DayOD!07mN~{$0`BlzeG*_G}=88c+SJ3P$r8HaUsinC;Kzlm2dr3&g z1t;ekM*GNEU+a`#?2xmp)W%NHy5aA)QoE4jIogNkRz4;l#ki#RZ?Zu7=m#gie1KN) zFT8H$^(a^H7tLD|9;4b1TyS-vJFA(KBi@3{;^?oRr~hGcV~uc+Qw)2(zh;| zCs(?*U8CcfL-&s_8J4?>+BbGtXcT&Sqn=}0=gItvHZ8u{0eMbj-?QkX-p**;q_H*) z<sLSF3mm2PW@bIoANs(Hr|WU+?R|*zDPo;N4_>f`#*gy(Jf7-yO~yb|ChaY0c`5H z^2SHkvMdW@{NRlN*_dDwY}v*(hCr|^OW482j%^a!kjk7o9^Olzcx+6R_*oyNp|a`EOnb~`JXd)Mw)w(gov-~ z?Emv5X6|q1chAh6IrF$z(wx2%w7w^X4SDmSoq1IIf792@YXd3rPHawl1?;|xck0p|;(c^q_Vqq%@IKs^-OTo7d=`j%b8#T9KXtlcC~ z62O^;jsaTFr~CMRKIcAh|ClN4OlJmnruCPf>EqVO$Bg;DBH9nUWn|T-N9Akmi;z8{ zPZ+Wsp7>zZAbD%plg#RWTL}AkDbMipU+$exclM{=Y?x(yc@9m@eI>9rgFg8z{WpB_ zIr;9}V?Q_@*n6Uqy!xBHVAJ^tuOH6lHRA6VZlU#oXOKk!Ki-x2ZaOiy;=T$4A0KEJ zU=J(EO$({khwizWH~aiIjzAAcBlpPj@zreXk9}LK1RGCs%%V2FD=VqsSFe$?@KS9{;ORv#)3Z@47Rzs;%e5(`Mx9t%2ZCPi2 zn$3M3@m*W&_x@*;d$C__|4;c6!WV(?73mL%BO$2Gv=^Zc5Bo@YV!!0UgH5Ns2zB)i z=J&RHdh&M{=eN@ziuNl$wh#JAn)V{3iMd(AIw(@P6Pdh{royp8{I2>a! zBiX7z+te!!KY#MtlPM?J+_3+zQzKs2Fh9c5;+)Lbl{f80C}y92H*T8KUWDGS|HSvH zYwp5mf=Ae~ol{Ipnd~_S-9>5g`~C?PJr#@Hv=)b6=#z!4}s{UV=vB?Rp2D6vf{+4lO0#O^Ji+9kC;*f1kK_H!Wq_ zi;(R4mu_dkzYp#aG+q>N%rVKllsJ{Z&l8Qa_&Dl_w*VK)IJH81$f8jo7%J&AxrF^k%m->M@Tc{oY<3zQslH3A?LIgp=jUdQkl!N7a`eRro9M-{1a*O zQGLkJ=o$114@eqMe6)a|M;@)FQ>E0nC?#0uxF}@Wi%`%dk4tNxD$J*zW!j4n9_}UV zvgxP^>V4Xa5I*P2I#GG~nf4;2(hPG@6qkus{%SjO#iQv0p^!Z7MJViV2vl1EuCi$_ zLepM^=zCB)KTdlQ^7h`qn}lgELP0k>;>XoN=P}b>gq+h}gwUPTv=<@fnMw3X^uO1O z5c~wT4S$BLacBW~@%GGtCm{0h09;JAN19w-IK=-Bf0dd31IY)ChmsB(h7*tIk0v~b zzIg~~fxmd`A`8mk0S;@_z&p#0dxuKl6@WMg{#xK~GTV)(%TC-Y&5gHP)cpsc4rrHC zp$Bn1e2vy&*8$VPx~Qe~n0yazX08Z`m(VdW z^|~mTqOmFN9q@Xx_YPwDOQxWF(H_U4{HdNF@Z|BSsKY8KmxuS@qB3*$wR<>grq5-v zX6~+>F)4eRJYFG)%jx*&4_Bw1(&saGw*V*JYl#`k;6Xoy^M;vM0%9Yr$F2iO2Mvc3 z59@~$j!fQOTU^)Wu{(KQP{nbJWlzPJ5%+n&rgivWJojvax>&(8YT`ltp@hSeXAk0B zj%)i=t|jIvC||Tma6B;OeSn@8Cc6*BF>wXTugsjfXCKiX%cnpWqCHenT`2dukfaLp z1ZOAcJ9V~z(ThYnU~GvTbVQjisc?b{gYQtdA7@KB=vDcNDr}&9oY~}HP~|77u#xh& zaXNTtQPwY+=HtvDhh$a0iRPo#$ibw_pP|Ajl>ZQ?lN43{OjUU^Rr#qjAD;l^kgCd` zMe}iIE{9pF{4^C#SK$nL|2V%LJW46`ktxd$=4Yz%XRGiW%Ez6M9OkI<=hA%KnaE+T zDt{i$#~p(l=Be`M(|mkmA&2>@`~@n!kn-_~Rt^hQ`HNIIONAHH`|+)W92Tqcm(YBC zqbY|as{ExYY*yiHdjG%k+ex-6KZoYyn<_cvsPdPo@|O_<8;>}hUWuK2lllLFkTljJO{8IuJKO?N8kP#oo}(ABh};=3S2{8P~h9i6AFAY8ByR{ z$Swt5MYbz&KB-jT0+Oe|7LuyKh2%0;G+4hP@~Q$ClXD8ZntV-xOUOeCTuOWjTt+^m zzxXz-!6d31a>_@-qd#l{~M&>&f3J@CI^3fo~(d3cQhQRp1J; zUV&GV90j%#qXJiw|B}S|*~m{6xQcvRf$ikD0z1ed1>Qu;VZ7pWi)*F?>*XyB7}V*1iX5{t~i=<>Mzw5?M-CDCC*Rrx+jC7zx&w zB$khBiUgniyanSGL{oo%5?MyPtUu5U)1?(;2Vf8ZTp9l-lUEKHeUty3VKc=N`Dcc! zDNZ2g7)Jf0Z}PuY;6(C8hJQ`-4dfw)D=AJQA7ywO#YVD&VYCPIO-U@%s;Qf|DeK;tMF%3c)tqYr^5HD zuuFwMq{0mZ_g6vb%^ac4DNjlAZ z!GB-&7isz@d90ZLW4%l-fxTi3d=O1cXBq$7aEMuloN(h#AtQRzh+y2IZj7 zUehy-2j|mczUf(cy*7P|5S%wm-z4P27=K6hIchpb$is*s{{+T=PsmA(PZ9D{jDHM1 z1|gRIn#qUyVtJ-VLiNY-j`!m{VHza_+zrz9!0;s4K1Dt_@1*Vg0jnqI3!h9;U+pY@ zlEvc?i+aO1e5UV$e^QL0JSqobdLQWR0H%MD)$=)do-_R&9J^3EZCijbEv28{Ya{$-4T|7VOr4z3fZ&$$>w zyK%fpUxsVUhw`ajpxivfAdl7q?k__O<j3Iv&#*n@qVyqu56SRIjo{yO8^}DRTfY)O>6yCt((|!Pb zj39>oc!cFcQ)vBOVDT8sr~Lq#a}o3Yfcs}NoQ3fz*&j9b&z*?BL`VQN4mbI}t{b-*#7z1u(aXZGKpPd-P{kt%Rc5Y|))B1w2 z1AuY96E*B7IKQmvmU}7ipNS3rEHw zw@3OUTc189w?_h{R-pV(%f8d4&&YNm`Q`RWA7=P|hVNl`2g7$W+{rK~6)uV7VfZ5q z?_}7?@VyLgWf(dE{wGp1!`%#jh~XZFw=vwy@Lddh83rSy<@YgM&9IN*8ixBBzMbI# zhBq_3i{V;^cQaha@F2rm7~aEhJ;PwMv^@NuOZ(_KeVF$x*hBq(_gOkd$L8ld1 z8|w;Oe!tJtiibavf_}fx?`nm(lVADVT?Os#)`1;PdMYI;z=XEmo_>G3%kQGlQ{Zg& zbi3;Z{7r7(F1N4B(+`9mcbi|8-Qezl-vaMwbocQLxU3Sy*gD;9_cjmSG2k9>a|%ss z9JKk|?H)f=5z6-z)E2k7LdDp3@sgD3ww?}=4+W{1kfP++NG=fTRM^qgySu(eL7_<<9g4Inp)6EEs4&!|t-D>Bz)^jj zv&nNG*QyPn+u!K!c6oZBODYFCRJo1)-YxDOtm%RfNDq^!=tdL{9UG3e!_)6~`(!f_ zgx0`GtpbEbV9S*$q3#yb(O?AQ=-<;#?N_$VHu%Y@y9Xq@eBI7n9d2i*+tu#&5ir;) zH`Jrs)8n>vz(%vy)0&$LRUUBn`*U-F-Q{UTk5OLdR!=9paLF<4Y?_4~Enm3hX2}S; zoTfte$`{aKG=X-Od<7lV;PUmmqPPMD2y(|1pHcz{AudkT21+R(I>2kYTJ&|rMiy5XSzcig zfzfK~?dEH$zrok*?``Yt3JzDlVwhJBc)HrH!JSlYZgX{=v!=P#D^||dN*H3Kgw&O9x+u=MZr_b%}#f#2?*6jnW*K^ahUH*yncKAuXySvrd>W6cn zU@;6P_jYfG{S5qa$_h_mgs##=2M<8RR$Ne6M)bB`pWi*0UsqDl;U$SdL<}>N>XIds zAzhat&6eir=Ia*d7U~x1vUE!fIl5fkED!-pCDA3pMFzYrh%G!P$?u2_j9vmUzBAxK z&n_NU@!-*wm^lez$fn^lDjqzl(|0W_JILFw;=KZdJWhg`m%CHNBhWH@*TDlXcdLqL z2HqGaLCodZRJ=66l>!eS4FxJ*GvF4MhY^=ISH*h@FuV>32F@FY`oRD6y(MPi=a%mU zSs{6sR6IQhz;`k{fOr~SQ}MEZ_b?|x%**{J74IZu!0U)$;JoKlJY%B#&Xp56@1%-X z0)|roX*_V=BPyOB%yK>_LCo86M8$guc;WgNKS#o1xSi7PF<=4Vk7pB}w70)~a-i3wXm8p2EQs5m~7+$uDS20t5XRK~7mVvi(y<7%f zE+;|E+wo_(7J2hi<#(o>%Jp|q#rqNPaySWMF7LdG_XhBwDZ#*b&!~9gz#GPju)xcG z46sRzF_O>%ik>VH&^wg^Cvd-T`5P=Bg}bzftR}i61Z&4`v>3+;ROpkPt7Z9kiRQ&J>K_#cYu>1jwH_k?;iaz@V*Va zSmfQ-7#r_i076VyWMquz2i^MIP{Ck_YdqW8u9Dyx|ziZH0H$vB>)^ z@M4kI1Mk9Pk@pVphGM9n4;Hsrc<%r&mU4H&yZl&qe+Hho{zkIrPr_#tBQdmN34BHo zi~hbABd=h4YK69_*69FYZ>I- zq2fIPJQ$jkhkF_>Z=;HL8F;)Muw@MLZdUR1-jH6fd@c{a8zbs3SKwhf=Uvt*c~!v6 zgM4fUuA7|q8x^k$c)Yzc1m4e7Jij0h_fK5jiz?nDLjAxTg1l!`yyt*71o>D$*lGoN zPpWw9`@l9BZ8pfp<{F`!(<|AInV_cmpclW#Bb19&BZT^>eFuRlbn@ zWeU6xsd(Fg*TUq@7I?KP-gAPyIRfuC74Ij4Jbdor{ZXvqmGsNsy}|a*6L^bNyeENI z4f)8!@x&crU4VwZP;3nYiD+wo<%7VGyD;PH6_pW`_1sEYR%@Ob@}3OxA8St0K|;1xm|mYXf` zT2;JN@L4!7H%H*vRJ45@KSb# z}PH-YCZ22ctufo4+*^D zD7;4m-s&j4Cj}nbNTm8bC-6$6@Lm#lWl?yq3%oT^cy9^3@+iFb1m4;xyp-J``&$=< zmnHCSjlx?c@YYA+trvLkb&ZI6t`&HaR%EG#R7wBoYDB8VWgnC`dNI&?ZN3HRlBbZ^cJxd_jU5E5}- z!CmEM*eRqvEjea5NcQ4@?oBI6ug&e$zd1xII**+}JdGn7#LqTys8qC$>Zkeko$-M>%fuH?D>I(qMNhR6El{A`8` zA0Ro&fvdE ztFh;={;nn~5j0hiwXgE(l|6q)%$J4!!#-LN!24&>K0pl(LLY&=AeMV+A2F~LxtCD; zC^G>4^xr{=*Oyl@d?WG-pH6h-QQOixQce-`@qLBQr#)=~Td2u`TIzm8tsx1lL2e@f zEBkI(d(b;(I>;>_J5RDd4ehm(+o^_NqcuqK`bV*^tOh&Pp9J| zEqIq~DI`tr!``$SWJ@v3_3lGd%D7`K_d~y0NfE^)&F}ys*-}WF4SL8*Zf4~lr06Dw zzSk?geZ4W3X@eJdztgb|#%2P=C6-1#}dr@|62V zD${6+iKSHR96EB0jrBy9CeJEKD_;To8K-5S?JT0QWm}YGGfC9;NE%AwvqmCIlkG8S z@peXCz5D_sDfhds^>+AHc2BzgF?it?4t4<19nY>ffv) zV1u2yH)XkoQA|l>DKHC}--8y>dA?1akGx>Vsg5FrEt|bwu;u#8C%hk zOEP;mp#=Ca-rL&)-@aRChEHV82t8eHpScu1;583;;S*=KxyYQ?ir`UTWe~owxa{|{_WSe`P>e54}NML^}}pfAfYzxZZCYtb;AdtI_*%MHt)cO;HT&C zSvn-Sylwp(JU#I3$KAcYd(HXvh4ANxukS*h*XIV8=UoHs?)bI65_8jn*x!LXMa_%a%fX?yHX4}qcvppwgLWkr}=w|LxSrZ|aw(fq9M!tW+tA$pQ zs4obOgt>RYpx0EE1;3a(00yds%i#{U%Rk_AYg9ol&El|Io3}RFowaw>G-z8=;vC!RA(SW|@}r@~Y%{XW=tP3ow`A}tg4nRUaH z0WG$z*EiYIY_MF5$GfX!Ds+vF#=^^{qHwn9o5G^$aGUD#Ene7_O=Tr|+nub~6*Q^`GX7O#o>&uf-jp|@xwEb(p%zSD`LrciwRHAPFoA7^Xb z6zm^=m)2vSNws+3?H~Mx!>6(SgW`L%-h&E~=^LN;sm9yo@^|$5y5po8E*>3M#=8jZ z9|d?fXfL_P)zeFVg`}}kU}^5}ZM)a4_4w@f_xfBrGvbZNA00YMf`g|TKjU9E89 zgp0n}*QSH`IM7C#&)=)jREd%-KL4P0^+IXecv!tD&@0XH#=kyv&Pt2v{1L0f*Q0kEOpIKK9dayzr8sVBzw*b+GLAba>$B!7hz< zDcA2REeu18$GedKY4OL=6YG=kGPQPIF4k9*N1q7QX34ER?g_s8i7vlwf_w1mNbile z_^t`=4zFAP?%tlbm?bM12V_qNd~aeRvr+U$?10nF;witg%@a@YU2x7>T!%ons|Ox3 zCis{hy$kR~Ks;Dk~_8XS@2_HM3+q zwN9(5`ur1pr61BU%F=qxr84Crv}`h*$kM&KSbK>U_*&8cp1KzY(VBcRsO&9S4Ho{g zfPE`14s}4J58_}h1Afm$Ulyx0PbCJ;WrC00VP(g|UgTP9tKi*T zF3qMhlx1-Z_&Z?;dfHs@5>YE-zE-l*@WfwJ5jrWFBCccT#Y#$qv2%qoucjdRW;`4&0`t2X^!Y``YT-rUX(MpHJ#$|{K z;$^$kR40D;8Jb3YNPplovC3&s8!Ey=e`n|P`g%LyS9lX_U)b|s&G}VT_B(5AcBj40 zY6Ap^mNzxo8=IYVO`8BVTN^joo8bd6`svha_&FcvH#O93fEQ0y;!kL3g40=7X$LtJ zsPD&(2p3vgv)N9$A)yWMIe5*M`mN34&7qHvfrzr3Ynz-+)z%^>Ryg#Da&PNS_>Eym zKC3h&IGwh-rkW-vN)lw$Rh3c^)lGJ2p|!DjYl9Pxo3~^6rGWQ;TLO0e4*IVzbX{v8@Zr#EPqqSw?pgU`Hr7u!ULmF8W+Z!ESo)mrbgQyOTMeQg0N!V7Dzs;PI@*_)cIo9s=D z=V;jK!~?DETNEAZaKH)qRa>FML-)%TK<{JvX|&hctxfh&yP;nJa6_;*+Dd3I@`So7 zC9blAn}ARO&5c_&iQ0|!hiLJOd)5EAImifrqu!WkG#HbNMq{$kWSo(dVoWs-NydGW@d3%WUosw$j0Yv-A<1}HG7d||Ba-o` zWPDIEJ|r1GAsIg@89yZ{&ws_UK>q()CZ6-e1NwcnW`6WQ;z9kPgu~J&b<%#5HIuyX zgBO2jodKj4_=~sR@!TsOX2XRw^J51R4nkevx&{7jto)=QDQTaS^njGKUrIV4B^{KK z4oOMT`W?&U0neDSW`6ttmfix_lUX*NU-tgXzHxiU@_4{Ap%r!j87=U4W9`53I*7X8 z4&_Z|`|-R&9`G!o7Wj*Id&M&GJfs^hb7J<5XJSpJj>WN!*VfFv2lNLM4n-SZMx9YI z#$is!vz;be-#FJ!roP4T)HumyPu#X|eEtyUFg#CEJ%>S(BJ4mTU_npbzS=HeJmJa( z81*Ix9Z}{>Dx5(1Rh&)|RQY@#InvZ)CIT%#=NvixLRlZS$ zlPMq9I5{M%@=Y{9ipN%nU^TgLn6lOHSa0`m6?ypViBfftec z6*!CFxw<^);N;fL3cQ3ADezJqs{F4+YL4|ER#rs9$cLq$6|4=Qw~^ z2c9YRD)4gBroeMa4JZn$fOANOq$7n46T>)1WJr4Q-_U<}Kh6mm zQX=^!!#D?INCxtP0wlNnMfNnse*@(gJf;eIM`3}#4aMTVjj{VFEls6 zIm>{{cqYVnrge@A&sAZR%|j0Gn*m5A@|oMxHu+3z6CBWp^~ZG78>Zv z0~^y(PslTaU3x7}+5Kv4KzWdfXH=uyn=l5sR36-qXThR8)Vl-+s#ahO z=Ov=v5mR{((|SUTXYiUJlVd!a+jNKQ7X{^`9#B5&8Sn4J*v9<9Lg5sHa=S2n1;e0R zikCCIhT%Mh%NbtD@LGnU@>CvlI=vqb@}>AzhT*_oiq|s?jiwk5KBas(fR|!8;FMxG zXqRF*$dqCW!xap}fw(l^%5W~jl?-Py49cPRFJl-E3Z)p0=6(9Zg%=IXeP_sRrR=9x zkxu<%hD(>dWY$pMossjI2hYd^aHL5h4c4MJWFR;%SkPAHW_4 z{wKKi!2sJPx}Tu{{?W6G6Dr;aq%Y(oh+*4C!>3ieCn2?#Lmuw0c;Gyj zikAl%|9IfM8WpbrD%8M95OW^hi?{Rk9*@9FQ}M=tH(QX$+l%!U<>_HBjXLCkm-`Dy z5P9XmtHJ~pIPZsmMc!V>XyGJ?Iqw@P-s_MNPS3+CUS6WSPvs)HJlv~^<$5FVP^TjA z8Q{(5!XV~)fo-UQcOH0Vfyc|m8$@|yzzgOH^2UIKJRUBqc>ErGRuy^Uz&i|kS{``b zFBuQIfrg<<oDxg9dw~~={>EbDwQq{8+yL-~VrWN8b!_$f3GiZRZv#BH#=?6E zc(LfE0vr&8>yMv_(Pl0!=DlU z9#`?60v@I#56j`aPpEj$3G#4kao#Q!?LEy@I@1g1izH z?*Q;{T|m8{zIi*Asd$eF<<5!1ds5)xdy`1=o)dWUqVQf4cv#O!@?IBs3!?De5_q^T ziX`tnfww3MF9lvUay!k6!pjnPi=*&X2|UpUmbyRI3p~*WmYP>9@XS%l-7fI5qwu-} zUQQI=UV(>oilpa<1YT|w-Xj8UxxmA|PJllio&+Ag+vEYJ3mVelUy=8GGa>(sm12SO zFb1BNrw_w>!w9}zyf@<8Wp!z3X|Wl@^?kdL0a|*{x64E12>4jht<;T5W)dLgiZ>o0 z=T29^R?E8y{SBlzS{Cm+Eql)(i_zDB8K_2jpxrqzyr8{pC;hC2@ZUkXGzi>Db?C zb{yN}WnNg|@zIOl8It9Zvoo2rd_kHK(#}z7pYJm;Y3R*mrQ>@bYb1;;^fxodA>}U} zJus%zksR6c43}Pi`OAIWO9MHJ(uoIKupwQPuJaT+hTn(muc>5LP}y|~+19YK^Dm9t zhNxDv9J9xDi$0Ym6|5aK4<3Xz-0FZ=>?0M_%LzHVfNH7!^2xq=L7mTrv>{rSD?Njy z<_u!*taa@7RDjO$diWGMn*uTRS^ed|5B5&ZU=n2}bRzTli{txcE9U)!$V>hBfWMrx zAx(a}FVyR_pJ)vRf~{RSh&}Z^Xz#WClz-`}bD!fV^b~FHjD!(vb!xJdpEx?JKsTy0 z8^B`qfmC{p*1O-)p4FZOtdAmd(;K=K6fM$?B^k-tG$;vM^`pL7L9NVyG_n(W_tWXg zEY(o`<4d|{$mdDt`Em2Pn;myJsvQYm3P7u`eg)gf+Z?Vx7KiB%ECcn5R$l=%sCehA z>D=mb2Ehjo^nfjbUO@--51w4&nEwd2XgJL@Le8#&J5b8=>9+*iu>xg7JL)h0qHj4% z)fMDlV7j;)@79fNG(r3<{LM&4UCuC4jT($AJ@V(^3v4q46myBt; zCmy?Ko<%{EaFfxekRU4{A~QBeX}rq9WCZ0am@JOh0_woj~c{-wXv?{my@jDRg(7%x2j%-hl| z+vxqPaxR!*ew0pNd5Ml}bDp=wKvFxsFZ|)fG+nmt%?fhDn*$bfF^hVA$qr->ho600H%l5ttHF_`8zGi%M2oV=bcqoEZT%ZN zP13Q7D*c-#-Eieyqlsfu@^XA-GB!&`R@z2M`mDT)mw$1QjBPZgZrnI`@y2C07jN9S zv7F?9Pn(2esE1nvO^(|Ek%wixI0=~(MH zKTggi91Cnp3Nr@Kw&eNa2+VIw9Omp!=Ao*F`S&q?3D! zEMmQO6{QAk+JtqWsk@7eEET+2b&_Ry}tBE%ULPp?7RT#D(w`m zY(txH?@*DI0y1X=uKo^ZfwWV&sts+ze=D*QA?Nvv??aK4u(r*Do(lET+F(C5 zK|krt$GwH1W3=M&=cBQgUc>$il|9=bW%GHYYRpCQKxQZOzmyGaO_RU^3fXM&m*>OX z@o3aLVE(ctK|iCdT^P?B(X+Dj4*S?IiP@V7wSpbsn}|e#n9OF7TpeVrAk=EzhVp zBT8sJ+0yOlEwcYB>_;7>aTHA_cU+^B1LFxJku-v<^!}4WtbKF8b>ULx7sVESnzb;b z;k07`?}bb0x{5dUk%~9|5oXDay6ip^{OjtQbL@EEf$^l1D|~BBV(TiPZF*{9@{AJA z$~InOWzpFE*RWwtg}v8H_WmC3slRg7OWtshmZ9SgE1RK; z78}RmNhdUW7NrMgDIACLEcKBhzBYXu=40LYa_mcUg2TJ`0rV0Hdv~0*svS6IjnNSq z+CN}F+WsH&Wd;v~@H>qUj4v~9!L%>44o^EC=%LXuz7zXVBA(HVUX`YOnOVaA6f&Q> zwqyOp-N#vEzi89G%z|#xR8EbwvB{X7OHFcd`P074)>&-5?QY8saN+55dwcPsbD;G` zhEU9%i`u5Xv4jI@g-h*@N!GGPynnZ?mGr+t}C-ZY?aq&C5W zG;eqq(ZV%3Wn@A{Px~?hcgC_8uSs6=MFR-A5&J+?V%nEkalU+lSAY1;dT_B6oK{Wy zGSg)5CTKL?4#3b=nkL88Uo!)%8!_$6Ony5NeA*2+fT$NU%d{^u*#S9K6?hrLGqN;Z z6wq9mWL`>~O5mp&$60(Fb;MhMt96`Op}pj3UuIf75l{Ovo9GJ}?ypOmfy1To7a{ym zu=q;nrHO~bX<=QFT61lAN*__$v{pWw6OP-`qA5%muQ@$7Ek1IEBD8x+cWw1m#c&v> zH*fF1{Apii)4t5)Lo>OFvO@+nF$`@_PZfQGO>Ei;oi;4W)cP!0h3xpLf<1p)rhS?D z+T0fKdJ;zO7Wk6uv@bL8tQ*1dS@N_mv*`Mn_GQMua}ZrmL5FG6zRY^^cSm>=99@Oe zzRYgm-)aH5;8>e0HM|PpL&y+ z_GN~CB(7cAsd9pT!8BEQP^#9?T*^Af!Se7)V%nFP?0|FHml-^5Qj44RWv2X=gL1aE zO#3p6G`%v-O#3nmZ!z+V?P*_TVZTZgL1ojv%%**r(f6QqWt#S7c0)e|nD%8BbQmRm zTpe^_HSNpHIqk~~o!U+NGGqSXM9*mdn|+zlbBR9vAHJl|{dyqvEC0DS`PdsD&HBXE zo<&E;JsJDoZkco7%8v4HymtG>Z@ykv_Vxc;RdoDiTkg|8ymQ&_2YHf9_wL z-d}!J+Wp&y6F>g@zfRe6@ryIM{^wIm?)~%dg4RFmOLJd7G_U&Sf4i>!-=Eyz_}N!W ztmhwF-TZ@Z-PH8Gli45s=QDZty!0JQpfBMwzuTq%tN*%x<|CH|O<#Jid+8_N-8uir zJ8kJh|J^?K@GCX9KJkk!>;KPBHH zEx+rNVaJbV%^Dl>N-Fda-jWIUWSY&ep5RR3VYr1{qq?V%XzV$B>3`5Oe> z0)LY^9=FgsT;C6wmi9QU147K8cOLMpP_)UUgN8$ihxNk=M<&nTqnTF%VtH%~PDwq) zIbtg2C~=N>nD&Qn%H{~MPvAJ>4}@*pN$W8+wvh*A^Y9{ERA%-cNIqyhlyulIoOnck zG~q!QFV@UX=_8rDTOfZj=g+CO)yJql{MYIO(kELNQ?a&x5Y`gWJ{#c}rwI1xl^&lQ z`xJFj0Cr%7J!jCT@g&*B2cZt)oW2X%U70y`<3zL(xh`SnFz>F+-IFqIKM4KvL8yZn z?1BfmU#4b_6K!=iokRRLy#Fx9!A~&0FKB_k@M~&(d=ndZhX`@5kchr&vjvPE7?fC2 z;RLb-_&Gs&395WO&BwJ|4tiC7BF)G3O%92wd;`tLXDK-tRQXA&{3KPrk>=z6TMkB5 zelpDu)h}6az=qu$Y}+hNxrJUspQKFJd1omfz!xm6*!#? zD{uzct-zV&UIm^_TnapgG%N62Qmw%A$OZ+TPl^?I0YU#%JS2dJvH1$Th$Jd-7WuQD zv#~!Hliw@w67nAkyp;T0fz9M!6gZo#5HR{qUdS=n5BdsDVi+SG*w5PuvJVQ5{{t}E zKgXkh(*%4DFuup-`CkRhgAP3DKB&NX3g6Lil(xcmw2s_NHYoVFkYx(IiX5IM&1g}Wmvy8 z!9k2@1TCTnbem>Q_O;PeF9V zN}g8aSCTI&u#N0f;3~31f$by_<|8Z;=O+oS{s-(GG1`m-|NVjC9EuajTMSoHtS7%? z7}q3;fG=}~aZQ)N>)k5~oJ3w`80Sn0=A)MwmgOarA2N(Wf8O5j=fIKz)oJd1pZVY$9(^|%VydU+2@d(6N{v#NFL>?!Yj{3ux*AJ>rv5&>n ze&IeU|2QFNZ^);133AK~^KyR#7|V&&eiQP)#`JJd_C1dB6msEyD))fA=QMqtkPqX1 zj}y{?F{D3$F{Fb^XgZE_l%v)wZO4O*|7lqdrccOvFbxy(1m5=$A>YOrj0MM|=?Eb| z!T2a4Z(s~cdymCwV3b(SO)PGP7~9)|u~S~N&<++Nf4}UT(**6TLJarOc0fD`81M69 zI{2Zu597}eatPzYguo>+0XT{AXIZ@<{wd-Upg%0n1$x35Itl%?NiEE`JCslL59Q|} zA3C4gXV`Sm=PKlZeko7DRIh-mBIHwfkl!QZW4qD-W4(+RgPm|Wm5hh;H1=Z`!%^!O zrac*W-`8Xx@Tli9#GvOb7=wP>Sqx35dhW#7%Y3A-V?NVA%J8iWw=uk)VGx4#lQuEz zW_Sa`9Snou0eLnqPt?qwJjD~dnH@LddloMD)3X#V{SgAXu@hZx?>@IHoX8HP!Mmez>*WoB%U~OV)fZ}Rb9J>j+PHRQpVtNbd%9`AQb*MVaHe^`pI>%&!*Oq+1P=<@3Er@`z}A+3AX6m;qy90bIV;@ z9xREkh{`F8sGQP>$|;Sg zoYIKODUGO{h*c|zsGO3B$|;GcoYfJPvpQl8R!3A$aYW@5M^sL6MCBAmR8CPu9TY{> zK~Y2<6crYc_SPLRQOQ$T+r2OlA;AU%kWOrL_z4soiC#aVd5um!ICb+&7r&wtG+&Tlx#E{FMe|ExnNlTj3QXfH2j_8ii4!@yq)Srh8m4jv zU@qrZxD4^@;1a|VaQX2R$n}S1$5TL;98ZC;+yKDE*HeJY4E#&$PwORDNv;iDQalCn za^fkV#nWZPQ^1!HSOmJdda*pd7!>eTgD)Vt?IhPvZ0ok;@pId`KLES{e*oLB?^0vC z{L`B4s>5W0$-Uj%vBSWVrxka#baf#**t-#1aY11j(c5}`e)nL0T}eTQmm~%eG0aS= zOO{NAbX|rtTbievuUnv72(ApXbW035x?J5X5CJO=(Ivq}20S>#7#2zLGr58BOCZL5 zJP(jf!!JQ3O65G*j?w+UoD2JDcJXg2UJIn>aT3IOcKst2Zy3^H%Nz`xcUHxF1sGU1 z51jY+Djq&NZRaG2Iq!suHxz+~@6zD^V0&K&a6F8>hgH12ponnocu>WA33%b;?Njl( z66EI|UNmpVZWZr5@P5Kc5OZFaiuX8Vgsb1(D&A$_wTF?1?+oGppkB5m67rb9<94t~ z#d{BU;reZZidPK=){X_Rz}r!v;ynp=et?r8=DYnRz{N99%#zXiO4 zF!JE>Ucp-kl?%r!SMjQW_lO{mw|53q6wBq|*TCa>n8vRq74IVO4zK5Tg=G8@grPj% z{@xk@LIM2pZN`J)O@kMdC(h5j+!e~($uRIx_dIZUYTkRm8{#C0Bk}fbCS-36ym8W^bF z^33p_X^0DhIFh{Mz>7tHtKhv*EcJUTM&5dOPc#xk{aylIEbXXmj;$T9052AK+hD>u z5JUZ52VN}g=z{llvB(>Xk>`i^YO(YizTA(cej~t(rGB&FeO)ZPW5A2WUd-@*HI{Zf z3A|Y5HS^u!d6!@S@HrQ|^`<@zx8x6oJ>N z;x!ArnF8-F6|W0;d62&e{!#^At%~li`ntc0t}^NaXEs!L`Wq3%n%)50+&G?*Q<4zbzGbHWlv?foB$Y zB`V%iz$=6_Y)7`hTc+auTBzSmQFxaH-ijzZ{mzgb(2DSkt0&h)j$5_>iF|Y{`ynbGT{4Jm&U9H$1KNeM>dn3=vaPct;0-9 zNp$3&(O2thj4k?Vl$qyv{^Hm^S|#=m-0$4yNOgS1vDDG%C~{QO`-U9PyiI0hjmk*x z@EQ!M=E1ZxjxlI)pwO}3@#qoj8#5|UW};)}so%Gfz>ZdZbt06MNK2}~lD;CAMC)3A z=>uuN_J}hNbHrQvSSAtkV$4^JmXx zb((!l_l-v{>Qa9^PKE+I&yO3=t%H8d_)_Arz^1tYUgFvZ9sd=HA|}b!PZlKwF#n z?vnP^rLOjShz#@d+t#i%=jZo(yTDO&zq`%vfo~p|^T9b+{*ImjbAImxJ~*n}T2ouK z9lo{V@85onvzP5q_uywpNpUCv#l7SK8V*=*ZcZMNs+Oz14z3Ej-y7iuEJ($?MY(Z~Z6oM5VzB%f!O+ozE* z_bwRpn#!`^cZLSQK(+8M#hp-UE6w7tTbs8w+MTs`)ilIWH1*t^Pls=Zt4(8-C>o(E zX)0Vs=ezwlJHX5^QJ-|Y)34h?EYjlgwM|*Mf={QZYPwJb;Zi%-Yd78*LN$a-tPzLT zEZmc=y#75JO?k0v2a22uQ;maDRB`eQH}6od=`OElk~@_a+t%xw>}fVwuEpcsRWenL z#=^^{qHs;Tpj_jfJ0=@rMNh?IM>}0C-{OT`*%a#E(&P4fI;Ok=7Oxi`TPAfApy&#! z1+0X{+uH@-;qUL7irU1ZFGBw6HEvNzuw{qO4Nn7ZSAJWU2QDV9ps6cZ{vK-l8amM9 z@$ZSVcukzJTr&d;WnP<#)(`_pt$5G2z#KJinHx69@4==F8SsR3L(`e}-H5&gb+6`{T49#>CqzaM^r zqOnq7Y3}dEAH--Zx8L9EbM4UR*`w2?(Y6HySu_>Kn(1`4!Y@T#^v%9Disa)!8)-g& zuSQcPO0xL;gWA;#rSTUbw))0q`!;7?e5Lc!M28bv%*I?dTt06N$D#5p&B{~!wJ2S7 zU8GSrGhw{u;G8@K0FEvhY-rj%tmUj0pk5;e7CtMAsojRMEt0u_| zBKD7^zg?pxa01GKI#_mlIy~U{-KEhM;`+7G!Z5UWybE~&6aC&#%r3&q)Y@04SYJ&Z zeIitwCAaptC;09sy8N~Y?!m7ky*J+CyC%3hyl(w9bekH+bm&ao(*fU`n8@lKy%9U$ zRFZhg?`)gkrxMYt-&Ne^it7;QcJ;tR#snYJqqhNH1jMroP`>4^+M@DFDa6v$u)1LN zT5@oZOryJnW$?eb{mP#nFUYt?L&rS+OiWy;;CWi_4s{_fSq z+Do)>$I5XKt;r{Yp%Fp--BUGK_{#$Jt+Y7QT~&ewzAst0wyZS2Fdlsn2Xh(ldnWp_ zSfzO?F=#FmeC!S@J0A8T*IHWzquW=lOpdycbq)AC;o~+>n+skd#!s@=Q{A<7*Z3iW z7SQJLcDj9@o*kMhCMY#7N(o8V-tsK)eRK^s`m&Cx$hfFN>-B}!mkYH__*+JyiAX89 zW1vg3ZH7{E|88fyyB|&n)YP7X8VQO=pYFwj6MSzSNj-{ER+nmA3jKbww(6lG<740o z(eS#?quCR(Y&a_U6a8MDx=Us8{kfMMr_gdqXM{-$ZD(j}1wL&-ePf^4nVRc|lYC z_78aB7gcSpiGDFlWga21aT%h5c)4Irb>fGgp=s2I^aoB8tDFY4p&~5wcXm#%ueSq! zg*UkrOK%`b4?6btnABFeIN<8WNmNTU}F4lM^KgGU}>Isfg+(JG9W+*u1sD z*<4d+$MQ=H3k!jISFLr6)4s)8S!;)n0IO`3PFr75{@u3-cF zadB~JX~7!cG;M9bb~(!ni;Ie?oYvaAtRKQ^Fx~J^%OQnzh0VG}R36n6XO)C*tP`%c z-dWRB-{{=Bg%w6?%fvx<)>vz)M3z#srPa z&?@`d0#<|<)?8In@2s;oHCZ>=n;6g0u+@p@u-dmMI@aNUQ=hB0LWhU$mo0$a$Mn-^ zueDp7?4fqk59Nb~U~ROO&|c)0QCFqJRrV&D&nnp5xMhu7M($@rKL=EGJaC zrdqolx;IpnFdw5=p*7uUt=($hP+S5=B-;@f4pq7X4yScCfr?Ou_+1G3Gv=Tc8)`y& zW)-(?vDVgaQubKGU3I*N6w*LC{1nq!XKk*A20-`ZcMo*=J*|8EZf9F3d>x7@F_}$&?JaEi{)4<`Nco<(3_?4_Y@n7e(*FiY# zRS{YMh4;OeBqfFQ_ct*g^?1I;RQRaJb8&c>syg7=GCT~!MFc;tJ@-$6k4`*aVJiA1 zmn#HfJX-?&l$#DFA2J?J8a5nBJgR>%;gfJy0%?K2$+S~E$7ZVi+U87A9Yi~=g*sGb z?!MOlvo*8FHA!}QBlUsmD#9W-z=Q|%>p5S*c-n{(ODdc|<^W$ldjzETKf?Jh3D90RBqbQo zkK!u|oIqYsU_JSk0w3OtAWg%<{~j?5&#QDE?s2JOLH zu+JotL>^XPBYBWv>=Ox2OS{T2&L$x&`FIW$4_KZ!RuSX5a6BN! z^Z0l`EU2I405(FV2@c=78Dls!i(_2BO;8w~hiHPs$ne}e6C4gkdC(cCKXCIV_X`}# zh38a(n>X;(3OrE08Dlsk>^6)+elx~!Ukk)|UpvNdUnjPJr)vV$VP;4wkK^>xn1ey?x?Cb;{qNdPw*;I^j+9!a?*N(_2BYI6JF_zoe@*4-ZR z2V?^>Bv2nf+(h#tnJ;N9*3u={Z5ao+SStz{ywhBl2dG+_DEz~C(W^ykM1sSJUb7(t*VxhW@L@n6 zIzb=|8=j^fGIBZ_E4kPbRjK{Ms0*{x4Y5aOj#d`~Q;d~pw z5>Ly8Y#RJ`Gb>@A6)o-XGJhQ;Vayah^6|WF@IDSzc6d&Y$M#XCZ9@-G{P!^ZBPsKYXl$$8Gl)z3W04rNV1m+`PThr0qxtL zC7|!_UmzgefjQOWzKYW%usDz@NF44X=2-%+?z1kLA>8-f)+8BG9eST{&%#qqk5_KI za>w5h^OfJp{f_$1W2eKCv$pT-*4iFeeGT`df>dY>oo?11O7f-SUx;lO<- zPRr+}%J+Sz&&*ChHG9mb%pS}mX0vNab;X{OXUv0{dC8-*v*mMhNzNTh<%+sdvZ5 z$m!J0^Y_hnocxoKoP75kz#QrFbg$~n^YfNg2@V=2P{TFT2v2ejYky9@OROM+vh5-iJ>JB_#!dw#Y4oYE)TP{-yV< zNl@AxNBx-2ST0)cm9@HBRvtNf{5~k}e8rV@x=q2fo6b~Rxm9NiVv?_az2eGx-EF}X zwBCv<8+7Y}DG&b%R_;9gs})x^>PlEDTIfBaa*q9iWIpa|*;BEk;&e+N%n5s1&g54Q z?IqbizC_X#6!NV$296zHKCEPiB|dlQ?Ad7z?vK)h*ecn;q4iMO0VF zBXB=Ci>FAx$Ie-n$2In=_i4T3I33$C7gH<$iz|(_J8v*OFLg8{Tkfahr^&K~js;XI zTxVmsShGAB(eFkbo7c=ASB$#Upl;LiOrvvy7SPgn;7Chb%`6STp(*%ovXz8LljTZ6Td6q`agHASG=sMMF#WRnB-dljWFSNBL`Vdo1xZ=A5Y1y$W#y^bEDiXLSaq5t8FME!PI;7YypL7aTWq4*ywt0=pCE zj+P;%eo*%$H!Z+c3%16ds5Fd*UoqZzg_!@y){8W3`&rcN@k;$G^_O4nOJOC=6jmF) zVjIqj5@D_~zXx)}x?@`sYHIc*pCM)v(6Lz(_VU$aP@XaI?C-zW^z>A7-HMB+KQV43 z8zHwM>)h!LHAe3z#*<0lzO+-FStPG#)O@7n4AySQ(K1|idq(FSJBK%oygN?&oSZF& zu~+`A&K&UR3X(?)=*V(C*fM;pLwW-5G6hx!$E}!-vMbIX-&3)u;`H%8x!)4sg}oM7 zQc2)A9m(c17)wOTyJZwhkW(8@%>jwCZzm(8M?&Syr1waq`qWIwO;P1`W;L7&U)J*% z|FR!7CI_(dP5iX?t#nrDJzpWthVT5es3AC}X6ALA$5nN9UjOKAf#XL{RHlwXDOuPe z*|w^xNoTQRt;6Q2a2(roOQ7Y!6P0UveJhFB0T;hU5pOE)7c6S#+Zbfs%k^ zA#h4NIh#+V``B*)>nDzy%Jn!6NoySu122;zE@)o`Pi;HAz!NPe9=j!K^ zeXCN>XH=g%a+w;AP1Ik$qwg-kCj87Mc8=a2)+RP9Y+?9ZdI+Zx$a7VOpQ*~%TXR%Y7Ei-mH-*$O=4GYiyN5=IjPrGdmiVbESyQAsPPq+CIg zIcP8QgVvG?lHRYiDDCCiJ!8c?AGgjA+RFT(t=w5!9MS^ zj>V1(<9R_Z7O?9x$nfH{5m3d1I zugRxQ8Ce?iHM{!7`0%+$#xn{Zd+1SEweU{Z%bAu1mIdZQUG;fOMiUux9<)o!S?S=? zmY(7*#yd;_Q-OYzmzfaYSMr{`{<77l7xq^T%-4w6H)vBlGECHV*se5Se zFpnD8OZAsi`|5+elmI=Hl=somn*#1LXU5?>Bv%r%hhgXOh4D0^%acY|9Kia08@!{C z^M8Fx&stMSdugqMP`UdZ&q98}c>~KOXLkfX_G}vT^jfOp6K4!#X(SD#>C7z$Oaa4~ znV11dfD!_{cOM_WY3S<@R0Qz8RrJ2WXG8ZL|Nq$g7WlY|djHvzO?H!}Nt%?t=wp+n zZCaXV(>5SrHjixrX%m_hs#Z3yO|y_D+hkh;^kNEqq~%qwUJWYJ>(wj1+X`HI6C@KioTWYTsAD934H)rPToRi&cFuMtU-1BKV`<>tK{N^{m`OTb}^Z3oa z8REPooOg7eeaxYpSunKyuBBsXg^NbV?m2ecb?;H5t;p`}_x|(Y@S3J#ESKdcjmfss ztzLQV19{0NtJ`TOmWRyaiL^PT)He_C{a)t6_IgXx?2K&AcCIpPPGfLN!BwMquz8ZO zS=at$(3GzB`gu8Hn(N*RvvCV0^V|RRa?;ZOdf8@^_FYhacu(uF?NhuDogyi+4qf|m zOj6Ru_7>VlWvh*^;fg%fub3-^YB+BFA?p@yy!yd)#(F!#c=g7H6we{74dr;HTcq;b z3)d|$ERqR}WECvKJR+HoSjl|Ex^(mtcVgY#&2AbxK6dzX7qI%m|9HO){S4y}C^vcB zo}`;fFoVGS<9L?zKhrqITkW8=uV4<_NV^j~|8nMMo_~4fA-PKtTfG7^r6ODfusAQ8(XxVX$#r=$Pv}rFCim7^gZ+a@V_EOj*U34^Y<{g-GRjua z>fBbqMr|wXuiy|D1~<({z(E-u4m)G=vH&Z?5eY@$reM(?M# zQtN8H4?w>7>9)&+w)!f?<&)&He0W+-&o-wtk8`T>Fi+w$Hk?x#tgbdH7c zWXpx->bcx*6|mbHUfLX9THns`^ODB%zipHA61}vhFr}rAWkfAczaEF{>$J90ckOzk zum$}A_aT2jd)7)>%fYmQw~w;Iic!5MN}tUaKKnht+w=H_2QS#!@bL$+It(0_n#%Qx zYW3O1)pYFcijz5wU)mG8nx>3p0{{GOd38-1lht-fXnIqkz)p4qV3wcRXtWW)Ti!G+x?rN4xHBc1yOt>d7{s5YkI ze|Ab6YdrgxRO(rEd^QlK&KP%xJ@3U_&H0dd1lrIx)2M3>?jD&}ovA2q6<>AoaaHf9 zG!Gp&hMs+N|1s59bW8qQ+uIE3$pzP*nNhI*OnQNLbk~Fg+SGMEehXEE|Ghi4U8;M12IBYik8vX8y-YdI?`8+-T3bYbI5 z>H2@q3x{ywELZIo6J&qop24#L?6#7NW%KRXw=57yz%5^%8EkoGfOa!oLR7Nl;IA> z9RA$l=uYNx?fpw(2Jd|i+)sy9^Q3ibqTZqFgVcO&*#y?A?%`v0%<#?qx*k57@)^gc zWxt+>nc=%fS<$;jX&zpMxpWnuuhGo12s-I7Xw1V~hYRZ|2XYEGoROnI)mXHVWsNbi%r}i9E5;tYun={aH99+QUcK#M zlB>zSotwLFrZT^pCFWt7@Dke>GXFz*iCy7gr<{D=#2X&}S^HuIJ>0`F{#sml?%>W; zQQxtfDi>xQ*PrpM@vQQs)H4@pHvU-;$+CIU?$FNKv;`+A)wHzZHh#wUZb@#~**qmN|2jRw`SL%Td;r ztIM%rq_bfKV$0NcFIYGhntjX>cl@)SpL>$-YGjPgJjs^hzU6Woo&aQ{XOw#G^w(i# zf^{u&=pON`QI~%Zcb4fH!i?va`_Y@)%7*JaJG;r+`Z%HAYqGYZEudQruXX+1><`%E zqc4^8$Bg)v|E;l0psG}2ufQ&UCk4!jQJCz>ee_GA=nD}fIJCZ>=igI+a$^;)A;sT`5C(~{lV^C?QiCyGGYHS_UxPDanC3>u~*>K?GkI+Ag<>Y|0Ltu%K6@#b2bsc zh+pLsdj%TX^i4=oD++=UoJau+{}K^NnTLSnB#U;o7h zc4;FS_nhWTacYLxOHS++IGG(;Ixmy4(*hHXTPwllMhr(7pIdm!+w} z7h~aFk!mx(Jo6rGv8k;d`xfEsVo?<#Olr=<62?caQbg=-(v4T&QjCOQf*ejsH6xav z*ej4nV~uQ|#9o1uxUC-B=)~#CtYc zZ|Y^T#9o2MW_s%5YGaGI#9o2k#9o24X=GxrK(YU#y7S=Q>Ry5Bm#`i5UHG5MKkOZ1 zY=}|NZ5*~Ay=-gzUCpoWy8q|PPrh({ev$>-EjZbNX`>(;_CumW#)D5%@;E{Kr(IcN zz;xnYiF4CJc|@GZxfFjq+_`jqybc=$T~`j&xD_zoTiKDB>e{XN zi?@%fbuOERI+LB{@f3bow(NB01T}BYZBt_ljMm0+BmA!_r+@s`o!Vz|c7v-GfAMY` z7s`-F2G?izKF9u)1IY*N!%2szS5A!{s$bGJaIN^8%DR6I<RXrHMbt7-c}c{Fib463%65+7Cj1#Pv` ziobaG3$@It>Wiwa8^-(Hl+;`Gw<}=hsrEM)%9O{`_)(QJxX-!YaUkVj^056-(&4F^ zBdKliaju7H449I(a7jZTy+ic9>9B>WN9Q!^p|;5p*u*l2nUXe9`^O-3nCkwamcMG6 z%cuFmRM%g-mMMg z+};X?cYG&8iC({)HmBxHa@w8A&J?G^>2#(#)0{IL>CO!2kmlU0 zIq%e*cWKUjnsdMAJfJxbYR+NJc}Q~})|_{1&U-ZHy_)kr&3QlWm#XtxJ9HpD;%#&F znzaq(P4zWHEq`R1%ilW9SUek5DyDV!b}&{8aPhXp%1KMnf&;k3|G zIlWbqvAeCgzG<9J1DJlKS?Du3ooutGnwE%Y2tryJ_}kz=9H=5%_% zqaU*^^h@;f4f|bUq0ixTT7c@u91DFer`Jd_o6G493MPN1g`>u+R%Q z{o|612i0c%S8_VtP}Yx?7Wyhqr<-p2vC2Zf%z{^2a3MdRZjkCnp@m+=>GbePKZ-2$ zVos-&TY z#BMfWJ8LoFWOjuKr?5pP>|hxt>|}omT^vw;D*KfQr?IC^cm}r9BTe-q2~*`yn($0^ z$b>W4pb2NPZWGR8jV3&ctvBIpw#tNa*gO-S&C*Qx687Q@sU6vK4*QY`&t>m3;d!jv zgy*w56JEepnDC|S4{56Wh3qL4Uc`=?@M3nC2`^zj6Lzr%6V7F2CY;9>oA6SWWWxFE zwNzD~W$foByqrB@!YkMVCS1VoFyWOfV8W}|4JLdUyV`_TvqBRtWOGcoh&fHTnEl16 z>RZCDS1`l;>KcKm|Jcxf-X?Gs$K`A#FpY=z2s{V)IsC2^I0<+mIu|WsZRl@j9gLL# zlNiFk0j7icpAG%*djjiu*Rw}V_y+cX32$ZZG2sf?OO@j@q+^eb0o~ zu}4j~mVMZSJ#4QDZ(!R^xQ=Z!;d-{lgs)-qP54^&Mv|&e1N)^3Z)D##;Z5v>39n}( zCfvyGFySWFX~NgBYfN}ED>30_Hphfp*q=33zb)+ZxE@enpf!w!Uq=OAg*@!T%WlK? zN_3htYuHfmCV}%g&SKXIOmkw5&0?1eT*YxVTP-lnc{P^976?pkrlFUnOFA$A680;M zw^Sa@VKt23PY6tNQVsLfe-fDHpc>|*Hwiq*>GRn&0WM=13Y_ z#oi(C0*)_Zl_tEJ6$?yrB8?TYc>>cMNMl7TO<;slc=*&DLhHuL``C)6?0fB%R}#>~4W+jhU@w zunyEm9@+T4S;4dLyGp@CUt_^bEqJB{|DKF34m$ru3;u=$KVZSV7EJR{d5}E0&k^Mj z&bQDrEci8fvfzK#f=^p8w%#-jlK&n9>E#Vru+M_8vtW+}ht>kRyww)^A`6~l!AkX5 z9`xIWjI0^{4pXShMXR+NDr8sXhrQqun z<)jlI%8`D;?T+$z`-1OIqQjnWFU)&Z2O0Y~r6_bZm52J~3q5WW<#RhJ^|^=g7u$4yf!rqr zew9*SsLu6+i*h?Grxf{RBIW%TxPdV2Pwhtf1SmbvSdh~H9Y2m#2z}}(ooQp80tYCC zQSK1oXG@}5RYS^_35AmUVUN7{2t|!WudU1K6e}wp;-@}xGkIM%imk-R_9r(LMM}Oq) zkMrnr6OxZh4nLp!0r=rEyq>Em1uhr(YD#hbR-~kF8p%`oT@hi}e=DW`%~(67D7TkV z$Qcy)Fs0}ZxPJ83aY~W@ zeUblDO5yJ>iTn$cqJDDR$0d^cwY6OCpQuj_@k2jePpJp|^nj4}0U_@gQlmYSQi6(*B>zVN&8{b@OsgLzyTrMTGD zA=Q4V`-$N%sLx`eqx^EBqnr%FX!kryLEj|k*Ha4rd6LpM82c8b=%-^y>AbC!LXSa8 z&olk{gT^Gg5uN-%dx3GgX+PKfm&U`>l>cj8F7cfq{2bHAv*-1DU)nF2UJi^06__^0 z7>Z!p&-Cl22Is+0&a~g?cBGX1&CB|Ap3Zj>9p~p$`eXgNuVHduLiicI-)cV*^TjWV z`68UAo67kQfzf$5{+PhG2>dyLQF%^3F7S4NPYAqQ;4cb%tH6&43?uRL9~F3?z>f)h zm%#rf@a+OWF7SH=J}K~Ffzi2ps2+C;{3U_!7x)Q*cM1Fzfp-dgO5pbid|Kdt6!@zG z9}@U$0v{3h>jM9iz;Gh24>}XC?>7X#L*Q=;jKPG{pAz^V1pZHfvDo5tI3t$_!11>Q z9v1jJ0v{CkzXaYd@OK41An-#14+(r!;JpI>v%vQV{4WCEE%3($zE|K+2;3|1zY5$Z z@FxY{A@IWj2L%3OyBG}jOtM2!8`hzGF0{un)-rapS`)YS%s}3W_ zk3B_$zGh$lZhwcb#y`-}x7*i$s~~r`^>+67Zs_+1ebwD<{cRmVU%!7K=}%_+j>I61*wpXe(bj*fFm2VXTXy+7tu>Im z?w%gAfd?A9#EBC=rN%eV(eDqS*$1rW2-`-lm|%)pH?xx0xApAuZR!j9yZjw(;Tq^7 z>?XU0;jQoOoVef+vk<%8zuV&f+kL@}ZG)TI`y0E+0VJOF?VC$-cn|v^w5H1hK2%=QGX}c^%!pj+-|Rn!UTDy}EH@L#=nf7u@XI(dO^<_inG+ z)z$33P3j;y`Ue7=eA`JVI=K`n&IT<4!MBqJ3M;#BXC(IR=+wS`3qQ27mZ%%h)8Dqk z7e-f5Bau4zIDlPm!rP%^M`x(NN;TSgJACM$p~0%Hr>C!js=!+Y!+R!aTuVWSSKgwoq8NWwgzg* zy~iCI%~^xLJwJc5Z|5$IxcT`gx5wYkcKCL5>mqA+v^O?; zef|A?{bkB;{H&{WH+gsP+LFrt4s)JFW8pHw_-t=c*} z#h8o}s(Jr4U!RO@U&k&q$gP`vzD_un*W2c6YxjG}DFU~aTd)cC^p~@Z?yX*Tb%VE| ze$%zh-iBI64GixNwDtSw8baP8hmU@22;S7!Poqd*(AVVi^}9Pe`)Md8&M=Ik|3%^8 z&L3HTumBhDMVOI|-tGMXuR43lzq|r<3Qt)Zkx~|kQgL}i%DRY@H4!N#5h;-f>(@u5 zP+Nwr==#z~lywn}vo4}>)W$#wm+voU(|F(ug)FEst1GX?etwO3Nb`715}rYa(m0Cdye6+oH5A zVq=t+MQn}IvWU%5S{kuEN=qZ#sWh^kN+a7Tae7ok~jCfN$rfenxvR=vRko zT%oJlI&S7!`o+$3;jrrGmn*3|>Yqz%4l&&MtjQ=*e^P6h(-B&b} zm2GJ#FWu5mR+_){iiXnC{AT1dBc~ZT^|iIN`2U9dEzPyf*RRXJqq*hU>T7FsxE`>s zA-}P?$z5HWUt8s_$lqLhT}6J==Gx|p{91Qa{q8dJv`Sr{>Z?_ntC`lOeyl@H>(akw zGN!I#X-ykp1?w-;mwVAxuTgmP=@BiYLQHgNRG^&8N`^42RY_7;sxoiyt9%hw zqb0-eVM?p4JfjEveqY*}TF&lf99f0220=`XUZERkVM3&*c2 zLsavM(v&ayD{3M|^^29HDJLA8SV4yP`06nP!>pW4M6An0Yey3$Ty}?CwS~H%)Y!a~ zgd}Ad=`X@yY+6FfrK54DjTVpjoh(1ds;}5ayCZIsTOQMo?p^KMcD48P4HouA*==B( z9{F{fWv?S6n}&HJ^6|c?gSj{1E+JncFk20NR+kl(tYh|S%B5_$>O(2A`Bcyb#ZiFIeQw1K(CbqePxFV&Myb54YQmL-M`H!uKlp za2we;B%j~Hw-vaR3?&Z9*JR`nZsA*q2HX~gFWbU52)@=Ze1C!7YP&rH zK0KZ<4q5KY7QSw{Wr@KR((gMKz7gQpn1uLJ+!uNEV{_NArcOH(Y+BrA_b`DeSH!OVi znfkLrtGs`<@ZAHxaQ%0Wh3`r5h4be+3twdh`gs`rF0t^vgmG#x4ByMhqii|8w9e9> zSz7Dyl!fog?C|yYR|{Vdd?QjAQrT{YEPUxXj6XY0{G5LVM@7p^lsvNb#D0a;O96;mDe;+f3_<{O8xMt z)5O;^Uw_tY<-@ChCO+4K@Z;4X3*XSC;m7+=S;pt@fDa;#1Mb9+BNo12Mc@m9Tdgm> zh=wW~hpg{AEPV68S7UI6{AGiMZyWet48ynIqF?2rkPKp%_1Go&q=*^|pVTh^J`6n! z!v{a=z!$C_+b!~l?}01DNl3^RbX4GveoH-GgaOoder36BLY^$Q=v^ThBuC0yq5P)& zV(^jeEhiIX6zMz6ZfKk$O11`nOB6 zDv|2@KJcm6-$;B*Tg}&nNPM3G-$dGNN!!HaeG+{4$VwoMRPLJgiSeBR-_Qi)y}d(! zcSf>CD);N)n@D}vcTSA&GvM1N3q=~K++yFv>hT5e4NpMc`mTwU`z7#AL|*mwiSd0K zd=sf}WB0`B`@ISBHR2tPp$XXKd*GXh|Gf+Ea7?5gKLg)HsO_^2GoH^;&^0=_1}M{@?r_Xqq?%Y6xaR1V1_9?AEdh3_o* zNN?gpQ3l^vEPV8Ws+5R<7 zIfKt<;d>Z-a6!(8rJTXnVBwp0P+upLymW=H#KKnxK3NYe(F}PR7QTSOhb5Z9_c|I! zZI2P~$@ZmNNf5*BN#CWae8<2i+k;Zc_mqY2w8Dp_oWb{53*Q-~T)3;j_hAd)OW>33 zi=~&rx8K5dR^gki@C{h_E`U$A+a(HLy@ju2Sbw*V+5<~3quhlSz7g=1fKGf^dKr9Y z(OFdcJ*CJadrSL$)xuYDC?pR{FN2T1lT_ukf={*wt&^m@K?`31e6oG9R5JK#EPTV@ zdj@o>$3lgVzEL!ldsv@$5+9ZrhP+>5!lUw?1z$Jl#J5=Cd(y(U_3ltTmMDB5v+#9; zuRzFiDSZ1ad`G}1%gt5zwp;ivfUgpC(l1ZpYqaoH;G%j=@GVvN=)GsPzAu5VRq*92 ze0T-l#8-E3Xq;T8@X@R6s=N{KxrDss3g1uhTjhHke1n2-g~Eqdo=tou_vzmdQhmve z(qBGk;Tr_s8RQY)N`()@u}NOt{h{_)rSJtTd;#z|kw@|h6}~MNzCrLwKP^)Dsx5p+ zz*m7hl2@$om0S3p0^d`Dk7%;K)P}14jvNX3-?}J#M-{&HQTUE2e57Zja!)IKmq+0{ zqwrl3g>OvZds`H~vkKppQTW(D|MQXQz!dDZ8Z%E;*jly?C;qye{JF4()h{AVF;j4?ncUs}AkHU9G;kzaZ z-F@HIx^D^d8GqVQEJeAh+cYf|_&N8xK# z_?n~e1r)xPD11W-AC0w<{P~E&cYPGTqYB>*QTUE2d|RXNomTkh9&9B2&M18EjKVjj z@Zr{CM0sZwzHL$X*!x2Mhg*RW+xWyNd&!zC;)?Gxt5{0id3SXtd*A|7ZN#Sdc z!q=+sbwuF{D14n!_=XfdpTb9T+9dqR;|TbEmMl@|zS%5fseFA8;7NJLcs@*1 zCqBs-wSzo}P6r;qw+Fqug8rU?qP}96tF(N5#o9IN)>o`^xk_Ag=>M0Nl&o8aywb}{ z%JiJpwD;6Dcx*N)iF7P5?(dQ8*)(utnM(5vniXA&nM~kOyJx0{omzNuZEpI}H~#Q{ zZ?IGB)S{E?a#ICL$y@1hd5BVQ^60Ifx^=k9HfnPPo?xy&|JtlCwMSaF)_QpO&Y{D% z-nlbC7l1ncKg&WnTD>kO>j^3!_NbTKhi=`gbMt(9!KkknZ_Quf!W#oFg8m*~ziTaC zKyd8};Oz*XtJGD{PH&^R)|IYwwe6 z1bX~IeA&=JAA}6J3OkUuy?2+Zux}D?R8(!LZ>ZUZucv|o+qP6SG;a0QUVp8(v8H~L z_lB}<(A{{sqTTD;!CQ79ht<3bLiFS3*e)wtKM3QbwaU@z^UDwnCpw6m?@m z={(oAyy`28ul4zRyt~&HqaEn4x_XYHM#s7Z8j&n^ByA@9CjZ5=T-Nwku9!BbZ;y`H`xjSeyBbzz&y zVoRgQ;JT~R^#xu(oh{?^k-Dmd<9KGmuY+#1gjC9JEW z$mwv^;(>n5#iq1ZQjx`N0snLq+kwyDr>opze_;1icRFrssx%e8ZaQi%CVkUbH1BTH zU4C%@v$E+_qSuG-A*Nk{;y?h)mZ=|ZgclZbE07Y!fxe!${(*s>>Ch$~ZP7*F-_s&6 z)>p2O;NtE0xEyQEw!#h`<|4+Xi(Jt36|8@>5xO>Zr1b}5bqAOv754`RW2YBMlQ%-D8#lMqZuQ3K z=8@FZDqZ5uEr>m|vD~|HeSB*(zP#d=#>R%~Iyau&&?BdqED#Wd2j3UR=!z(WNzG$+ zKX1HTrHI(wq`PP_veY=;dHd_jFYfeF48oYYgsd!DQTa*MmT;UIgc@c)#ckc1X;*BZ z6Oa93v7nwr8$pNSTM%slPg&byG)uX-HnDJwSgee68O4_G`X|>W;bqbskRIp8MRxp5 zAy!qz?Y+K9-usDQ7MVTCIk*&Kepx_jkGKqRw0kiR`w-^>c1(6M7TrSBA$z;};#mob zvlLJH-5ryBDiPg6J!KtjaqR*-+Iq3bnB+1&dL8ISKs=j(k88c6&ShulKwLdu7TlygzldM=@bGb~th*(zHI}qHl zrY!ani}700E{dQV2hlN}&5&hvGZf341>&u=IOuLEfo6Xtm#U- zp^H2Gfo=rR?A;zKZ{}(nQsZKjko0&Mgum4sTWfHUaWO@#uP?myq|nK~WfU5S%!0di z^-S^>d?d*Ow|F~!1ODx?9YPF?7~+fjZs{o-oaBA$i&lb4S+h3ArSSKgW9s0YTx5J4 z+$6eqpwl0-6|(M<7WtEXug=<}y7+;*S$h0wM!TdZ-VLt^97MHTUSo5s{8L42APqc-FpI89Eu7-+*q6!UNIyn+6{E_|6c z$@+!;+{sl~Q&W3=eRZw3cB8u*2wPe-H`i`%@osG102unNfgYQ!!6$x_zqzUYD%^Og zQ9q&K8D8(ks#?h5zI(Mm; z6b?O6?rXmZ-yMeJY0UDZ&FM}RfeRo?2l`X(>kx7@l_i1PC96Zx5tva#tZ@iA%H+OBz$J>D`b{mhn>TN1f~`&2Wz{MqrDapd6U(Zb8{F5|ayD31ytY7! z$iiA`>KnZqYnz+h8)};cpQmYym$nY5-DGN5j|Xo7)NDb6htAhMfS)Jqv$?jR*4QDhRPvMSTJwbo_twEo+1KayxC@F03_xrlMo&L7% z^oEt6zDg|Y?ZcvkzKZqYGnJrkhuA@jNVIoDzaRZ;65q?}1Ammz=y-Bv`b?KTb>>Ga z{(l2U693%zGN$dx$ezg@%wcnAjwGkune0q)I-E{tsx!?w!;$XHa13dVy_(}r&2g9J z*rz%6YmNh&=G?0}@6?=kY0iC`bHC<1pgE(}onnm1BMU!T z@fWVXPMcGUN0}7wAyS#t#_=dq2_Jyc_2ZAB&-xLQ;k7sZpkVsa|2#0owb2h7Gt)H- zPU8GjH~mPm(CwTa(!*|{Cv!Trhkhh8ijPf)1Aj?~r1X77za;4QB@@=zgC?BB_r2!= z`1y9$ZlWi%FG(U#Uwh+I0#kW5l!q`%#$jVK*e(MRJ)Kdk4SCquOhz$w z5A6QUo<{kk0@*Yhn}RPr>7}_E+!cJ=u zH>rxeMOEYtpd#=8g#D!as$qTDC**HtlP1OR;~d1~K33;25yv@(i5hBAb9TsALOv4z z4OYg_BHkLCte~4eh(8*GQt(Fy#fWL*zx4m)wPFlV<=Y1wx=t`2dzH?(-NN^NU?&m8 zA>~o5Bvsx=fYtei9lMR2=t z@*Y7MvaVFzcPI!RGAJGrE;rnMxNIx8P5WWB4NYD4+O} z@F)2wrkBe1D)^`z;v*i(S8n0^vm%eeGfBRs7Cw7bNFJ3FiEp;TmllODU*Ve(g|A%U z!{s<)xitzOU3R5@);Lrx;QIsU@*rE&VU0s|Z8fgtnogttB_E}*dq7gYh@gKrN}%xZ zPg}ec$fti|ai}WRmLeP#j*G{kda;HVXvCqK!*URZD%q3aDfhU~En)ksl15#Jo_?9- z9@&66Q>^giv+iV1x@V4utytzu{YO~QpdW9PIA;bcXJi>|0n>}-%~s))ed-8^wx<-r7D() zN7d!;q?a;c^eNWlZY)gZbuc zorp)}pX9d_a=!QG>@HrC;aB-YJSrm;)D&NL_;4ee!cZa+kE*Ote+zS75(%e*t z6h-ej#&|4|fsi0smJ+8D&@f4em zBc;h3A@aq}_)3?hsW14(!n-2XW_)?(I6twet%zt7Q(;nb{_1NiOeB<4k{v%&$cRpfcvSrz zK5N`EX`DnnD*kNWFh}^HV2OBC5k>})orp&zZ(~NclM(bP5sxbJjm79DOvIyl6Z_YN zOqqyBWkih<&tzgXQ%c06>WuP~!0dr~9Hy9BJ`s;*e;*9Bc+2bcU5sxbDt3=kpQ*UpCvq;3FO2nf= z1YbT1B;rv8`rgEyghV_lBVd#IxY`Iql!!-#9i^1ONQrneAs+`;QrR+~WU_Y2Ne6fH~u?mKz>fo9t9cC+bppW_|5)dm^ z^`{^V@>qZ$YA`UFucTj-AO0hc;zpfPFhvD0V~u?obeD0yW}zopu$}XhE9i%veO8fA zai5Nwu*Uw$gp=4ECTwRvlA?I}+8g-%-#92v)4v#qv`=G)P1wP9ny{0{m7*d@M-3ME zJOE)b9mRF}n7}TMHTFS)saYwmlNvW_7UC(?BVQgAw+Z1pjDzqR1JU`6EwkW@#eE{z zN<+{G7g7yD9Vi}48kD727-={eA)r_q;yIO23SX#0sv%wz#VgPd--*X9OOK^<9791nE2FFgE{8z_$;xQs>2Lt|oUuSh&PfvSW$IT+Z6Jl0+n}dA;6Kv}b zvZ7FgrbuC#=-j%t-p(H1#)0iDd_1O(c8ZF**^7{~9ljnWVOtk=3I;-yrU8Tu)PMQ< z`}_LK^xx33uVW*EC1I~31U~!ZxzM$Y@~s zlNwk59csI&iK}G38op)XDp6cI8gJCNN;LM!149Hq+VQ{2*94rellcD>4~C9r{Hc6F z;B+F0L&~G^PURZ{ZV)__NO|wUZ{m~3ckn~fC{O<0jo&KY8Q^g7lC1HKc42_rM}ov5 zWmx%MpCI2qAimK=;w8Nfz9CsCQdw>c@N?nod%J{U4+r&^~JEsW8$dsh^}<& zV=%?~q4UWuG;B8FPvvU>ALSDt;_MiF-(xzJuyY5XcN ze(BMR7NJCT%IRU<^G^O(?tF3Pyt?G>+E)GinuU3u%RPDoq-8a;>h`zl(kS0;qki7Kp2ME^c@}w|e>rV;`bQeiGG})EQ{7a@ zqgC^MkXd)S+cv*UNSq-kr%$j;k5#4o#Gzm|R^q7`vW+#KbvP?2Qj>5L*f2~Pv+CS zsmZ!A#6%7X72}4CTu>tVRFv;Z#*K}N9TU-~)bAFeS}KTLy<+k)z{N{RM4w7TpSoDg zKk_09%w>dzieH2-qlnnYh?2F4z2rpnsaUKd649p;(Wkr{3KbS0ehxkR6X`WqQmk-RiMY znLetIrL5va^eOczPN<9U=mkccsF<4EkQ(bXms#f+cWqsGBKnjZg^Cl=r$meo!y=}* zP-TOIG3_=i4eJaXz%@jCGgtsd0^7rq!rLEr=+g>Z8Lbdg8_XTB1 ze(XTsAB;;miRe=UJ&EX3iRe>4x`E*B_a&lFt+|{gA~h}U%^UEnr=kAZS}(;6LRL-f z_4U=Y-loRQE%lokx3pYU8sbwQS0|!Rh3t}uKGo9D>~(LhF85Z$Dv9V*f8)`o!hH_g z!B_!eEFfSF#iWtn_9uxv^$YWrt8_j!FC1U~1o@Uvkgp&NU-cE+=zXJYa@?mMcrAO| z#c#%M)9-rF$I9yS44EC?M6IZEyd!kwD|US+eplt}-j}vN^?>uBV>snd@?rbkN%v9n zwBm0nb-6L2i{`vfbKZ{-7-}2+b#`%T&LpSZne0q)I-E{tsx!?w!;$XHa1LqCy_)k* z&3TvR+^0GBYt93j^PuJ&)|`hl=V8rxx8}S@bKYy{qK1w^G^i=@3m3|f$M^B0Draz? zbHC$2%E9De`=O-6(IUw?ZSko)g+Up2d|HWDLb206sbCuA%vfU|2c3+lADV@p#OYLF z{YbLV?VL^yp&xb&J(<&~Q|m{vg`Q$LKgB|KSm+M+kf;yEyGcS6oA(R+2*)$nL4o@? zPG{Q%rt&Ga+ZGen*xOAwiLEeUJDXv`$?W&?Lc!&wu%DW+gRNIEgZ&ExCjD%PoRgu@ zZ7h?WC&k2JL&UV7NPyJFX0g*IoX!5#gmc)vCOne`O*n(Cg#J_{wGqXVn<+50iN=!I z1rS5@6gFnU4jyZbM3TK{X{pRF&L`)iSadfCOg@yYY0ND!`3%LPdpA;fP;9wtB|sW3 z7G0@@t`0oJf3a9}q^GuA=SwT(mv~0$I^F@ZlX@V^WE6s4Cj_B2w8f%goh(BnBu7wED3s5}(G(ux@?rxdtGq^(GaAFMpz z%2y@wNzZ6}6P0J>DPG2N&j=+lro-ObafwNKAUm4r4sH3lUAlTU!Y!dk87% zuW+=Dm{#?KCA9VK>T2rU#}(3U|p@d$-9Gx8U$s7yQRh3*4f$Y>)-9~ z@FBino3E|i@7>|sL2|^5F?L}G%hp7aRaO#-Qo24OC0Yb)@J(MFdfpN?~E#qbN6w@Prux#Ieof+3C$ zx(?X+Fa1AU;`l+=Pr5Ekz6$)tFlij}oX3%)@-+aD8C)URAF=SQ#z~!F`1V-%j)1Q< z3}1(Z?`#Bl6oO9GuLTthSFQt0#3zr(!6)lTdGa@=96VNGl3@HY_~@E156SmBGE{lQ z_wbdHD?}r^5+BI?=tOMAN5pSRq`X)0oA}Bo6UV$t#%PWy58@;G3X#hEgO!ZkBY{G* z^5wWE#`n+!`7W!Pn7n@jUvL8YT~^K5@C5k22)=OgUc|Z5#w4bo2JMDM%*Ss`d$^sc z9lwh|H8y1h9LR}0@_jm=>`a*2Nad>p-x1^yANhvl8?o@60bhaOBOb{&XyLn{@FgpJ zUJIYAE+mios+0#anDnbt_#6sfxrHwPJ{R(+9x~3R6Tg?@Pp$6}@R7ZUZzld^xmLcT z3SUMPzGDhsW)!~D3LljpsoXOPAH~&-#5bn!(X=lT-&utZ(?^5P8rzeCU8`#_>XUR> zV|%W@hOznNDB_TOlp;GI^P4t?kL}qO4Dy(sJX|OKD=lANv3AY6^%d(}t`eT9|6f{C zvThyn)|Qr*Pc*h?{wI0qMr_Yf^oqil-`HUHWOy#|Eb&lu%O!u@|GKRxWwfEzHfnRR zG3FZb4YB+37slc-H1*rz$=6W1%>j zfk#t3>5%N&V=G7*%^S|$bD2kv!x?yje&-4FhhOWFL}wzB=t8cAYp`vQy<&4M`Qy;* zFP*Rzq>gGuj?u?Y)G1oc8hh!4R**iLRg^ZGm6z+$BZ4|lO06l@CeveW9)x^%if5*0 zwuh~F_g0T=t34-<4Ml5yVwK7{lrTb?qZDmqyx=);ZX~O7 z>|+7V)jE*pNy=p-ROSWLWPF+PQKsu;<+&NN<|$>`f6{pVz|I^?sZXO+va9_}3TI*h6_k5YxX&&lSdG0!QnxNW@lIFV#0(xz1VdcX& z8t+2in~V6lh%bAXohlNwsyuh^tkpsuJN1<+`}2+G|6}J0BZp$^+MlaDcmJ$BBk$iS z5B7L!=OU4}mG{kL&yFv$Q{A__jyInF-cIQq&et4l?+NL3De$_kKuPw|z^?-p*{+@Y zE+ijm{LM<&(VbPE>pWwN$OlqjFFn$(e(oxd?i=vO`^h^(ZA3o57hX9B*1Jqt@8qmi zhNi5@{#@hv=XWkMa+bl1zBDUW;5x21dRuY%8Fs2-PYU;%U+kPO=r$L7<$$8S!(~T{ zQg6>1D;T8T1;Z?x(uXP2C zQ&qyM*UhRlbkVK)shw9EIfW-zz^=`+){7k7ANG1^^l61lpcXMz3M%5#snWy@eZ z+_Q-H;zz^u;>CQtV6Ik-N)h`p{5{ii1aYF-sb!*V4!f5cEx`(@x8ChuV&w213?1)r zOK;M>KE<;RI-cdd^?k<3_R_*oUtPp)2JgPTg8TR?M7q{3wJ6V)tJjqH%R*KPr zi=l76(6`ea8cWERD$n`ci^u8P<(9or*EiWy2z?*E-N9|zZ;X*=6^$>oXk2D!{P69S z3m+aJUS%}l+R8Q!Jeus8!y|Otb1&iPC3VTIHrMQWXJB@H>Y(kFy|!US<5M=Gg=e8I z?3E$5mu1v39^snhJI5M-|3<+6%064_HQC*H7jjwW!W8iBt2*~=fM3^mr?>o<^{AcC zTT;)A-ClR{=e%$=m+{Puhd*R3W769{97;%M1%X z`oHWwG>#AMTyEs)e(^$S$nw-T$#;KVDo61qJ{qQYx?tx3A5;FPRF2}^i$Z=e$6{r8 z$lZ;9;(wvL*sa=J2Z|z#%ol0F3lYp$#u_};dU8y zlr>6sUn=tS8YO$Sphg9I=J1|3-#uGU14^CdMyXSoQ77gq2+~=K5AoVaA5zEh1xDNS z=gL`&9JQB0AN@MHWT(8=heqvmsmskJyx)a-VEV+yZ(K`g9>`8z3LR+P^pCl+@3T`Y zPBxxjX1R{oJ%8pijC5|Hhm6@`x6!vSr*);^I=2c@@by-u`3BMREWKZ`g=p7Bo&wCr zK*5cZtdunQ_ ztYN)zEyIJHq46Yg8?7+f=ohm>y^rQmzcl7i<6ETh{Odc%w}^8RE#i#QB8tz2 zX^-q&YkTD6TH7NzOnY3C8@@eoRmVI$*I4gJD|d_8Wa?zv1Nvvs>XCbsKDK|+qJQK0 z!kr=gm!l;f&6U^t(2TYiePfVc-Ai`L*@+D^t{P)Lo9xNpGY*>1rjC^i(rTpyvm#0# zTS#-EqqV<#HUoCoS9J31i_K&8u?P2+F!nT_U$;~0hP^uY?BvI$(Wvs=PmGnMK0eCP zD1+Pim$`EGq>e_J6C8~~eU;X)w4T$~ue5%dx$_cnCD7}q&Ze(6#z47dwR_T}_lj{j zO&N{DuV3}+fohM+bDNE}lJ;me*`x9NB@ssFG;R-XSbNNP)Aq1oUZd=<;!ft{7~Pw( zIadd5t8Jr2L#boh>SWyWkUO6!cRKc}W5@Fs3XZT-YsE;>cz(yuHO5t0pN+srOXbX8 z*88#2l?IobrT$xKzLBS2&l}J88XhFanfov`j-!z|HWsHpXmKGRV%el&ZmN6e|=u+#L z-*~>$SZk`Y+yY*=#`D{E$}wM^QjfP6Bvh6vT6QK^HRLAEI4 zjNW&z8&?N-wB@>`uPpTI@{Pt-i&hHy2x<3ZTWSzmS!5fdJn<_nVY+VV>#x~-gsD8& zZ>d@m*j|*7Ty0bue3sTqIvn)?Tc`Kj^^+c$8F*s4s(qS zsIzjLr*2Qh$z<*eNoN+h>agCYU5wyKhiA3!-XJ*~GtTxC0B zE1bbg!~McD@}3dagD4N{2O&}CFFe_*uR1`@9J3WBj~*3xY``&w`=jUHu{r6V3-}cY zb0n-jStnGCpCu4*a&`fVl+j)_f&hKZYK|&hmUf=dxL76d7x{HH&@e&G+lXY&eno|*aF(buw=v*5qMk#%;9HmrR@`j8ua+a6ENn zZh`Ij)Dbo|*OhwY6wa*dc7jf49oewMbe5S{%T41Js5pKCXALQ5ZT`j6FI4^F7tl0R zV&=$K2idKcJ>FMjm%U;MoK=gj3el7hNb4kqLO zp@o@8l1FR>%SJOsh8Cax-TjQ}?Kr}q^_;QH5!+xTuiNKvUngXn&t1r7_6I<1g^d$!+7nd6lqO=7=+l zh31(ow1B0IvykI~)Df~!il|-X@yn@={oJQ`Jw`ToBi18h#DP)O=DPR7LX;%y^f^53 zagJ#`H!Cmmf%-*B50k%2Z>T$t8D;lrf6`~PBO2_b`|WD(@6S=>_xHKsFqLbh4oHNSa}R|0N6D z#C^3i^+V*VKYiii9{v*5Nk2M_qq#hy4@P=1m zWpxx&W$q;HEs~x#@n?)=R_G(kX?XARFK1*qYtk!Hj--sRBW+ZJ9mz+M;p>j2x*m_3 z&Q`}v*klp;e9oJiC4b^)` zs0Y1sY@T5~-0|sVz0!IcEn2A7%O$OQ&F!!@3cr4}sXLCRXx&4W^X8A~)RN=rq?=Lx z%&}C=bLx(#jSS&leezFIma@F(U!IXg;|^9Sr?QUW?yER5AHhtdasM%z0lm+Y^Mwz- zG~{4K{!x~{jn9Uz60;%9gmw;BT{lWIqzdHaUT`%r7tMaw>hmGnaF9@`Ky@4y3FPEx zl|%!?xk8|)I9e*u@BquDGL~>W#M}e6hmS(1Coa^n&s|{b!3)>0doO5g9%_8%!rlm zoNb6dmwWgGpZj_KaKbgLTPE|&qGIg~pVf}hT-r693@Z)6@}n2n>B~K1e72?=U7v5x z_F#6m@Mv)9aG7VN$L=DDfhY8N@Ep&^lU)OO!)rV<>o=S$X(C!{D{4@fI{GV~?=bR@ zwmSICc!OnT9MYRg{kz%wk>Ut$qgij?TVlgUL!HDfkBMC#FA^YAZZDz7hnQrXEh)^m z+t(Y6sjOn(&RxD;lMGZL)suVCOfDRSRa&vSb5|TiTlQX@x{{`2GnFr#**ARQ#=UJc68HF zD(2fT#;-bwT^`jqicuRPvCCsm@i+rf2JJQI=P@6B{W11bLws+n=b(yYUMo~0PP)rI z65}kMqD{xUh}bU$WHZEGa$=XqSnR`>*yS;?%VT1f$0)mQ&;VB0H&8r&H^$fu#^dG6 z{SL)uc2iW0EOp#2i_=|xOg8h2+={Z^a_c}5Xm*?#gc`*yjg6t0nb>;}k!WKv4qwy_ zq@Lpy8|b|Gt)N5kE&eV)B2c!)XqIwui%>wAj!8a7ipBCSwCji(e{*te5?*GkcN|gm zjmb(kg4!ZGvCCs(m&ZwNEtlBkF?ttE?DCk{<*}i(qPV$fP0_j{M8u!WZf#*n zSsV(}J7P=)Cw6(%Ju$J%V>h0s`8(Qzef_asUhq8!O*>S^c#&b=F)>#C!z?u}MhWd9 z8QZR%*yYj7O@e8ZH`zBoWE;j{DH#K8xQOERUH+aqMOzK1qgtlj9Y2J(8{&CRu&Tf7^aH-t766pzi;Tpr?YZmQ>7F{+=?@C+~C zxzX!YH)=G_PwevObvNALen)f2w$<3#vUaO?W5~4C?oF!k_->ezt2}gKVwcCnE{`{C zG`2)lpIF05+?zLgH@aKuyw&6_HNp0FXpXQuBszvP$6n2Gr{=gzbL`U``!&Y_ z%@J*fL@HAr-T2|oxouzae*1x>gHvY%RfpcUfDYK_1paW_zLfpR2kZxvhNJhr*tLb~ z3)sVA%6-9wGUYLZAJf$*@}&|;=bhdjalj+mN zrPzfw6MQSQ&y#N;d&Hc`j0=^95}sJ}e!!;k6m50_K|>EK&Lk3DY@Jx;tu^q5Zn zP{-6Ca(lcr#?FT@cI7aj0>6j0?q#=+#hQH~uh3coj;(AP1ozQ_19MDG9CV^>d-PxI=E1-JdWbWboCjRR08S8rcn>IO?sfm#QnkHlR;(eb-T~lLk_Gw*HQ+=slT5K^Tc2N7nX0FH7-``MmD4!-B zRDW0p9VT{vHFo!Su0)ygpnDrAzba>7-^~5#2WA{h8%{msJnXnT<-TNhPOsLM=FSa1QPXv}u!+%aX> z2z4w-cT(B6QQ2_&q$GRJ9aGZgst)Am)_cClvK~3K(Xu$~?6o(t6imB%&jhARo_^Sv znXXxIk_Fo>IN5?zEb>z|1?f-G3aR) z`V3B|+obw2!$MEzbh>q^AL$nQOimw?Wb9ULEZr_)qVKXNSe*_{4ONyd)cX8D(J`e}oHiG@Cg z(=l@r#~cfNE~oF2WH#4ApU3GxH0bjz^!c3rh(Vukp)cU{Ck^@n3;j~d`IlPg3pt%` zf$7IW3w;r%)2%7}SY)9u=Jb$%FSgK^Sk7N!p}ROeMT%!G3q99@^Em&n4E{U|eJQ6u zX3&>f==q%fxIxdi(3f#~XuMcvp)cq3&~$pag}#E*=@O|QD=hQ^3%$TXU&-loxzmr8 z7WyhqUnj|Im4$v8r_&=_{kY6RU(M-VlFU|H=!F(~p@m+=>7o8y#OWdb*6AUC(di#G z%G2o?cA25m7b=*>Yr6dChfbG>v0`3+XuK)5=vTt&^tezzN-XqJ3ohgQb&{QxF-=@Q zT*ymeYuTUEbYd#U>)3Aurrac4Uw&l58hg@&lh|<+wzKz}a5CF(!YM3Z!VdN>6Lzv% z6HaBtCY;9RnD7kt7gAgtNi3bcV!|`ok4-p(J!!(3>Eb144W8?6Fo0ol-> zt_7ywRBghgz_bLEc$wg*A;HGhu?4{NTjCsGomZz{NCr_HHg*Gh-h{WZubJ>W*uy4# zIlI?{-^uz-_+9J<6W+$IG~su%Tob;LrI@gny<&`Qq;D%bW5R9hQ4?-wA2Q(%He|wA zFrNu`vTID($BIq3i_JFS?dHFb?lucT+b>^_!_p{ zgs)}kCfvZz8FO8--$wR~32$OwG2uq`2@|ehcbjk%+iAkru^UWyGrP)!o7qwmZegh= zyoLQw$b8W6dbSvyg;?_Or?KTMLtvVtXc%Aq5B-6)&wB6hvNbPd;VJ%5|PRs8%CcA3Dm6x3KLn{)@y z9@$z3`=-D&$I8|+*>QnC#&H(=h`>iVp2glPa4W~z><)qT`sJ{0fxpS=v)N{WPjh?; zs}z{lFxlE1RwOXZ>9V!C>=J>0$niY(XW>7zCdt<3vzG*ZlH&#JX%qcY_7#C?jghS_ zWDg5WbHr?I5&Mw9-5f7w_n7EQ*c}3=aJq{H1TN<|m%U5iUvZqr8U%iffoaa4 zt>v>Kf%W!Y#-2vLJhIW(|5E~_gg|g$0M!0=hnn zEc7`Ryu*UY_vDcWeX0P`X4%+Qq}qoWqw~|o^zngG(ue4z2c;R5KEs%c(hM6$0Hi54 zwuw@w4J&3npT-xWlfJ}%wZL_hg1?>8pE6u=Q0`G?oVT3vab6LnIIl)vE+6L+Kb;pq zO6PHX!M~XD!B685oqr{z;BTVzXNU{l+Md0488@F;=B@pc|B!)z~6#=;&%zU zl+W#g^SNB4ygrb#Tkw$|Q2C#xbcT&RLMin48l{l?9i$|89$}o%?TD0@kCe9y;LU__UN5C6e~?m~KZG>g`BxJi=kfYM4zCw5 zKM!)gMRcUUrxf+dfwh7GJ zALn!XqWt?PANBeWrI7b=q!W>MqmU=Jg!pXw#9X4DsfzyS5rO^xy zd>>(~lhOx;KR*XWQaz<#)d;**q^*>q{&YU^4N;2v zKTIj~<^F*Be}(W*8G8yT>CNpAe(BfTpMb9?KBPBN8b$8oM2Ec7NL730iSyP`3OSXO z%JzgFR9`x85GkEEk1+VCzLau(P_9Q{>7Qgjst>Ox&ffz}=UeU4BF^Lf06F~v6F=$k z@03E$laxZA?@|hRU^Uf4_Lr-P4!yV@NO^w)Gp`5m5YZubgi^@;ETxe52vSu)Y2Ryz zj`Le7#re{|tnKw>qC*bpsoFPIdRfPXD}_EaltMpVPes2EQ9kVTX-bv)%@gOX66qBp z<@JS}tpaya3On)f4|Y007;=svrTWbwjPe#!it}Wq?FywuNQpo!}r4af!(l;Yd_JccwJgz6?eVj1tddwm>n=r~>Kq>T* z`d&d8`ZNjttw>3a*@S;2)(yZ^PpO|wiBA4YI1OnUE)HBi(jvk$_3IOjgB8SwagkCw z?;4Tvb_czO=nskOJov2s6A<)ybROy<{o`tZd3!z+@=yF^X+Ok$1G--QKU^Ov1-?_@ zO`47$p%nDhScejQm{QpB2&KsXmdO9T!1L_7o<&HBzmrn%-6`-nf#={p0MT!w6!Pw* z6ntM6`M(!0jCmYSGex^0t)zUkUmfv1uivxLp40t8`?20n zwVw#Tcvke^)1n=375Li%9~AiG0{^4HUl16RR_+In3Opk4V*;ada{9js+$Zqk0)J58 zlL9{=@V^U;&d1OHlEAwJ{<6U6Oq`A#Pq`ls2>ca+_X>PU;5!BWs=)gN{+hrC1pd0f z{~+*_0{?&V-UdFZ>dYTMck(s~0YX4P3^)k`3`pJs1VlSC$qb1kBoI)lw8F>P)AJF?- zy?1l`D#wR7evRY1IQ|*OJskfl$G3C*ZyfL8c!*=@eAGX~9Jg}(bB;SWeuU%Q96!qO zE{-4L7>uU+zQyrv96!M^2&w$r9D6w);CKhePjY-K$4_zG&GFM5-^cMY96!kMKXQCO z$1oU!X~gg)jt_I(%kdG8@8$R?$M5R!!v@Qo(z{(6_+MWGjxx!U}j+g#1buM3VnCfvg*EhOV+|Ax5cgs#cPr}4y?xL3FW_O(*fBm)5u}hMoN~gEOU0($B zW_Kg1kBU^(+@Q&)*xL?8!HmMmx4Zqe`X+C)v#q76gc{3}Kw(s7^T;}nyYALa?Y=6% z%kS32xm!oYl{VLpiUX6>akkByt9Q3~{ch07)rF(nt#VXRQ@tvx-MhWnU4IiMmjrJA zmYrS=)$QNZ(kLv(EZW?zdTpjOMw2JTl;eB5zDCJFjbv0Bd*|j(UxXAqJ_3JTTgy(L zUZSvYbjrq-+R>%3W2}bjYjgWtZEor-Eng$ir17@f{dQNoTXLnh*(=&7`jNHZ8(ob% z-5XkT1keyv)uu`jZlI{D!P{J4+T75hH82#bF%DyyJ89OVlcHdVuyhSa$mL(tXWceeqmsH%2jG4oWP;bV!zR$1NTYHVz& z!>;bFBh}R|x2x7$jcR?J8raxYK+0`ft8GPP)n%m{)>l=RIY?Pvk*ykR!hwzsd?IGM z7hZ~QQ;&s3kdNI}cPnGqFjG=eRO*1_j9lin`TZdle7gp`mcPBtSFIl9&8rK+sK}BP zx{^FSN#SZ;$x2;GzOE!kSE46awMth~pexDMldRNr&PrY9tkiYR3SH-{&~?rVUFWRO zb&jrS1-i~D&~;9Mu5UUHfti^bORlirjpC+w;drrCWo!dAe1Yo2Ofcxq142%GLK%uD+jg_5GBq?>nm5b!nAtSAp4Kt~3{$*PHF;D)TBwx%ozCr8nQ~*t)qmcO`-<_)~5(S31nLHD!5u zTgnP@x0L1Onzybg%gr@cK};3IR6$Is!{LCxH<`CoIjU}4X}+Us^ZKIo#SE?jSW;%L zsH(ITIm`~btq8RRiDF4VCIMGVf}mZ>d$S@e#pco`nn7G8p@htxN=0whdHeuk22m}Quw%vG*b<|$VxY085548^QW2Nke76oL1V#A^iJ;t0G3iT42T zYE(QB)2m$KT>u^&O@=PPE0A~|FdUBLLYLsplX$-Y9-d!`OYrdFImn9M+eBGqOl151 z3*yzh!+_zaICKepKaqIdAb2IjV$bR!#Pn)?m2vF8il7R84@taJz%ye)ehFTe#3Rt+ z;OH@Q37$vdbpQ{J@}GV^uC**ihQq> zc+UYZQol@)c$OKF_5A@VOYuS>i}xXBiY_g#q>1l}wd zW5gx=e4oU-umHvvG=yJ**9KT^pUK3Y50ZJGmv|oFr3n&*qW!Itc>963S;Z6iz6&2z z=8!jmCuB$$pMNFsP66+r%F#kcA*8|2!jAgS5dzfECG@??^}(=8ul>M-AvJUf-V%rr zx>0x!@B;XOUqUAHrh=o?^`^(`ijwyS;Hk%5J$+xOj?TWn0B^r21cZ9}x@w~1#kr#6 z^#CsrMZSr((Utc;;2nxW-~77hcuxW^8b9aON2l)u@S@S@a7X9Ap8_u$eH$C1E-wc?HqS1FB@S>Tw;&w)-?*QPjNqv9b)@M5510Jrkz3?Blq#=FyE}5El26$UJ54M^i-b)hC zdKc6i=OwFn&q%z0iU(WBkiG{c-XQQQxjxuJhIn6)cqw;>{Wo33tCx5sz!Ung-3b4! zmw0`^E8+P! zPm}|;EFpdPj-8r!26(vk#(ZHb65{<>;+gIV*V`Nw58ugC>#G5t$ak)acelhltm0j% z;Ij&amK7;{N?Y{xwVZX)tFsXR|De(@gc(^-WlMfaNc4S&n@vrfG7O2M8(@E@yLB)o<+sO zcPrI?HUdxNyHv%qNW8hg!*-12Sf=8^W3w84IVyeEsCa*X&+2@wz(c!G-*OdiNaA@^ z`DUtkPfNT2@JwI}>dR8`pnGZZ?f)`sPsqzw@tP&xAn=4=a#XyVCEgJ5M1AC{ctsNL zO;x^mDqexa8&UCAsCd{G)&84%f7rfNWAH30Uf~$LLKScI7`ze{Z_OCItt#HNWAHpG z9v+8?aY!z2hl+RI7`$#3@A@%#eJb8(#^4R8c-Ap^$5cGq7`#_hJo^~DH&r}rOL~4e zqv92h!5dNW9Aof|4}{y5a}3^G6>r@bJd27~G6t_u#VZ|ySEAzGFa~d{ino3Yo=3$i z8-v%O;+2oV>sIkLjKS+u@hZmP4XAjPWAKitcpJyyy`ti68iV(yidQuT?~IDKc?{l& zinnD9p7AT;_IKkLytyjgO=IvZDjv?)di|(S#ry0Syb=`;=K?)_TUESU#^8BWylrFf zI#fJ3!qv^UTg8JTS6yD8iU&ujy1W4uuVxJ1F%{1>2JaOWuXYUHn<`%27`!toUi}!n z5fu-PAa%=Yd@$Vp;Al~oH&?~mJ_gUC;(1g&T4Q9oK_D@~>x8pHnP=H#qg z3301du3E`rYLdR_D03=`(1bQx;D7k4{1g2gS3m;`e2>Q(CG)*=>*AeLopYQO=SbrE z65<&eF$YRZ6FrHCmKMK4KKbacpEv-O)RL1$Ahqr=9k-o-QnB@;gq%F~A(=jH=sL=O zm0XL=9X2P*tn@EvH7+^60#hEcrX?KhSYRpcI+_dEwx5_QgRy7#llZd%WjWP-%?+uZ z)I%A?*yjXGjo|~Brhc$(;vE;#xGE(32=R|(DWUdL*=unZRy21 zBe?{mO8nU_CDCgPkdxCvQo3UrPp?3pXt(Kz?fffBA}?Qk+B5cN-i`xJ86b}E(` zZ~fLgE8Rpn#1wP|JFRKK)?6n`l|$o=L6Ee@Ei^b4C+TGp^rm9!Z?%F2Bm0QSfd2OT zaDvB+;_eXkeJ>WQA?aDcG_XJ5C1+nGgWY|0^YC1XE5RfE_W8rJLefBYula<4A#+TP_$>pHr|$+VG^L9gjZ z#f2TNX(!cTC_c?nW@fa-1uwo+6O9#&m5-SO$Ra`Jt zK_6-R*?UA$(wPmc-B~X#9HVBIhWtQlCK1P%j}MOaC+kb<7PpLh!4mR<_2O#RB3{C9 zi(4bLxX-xKI0ySt?5GxZ#qe*tjJ&K@tRLOZ*1M8<`q8~;qbrWfL^~6$Ol}(~-2 zQdaVO$w`tGd&+ixtCAOr$)g@pEQv!o^b?Ldw)3A=w7nC?narZ0_z#l_+5+w8q!~0< z!;njDJGp;E>7QmY`5qrJ1Y&_zQ?s}Wy;DP5#{eCN209eWtl^pItY73i*EnsVUU~+` zAlvy{72&-P=opml^zbprcD_~7cyG#99DV*Fye`0b1~1?Dw$f2|kOW9c&X&@|j=34B ze^%mHuA54YHA|h9P*Sve1B8~Ga`bBr&hW$o^LvMK_C4E*3jq6Wi^oNqhMy z%42@5u_82jRS2_E#@=5^H#PE5n z-~PX+aBf3Ci%Y-VSw^+HrJvgFmPzdnN2;PBaHcOh2N~5!KR4(p_EQ5qaKl zQfOXZay*y!r`X^cr}!+!*&#^9P2*Dcwqa(>`i&dU%k zXUWi9+K$DV<-BWQxSaj*e5_5)usH|jV|x#ma>4KuUE!I>#%G>nUh*R6=y6zS6*W3~ z98PGBJd%tmtF%6gG^fmIjWnkiHRYV&s-9C4XnnTSgiCkD@YGNpzFR|JW@SDTHMdN+ zEEN~pqncB&Z3dh@up+x!cdc1*!5>;{vKbo3eCv=gT{-I{SRZWEw_bF%inZo;pAp9V z1{m>;FyiMqOQrFCmSyJfG(O&=RLuN1+FLJf3YAM9?X4HLYU@bVBGq#xU&o)E4lU2R zC(aW4w)JAyMzPYv6`FOA#fK}jfCp#K(mmFZbSuuE);-oVwnq@-nOd*nq_ZoG?`#Jl z_6rMw;T^$XH;ml74%<_QG53JiI+ANmrk`*(u{V$y`uw8^`+>Jc?FU$%FUon+vIX|U z(6Zg7DO-S-ZIG6&CseioFIzXvIc%&}mn{YMJ}{npV*Mt*%VH~t%=i9Ugu5baBha@4 zNv7%P*Fw+w*?WqS+_%)p*eA~XbzkOtpV;DIeLu@N-x)l5&qy*crQS0#l_Z){(hUn^ zo`Mu{&0)k zmWN`>!Co9;=p4;Q(t%b7m&f#B>%`XDF~ruu1KooQaK5OxaJ%bT&f0#2oE+$$T8Q!1 zi{EQq!Q(5=CBv$DpgZwwywXi&$6K?wEdIk3MS(A2X03k;v~^hL9ELScf9!`Te2rt{ zZGPR68c$Afu;vC>^#tk6qrlu7tT{vHpEDf>%T+M{objzXp6|3fH#(Ws@j-^jR~aTJ zEifZlFaAfXXvNFvjFj#i2<^sBw~AdxOz@L;VaGxYy@tL7^fTNmRM$1m(ai7NtX|(s z`N8Rtl3wQf#jvycU8|j!75ttZd&+w8e_O8)#az$*j;k9sgH>GkqD!nMnZ-Cm-!hb9 z;&niGqZeBO>7un> z^1PB^zo-y~QYeby=*{COGjP-osN#Z|r}I!*Yzj-4Ls1+@Mn3z;JF}pbS>fD7ftLQs z3X2mhh=={?70&d|YoNzvP#dt61>fxO3 zt4b5Qp??g=@|ubX#_>=2PTbqc`?~i-Ybv=0DlSxOXDzy~!*e6q|4;^70xjJ#XF5Lv zig!AXr_`tq_}e=pI~=pA;+d>Cb`3Dh?dp3$6Bk=gjXs zcxEt$m`(58PfH5>3ngbHoj`51cH8e5{>tHRUL9+)H9J_L6d-M#}F{0f{4 zbZKI`Tj!YeXk!8-y+dd<;O^zcRzKiC_Z-WvA(H9mCkQRtR5iDXG<4?`@WlBVq?iDV zye=tj#@7Z%3@Il@N>W}7d~@W66s7I662sZGS&BK>g}Xlzd>{yOAb13KdI3-W$h5!> z5;HK8(u=!4vPZF8IfOgEuI@@YXBteO(c14bq~qR?YGkGMRR>dpZ11P`sFF^11);s& zi@xQz15kjD3Y6~Znu+||24P+G%}B38#@N=iK6sBbd+qwTM_fR=U$c z?=2!Wr`=QN>|N(c`|(lS9|ZOc*w36Ii&BF{!NrIv3)6_&)25jZ94k*VBX}jIfYaz7 z!)f#}d%`fD4a@@ja4-I2*o$K>Gx%P7!2a$j?8!I|v36$~$w(n4+`EU%-0dSLaR<-q z@8a_B((`dTvf&)@F`OB(6Qi7dvM97ygVP=B`O@5v_$>Z|50&ZjhU2nghKyOt(DbZX z!xtdeL2uy5c^VSW)+7H*Kjk_No)Yj!oKwkEh7E8c-`^2fkZSS${6Ei-bAN3~T(m65#wRC9nVKhn?loWrK13|R9N!lJKuii zFQZCBOr%%o9f+uF7S*NIa%Th`jKMTL7*W$)O^NEq^vMB@hKwGv5WSkF(NOe`gZf16 z549C^L=V-B&|y;PNDTfV_-61I!6Puvwgs;b#sp`+L*TB$>~~H)pOlp{6qhw^sK4i! zeadN)op?Hsl`!;ZPY2wUC~-bUS1{(F+%DK@Gconos4dwPu{36tCFJC(;DJ%4NywTp z%=Fka8tQt6Ml6FQy~O!zPjFpIkZ}q%9MKXjnp~a?j@1$^5j8B=Xy^|9Y*hPU`QwNl z?g`MxZpA)kW&5|2jk@WQq;z{V=_-TrdW)RYvjFcXsx5d)qv;x2TgOHWhv6>P5$pLC zw(p+bMsP;}yNXeL8%M0cQ0vKae%84U#*98*p19x~@IFlo?S-6#6Ms16C1ix&v%}q~ zV#0mtQdsjd?~I%{_q~IM6W|_*xVP93r+s$}!(v>)`8xooh%s+j=_eA*an7+M zoyNTli^mx}&~1Qt5}ae|4?NP%^pQo2g8i@xc*OJ5o<}`j?s?2}OAqXE^M3YTOiI7! z#cr6RQ^;*NLoY=Qbi~J5wI4niJ`;Dp)f3;_@3D6%9fdG*HKmz=g=7BfFi)64v$AJU z)~jgs&V&?fz8Om|t!>cz#;Ii37vk>92tJ6h#0{%UlW_PPJ-?NGh9~;g^N-oC<70k5 z>{weNy}{Bvd@c3NVc3o3I1NGC8@l@g!m}}Osv5nISWm#YbF8w^JJ^4dk5Z%Z5j~Zm zJ_?T~%p-DNV0({gu)AZeAOQC~@SZ-NR(vP-O710Mo=azKtQ}ap!HjqXx5G>fUL{N1 z2~(hL;;a~VBraH=M)wY|#(D?V?(>f`{c*u-oFrpzIzwzX6UnA{Ct1SQFR+`#I=lF@ z+*zSIn?djQrdra5|J#c_F9`E*s)Y>iT_S3W^%>j^1w7skoLN^pU%E91th4a(L@)18 zD!LB$IKS*v=uUedx#w>u79WmpyxUxjGh}5Li5Hf#(u7?J&UI zl1-jr4?g`MP_O6od(#%;*wJ@nK}fr0WHF&DLB9iI{8bZ>+0j`eK02VI=524 z^4dE8z&5oolp9Np_X(Gb%plB0whI&OXaL#~u*iP7J3fWYx%`-s!-ITQ;QW*HvN=&O$ik!$1Mg5b zrEP(hjN{02!}xdcP)$#XV_s<1W~~zS;4@3%oYZ>QXgD)CGx%FqZBOEd3h6q^ypb4c z<4h0V_nn-gdscc5PPWyfYsCe->xz&kXIj!>Ty5zdy{2LNX*Qn13g8HiuY-JiB^j$> zg_8p-9Q6o0x^JDc#qsBXa-EDB%fo^rMR2zqV_%1LMQ|OC&^SMh=Bt^poQeCqzZP}D zIhr`zSC(hJO-Do+^_ISEcq*OWaf)-EJ|1JjykOjjKQUrVDWPLmoYQd}TQ2f`HbMee z|H&|4WjJT^wHnS|YNRX-BfMw8Hk^1CjdREq&WD`S9%dt|n8mi|7KZ#h!_olbV%p)a z!@UIs&ds0uW0Gm3(?s{?CC34g!*Jr(-!ou044a_6Bn=ThKBw|sBzi}vd9>A` zoVGf{XVU{$_IH`QU00^N@Kl=gKH8Jsv(U@Ri0jzz!Rg=VI{yUj%OykqRhHY{#&O>Y zHL~{Y7^o2|^?W=J#XZv{GsL~b+0PGjV?A^^2fD2b0!Ix`-+;B2aAG7mMWkJM9O}>{ z?z_doy@m{DGJpPt*Q_QE$D}ah#Fx57(#kyKp z&utF&cTBb9atmBNzxGtlT?Th$&|54YW>x&KI={IQ@>7ppVrOWjJ42S!YRD&5oHgmGC;1`tG_kB7!kV(~NP$!q zAMUf+Tuo9vJ~ngXTps8c@ZrwO%2#J3^^7lbK1t8HI&c(MFOM9JdwN;O#)Ko5;E9o0 zgv`&G7Z2-#StPDFzOM$_`79FKtC-?@!_tJ{>R>LiQ*b3ohNc9kz}#^4p8{~6iK|0C zS7-IYT#a*2;^`^pJ~71hk@+tkt>QUO4X!$#w9xKMNoQWgm0uWD(l(W>iNih=W=y3s zjk^C}kHT^AAg!zU+Ijop=hANq^`cn1mXEW10os>hQsAy#(6!gu60~%9;i*!^ge4j1 zc#nQQc=XtZ@zaxrEuG#@lm(84=k|nPO2*Rp>iOJJ+}{yvNg2i&9BV?f)oYzM(>`gW zGq?gP0%YJiU1lV62A)tJv@aY+ebcEvdJ4*0GU~(mp6Q!LwXt(hwjL02rVU<$>rMJl zNqQAl1WF&V+%*h;gA0QLM}F%<{l;NDA)2`!@@!-C`>Y_wq^M%x=^Yp~Snrg^4nFJ4 zb-_kBRwohr&-p)Y6l+`7f8wD3e1Z0#+f@Ar_GMY^!`OcYRQ=~B+J9~guBRst4i~g~Ox7K)P{E;QJe+1Gj^Kjif zizGn**edl8CXEj!>huoWeT$XsBfNJc^WG6iQ-W6q=LFS#WF_q*#!w%@d)fktKBA6e zeMB(y`^Y_qasM>mIaRZ^z0viHP#;OKwBt&F_I&Ig`0$JOQ=Lef7rukD&@So+vC21O`A*}Cr|I-w=T$0?DCviJyXn?g@^l)O3*K-T z#FFiEt|-Qy_!3{6|B9~7*U%H&*{9LAe%Rw3hC7z;b{$?|+PnAYYF*9a|Xp!2;@OG=|H34XCX2v0Ed zKR%KKPl+V=zU$h^{W62j11pLXuvHyq>k78Etb&sS^!zO9`S{-CK5JSs{^jlJ`_Qfm zpAF)!NNQJXHOe&NsgpP}K#k}{rg3KQUDvPqu4w9dRx9$pNbLH_$*10x$H!Or0GavT zM-_L{y+7Q4?j=j&)qV2fqcc|VKKTeVES&%0ylk;ExMpN_rIK0rHr_w89vZOcza9J3 zQYTB><;1g#baX1P79TvSK;H9$>)|PkY3YoC z*32ChGaY7OEhj#>EA8`+n729>JOa-#9ECf7aeay=?eT%;)wj;5!DWnRKydu;ZQq{GFU4QnNjSO=zL}gCu?` z$x6!h5h9N583cko1FTK)QrnGfryJHgS2&HDR&zqRIpnJ(OSxvxuq<>2z*fk(0u`%} zjGiLuEz_V8Mymv8HLMWaUE)dD^qyrrp9IxvfQ=sWBCPV+u7aNahfXq3f5Hx9-?4RU zEwPP`6rUabcF%Jo#@^>flHmDzWeVHlq-4$=PJyRZV?y&s8i}E^2kz*E&Ff)T&H6do zywAx_JAyD@$o-n-$i_$3ui0uzjE=KtsZ-&!MRqoYX&lu|-JQu*XS@^j? zud@8Ax2Msb+7Hj5;JJW>u5j52UNY>H4g8rv0#98SQ-qY=r(wH%wa!o1r$nU>pK!u6 zE@k;OZ{t03+$Arj_OUX?Ie&Z{{e>qN3hV%kDI$J8e{ySDa9?Kf5S~$pr?=RNMHu1E zS0Hg>fzMVkO`>H1aBj#6~fvHNu*-Ck8X z_Kc6ZPhlU!Ga!5tQ)}ZEn>Zr~!m8Oayl4kGY1%1A*ZV0i0inI|R_HP6j)y7q{CDkIOBw4dc-GW01$J3e;k}fkU`@w6 z9vBT%7WTNhE#0*qEZYo-CB5nxc>D0Asl$4Hc3vDWJ+^-4!#!|kP3?y-(s#v7&{B5O z=O2vIuF9CTbd@z{-R51N+to;FJ03}6eaIIKf8G(S>v*&qY@mIwPJ^~-&=x=$or1Xm zP%WflPY|x7mZP4><}*##gB-c6WUD})n4XdWB~CZ=y1ESug=AT{%$%DJF|MB4+ZWyr zY`E`fU_Ro~)KUCISer2~eUuTS^3oS2|KM|Qc%O30FniZ9&bi`_XEI4^i5&e9#<>wzaC2|UNCq#rq3IepKt#}lB~>*?uK&c!Om zqLL#X&)&|butj@|Jn(+s*ZN@AAldoD?8!|pt!wtor9wD*_A$7_PLoB+mHJ59c?!_#3kzUSdD zN$vOjDtHR~j`oE8GX=CyoTN#o`uez!|4aMI9#WYlXH&ebeA~dPA`F0^bUWH z+WEACjA4o^L9gf#f1RxE@D2(46ywKMi>Mk}#w9Ads_Bg!B= zdpzjrJz~h7I-Jwd+F^ZPSz6<{26h`mQ17T2_r!;SQ^B&HU<~}dlh?rClD?6q_tNwY zLCkUM5qR3-7V_0vPd<1voYPH|vpE=(Svg!o#{eTCmNIDZF}-NFBA%sw_C@E_K|FWD zG2^F6ti8PjJq<_r!Xxkre)<(h5UVk!cPg`)2st?t8+`IZB@y>3r=XuGK?U?PPsH>E zj>Ke68IEjUEVWNj{f+Mvcb;(W9;xVpQH?%*_g>P|xPHO+HLVvrTg5vIFtfn>n%0ZA zwTj&pIk^hTf$u`BprL`zo42=S^YN&Jjz#z`#0KeYO?We=RlKW|+*bo{GQijD!+Q_x zO$qD8{h_yd#(sx$7R;3!`MOa1F5MaWR?nBlc&q0tt>Voq_T)X3xDWO?qwbw!`!9l@ z!f9!SpQ&48f*-6fA@nx7+e|Cq_b*I4eejDMZd0zwQj5P6WLlZK)U>&!rE!f3ewVJU z&U8ybef|m;d<8XwnVEH~SDP|3+kK5*e|0o!I3H7&c+hQ-P*jnwlaeZ|~ap{KYoAS1S?c3U0cDB{Ix53K5-Bb%da#Rh!8B}+x zh{kWVKpFdX3$Uo(?StRrx$f`9qSWcY7PFcdf_< z-{b$HqHWxoZ5bKB0!C3wy*qn5v<3LJ%NG3L*;$*tv$nCNBeSL6+nl*OFSEYQ3qOO{ zo=Mf$Lp$`k8ZRkvHd>q60?qCcED%bv>zdlVEmP=)0K@s zUbzz*=y+5>gWKib+2$T61BJG1r^B{+%O*#4*-fRD<7=o!b#~)!uP>8!-v(FRIJ;!5 zoM^_AS1?viw;xA`|9ig=^}2}FB>6IwWwxuW?y}{Zz1g;Donv!#)#mccRdkgJs*m}3 z&Vs)`i-durCh*BNwY_s9N0f+76|%e>O*Ol{4c1?i+AA^3Y?se_IkK&5X`Ad}mKGQD z&G!0sO?Ic#WWMrpc$_c#E@RfTyIt=5vwg5CyPQTeyZzpV%Wgon&j;I<$scZbE6k=| zKqIn!Esd_W_V)4FO=L&CB%vL0BI=@{&DG?_P2hOXTw%r8+uPi*8*sZa>l(fAVVo;c zKcmZ+F*`JvxPtC%_WC;~Sbg@S6e4?~i-Ko66X+>aKk=TTx$K;PqTsQHzj3_#KG&M< zg;PNIsoS=3_J2ry^LVd8RhsFxapGL#YjpV=TH2Z>$TdQJHq2lXoyGWX1w=KBzvgCF za|=Dd9cQP&)ZE@ucdL86hnjYOOPg!^IPE<=<8%m`4T|vp`1lZ&@nTlHYTNy7E_%X0 zKFUQu7$0qI{_#2iMormm{*Ljp3$=-ZkfMrBn;l!L$La7$*eYumc+=*Js_OEB>he_+ zTbj}NWpA#iC@U(l!QC3X%``3>1i!0oJ9Or8RVFMSxAQ!1q)M;qPT^R$c%qt@s1Rsr*bD?5RX^G7^>Ev7JT}yq;2f|ad$+g2 z3wKss~Csmp1`I0_4x4+18#3Q&LcO=Y=-lafhxRb_rw{^VtKiML=ry=tiIXsK3a z)UPQUk34~wNbr5Z!cX&vKX7%_wcz2^~+=esMmF?Q;_dpl)*16yial9JyXwBo@AtU54{*KPB^ZGpQ zHgEIxadk{c>x4KZtbHOJGOi1KT8V7$Fd?oO@A-w=E0kXPQ%2!|NUOMEXX7QFn(Jw9 z-(6krZuf2<-ytOAk&ycAmfekc9hZ1+{i%h(T=G|pb1wAx=5g)r>@o9+Y2egap&E|s zyyLb*W=&Gkf2q&a$yLhKx3@I-FZpb5Ox40e6H%}1Fmd8EPh2a{W~TEDvKzc@O}kx} z`Uqp>deG*??)XoL%iK-4dLFmKF4_ymd2L8_;z`7~tz*L);r?EGV`g0~?ia?@zwJAH z@Mcw=>rx-glA1?Y?Synum3o%(xcbBoucM7q9nu$^F3q@cu!gG0rtjNT``TI>;BCB1 zEMLSIu1uN5#f}?GiyYOCa$6Cg>S|k6m1EQ9>hh{}0K@M!;N7Wwc&$(Ht13&cgM+7H z^(!Y zgTr@}TWWW}yM|%?{FWL-R96?3SCv*(qb7htM|trIs-mRI0k`;Un>KH$tlnH&?!f$4 zp!8`R~eeiE#LaKduc=PfsuR#j}O z-m-ybMy=&F3)NX_E2A2DOzDQrj!m1kRD!QH(RoE`h(?R55DD{&s>*CPIw%di${$-m zLqukqi%To2%N(uIbE6HDdb17uO8*jL|K+6dmS5@Y4 zK=p=A8FiZ$MA({cw3TgfT$fh>jfk})XgJjAP8)Q!DsU0%P(KU7?lFhFSXmnOGdJ9} z!B$qWPFrJ@HscrMR8>;KQ zuI>1Ql^5Si%xrFfO$ojaTMe(N_}xv_9=EF=-pd3LynN?x^Fsf+gg0f`z#rACx$pzC ze=hiXb%2lneBb}y$7Ru)0pBJuD#kD>hLD&j<4}7I{Qm^582T#pHN>!ITIy7iKoXP$ zLqd!());4uHzpX3#zbS1aY{n6aauyakkDmF*lS4GXGqv@NH}0fxYLku&|vH~7<&xH zy9~y=4aP$T<2?rBy$0i#41^?OM*MipY1bu?N2(8c&G7TLU(*m++DGE$3W>P$N%akxEwOI&urhHc))mP!om3N zxSrU%V(x~Tu+8)t?wh&025g$>HmLSZGPP&dXnQ8fHzvqOT+84C)>FcP_&ehc#&*Z_ zU<;j`Ix-0(AbbJ-+h=y{Hy%j1GyY&)cWh70U6a*U)OB-;+Hv{XtqJlM*DLVha{0t0 zjDYaxer$7CSe4GN2wi`XDm_A z`>8OH+F(qZ%z0m(KaOjYz3xztrGHOrfQGTw0NmJ?4Nmi4G<=CEi@2|V}}2-trJbcArSiDKhC$8V=a`XvI9TcX5JRA z8^AU2f1>Nf1bK)nCsOayiG7<)Q;YcplCk>@#;qYCFCdzcO<-aBATHME7fT z`w8gR*ABz;lT%+gP-by;#GsEN?#&xw>Xjth%-!}WK(2xR6YVGU7>qXBVGNEx5O-(n z!INWkkYBanvId!G>$)nUKyDqCw_EVok9FH3fCnm=yCh&u}m{0tdWzVCo zn>(prIxcJ7{1u#nV{e3Wwr0a^lV3L;YR~0a&#C+IH}w1Q4#Q6;$1iGo_UPNwXgEGO z_LxKmg0O?u)8#pXRIfGf1v@5tt!aWh#Z?9${vOU^EB{XH*n1i6P_N_IxE67Z($>aT zC^cZ~WUfz`Zzg|zqMmc`4C8XFk<|CLu+L1k@7X<*%j^5gwLVqXf8%AUf3*#J{tj$7 zbeU{e3;Bx6W1w>vZl$IkNWOE*!KCiQ9^+jJcgNowXPem^vk|szx?B${PQb6 zef3{pS5*UvCwj~>2?HTK#@DEq<9tm$&)0(;lReMFZ%2eK{A`x2eLi3*7 zXA%By`5O(!h|hl*0|sN4!MN98+-ETEHy95XjCUH0(LVo?1m&-R|B>7M<;YX-IhVh^ zoN7Pce985EY5Ct4b^a6Mb6g|T!2ijt=dttDtLMM{c_wu|=SA)3|L^2)f-;M%06yTJ zNp((l<4kCLH4q=U?kC0%8Ia#(&nfD5fct^T&ff%iifav@+b_qxfA!p&1qO+^RoEs% zgNhhSKK$g9nL>i0LOuqJoe8E6L-i9LGs^#YysbDt|?Y zNxURapz>Ek@&rk4q;eb|*kzRDiIO}~k|$C5d6AqXN%ARF{z6DTMUp2|Io1cek|p_6 zD#vF8*fmv>Por{NtFddEB%dy&pDxK$sQl+5IXqOWt!mL$J|%5lzM*AI2zCglPOV}jgbgJ*DP)E`wc?Ok-?=59W@`Y3$ zu8)P1+)U+VA^m1azKF^Es^9FD)$L7u~0dV>+E83 z0?$hbjO{r^g>n4C=PA^3fe2YD<+qIHhxhr}wM>#`A~`9N-cLP{llH&A`}Oai-ZkmTznTt@kL z51L(NlDwSC@mY3um6H#_9=v`B|6@ocIm#7 z8oZc1tiemjJsNBwof^E9RBP}u;?Ur0$TAIHPNr*cCi!rh+TJYk?;4y`_@Jf=T!K=vcr>gBMByVW&YVv&zUPB(%;A_bN4PHxj zXz+EULW8d-Yc=>YWT^&Q$#f02kv}J^?X#12HMofUy9O7N;~MNB-_l?wxle=FkuD7` zAx#=wN^aKR8%Tu)uP4`Pa2Z*o!R6!*d@w0=efUWW$JneD82@Sk ztL^&=c};^KBu6y(tK>lq?jyHr@YhI<20ug`8vJ##OoP8cQZ#rg`9qxAo^O)3H27gM zsKK8lPiXMXQnGAEhiQ+}%ILEjrH;~1opJUvE8^{v!C5~~=Y=Hgt?Hs4k^h=40W85Pf$TG5y zW84!P$Teg+$9pM%Ihn!n4vI6$?_oYhdrg#|Mc&}}B`VJ*Kjawqum+MtzRfZ2Sq&tY z+{1Ar<>!%hj+sC5$!9rUM&$+MdXAYrE675QagSyoD@iiPk5asf`~l`;v=8@~22x1= zgJaxN8pvvLoMYTW8ps;b&vAg_Yso>5agS&qYe^%=EWhi>Mvgr+zw62M9JBmCL$2W% z_jvH@=wt@Rm6UHIe}VZHM1<9^oxH~}?%52mUweb&dnqm^&vSf;Vh8y)$G8VG5GT2x zV^%-w$Ucs74`qN>)xxov@=M7!j&aXqAUBYW9AmdKkoDv`j&YA<04vY(_KJHV11TrJ zg#8HGk7vrM28H~PV;{t&8VsbLW1L1)4KZY|2FDT?$9P7ZYKSBG9KS+wJc;M{Rf-eH zuVEp9`Q=e;Brj-iB6*PG^HiQhIylBN&Q!w`Qp<4`#mQs?$9P7YYM4r_9OId6s$m*g zrjbu4(>VS)<)@GjVE=*koT7LJd5vS1Un&{kn3ZQH>E#&vcPbp#@8B5R4EPGNo?|={ zO*PCW%QW&iBvq4sE>SqfGtN}QmEbOg|z3goyuJ!f#6WUnJZD?MGag{s#g;I0NugDva{4OZaXHe?h`N3D-*a zMhRoT6Bp)({X$%bmkIzO;`tKBd0bp5SGkX505*Xz=~)G45(uI4G5@6RC}bOkM-_te zY7$IF^DqSYS_lmv5CYQ{NxDv<<64qiA;pMm6&R5rgmjR?8f<2pfydOi*zaPW<74iU&e;mUj3OUR%j#sFEImhTH)Mv#I^i}eB zst?L{2V&5B7l!|!kcYS&>lgL@6UVPXhXDkQCFF?L1 z7lfkza9+TCJs3j1xK2P`ABIq_XE22Pk74+rLa-iDj{Ow#{|(33?=hcwh@VrKAD`jv zqE8{e!1(Vf1SmAb`4HO|jz^fT5yLZ|ZYT8z7s}g> zdLQHM`RfXy?HTf=^$O)4L^)urSF|7Jf5dwIWCzN@PFjy(_gx%+8AHgA)+f~OcetJ( zVhH)X%JC@(F`rMf--mqBUcl~8YcH}sxqmmJKCnB$^-{YZ(eIDgKG4p&$OnIvaGcD; zZ9J^O5b9sVN8%@aOChs3KLf&~?R-3fkYdnZfbkG+<{|3G_Iw-1)W0AXetiMs!T;z_ zEZ6UNi0j#;0nm%#w_)7G5YoXAN$X()$9@R0e4m!Thv(CQA?SGuL#P+p55A<3_Yr?h zA%EiXB%aS~o=+jq2mO=u6pZf}9)j^6Ls%TA@sQRZ;6jd_Jf!}B_*#xrFg&Qxvo-V& zO%Hxpj`3jM^%#ObwqXc%Ht^7o;Wv3d2HpdRpR%`awev2%zJ>B^!t@VAyo4mb3NcDoA9T*SgrTU>9&=jd2$db-W(AA0I{qQ*OY4#6d zeqjGf)Z5R;cTlz&F@!f`2>E(ArsaWnnqLI_{oH=47wr5AVzBcy3_;JIFogY1GU@|= z&%+RSCJcc``wj5mAFY>{IPW#i`#FXnJcS|f@w@@?Gz>w{EDRxj9*@_|FTgA0@)|CG z6~o7%U-5At&z~_pokxJb6*1UJ=MT{D;qqn-LB1bCtVf(za6fhkL)ed`VmYDxXJ82J zXE}z@ZZ=>D{e!k!@cRRZ!I@9+@E8w&hvB2Ve?dOzuSor%0C`~78Vtei&tnLDtOw-N z{sQ^YaRTh2e6Z(w7L^2Y^a}FjEB(2LmY1~T|8p&E1l25uUUwpeALfSURvK^e*=$i#1P`CKOp`a zfKg8p#)F=D7=j*Z2ZSYvUA(;je=p+ivHfZ^>8Rb1jQ*A3}09c`b7`S`q#=d%mi zJJ(OgS4g)Q@wI$@ZRPVs8!uNgUq3hTdf(04&ux6a2bI%@={xy64*Qsw5qI(Nct3C7 zF!{z~J%WA7C05YqVq zLh4tjUs?|6cXXVGc-kKzd2E31Eljq6*&_5BxN`tvwG#_>5gZ^3+@=lIVYe~V*id{q8D zj%RQThqct+G>(sQd^N|=*r*&PFPi>Ij?+1Qn&S+P2RL5H@xvU$phwgH1ILRvevISA z96!pjh2!HKFXcGMF$|tm-#Z*%!|}H{Ue57z9A|R;pB!g#{3DLDIUeLVhhrGTY58+G zev#vRj$h)qfa4P!ui*FwgE#~*V18;;L&{2v_up5r$;zQFOnar_64hd92-@f#d}#PKgUhE7ZE8Rqzp9RHl- zKXLpv#~*WiisQd<{1(T5<@lEzf5P$4I40ab|H`q#F$})6z6>1ynBy3ZU*I^F}VPT=@ej*T4uisM9%Pjj5a@eetk!tqItVUVW&d4l7q93SC$8pqFYJe}ji9H(#$ zH$Q0kQaSzx$1^$p4#%@N{wBv)aQu%P&*u2M9M9pnpJNz&slAVId?m-vay*aYf8zKm zj=#_Ge2%}y@dA!<63c?`sLz65`fc;p?)1CcNfvy=yx&y|p+|gbb2nzyyK8rDuWo2_ zHMvO^M%1-5xBKf|eiwz_tle#1zq<&&*4|a;ho6YUFSA!mY>-14#FoMr+Vl7}_*(l2 z(eOhXb?)}|P43px=6a{Mp@q{m@!Gheruq#neihf_YOZf|-$YGnsxNA8;CvQeLZvsl z8h5%OnJfj9Xu?hHK254nyt_4GJQyLzSHUlfx$A`)vUC%aKSCxndUPHbU5>vW;A?d2 zqzZ{6r?z))?)2%U)Kj&`o>HiX6Wc>Y^l|;+m52qsVdvtKKS`1y~@ytN2k_S zvg~`66k6FB(g>}?>20nrh2P$eP@0fvv^^+dPNoe{C$X9_T8E>*V`-;8oFgi5D@4z^A`DI}dNQzqESE<6X?QVY+ z{2-Pe2Ll`*?47K7cv28UH-&0qu_8N&MqRf0CU3K|t))p$qob`JjoamJvo$tWx!ZPm zVXWc#zz;8Cd)uMI)i$~v&HlDd5nH>?ws~{)ZX9L8uBlVSmbEl* zk2oZ%Nm{}NRkPA(LBSim+auVaRi-7hyZxJ58rkse&Em@2+}mMPcDJD~+@bQaGK6Jy zJE4%gR&+>_sz}PC*xlfQ5iAO3QKJ`rgH>xjP8VW?8>^Ve`!vTRN2|l$iS<4@M=eV$ zZ*K8>8}Nr>y)DgJiMQD+Sr5HGBD0~*?Uvgi^L_&zX6hPu*1PK?GelFaZ1Xm`+B!KY zQb`1pHhSor^%Oet{a?{yL8Ub{=41rpZ4#m4o<@CD;oix?okVo@Ax2b5`m)XQi%lR_Hosg|2f} z=sIVGu5)xvE6{aLfv$53be)s0>zsUD3-WcHlc(#PJYDDH<*wHCQ|@YAKjjwc z`YE?i*H5{Hx_-)CrR%5MRl0u4U8U=%+*SJC(09hlF+}=)TB+}+75aW!q3@>^`hF_V z_fvtsp9=K-RG{xC{SxQv`ze2nRQi6()Av)JzMt~+{gkWkr(AtMSKm+i#mdq5 zQ;xo$azLSv?%fG2T{XKLx@N3ycWd`4EY_#l>aaMM-(LhvWxK2HR=U8b_1j(TbQ@3X zJH3tcjFBB~n$4R_%BxGOY`Y4~4s)fs*u36sH&>ZgIm*p9IxD^TX2;ge#kngHRKcHe zo4L|qwyi14%iB^`kh`TUFW0!d3(XFjy>wR|>=)=Ef_7gdV(}azbaJZN zS$N?XRysiSW@!#d>4B&e2U2kS^V z4tENwIO%XyCE3LH3UZWIC$d7j1XvqO?2u@5s_;HSN)z5rj1q*m52Le^HWzYQzQ>3Z zt+h>aqN&YBBhseQR*>2aDhX~wR0gOdQjI!c(;*HwRS81T+PpDZ+M-B_)KYC)&1t2! zv>K6|D!f;b6NM#G8nKyC+2)`Jm#T6sDICDX9QE zw&u9go25D=2_5;sQC)6OoTHrEkQf{u!G347*H@ggdB?!7K+2i z5L+DEU^(I7F+#ld&~X$&c6Bs|jiZ$CgGN<+cu>*$Lv3Ni14fMwZCZXLHwGiDU2~`y zNd&zB!**Ych*d=?cuycbJL#m$<_*1#KXf-PAZmGU4;BVlh#41L&Hc4 zwPf{yVVE5{<Aw=S*CX^={lHzA5@LH>3jxtxdQkkb*rKBkf z;xiPp0`H9zIGG>{egOmA;EwW|m&o3+i|70T2;s4s&=t!+{n@DH1%TrVvEbPm{`r>@ z?;P+_R6L>Y`w|ZoMB;r};-vs@e*}H_JsN1XD8~c9gU2&Mm&i9;;^FrX1Vb$LJt+ti zBwiUPD2c#34er+DtHXO%;++B>JVp_^gnjo(ykH!m&#DQc;O&-phoRtDcj6MfYKiw7 z;KAbseGz#15^o!{pGf*T*H3;AFxO5zmh5Nj&lUwPbFSK zGJCgAP(?W&k$42Y4S7zo*8({R6NmtACh<*fTwO(g6Efb`+?UHp}kZ{ypN%i z!{fD~OZa)U#4CgcP%}cT@c6P&;@u3qy%Bhc67Ll7W=G)tFBqWq^9A6&tl|m#-jI05 z;CmC)ei6K567K`xRYuVFh{Rhvi_m8z1y$(VEAe`P7pWaINW3$^^NGp=r9xk+#M?TD zkiiJ`Q6TZ=UP;I^LWxRWn#6l~K6|EIltY;CR~Tp2ehvZ;9{USjLUmB$&AOVN4#SBdvJ@FI-|-<5b|3B1do z(kIH>EAhI4mlB~IJ0)J9g?(R{P$~4?Eb+>g64DnzAHJ`lF7I!k5YI&5&6aq*%h|gC za=w3rv}%3ktjP6tO5#124LqnLafx!Aka)%Uk^KU%25Iu$T)=+QOxAZ$;=KmE=L88t zkuT2O@GsO30xKf>4<6mt@aC?HJPyI5>>6Gp@FI zgXar$dL6cD^A)_c67M@B&2eW$Bn3VkcNKH-YOFGkK6h7+n! zq+bg>zW^$k%sULcKoq zZ`;1;@;w7Q^?0wBuWx^Jypbq*fdkR`FXhhY^6iU~XF3?2z5(DtQwUvpezAb_qTvky zFPe5x&=Z|sUItz?`4-<5U3p&vUNrV?y*oO6LEu4C2wi&qtA|XZX@4I8FPic;-V>ew zK8})i=-%k`rF|(n{|x}|fsj|iW1c*|tc8gO=N@tC`R_F#^$8M$dc6AkqN|THz>6l| zjxR^2?_=OaqwmoD(Y1qF;Jj$sRUh!8$=C9g=<+=bylC`UAB>JS1iWb4{noEW*Y4j0 zUNrh@ps_^5I};_(2k)>%)1G4=imu+eqvR#SyFUIX+I;|c(X^LXSae3i>yDC_4DS|2 zqpvqg-mHfSeaBT4S+AcT170-sYyF4l+SMTN_J~Z!7+==*N2l+FD0yoiiLQPRN69lk z8l8QQN69lk7M*>4QSy=>kIueBQSy?%693UWSE)Pc{fy5*{sAzIY4sv?Q9e0-y6f0;{w5YVD6>DwJmR7B{g(|J~r-drD z)StGY@@uI@o3^F_A6i68)7IAicV=hrzB9R9ujP{T^_SJK_t|;RcV@oxu(P{&vozn- zULxYwO59_>)o?BeahFKk0C0_*OGaFR#H~3>7|JO;MR7S8z*sHz^&o-Xg)Q+oPf%~{_6ow%inm!{aE6PeiEr)xD_3?_prom z15Qg9ZZU_strFJ@oaVoD#I2UNlfcpXr~W%1afK2$fb7xx=~{WmNu2di#NI^2eUK>n zB^5X=f0GdRro<_Tn~b>UB`z1GI|XrHkhmhm!SE3-hfm^)f!hM%)Gt#Jw@l&=0N2Vn zxV0U&H(%m1ei|w7bi~b&xFX<+xV;&OOO!Yta8}MKhoGx9j33D~TY3-^IaZgCx8sN14 z2Di$?_O?sh4&bzYv;c7%B=dbwZk@F=@U-Ms~#O(pD6~bx#E|KhuqY`%%I9SerrMm=i&r00M!;y3^L);f7uHqMw z`n?=+u*8s%zb@c3KVN}3kHqx=7lLr=mty$S{0B?L2=;uhsn5kJXGa_?Eh2E+5LbdY zSb{;|LcnS5r4(_nRE)qK1+D_ZX}V>II}V?5eJDpF_R0|l?iaW9Wxa%bD8Q^j`SA{t0OYE29 zz-jqgj<`aJTk}ge0KTW`)*$X8nfp~_+^99+S`k-gz;z+6-hkVNxRnOnF2t=e;2uNV zY6I>W#L@nw)vxTALx{WDfIEt~YYe#Kh`ZK+8$jGz1I~IhQg5^^>6K#=;;uK~G7#5b zz!f2`(SWN!oYR0?gSaLGt`%|323!~7S`4^th;tcmyAZd|fO`ya>kYVP5Z7wJ9YUPj zfIEt~8w|MPh`Z5%8$g`LfV2KO(*D{ExJig>H{dc5=QZGp5J$&By>?%LxD5u}8pQbx zxK_jk47e`D1r4}ui0d%mb|J3QfO`ya8x6Q;5Z7hE9YWkD1MVo|ZZhDGBkpDcZUAxg zKB`{*T3?T}zgrBrNr?ND0hfWeTMf7(#BDL)DiF8TfLnvO+YGo?#NBSdbs?_XfZK++ zI}Es8h`ZB(dkk@R8F0@aZkqvj2yu5Ca7Ph$j{$caaqy^Bw_Ob&j?VdX+uv^@?eAU# zZW7||GvG21cfSEwgt#3BTm|AjW5BIJ+-D8AR>XbIfa^lsP6KWm;y!P{?Lyoa47kS- z_kaQS4B~bfaEB20paFLjabGmxjw9|N18x9uUozmV$0F_TVFPXw;=YWy$?!P={C4G*l8Ty14mEEY&-Qg!q!&Sw8k|zHLQ0AgAE-)wEG)pw?jBxriox-bG zYKetxmqBL2>atlUPTG?k;~eKZh?3#EelM{l_2yrf_)Zx~e&nOS{_CTbsn3<1`AtG^ z;v*RjsxutVA3wR3klDHUYp9uw_70CHlaO2YSsY^>%4SnW;^A4_Mn96v=yAPdc4F_3 z-ycVmwPOYnN!!%atiS#y-;p}Am4%c2xem)7-}BU7A+u+4jLt0Xu^wCVi{BnMot%Af z<|SD8r~30k zC;JOSf9hWxdbj`b(A)hbq2v9I&>#Dkhu-S15Bb*Q(0ZRpK@XXse}y3p(W?$FVG zPw1EZzR;2W&d@LVZwmGF-x~T^KT%%kuZGEEWqYU7<8Dz}*-vW;p}%BR;CEk&&*g7( z2ZOE_Lf9{BrGr|$nzEH(Bhax97N4T)WGT*$U@Ppk1*Z6FLo9Zn!{?*F00NWYbiM1= z!O!uimTY+a?wi!rtO)YUSny1;>uPWI zZ}J6|8(o`}fcqwTt)P`75*Pf@;Zi)V_Vq!S)URy!xNmfMHYsdrr0DkOl3Obw|Gad{ zdb&WN5`+Z~CEo7}csu-bl{Zor{)s1Z2dVA|D&BR9pDu?(+p66|e^I?jakne*8|n2B zGeFeef+@|gu%!Y&NQWOhcKErANIk?1z;c(67bWO!b9p<0P?sJzT__G>z?yN&I;Y#i z5-W3goSR%N3K;dl%9$*^ROl1gv#c{`RM4JdISFrB*ju7Zt+e_qC(Xp1VLn`|OscE^ zWg!+&tCaIAw}G+}E2!1V_{u||Qb{VP70TF3>juk71-hyEaHWz`Splk;6oaxW$(7qc zZ6RAgl`9FAhc*z!Txs=N9jVZ_=$5+gzC9M`&ZK2KQqRxs>Ytt$3lNOP%|cDE%Zuq@}Vz>zPkGxkA3snC%?1z zDN=mq1OK)upDC&CNj{dG`5x=HS3>BM-`+zKGRmPpnlegz%o&#-e!O?jU$)$Oc~9t+ zDV1cLIs9mE@u}oA8h3urv}47mOlgn2V|w)>|dE#(9cbom-LvS4<}^)_VBLW zk21YId%?o5;d4^PGb}IXKlsqYUwLFq#$Kkz@|;21PkomZW`5%rV|q=0`10?Ay;t}C z>-VnS8+z&AUA;H;26{ccZN0xeKK|rs^XJT;H$Py0(EO13Ve?nakC?w^{<`^5^J(+r z<|oYGGJnUs*Zh=upZWXdXU)%Q`DODf=AW5+%)c-nG5^wh)cm^n znE6d}ulWz=K6AhMg!vuwd*(lz-#7PLPFUWt6o$s`Nqv4n=pQi7{H_18&|mwn2>qqs z9{QlaEcAYVW$4fSRiXF#Gka@b1geJ-=xP{&u7wfkIv9bRFaou}2(%tXpc`QX^1%oc zfDvdDj6hpp1nPzn=pGn>J{x+a|H079{f~qW^*46WWa7p!y$4>Lx%=CAXI|k7 zZuI(ZRP3G5V_}sv53B@7(^>6=h16QS^p*s*X1yW~1GhpRb9IW~V<;A`phHjW7 zxio;+_X@gpvEAo`T699gf&049I(^VEoE|8eyVKdcNpX0b>!EFdKk4$NbYQo)w6GHa z)W5*f_U8wuKz21WTwUNF-UfIxg!3eA-Aa|K)8z@bYc5F{%`0!%WzJ3XoV42Ix)F|V zQgB##7o2PusKE4&5Tx^AwJt)NeKkL~Q*+8S&_*HORo-SOB0D0q`AEBo(CpJjH*^`W z2635&4h(hHOgjYAb?l5v3PNA+TNL_Q-;&THeI=o<^f^Kg_bm-Q)OTg*!M+ut2l{G5 zpYK~8`dr_&q0jU=L-+Ts3*Fo234OY6L+I|lKt5L)Y~EZ)i>5&qJ&Feif<*YsYf0>icD=y6@Ma<$Z64 zmi7HERN2=bTH5zcsJ!okP-)*^L-xME{qC>7lg1RmSFGG6ey_8o*%^Sj6VvLbLz_U* z?}bL>b;F{iVi;cql9YI1=~ZWYc#Ke6LS)Qf105SlTq47d)w|lD@4-0ZcPYzVPCB5l zr6=)mx;`@`5B(iR6Kz;U01ZQu&T~p#o`9Qb&cMdST0*?Hw?HQvdiB+S8FuxknqrKIK&Ck~)xHxyRM%WTPnb z6ZjB>#h{0_~`r*Isb@pO1v;>t#h>pATzYD^WvcM)u1LyYF%yKPC8MA z{Agnpy>4*Bm`2NA$F3~siAs^0M!3lkt=81BO*;$1xfv=SYC-N6+VMJ9Fi4vR9}`Pq z^jq(R(^nVO<&#ghfS}ZNCIs&DK|N9 z`sz)8xarjsX3&;YOU%UDDH_xb?&a6zW@b}e)uS~+JD_Uuof5YKIj>Cx5 zMjWt$E1N^CY`?MHyRltaxw5isv69=RT^CcEbo0SA#TZAXL!HCZD`z-A!um0ACTI^X zR$xU3@L8J=u1fsMd{`ht>0mP_B~Qs{qKjoI3-U6RdKj!0E3j5=bF*@7VN1b$XUla& zm04NMixw$aSpgr+kmw>^w6O)0tY$d2zP&@q@}9+d7bPnztIF2GTL^-IwJS@is@F7> zuUghnT~@iGVRimm$opFLT5c`e1#z`CH8epEg0SqDc9`B7p<#5d-64T|wYYrHQ!o4P z%2*3ztl8IbS$IVbSf2w9IepE6%iuKP^0Vn^R&}nDRUM=!^Q{cbKa+b1oR_WrLWiGd;p>uu?)C2u1EnUlVvv$@jpnxcalRyp(o3Pri&r3hF zb~NR5G6_Rd)CJMtQMGP!O)n+%(u{+7I20*o5(pdw^?3jf@hHf%}7pjTfiMB zQ!U=+cv(_?7M~Kr475EMr;Mq#a_HjLaQh}M6|hbn=;D+?&03D5++M%3w!EQgb!AO_ zGb)(Q@oaSavRLSB@Ax~vmnVFr@wi`(#@&2*DfuuZ>XzZ zK2k+TSwJ5P@*Rc$eL2!HIOt?P+*u858p;tx>h`LHBuApD<^=pO7mLTaFzVnLt*A7~ z9H-Ac63I4u;W}~zic8bYar-)lyVEgWYl$xyiIVe4-v}nn+Tcj1pW}mB*+^!h-39lN zM?3>LJ|A4R4F7P$TVW3K0?kB@&kHxi1A+KlP2~K0gWpip1$);Xy$Fo=nJZ#A2X2(Z z)qu;HrLJ%p=Ze%%Xyg)BZy*d^K|A2hPn(9=e9o{GB4?dao z#cXgk1%mV`J$+gim+79?58`9ZAB@)>U}`DHAMA=>zNj_rMo4LOZGHKghB)0k(()=> z*K}E+Z{S67u**x|_yedH9E76Y${g_keH>5RyYX*rME{k*|; zQ4;aHN%yhIXsHg-owxry{hSu{+gI^y5?W!Q7STuQZA}hx1J8!oPT{t0SzOzymi)hy zu|Ug>{|$M_*$5B+;VG*#PP3GcZ!z&`81c9=Qf=f&&zR4yPNLhSb3poj-yyL*bgtl6 zRXI)VuCu)NqvICs@LA5mH8bLu1+?75TXlxe?>S%|z6E|(quj^lzwK-%W5y}a4hi3p z9m+z`Z)yys{nqBQd@5n=Ay0m@b4a@Yd^s2{GS2cc-M9?&M!-;30kxmAx+tpe1fCxy=b*EsfLA=MSFkE&Yg(sjYaQbD2#w ziFg(nzS!1QkRN}GIqV_QcW&!_J+7RSjN`cP)au+R_pOrfl zbua|Yh5a5hu6|(_!_DO^FT2G)sD3wdD0(8d9A5`-^uTX%;xwF5TRG_Wn(&qFA+sEB z2M^ABT%NB)+6GIYnf)dQz91e~$Aqm8iBlrhIuUiT-^1BB5 z*sK74;-~R-HI4)p<#JRIoM%Bj!!2dn$fDtW#x>G7_EWl;FT+?SJvam z_;Ga^wOwCT*HBks&ugF=jyzHJHr)WfJB-+er)%nyRme=~^18~p25JeyH5<#z<}(u& zb>;Ag&t6-?<0|SJ+Fc%Ha`US!qc_X+>pC1HEs#W(_yh zz>RuRh4zswGAs*@WfbddCfv~R@$qWMSi4mMSXc~?aCVPwQxAU6ib?E zttzyL`K5JL_EqH!1F!P0Ezpc;iPe`?RyQm!udA~!EwAI8qh@78O>KEy`3j+89S-;w zK-o&D@JM{M1+aMBKegpm<@UPrNV(ZV`EVuLYfB4REkoJi*Cs>;iudLvmG^!yltXlq(!uUc7tS$-ijBDEbs!(mQ$*rBV{ zfs3dO{9Oq38FSc+HI)%R^Nib9*sH3SiZxcVdbw6Zf;F%X->+y`Zm+L^0zma-wRL!c z?xsyaS3@(bs{unvR+HcDTGs%JtgNTsuyWI1C1$mI;i828Dz*WBrUF0WZ)k;IO~dap zAqZBxfS>O}|2m7`%c=wazwtBOX7Z21hZ?pJvW2a}PJgvb*MY*nb*3wd;lC_R7<|wW zZBH7(>_@OAuwOG@Ld=`Tri~%VB-xZ~PEN2|tclhnYqHg99c4|io|in@IyQNWIeDu& z`8IR%?dIfebMhVLPn)gV&DML(*89xX`^|);)4cPIF8OGm z@TqR|eI~=Stx?mqZZTW8nyt5)t+$)4-Dc|@X6v11t5MpcwS-}R0R9@`Z>Y0dWt^YHj#67oYT%fn_Z4=99xd>9(6wpqygAAJ#Nx+Rqi7dQI3x+ox(fHROP3_Zl zlhsWP@6;slH2f&iH2#}N)9^ncO~X$kO~a>zmsC{k--a{|UjcvWriRmZ;AonLTaqK1 z+CQEW(KMWPDs@xiYl^1VoBCe{70ryI?$3GxfC z^$2e!GL}3QRy2GZc~H=)gswHLZ6-3FtkVSSO=L8oYy4}Q3Et$?4CSL)q-{FQY$8{1 zP1|sq*-R#LeSql%atdI|(>9o9wvfYI(>h5rCz5?!)BLBIlUUi{Birb^Gzv5Ud#Y`c zzChA6Ep3|xJRML{77;R!@6-4`pYC(vkM4`qcc7Uw2zU%M6s`v1nlFYw$R~|o!S@GX zPmdp@`x!j`LiODp=4?Xf!anAUxX$5v7T0sRhC;wHjl_Hj*9zB=Nfv)5*I8W81~?n$ zDcSIC4|N5}0Lg|~M$p*=`&R9f-{r|}aW!?UZ(zS1BH3`jo!#8D)LviTu(G}qt_J+D z3)mUl6Thiw`;c-nNw;?v{^*(4uD1?NzwCKHem(KIg3W0t)5X)W*sM zD_p=jChAH^*-TJ~z(-i}4%UgvZh}SbvSA+5(7DdV=U+rBu27tEzu)VpOKiaEMD8Y= zjW6?Qvw;ndyNNV6)z#NF1mJgx?ZI`Vp~2~bb?h42Ty1o*&x+E@hPsVTAECZ<2TFn^ z&VY+K2rdL+2D#qvYrxL86@i7Q0rT|&@^ke<@)qib6zYcLv8*;lG78gFpFK$Hi>M!2 z_DkrhHTH13vf1h@mN!(^**gnu<+d7InQfV^#8zipSiao0%2DGku$8Z=FUwm%MIHRJ z+-|EWx7in0<>#-gD$HA1m7ix@v$!fR&sGOV>flHn9HA>n!N03*E9=VZRxPl7s;+)n z>9R6aE(BRoWvi~MfjPgeyu@B)t1Z8($VM-OifrZflFH6}xnhNOY*gv2j79)zzeZT3 z@eHO0w{VF;ty`~E)5dITA+{hH-pdC23K&~hODCo>_*j|`iy9FNUR8%Ah80N~le~PC zIVEYlDb1X2o@kn6nrxb4y3jP$G(BmS$z~b{CZN?56FnuT;lUWR(bfZj6xUAeh48ro zMX>PCkHH>uFei-4T?`QB4g&WIjOp5@*}DY}U~Wf(_+Ds@ql+hFZYl&Ef^&ejX&jtN z1nw>H2tBuHo0f%%Jb&8p)4*vq=rQdx^`R9sWQ%PBz|pyiw$VJ%ZIon>a$lzt1-@zA zzd+N^T0S1G67#2V?{kixC+W5aI64Q?Hkv=m!l{t$wc`meVW4%QZJIrqyA?RPew?=H zaUTG;O@m;s$K4F=xH|^!qZql{tLe3LWYf|;0f#i-(NIeb_y#HmrULB!Nz^a2zF&bq zw46D48k|Ru)A5Fpna*G)G@$1st-eXCH*QM_>{odr;mk8_06I*I;N=40pjjY*gW&7gR z+`WnHQ>LS&HP^9YY0K1vdGEfau7szpk9UD1xq`IT>`j7yX$%YO^BprCrL7r`T}wrl z>>mZ8%Cp6%wr{Y8=t|vWeo%+6$<3e6R{LD_4Dz3GNX44lSC`)=Pe)$zuO(W}V*^MIrI z+;?tkyU; zm(?~=wAzkvYTigVZ)PEH^nD0)g~baTGaOb(uW>K6y@mOhv|j3 z0wD|crGsBb1E)M&efp?Vs~uWjHG5Ow-(q(zv|rLX%Teln;{-A7T6#He8`#IJO+g)v zg|{)NC88cbz}qh^`HNB7Z=~#$q&}i$f3Y=EcBzfJc^idR9ciNx|ET`ng8Y3uN>z`e zY2J>~R5@DaHLMpNXf0yBkX$qc$d|z4o^U^m_9iC;|H88z&M>ubwcO$bQYv^-=AZ9)H12 zlpRYG_Yj@FsKtL>h%dJFkDv{!Il=i*{j24m`t;wOqxhJ>dMR%+axWlo5y{4Jb^HQ9 zjsZ_291Z8yP<$6lNdwg0HOs6Kt#iAUiBkPF(T zUxZ!?Jts};IfLVCqvNwe4z`5b-5uP*V^RB_ng`9sqfu>Ks9d5OET;%vMcp9g0D{#};NF6j&R795+|W6fN4ct-CdXAb85ZLcY_{P471>x?NGcJ@w)snd$5 z&roL0D!!=LHhWI-#l?Kf$Rzv!!~bAbGKtShE?|4=fpk7AF{4?@#NLU$#5TTn3=3=A zdmg8Y_-tk|tmJz;@VnS7=AGAQezda+tr2=oO@vv{cs>hiLg~X_)MkU40WT< zgWd_xgHrcJkEPC?)L3+EqO+%WUQ@@Hk5B80|0pdQYj9e0?4dn?pO0_Q<_cyQxg&E0 zZJg8QXq$wQa!YuQcAL%|O&srE5@Ks}fSC?+>qp>=Xyd&Y|2f_Gw0!#UwcLL}I9C<( zbCuoTTs0GV%rwGgrAq4asryP!%?K-PyvYx*2Tc?oFc!W#G=Uf@qpcS$hC_Z8-%^#J zqkQqHam8v%J|2%9J(CtbN^Jvo#`3XwD2D#4Ud4 z9#N0udZ<1#v4$S?J)d>r!=+(+CsOX#@(b4hcT?i|;~(CYy07}oHpZs{|55c_@b(`% zt3Cfa4;E+CZmyB(b^qtKhl)NHxIF>7Y^nIz^Hi(`&2 zH?7fU-UTn8@MWYZ8!|>WZpauL+R(qDC{6K?-PPzHw=3jN-PP+Kze@>>-$l|I18KWL z@JG^m0~2;B!R~?aTdLpAP(s1;clE*_NmDv5*wxrEaaX8g(ym_kgCm{Y1Cw`Dzn!Us zI;ZUF1vNEP{q|g?abx$u^gY#YU!wGGoVKfbKq1rN-!&@-ekLKT)b=BfWpq3$58GE6b=;cHkB0mEnbN4-7@h*|ZN+C6 z3b7-(#3@V_7@Cu%;S^}u=#fc-j^I&*GIlhc(pZtS2!B5x%+fC=HdA&=k2%}YlaM{C z$C90N*wkyecyzD%;*{Qmi>qsPU^$e{+Kc#aGzd{_s4J&Jn16`lr4Tkk~A}M6p)d;VuoGO$;1O zVsA-M|4n3{>3K(;&)|Pk_pzKp&BJ{whq=PkNY6(qq0U7{^{O)_<=Igc#RIk)YKNxr z0nC)DPw)39K0*|=wACj+%01by#>M%S{VAs->jywESm!?X?ggV)QiNX!!QWSLc3%^xtLDKgDss-fdm%o4jAe1&;Y(>G zmZPRGLKx-}o_qH~bF2P(UL#c*`Z>}$1sNk&#^f&!+z8FE4S%sW? z_rlcyBFviLA50kwA(ItF^hQI zZ;Aa~58|5k@u_3JdV5@rX`W)sJjBCAJd?;S`grc$3#;?by?cQz6r;6@L3c)BF}HK? zUigpir^R=*Cs$ijLsJme|8+K>Wt~J;slztoz4n!0d+1!Dy}jVvyBGY;F8LiDnsd&* zdqKT=)@k|t@VR#{82jhkyBGL(M8e%F`ioS;FL*fj?uGWOjrm#pDbZ9>w76sG%*;>c-o4Ne@dF>}&hAb@q>IxPYvXC_ z+`AWaPD^ZQ;P874;_C9S)p%cXiFqD^mUr&m3+>@Iz?^&c0(_mFwYYQdUeKG{s_qe9 zU=Y`lM0~BoxpyzHJ0RHU{Iw24GSG78t9RLlqFRL)77Td;=ia@b{RRYGoU*nQ=W7XO z^W3`^m>bZ`5r)Fc$hg-N7tx=re;c8=L;W&>Nyw#(;j?{0WD)-1NIxB=PuIDO@+-vvmkw!a>*NY=pn)?QLk%q~+C5Gkz~R!EKzbrypAzABi%bOY>}A zBxBs3M#8u8Yr}Y)pzHU3+&D2*FA5s&F?uA+jmHi8{)^bgjsHLDe5A`x-zTDN)8WHN zpPT7=-6PfKhC6LVb3E+lz+VZx94h&aq&pMuvTRGZo4%rIc+T6n?+>>RY{&=jIvMam zuzS=U);p8$O4^oqx8>7%`{8bLBVG29PJbkQkJJ7n_4iL|xp7-p>wDzxc@FnD^GU7q|CVx(WPOih+MlFx z6^}2UwEIT5pAC0=!+sx$aUG{m{V?433l((Fg5JLNJw z`~CQy;|`Xe&cXc#jt@s(@HkH2?>L|WDSj4_%Y1QDcj6tEI}`32nR~z^`3!C( z)1EiX?NEXAw2i*v*FIrmq~7flg4a&Cd06@)9w+Jf)IQ;+?u0vrukHQ!r9Zsa>x0Wb za_Q4^#Bk3marx=K~V1ZT}-T{;B2f z>bBgGaOZGcPvJI5=N}{821mLL%o^b_h<+bsIOoH-{j1+!9NzYi+aDc&KZ)%RpM%tE zfKPP~SO3TLKN92rC%Np{_ai;`I+yaU{M`F%{+x|$DAJ_eGU-u0z`|!@WMzZWU?cwfoBbhd?^H1753;TVz z`x;JrxUa1~scGZ39^1LaN`~sUhh}Ypf%adc4S{bK^8QC5q~R^g%);q21a(W6!mUz#s}w#; zN`I6Tp2EUuJ*r!Z6n>r*|2!#tGz+KK7wR@z3LhhdkCDR1O6iZ4!pE`jh`+~4;i)W~ z-rG>OR4IHs3y;+2cqu%Mg-7zACWTL6;gR~AAcdz(@zbU7^QG|frSJ<_cqD%pNZ}J% zc%*$yl)@)T;gh8B$t;|ni`8wi6h4K87iqy{iWGh!3y=8!LMePI3y<`tsZ#hfDSVm~ zK3xi*E``sK(w`xPD^h$#3ZE&3&y>PvvG9ohXG!4~vG7RyxJU}ON%3t`_-qy)slVA$ z_#Dap94Y)_Dg0t7JcEVb8Lqz!79K*Hj(7C=gSx5Vnj$2V#gEiqreuFE3y;+QTq*n# zDgGr=_&h28JSjYjg-6DpEGax&ik~fo=dkcd`_7TVbEWWHDLjvbN9rd}3eT5xfusv1 zJzvrbB)w45MUq}5>BW-1RMJZ%eVL>$m-H2qE|#=i(j}5Em2{b;%O&lQ^ioMzNV-ze zS4w)Bq^l&oT+%BfT`lPvNna)DT1nSQx?a*NCA~`0t0lcg(pO9R8cAO(>9vx+PSV#) zxUec|Sc1!vON#7`G59`0(;Q`Gfg}1SAx;}}zwMpUa zlJ+v5t_PrQUMbwi!XxtypA^19(tgRFUkVRM;Q=W;DCrJ~?~uYfrSMKEe4`Y;k?i7= zo6%6<1hR?T%k?p)ZzgwfP3QdyWHV{!n))XJ=F?XS+Dx(poj@)Ww1rp&ok-rFMlGpZ z0!bpT3p$znNYGaDxS&Uo9fD3FU4lN3TqEewWQm~1kQss=OA-Y=j{Ffl#7ZEkjZrXnJ?&h(6uB}&~+q5(DmdUbmJ(2 ztR$}rdKGz6(5uOvf?h-1g1(xR3i=u{SuBUuO~kjbSwG3pxxvFLEk`b7W9q8C1?*> zBj`4=OwjElU(jAMPS8H`-gunf4di7(`^lq%4vN?rj=*Ot*O{ERFuj?igQlM~{n0p;)$~cw zG%Zd41~fIH=@&rLCZ_2}L2Db_Z6n(S{bjO2&|e{|1$`@7BIppADd^kbw_(2tWGL2n`Hg8nA?+ZddmC&-(Eev-T> z=x>q71pRGtub{s}{DR&?RttJBSt97~l9_^jiX;nqD|wezCf`itX>wT5`^fhM{XO!K zpubPH2>Kb~67;j=NH>DLI0AxM+X|dnaHomF9dy*d|%MNCSMZt>tw5-e?!&_`VLYh=wl>L&~K0n1pOxY zN3xb1+P;2EdIjA}ek|zUk#7q6_vC&-|A7Pr{T8`e(0$|zLElMig8m~JCFp+grzD)e z=*Pd@^wK!NIos- zFOm&{eu%6V^p}VauBYkk-F)~o9`LuLx` z$C6~O)%=em$Km>z=5GOupGscgS}pH*vWIKcej3@ywVJ;P6Um?8dO6~sN#qdM*(^Vk$yd29VtNX>m1{Ns7m~GHtMxUNTrTKoWSXF-lYheX zFilU5KZEpgt;Sc#i-Mj>zQMJc|5;=^*Q!4*B3>cfM(Vg$%Qu@W68Je}hM+Gd|A6af znjiX1AM}N6MQ`{+Dajzd7Vl zLFbZfT&wxdBW+x#G5_b2)m+nQTAI0lEaIA8CZ?GS$#fxnKKUnH@6ztLc@Hmjqo(zQHx@Apd1#yAWPZI=NQ+i-TMvgfAtPT&w=5Ah|+# zC7Hyvnx8940@rGLTt?o5>tUK-I1K4mk=MAU*AQvu<>Xne)%LoAe3ff8y=twL!7 z5VxSOB1^eWW#P5t60TMIb!4=l>&bf%K=Y%fx03vvYt{ZL@@=jUF?*}YHm-Lty@uS# zwc6gVCgohK{=bG?$hGQ^Ye|Zr*OEWL^>C!UT}NKwTIH`N`-E_~e=q1pay!?mKb_PmUB&~y=mrlQYdII8PD|s7VaZ|hU;aTU)BBw@(R~#d_Q?y&;fEU z*J^tT5}y#>L6!@;lgttHMzS28f79S3S}N%*NspEEX?o)28;yTN(m#;&9!Wna>3bx7 zlcZZET`y^eq~}X|hNR7s{u6aRD$i?@en!$?mh|0{Zj_R+kPsi~TdqlHx<#W9xVprptodPp~X*x-P!HdO*{ILBM{P==M zJX#+q3(c%ur4(_yP;M<2Qa_opB6apM3VH}>)V^DEw;_L$Us9p?S;7rb1r@pAppL~3Zd&zr~^y5DOe zYw7+46C1zH`%R>k>X%H!L-#*65g*D(8bJa|`?Ln#ePB z|1%SLj_!L+x;R5i0k)we!j%@OdbxC5oZ4s5C00+A8;Mw`p;ZH!u5w-f0gTha{V=~ z|H1Wcu1!3>uXFuA5B~<&r@4NV>yNm8oNF_W|4ptZbNvL@6S#hoYr^%nxIW44eVgkG zdH8p@p3e0mu4ix!7x~OTQ@OsB>xo=n#&sIkmvcRZ>nphaJ5Rru>+w9?&h;d&OSry( z>r$?#ab3oBD%a&)pU*W+4q1NB@boIU9^kr?>%Vb*CD(u9dKuS$<+_UNbZ&n+*9zAw zxIWJLYOderx`yi$TwlfYJ6zXs{Vvz_Tqkh*E4j9Cy^8B(u2*w?9@lHQPT~4$u19ly z4cDW%zLx7TT(9MNEZ5g_ZRNUw>m;rlxgN*0lk0!+@-%Us$iththLb28KU=tdo@*D^ zzv6lw*T3X?J=d>s?dJLj*EettgC4VgBiBFS+QT&rmMpxD>o>V>=lc6xd%1=|lJP#S zf6eshNC^+B#Xx&A5F8@Yao>n^Te<$4p>uW)@6*T3ibX0Ct7 z^=7VnxxR(#-*SB`*DrFth3gl%-pcj=a(x@uFLQl6*Kcs$&Gj*^@8B9vI;{M6a{Y6z z@8bF`uD5ah2d?ko`dO|&&2>N5+qwQfuJ7ggXI$UM^&h#upX)xZcX0g+u0O*yTokhW zewORsaQ!*1|A*_(bNwT(zrgi=t{>p~0N1;?{sEkHv+cFZvz@`9-`&&^bOlIuAm|S| zn_%Cnee%0J*)6W7j`a=e{LVHP$)*S3_4a{ai!|^azdDl||O?v56x!Z573p#@x0mF1CR^#=!n>QI_ zE_+Lh-xUbdx&mHLr^_F;Y)f73F2B3EywlhPQB(5zTW(^IpHwWFF?%<}uF;{5KODhPA#A>d?=kj;D18#47 z)HEa2R_6)^p+L}*p_vMHD%&^c=ZpvH=M8}6-j*n3D(?zHSZ%;JIK{G#pq}^2TtyHf>+mTH%GR)#_|-cX>)Z&OpGu&fV+`f`_8goU{i5&}!RU?ZIfJsdumT zyMwNZjkUZZ%ceL0S#mX(vbPJDw?h`1U4ybXm@KKU9BhvEYnNYb$Ms#cU3vs02G#2A z2-JT(63q%Ui>thKmFW2b!?3jhRQ*0 zu-;u(ThjzXhD+?p(9G-IY6&}ZiWmtUT)MiAZs_E-UeBP`S=a7fw=P;mLsrW>X(Mn3 z#9$||Lj?t19KEMyQ3|)_Rrsd8- zo&G9s0DRjq=s2X<;r7ExC7OSDpqx~BmpiCigJmv{E9j!7T;>{7OEiD$p%K!v!=RD4 zsvOSK?5wpE&K*Io-^I!*qz()ldtorBa?ydNuER&)EguEaZAxIH6dE?KLFjn2bI1lL z0f)=m#Q{W(TkC3exuF%Jh!xKE7LTi<+3jK@6&=vk&RW{Oj@y=y4=(*o_1t-*JmQlNgTxuGiww{H|LQ^;#nZZlmYzk7hss z24zhc0Hd|5$atoceF2D?0cph4PemIW^-97FA!u-ET+Wsl`atbqEPBSBEmhuTrzbo> z>a`wfa4@N7lMjI~jp9|$#$_Yhk=6{u@V^B{%|l&XrCw#KLD6Etlwy_J>tVC5%J2{t z889H6oelJ|hr^@Ur*mvN#MQcd^ei5&t<&S`a33|)*;VK9vT5S_sL|1BQm6PL5iOTh zuKF(4C8G?35T*|A(OP(wt5!Fn)*zr2X{Wb{U$wJolmsg_mizr)e>7*nbUa!vgfnS0 z0BWy2axT?(wmKxi6(&nOu&Iq*NUImg&E7UT=_c7t0XY9S{cR1M>s$@3P&&AF3}2>r zya5-eNI}aw+S)b|Qsr*4+291$0lu`^AhyTdM4Fqb>l$3Nu=(gSq1WN;+z6v@8w|y2 z&hz0g3({ux_)o`a z3)eC{&sqqyqwqD1UJ%Ug!$Ih3BYZ5{RYo{aO@LoQ@S~9lq;`N^_iL#Ps#B=9$k|Jy z!n0a#Lz}QtY4>=%a4m@18jV#SZXD$eaLqvPk%+TRU}%VZzbJe!L~{Vm&~BBB>EUpFLQFQjOZZpZ@NkOJM1T-^}8 zfQ1WnLke|6^7KL$=sIVCu5%XXI%mGFbLQ(hXTGj;=Ic5~H*1Bu&MDM&PNA-I3Ur-Q zpkLAg{h}7=m$g8@um!rMEzmD+fqr=l3<_*eVuNfH=r)LgeBBmNkgwY$3i5T^L_xl8 zqcF%to^G=!$kS~X1$p`nBUis=Z$}iIOQ~p9-Kjkmf^;7;reLpSG_tOG>KP}Mr(*k`z>D!yH@2C0tewwfEr$T){ z73%w`P~T4l`hF_VFIR!Sp9=K-q#r3?-%t7ae#+PPQ=Yz`^7Q?br|+j+eLv;u`zcqy z$hrD{(hbR5r0b`=MY?{f_Qh5C`75gm^Hx^n=h@aQuFA`^ z)xnWEI8p~kD$C2u;osG^m38HHs}|TkRad{PbXl1y7lN#)vQ^jB*h|Z8 zN4_2)9@hP8fPm3kXTkx)+h;P#pJ0m5bg;d_Uj;xW20z>ne+|HpqF(_J0NS^NTV_#0 z@oh7sV7PTA1VgprNB(ly;K%&}fo{GD$D`eV6M)Dge&MiiZ%!vfECG6~kNC*_JbVy8 z&PT_ECt27#>SKINN)Mz&SbMxb_^9^eNeBr)^hJ;Daa!sld*KLr${?D84y8R5QXka| z(ZWxm#7M%kAsiIGk%_GEo0C9F;3y9rKaQbKmj*F|2Xg33 z>!Ne~TpBez(kP-oXdjfYQG}>DjYJT~RhnP=l-nSM!4c#X^d78Zqmjqva&nOn*)E&j zpoi($p75Mpjwl2QWfO)S`b15z85wB?dnNMd0iq2`FcOn}jV8KfZA8*FfB-3DQ6H3x zc^`xf&SbR5-g0&5KOC2n`6HoIvM?6RAQeFc1F-RW{RxrwO^ zK9=TZ!(BH^DLfB$b!9Ct%wFdsiD5;O#w0HvWll*NZ%Q+#nN zWwM#*B5v>qkeKLdNbu{S*f%>wr9A!JAl(Y#uZVq8|FQ7TlO>M+E@)m9ZUBBriS6wI zrZ@_>Q?ds?31Po^)KL2SN4ot^vIjqfV83Z*f$)!(zn3JAW@3p3A?^u@TLN5F6z)EW zgP&4Fwda?(gTUFM*jp)a$AQa;!Yz`xRB%KzdlMxNeqtQe-d|w7I!G#9ziV~4BNErG z!+lTUo&=7z8Ew<*<8u<%3tTim2PAG@LiBc3Cvj_li{`%qiQ58PH2+PKxZOJT{yAFo z-zz%Y5s5nu+&s-Gu-E+Zgv2QjkQ;^DBylysMQhL161N?=;wbiJOWZ5KRYc+b1?%$8N?a>&(aO7B;vUmUw_W0TbU25^4FFe03&uBS zK5QE=aZ6zR!f5A@V{jb%g|3qrZQOWN;vUnn=a;x%9eXPzE*2-+iEgF@TP{6nY2T?rhVD#Dw_)k_>* z*AuUWqH*&ju3g7os>E&9$=|!sj<8?odZREjg*PqTJEi%-7lG62fWjL0ie&H0z(p&^ zcO>p<9qzLd_cCzN{Cu;-9n-OQy~LdYE?Rv!B#t^|ZrCf4@?I=)bAgMNztIx61h{DF zz769Tt`EB2Y&7mwiCd$S?)N3`1|9Bm61N$+X!X`1ai7((cdf+j25x#3|6M9^FX-5t zBXRWn4*!QYt^JLXxLzH5@4@*D`}q`b(foWw;t0%B=7dv?w1Xc=+#KMd`R_{-N7pw_ zk7Dmr5?2G9Eeh8xaY5js`Q>tn+X7sE6nnEI?z=kNhtT=4|K0*FHHtmDektZo0~f8l z&q|yXDkB>A1&NyqoGnVablp>&ZZUAt%3CdQ^!njY6nnEJZZV99JECwFiF+A1JfGCs z>FY2b#rgX?aM8w%Cnat)I2p1S-ZXm;NZb@1&LeRdz(q^#Wk}p+;G&fm zmb?+t-L8`^ES({6U((^|k_likd|%*6;G&J=4@%rKI`;e$cSwg@Dse}3xK2L*1DtKg zfzy0T4``q1`ww913GX6Nw|9ZV<>{Fv6c4-a6v6mgYs6?$HqMuBbU1}Hha5cpKsf-y1q|G2mkH-`e)r(tQ`W zSnPScvDy0&xLD3J+kCOruVq7Q>FxxsJK|>D`Q#*jZ0YWdkxLE4W^X%iv7FD-VUie2 zee8^pOYex$UW{CNXN>k@FBbpp zh>=U(8l$}!xzyWYv=<|ndV6es-VR(Wei;poDi&^gjNIruV$0t);9^PFdS`6*x?|+X zU9s8Q3|uVv`!Gg(U2rmrrGK1`k@MXho4t2qZ!>T- z9cnKDac@Z6c4RLRaW6>RPGm0$agR#eZp0-c?jDJI8gaCoS~=P!?jXt^EuY3+C2_AH zE(LM(CGH5~;E{3I-UNv|hPcs)dmo;AVL!ixI0y>c>yfy35eG?yIr>}<+dGXosQNH> zzr=kA+$0F6^_z+~uf(PAjkK%rh^v;ksfbHMT#m%q5H|sF=@K^&ap{Qr8#oh}w-9mX zBd$l{mLTo|#62o;Wr&-IxDJV{0*?BP`j7fiYgfx8ZY|;_BW|X|c@Q@Raes$KhReGd zaTg-)HHq7fxT%QSD{)^!+%&{(m$)YpHyv@U689Y9W*}~<#Jz$z1#xpE?ik``A}&$l z-UW`11GGM7A+8@fGxpzU#9f5Amn7~(#Muz{4T-aSH`0$_m=3ptZ4x&XI4ys35O;&b z*${Uz;z}fL9&lRw%Rt;1iCco~Wg_kYYnQls#LYw8l@hlW zaao9)E^#fuY30pE+!=5xpy4fuxE#d&Oyar`my5V3ByK0-@({OO;&uZEhgkc|N1R{c zo+#!iOg1AM9dqU!l zA#O3^?vuE;5O*o!HcH&Ph+BfVYb5S8;x0p6iNt+~xXTfDk;GY^iq!8Fh_g!EXv7sG z?vF6(!G2ChoE>pLmAI*hD?!{-5@$nPDdO&zxOs>xL)-?5D@0s5;#N!C62v(Ww@~8B z5VsU@vm~wxaTSP5l(>4tRU+;LOhU1r*COsp#PvvA3*wd`?t2pFL0lE$==Y~_xj_cY>GBF-mq&mnFV;+9F=LEyCW$7;mQl(-{^TZ1@yV#j`Y3vpK??w4?} zgt^lwf7c-HF^T&San~a5a}sBHIx-HeMO>@IjYiych@v5C{2hd3wVej{;(h-*UJ_a$x#;+hfnIf*MnTnplEk+>?vxe#}~#ML8i z9pd0sctUyCB5pn6;8k$~*MhiK#Eq3W58~X2dmAqPv7dv8y8&@8OWbC}-H14P&jH)( z22Sfo9>je`;&uW@$Dh;i*M>NFRgGZpEtGCM;^37-0{1TByokF};!Xpn<NFgOTkm1+B8l4#1=IX|ivjmE;^5Y{uDyeZgIm_R+!4fWG2q@p z+*SkbG~#YE;4I&dl=pT6E*){*2AmCXcNlPmh`ZB(D?{8}23$Sjwi$3Oh`ZZ>3nK0w z1Fjo!pElrjB5u0@w;OTy8gNe|?mh$VAmZ*f;Eo_}hXMB%;yz=*okrYe4LHj)k@ojF z11=qLI}JD+;y!P{6(a5n23#599x&kQ5x2{LYeC$D23!zvUo_yl5%-V*w-a$+GT?S2 z?qLJ&X~ccmfIEn|uNZJg5EnAw-a_0X2Ha`Hebs=oJR50$Uo+s+5x3ibvmx&523#TH zzG1+XA?{HFt{!oZ8E`F#d)$BvBJP_8TsPvLFyM9~?nwh~H{!l!z&(w)ZyRt25%(Pf z?g--c7;tYPZm$7%8gXzdM)$mL`9Y-p!KIQemyWon4LBR(V9KLwuMlxCRnX;$AY~$`JPx1Fjx%hYYwD#QoHO z3nK1i1Fjo!|7*bQMBFO|+-}6ZYQQ~>xSttt2NCyk1MUdodJMR?5O>&sJB_$s7;qNo zj9UA9&45cs+z|uLhPeMT;0h7JfL;fNMeAuMM~$;$Ao4x)Jvq18yhc zju~*f5%-1x_cY?(G~f;*?zaZq5ybTxaBm^*cLv;P#QolYv%ny)wZA_YaOsG9%Yd^X zuFrrgMBE<@xH81`8*ufAJ8r_0hG zjelr>6wmf$q%=azv3vWcl3sFg5sR%Zg$BQg+?V7S?Z|Uj6&fRvS*kvL|Au64iR`yM zTYY-Rh6JuXjTsIf)Tb6db>I1whuk!7^~sNN(<%=+54EakC-*82`e{t1c7)9P%i&R# zRz_PKT6kjk2n{zWrb??X6;gn6eKzC%9ihL4nr4U;RjHJTJ_=a%V*oJ83= zppdNtGfCNA)BCf?%vMw5Bipuad1TYp4GFztD`w@=d=q6%rL{3tp`S-p9^#*pDy>cn zI|gNMf;5~a#S-=yA%Fhix9BN|ZPb5c{{DgSw}!nR@wHZNEls+I8f^3}RgYY`$?QwnRN{NN z>o(s#T`%~q>@sgi=_=Vk!%dYHY)?tr_LHF{PTXtC*?73S*Huy6m5^cXv1IrUH}IB} z`0l9jW%q z1pCFz{^eo&mxBGVy^EoZ&kVN`QYdgb9YM}_sJ%VeQT}#vMPlWl8|*CROh+!;YjIQenQV#R`HW|w{j!mQ>?JnEq4iv| z!~4NFGyIwEDKWul0PRHi5Ki`LTdqD`=udb=O^NKMaU%Kn&~9-wf=4p;&T?30nw0C9 zKjw6e%{KRp%k~}i^@h5xh8phcQZ|*pO=d$|D!!v+e9s+w$$nbvv{hK%C_Z)h%o<)V zw1pH;ud1|eSjOsL)M4tiNqa5IQt++0H$f?fz5UcEa!1MH!;egBWhE`H*a7{t`)O-Y3d@s7G}qP|I{dZ!YH>_Y&pafg~~yGP}I|6dH%tkQr(yk<}2ihE_W( zjn)Qe9J;0MBl~F%EE$%b>eD$J&f|Hu@-|MCq{<4XRwoHOZ!oIx^M{rP-##+?66oQk zj0L~Rq-~G&`rOy&z~|X)G?@GPMd7oQ?J3m{Y_uu9v&7mnm5mM;3ZuhB)&nQ<(wJrv zC7qQfHV zSl^(n@sj*exHZE0HCY(pwX>V%M=ekEjm+M5Sa@}@0t=riRJuJbzcL@zQB^v8u)wQJ z$x||#=sQ1@1$miDz1QnmtiT&bo12wu3tI~2J6o0VS98$q zZ4W3}&2Vgedxw(cJ&Q$QOIB7^m8}iJs^o#SD@&@X*EE!`TGmiqR=J{Kb^cn&yS6^8 z!LqTm@LtGFiwoZS*mBu_L2gNt_T3kb0fVL)AO9NY%cYSuNl2tiNSv#wAan3TA+tbiFKLk-=n%gWdG`6$Ifo3G9xh>$1lc^SObG$66 zOC`srgsx8L@^Q+TYAc7njJN|DXgn%loy!^QfY%?y*IJIF++M%3w!EQgb!E*En$GcT zbo>4vckcop)pebV?>Tx6LVysMmjxcl0|?vF=miL3CmKmJXpDqpjRe@n8I7coG+2*e zGy>t+j=+Eczet*-#B~y!I*I#FnmTTLuieJQ=}l6nOd+q0W?Oo2BZ@<4c%`P!y!la4A`OBEDJrJSZ z;kR%1(N-r5{i-=Ehf0S(+`C|U9i7gOU9L`_x3hJjvaXn*{H&>V*S_~Gk_OHiw&&Z_ zv7?#nQQ|ema;RL0s_GaEW7ajVt&&ta{Gs4NsO=pM&v!S=vrBp%!O-FPZgd9a+ZMv( zV$!#OsuyCg<9-)e=lUHX%*qzh2_u0>uz$e~aD+m*Y?=S=MivG40vX{5jSl(4V`D=L zVNE8=qCe~(4$wtlx<{^fUALkzr1%Sh#zToU1CKGr&!-%CUY4b9|=Z|W>~yq zUNYgxbXMq&P6jEMUpg+R=inUJ;5ZWO4`Lfmf0||~SGOh|6(b#2M!F1#>1p!Z$|Sx_ zngi0~+>FT1oGZjtm7`}QFvoj83EU#1=QszKVvM`VO6z+^GcA57lLhO5{llXp8LT?I zryl9YYZG(njgl9_fIl+FiFtDQc<&>V<_}f(`ZL-DhW#VB$e810dU6-hjet!0h~zu= zwN%y3ixP*oy{4jO{#4EJ5zN(#hP#gEYFkBBCi6Acm$sTb><^}`V+u#+dP_g%W0IBb zF_+8KRivwQNF;VXAFioRzeERKOBx@Z^SyqfPjzE6;aMSB-YgJrrDeb^CJi+EtK6|| zYk6fR${+*PWjqp`>&;?QnR1EI>N3a6?zpnkJp1L%Mz=b>4n8vEPg{3JvK;>L$RL_v zu-A{9i0P`#vn8jyLB`RLen&fcgQ3AdI5;wpR>wr8X2dBm>6vgyS||Fv5cO+^jJP7* z;|sS}3Z45~MzM~_D7b%oXpXnw6G-$w z*_vi8{Qc&%HupX*GBXw2AR4#pf@!-#)~lpR{#@UyGZ(2Yer&WqGUt1HNkwPU`TEVo zOw<@%a^`Be!=S*?9}Ev4@z3=Y#`xu6)TBT0&xp$c!!&zN+s!WC3er3`+e6n2Y4z{ecnIH9_4?=fVwS0T#KdN#i7MiC#cB0P1RtTLsSHO)`h#Z;ttk`@xm1ys62x*VE|oxmul#Kt7+->veT>`dYoa0At@Z z(9@|Je9R~L-geI|xbf7aenP_|e7@EO7vykYKA$EcQfP~3w~KRQLfi2i+_R^xt5ZE$ zeO%o{vO8P6K5w(L%0~vro+yv@9K;ufG5L79raxJQF^#QWkJm?%kS=AkHf`l1n!PSO z;&XO%cD4IDJ*_U%zqPWm64ZSy&OJWY9%n;~3y%Ps8XJ6#&7O82-M8GoUx@PYFA@2f zkkZqy3yO> z-0R{rcvZZ%K!!+VolTxLU#rXOb?$O`1<&2yEr6yj6nN}>y$0~} zgnv3*EiR|m70Wk&C?73EXGdc#FU44?8gY}$%hQE{ogI62sp3T~so8Od2P#D6ja3)a zoS1Rm7MBaf8#86rV_GCpZQAQ>>2lptU5iSj*CSLM?sT^kP0b4zkqq@+2>lsz)Qjz& zn4g8=&OOeSwq3>&Yv0!@OUNJ%((!(UuhrSvj0~W7%7@2?BEg=ck$|sv5br}HrY9T> z^!xgP{sDT!Do9@?mXD0$qJ%z$_2Dy>NMP7E81VN6I2|9~MZ!U}uQ_}qt9SedOpj3I zce;2ebHMyHvivGJ7Ix$3yEwA=C&o82?cSwDOIRMuv*c-cS=MZ8jy2bsXSG@vS@W%n z^9rm>^Cq>tV_M#EE$;y>?}V0jQp-D~`jp3tl(HR~zOnoM_rqB|GA6YET0 ze%B~E@5gWFihECFpUgUyJkROVulk$vdv$+jM)&>&)Jo(1IU!#`!)0Ty=cQ-9i zy;H}TRj{EOf0-Uv)jp>T`sTar)wZ^d>rXzeTP>MsYuV7%5 z8Pj^u^IgVj`##0n_r$!9D{4Kvf%_nNJpYu_%cmw#gWb4 ze)o$C#>#Qbh&A>!(kUy6(`Ad{g>jp585!*BnkQ`Wl{2*Gc-ZhW);9b|oUR*gAGz zU|R1qixsnv3QS{e7F*Ab#tH`**OdmWvD*wdi@6Lqn^hWc4qIcuxy)+7d2A*}x0L?R z!Y-FTG~h+-?+iGf{gnYPW?wPj0`@5bUcx?Pz)M-sfS0j$11@Ac40t(PXTU{lsR6HG zzlt?B*uRqfiveH5{@Q?7v5N-0nmuE{YuF+MGxR?>0#o@}P=1%QV*au)8@pt{CG3A1 za4Gwg0bkD^Fkm|i8t_KeX26@+Rs-J5t~Fq+Eo;DA*pG3KLLL@&1N*K4-^l*hfNx@t z8}J4;X~5;I-+(Jvivc@WwE?YU3KDd|hB_(;8dNo)wtd zu!h~A&kFt2UYBdd>_Y-muv}Zug7|?`_#fdrfUOGt5ZW7Y=^C;~v#=h4Nq>>1F|WWh zMipsUY?r_^CKYMftXg0igNn2qwoYK`FN(BWmM<{bP^9ItUkZPea%^S)M_?LLinK-S z6@h6CDbn)UcLna|crp89fgu*@1?)2dQy*QVEn)W=(wDNk1*S2eNL$7_1g1W}NGoLT zGn~Jixyc#gC_-JSGT{;vUSYy;Vf3K$--#m9$JjrZaCD(w#8dhonbJRN!VjBptS{Hk zA2p@-n(%EV>^9+@CQN>k2idn?0)&KPW1Wtb?6Xp&Q$5I^)bC5?KgKYk0Dl;N6h6Yx zVmu(R3Eil_5HB(&j~){5TD}fD8$;< zT>de=Jy1Ng8`8U!!ZSi2aG5xd@~^>(T+b=SI*9imV+TaoFT#6?2YDwb9AXS6G3{>n zgwi38+kKp|y@X+3H>HCQD(8nNJjhstLfC1ga9D)k*?{xMh5iQ^qy8Wt;WsEe%h=yh z2t7X%_~!yIMSq`_ue*wvXUS4iE&rTSb<$eK= z`|Tk;ozCMJ`t}I@+&_cp?+Bw&KSAL~8T&GY;Qcv;#~Aw#g(n%SCOeQ1YKIih?Zx@0 zfythSDTJQ$6vBDZj!K+Q>AbuVFa6H#hMY|#A98Lc9?mZ#d>Z;FME*u7gnuSQ{8Ivd z6(RATrx5ZRDETufS+* zoZl%h8WYD|0)IeYRBkS>Uf_KK!)cs2fp2xf!5&)df>q!dQN-Vaa8UjV2Zk#80zKmcKECb? ztDp$1B03hqQnG#ygB3^mI<;#iiYPoBiZu5I_l1Lz z0If?q6o>?jNzUG(CP;1f)0h29l8aWioE;kukA?-Sx2L($;|q>84)?hx0=;-&cw|5% zQ3BVg3)qMCOFR7u5|vZDfk>-=qHR2ayDS3u-xwn<283-w~%RU^Hj&)L@}vrOvUSm`I8(?DI!@ z2m40V{5B4aj;Vs3Lqnsztz#;MN1=@Hp;Dj0?bZ*3jO^k79e~pAE1g-t^C%1qP8O6fw3`s zi-nkGm$My}JV3wQ9(NmRlWRB>IU0o{V}Wo)qW%Ew zudCC8w;sj<5zokB|4^_`l%$dt95W`77f_qMc*AQbz<@f{TC7LN+NUF`45F|&otKl+ zo??-ZD~M>5YSj&)ee%W@t;}fZk?`mcmXPMPm)dYN4KJJEDfK`&!qiZ3(4q+nVs4>O?79cO*>NmN2CzVM=Afltc-&+Y_cFbWUwT=hP&0PEA7R)FgCH zbwcMY!ez_Qyrn_GPzuk&!N-DPjLH`#aF z8|+^Dc2}!?ue&{1V|VTEY^vHuz>EJ{o%VK@-MO=+y1J{SwyLY8y2`$PXG>L;-HRA6 zV!Vj)xLhv$zt7&~b$R!0v)}LS+}*glNr&43n_KK{-gdkSVs|w->+Bt_+v@D}eoUR+ z4s_9p5Dj(qK4y=wd3eLdiCHf52mC!jX2HadHCAJJf0nJTI?r;Vh~+NH zYh9$}=PtJtX)CqWmNk~OmUWhEEyb1%xuq7nWf?@ED`%EG{3yazMQTTtrr$To6?9C& z`8^bQHj??V(!|5mpOMw_$QC~=Cf?JCua_i*lJ_<&BqOEXH}D(N*mVU27ij;m?ZIWjPFP=P$iB}2U^Q1r= zQtyv|RlRQ@fv#=kA$i|Mgvwik`&c$fLMVBMP5Gz;ZyZBuws-tU`u zA@H7{6U8BUr-4;@1!!LJ$`_Z^23`|*%~BXbDG!&52HwNqeJu`emx{)8L&*As>C7)Oc@zmr6eRa8D=|KfeNADt_LNdqSz?Uf(Z9^pb0Zvs3zpLnE4@_vnmtjaqL-WtK9 zK1cHY&BVI^UcKNENAiAP;!T5R6TBRSM`NCYBq`aq0JgdUXQ+Vf0yh4RX za;3a+6K@T8Hl&kZ$R5e-H}UGgqduE>`3i5Ji5F6Mixu7u6YpuoKI+e7RJVd71JC+pue3NL8ly#byLaU^dQ{$xJ(;S-6oZ0xhF?+^L8LuL8Xhc<^#%q*Hb zF_V9;?aj5eX`q4&>^w1Fd}HP@+JSh9`v!N3yZ%ZpKR@(h`A^<$JNC?R_e1WbU;e}! zFJ-Zf2i@0{w7p~L*5z+;4;N?8ST6kK&$3GCcTcB?dFBS7tWQ4KNntiZitq3I*3a?; z55F49+`;1SK3m#Zy;T0v!_A$40iKM*?H?7w3cSoD$l>RnNCY$t~qd&HVtZmspoH^Ww~N`aauS z$`y-{QZ``=4Ni22o}Rc6`q$9rLy{fy`UaHgvNKCRL;6=je;!NK@A3Stm(Y9J+o;Wr z_sSFU@D z*p*t>O8o)V@|EyNUWs1jIqn_qGVaMQMf(BjH44D7l;|nB?%GgH0_|RY4N|odea~!4 z9aqw6muyOv@^1>+@&}c4I)4=yS>pU0x6b&ofkS%%AH@FFx{hr3#t>Q_{85=d9pzEU zCi@uK;0r|7;PS)yfM4(?GNx$&c)vGIn&>Gdl4%;P}$X8 z{EcVxZ~Db+GQWE1WuZ>kIUDt7qAb)sF&Mfq@wBi+uS4WBwmIjr3%eD6{n>+P={tq| z9qtbok9VSHur8l2ov3pkE&iKlt2=w5zdjrN^`m0z+ZOB7uFFEdZgDp9c+mYeZ0Ha+ z+!T7Nw8}lmTd}m1N?)&I^~K+W{u%IB2n%R*6>Xf4yE89VK9}WYw(RL82Rb*{*RAiW zFFw~W^IGMLdVcdt8m=s7)aU28FB~lkl^AsK{9^Q{{_>O5>wS^h%~G7Rf}fL(dZ&-N zvNh=KWoHqE(Xo26?aeY}Jfn8i_U0C2%!Rf$Z!pF@)Ar_#N=(7|?#_bqnvksff@T%^ zSVlHd`)YsYAAhp^aVqz3wit&w^~;)yV!KlU4*mN z34c_%4;K%0egl0N{W{qB^jbQbYJqwlou%QdYZII$xq3}vV6NfJ5~00LsbfV#M!Y&k z^_l8D<;yB~@Z0X|ZnC^;bF=B|Y#Qd7dJiRa(r8R&{t@@%R4*T*5?_Y%bH({o0*OkT z(x{|Fcp+BuG@fTo$@0Ij{)8wiDwh&>Pw~f|EkK#;Hc;Kub8dxRi_mKxb96=y7%OGY zP-1Fcq?dBR$%$HTWXQS4YHEcuWf%0(tKrIG&evNZTGgc98mpDoH-LI>Xp4MAqZxH9 z7pnjD-PLp4DfmA&mcsYNuzqdSdh$KZS@m{Mw$@te;kC59p&b z^*EHvEXduUypglXk9xoQ`9nXZan~T7&N%2^1@>aj&I4N?vzR>>qslT?b>PDK9i839C!Q_5 z>F3dLMYoI3Hm=kPt7MyfE;tw{n8;@{u_sE1!ZB|(m^qcpm9ONxL}=Lai9g`!pgf=c2c+kug>T4BTPfPg+pySATLkZ*A}tgSh-Jnyn-SVHORQX6 zK|5EM+76Ur*X-Sa;E?a|RtHLe{u&z(2x|_MmdW z<7O_uoyXI%((Rm7FT`NS{VuZ3^*chCl`TZ!OCvI|hr7CFYQiRGFo3qQUvMvw5suL4 z5Y~^J>*hPZUB%2qS;TguPqTkxf){RE`vH8>H4+K<%X^1{_%Uxe%=`xH_!9DH=CZ^0 zxSyX)IJmA1W+elg&?{A&?{S}bPf;cuTvwVsMIBM*HjUR;*PrV~eX}}CVKlANo*8$L zWPZmdbFPs)Yh@?{QhWw|6jhP_O95HH>6bj>r`4YEm3f-|j-h#Ml)k!8vs|&!e0rn~ z`scWrk8Ft$V*X>AOjHRW(v;hVH!m z_WJoQ&An-QS}mVI1We$d6FZ;B%7g-Zf#g(5_6(yWiN3coQ-Hs!{{-7@~ z=RLP%Pk42Y^aTzF=UOq+yMs?)xX0In=i76imgsiTF0HD}bnjMgnuZ z_mjXaGCI>6-p{R_Nh?idDx*h-hvwMJNl6J643DO5lg2nzhxgPY{b}1RFrJD5tkIRp zQoswynG`=%-RsY26TmW6Si>o8d+x?70@`IRlRhH(d{g*&QNnkgubDqpb9@AoyopC$ z$8)u<0vkNdWpa{S*;rrNYVxo@n6{3IHY-e5wnqbvb8{TKeBT@0R z2Y5AYW1F5SVuDO$Zm03|8gAH>K7*oht1OtdD`eg02Gbp5bA7MQT;p}|W260%Ip5n$ zDmpX0i*CJsGcgmzs!PsXEq53cIQoO(;UoTV+HMr7HOQz*f8w7Jmj$qpGkraj&YmaD zb3^VIx|~kiJT@i~PYcI}%6oh0dLgYoi0w?DA+Z^0qA{z}^7f6Xk4eK0_EO^LNPlo( zZk|npHC%*)e|6^zg-84GP2L>q=y=c2=tTJ_R`xGHQeEE1drXLwTX?%#owPkYRxqlS;e_>J zy?-!zc{L4gs zCZx1t!}Z$jbz5t;Rd3x|u^k+-#l5etvbw6O$>(g@=e(WF5Wba9=Mf`zPH%MT+uRER z_mgDR#!jSt(xs5Dy&i8{hp%goP^LN+#p!Xj@Zt~(_}1%*5Zk-)In!h({*c%v~KMEjbjf@^AISgmpf&9pR!p48JDGbb z=fUjLS!WieJg9ywgfHG}^^(@iTxdVgx|j=X1FbE&5H?W1AP+2=jka<4#G;edQ+W^O zp3XUweKzZ%`D-6)pG{-OLhcv7lk1=VKHCPp@~Fp;h3czp(g=jK?(ciSj`vF6{a)xV zXsy?U=r3&0E00e6Sg3kIa|wC;5e!(0cO=*+$j5#T(p~ z1aqCy`JY=X#JH-q*M-op){W1mwQg7^HS00WdR((Upjl67){~m`lxBTUv!2$hXEf_s z&H9jLeOR+TqFEo+tdD8>9xE_`ALJM3iu>mEKBrn1jUjSvk*4epjRH`hxA-` z%&l+I`|0`Zo7A$Py@kwWA$=sn2WX=)ab&Z%-xk!Gv!#;hRjj z+=MGk*kQtzCR}C0)h1kH!nJHjX-`>bPx}p6V{QY^Vm1TLX3GpXhy9v15EMrib{77L z0q3zx25e=2YQT%w1q04!=L~o;yU&0NSib=;Va*1-lx;KMWo*3x7qWZoDL_R%gK1vtk3bvn&JN$lg%)3(I1g*k2j&X7&{W zE@K}t;4N(2fNx;88}N;6rvcx@>;_!URv2&v`(>``F9-XH0avmg7;qK)wgFeOFBxzR zJ8i(V?1!}RXY_dc-ES$_!uGK*8t{I0&VX-chYffKyVHR0VD$!kC);Si2UxxV-^KnT zJ8BGC^9R`v4A{qBFyL>>~zzkR37L_p!SS_-58&; z>`4ReVhoXo0@Ho;BJCP>pTN5QRjg0o13Y~-YZF+Pw}yQ{VBLRfS-HS;JzJ!$V+8{1 z@~&n7f&QQD`z%i{X5SO|4UX5dKNFa)!;7>H?DGQa{=berBrsi<6=^nhkHB=zT%?t- zPJwlOrEI6bdVa5G8w5VZ`F55guwH%}*_#*-V*cC2zALbvzM1{8z;r*cNGoH%Bd{)i z3p*k(T|*aXH?TVe*6qKM-7N48JpCrN$#8x-yGG!hJiUVbDp$8h&yRy$7Py|LSF*no zn4TpUX;tj64E$>LWr3IS^cr?nV7kvzq}9eY<>c77FK3a)*dD~ogYb3<5E3pk;q@j= z^VX}kHqjp04w*+1( z@CFJYpXxdBYDN5h5k^G#c@aKOA^0y-_z#TzRK({a10=smgq;+EM|)%w?_Lp}rVx4x z#ChBbKf(@S2hSJM zWxJ4mqw#~vSEh4&VE;`bUgnqEi}>0E@iq}(L?QI>{DNPXfG_1+DgEz+zyDs}FI~eP zzC(!Df&!lx*eUR+z`F##N8o0Gj|=P(_yK`$75Id}E`d)9>=yWxz>NYwC~%X&rv-kW zz-I(Tr#VP=pA{IH=lCIk`viVi;C_K075El`9}~D&;Bx{81pbJ?0|I|kV05Zn-|q-~ zv%nt{c!$6r7x)7Le?s6kfqz%v7J)x0aJ|5f3%pa{-xIi1;3ov$E%2uVe!sw<7I=@q zpAq;@fl>Ip{O=NYSl~MZ9ufF z0=El%MBoDgPY8Ta;G+U}3j85~_X&Kjz}*7hCvca*_Y1sN;13Jz7kE-&WR~amn7}=# zd=>cOp#tkhg@Zk`@G`5w_X-hz55htDD;yZA=nM3W5BT_s(5wOx!HVWak8fW%7ztqS zGc2ss*N)X@1CeS(?+Zo-JN*M!>JQ!BHCq$A_d&aSpXSl7OHjW$$L;|Aw zR2war?xE2m-cX>|D6}a!)~i=uW4x&B=(>*%^DdkgCP9T`71(Fecep!PqdAVFm$Tb(>QJzUVJsL5jIiFGHm@%b4v&VJ&*u-I_w@}2 zhI>OtS#&ti#{oG8n4&qY1H0yh#{vy~q?X4xhlWOb4dV#J)2Da?;gC-qd+a;v5~gfT zm{Of6rEW*Ulx+!9Y7(YYCQM0`uzh>Nl-h(TRf$rzC3McVgwENP&^cQZI%jJ_=WI>r zoUI9+lhCx~F; z>|XnJSF3%myFFNAckS>aM#>g@Efd!60o zZ15be79&&gD~x1UA+tw0(?y1UG9u*#Ml`~FaS=_B7Z%Y7!$pN2oA81{O*UUlsA=X4 z2}4?(i-%a4l$HNtd(kRZu$ zio7sTxw9?`42k9o0yQ!2#ehywCr=`VE-3jFQNgjx0wvOTNuVa+azKGeF9l*e^ZcIX zbaYvuh%!^+C-F)9Y`I3VI_)=bXP@05C-ZW;Z{*9=nEco@KgtwS{1~1!y;qaWm3H>D zKFU_6^wGHJbUqp*r}EK=q|^8)D>{Xb#wgSGXq=q7+xwV3!scsW1t#9j z;9XGiku6TRf*-2h*MUo=FoaUx_f5Rt0C&gXT{Q7N2s>8A;XQ5QMZm*t%;+KYK4Rj% z3|>6@?l$q>1aDJRS}Y%3CSD;bPH`Mwor!l7c(ypa5)-c_0WZtM8v@TBN8XQ6PHK6a z1FtL&??n^udGM(2%R~B)-d|DW{S>@PNkS-j_nUadXo#EQ@cbrT19-SS9X+JHW)ttz z;Kj>Ft%>(7@Zz-(YT#-<-T`k-RBJ3B^nQ)XE3n4T$G^i+l~)bkXXD8Gu8H>p@ZN~S zd(OoB8s1ab7Kisq6OZ1nz~h_ffnY9-cIm##*z0&CSC-*c=h0M6Yp{G>f^{eX5zgHUUeMaf1*ED^INbqzTR$=ylU|9 zFM3EnlTTH7^&k~RSuy|pi_j~RI>AF%96jXk*G;_r;5~73l*V-t+KfNaE01?>#XA}j zAe3olUT8OClPU1t0`Ei$yhuxGyqOev_qH;2It9Jids5STIz?Uqo&~3p-*YMQR^r)d zD)P>Q_izgNwd2|CWD2~ez)MAM8J_i~;^${lb1L#)0xuQ&nlK4Vh4(UespxIT zv*vRt_-{HzUI@>sQz?(Pz)K|`5j-nTMczB$rIO!!_ot?p;hln1p z3hz7MrDEUy?$qSHk|J-vKSg=qrQ+uUJ*mli9lTWPeP3^Cdf!NqH`JG!-gm%DrQGn8 zJFZ`TfO&+Rqc9vZ;Jt)7(f9HD0{*h`SBSrh;9=??J)XzALTiBT#vjcgh-by$7fie< z@F<>mq(|~TV&c659_b+-E{USN0Tb^Hg-5caybcp@M&ThT%DdUbvqoZiamg0t*-gAP z;K}^rQZCA~ns}Aq4I-WLLHU;U{X2fB{yVSerFhBv8x!wog@;R)DDO{Ayyq3(VukmV ziTAR?D^Pf6OuSdXllet;i0U0M@!nE+n1V)mx0!fWygMe#mu{XRnfs^K#9O2Ah%b5T zO}sLNw_M@9i^`+=xlZBHd|S$!Hu0Jj-U@~Hf{C|Z;jL77kC=Fa3hx?)caMoTq44Ow zleCY%(^2zrTH&o$cugkWdGKVpQ7GkAnt0EEXG1#G)3pk3v57aO$h%hIy@|%G+V_TH zU$Mgbwuv{R$Xl=QzGC7P9*)_!LE(Me#H$2P=Jz^5JziNf1% z;teW#OBLQ)6K_)CU9a%|3!SFwzw-*uuJB$r@t#ra+o9f_647KOLd#9ITN4e3<>=stqfyUxU`15cLQjSBA<_^tY{ zS>fHJ@cz-n+Yg?sFXamFWfL!?@G2DE7frm=3eTbNK4IcrP-and4*S{@G#9Z zsENU^^}koQh4o2c#{ebw~7+VJE!n)3n(G)g2MAA;XR}9 zI+O5TQg~fScvA{*ZxY_L!rPaG_m;xjpM=NmiPgW`lkf@^9&U9c^q)=P-I;_}sqkpb zNYtO!E4;gs@Y)p~ZY3m?*RAkyiy$E{r0}|v@Fo?WKMC)g!s|)GyP)uTlklEVczsED zFDbl065f=;>rcX)R(JzRcyB4Z!6ZEPp;-M3CgBw-yn_mFEq-U=PaZb#is%Aa9GIr@ zgRZ?)UiC4?{(Z4XL?C$-f)|o0wnvQ5w`sqyJx3 zS-EW+;%aJlY^&q(-T5DOwYV)7DT#EKMfH>3mobOMkwfz!db%5Cqip86Z1)nkwRtjF zU!3bX?LX+=;%2sYfAO1lbKRA03T@rC!I>B7j6!g2Jg)G?5Pq|bI?8otHM5CR4eXL- zW0^a|xgiW<#Mf-O9&0GKIlDWznWQ#wXY{m7Gg8oT(y z+icmy6ubCv^W-BBdA|L~>4xmr>aT1rIU{5`-8wT5Iyb*if8~af<09q5&65YSFXJoU z%g0##>H6XidCm~lESHa4nkOe9ufF)O=k&=PZi|iVE1n+nG~Z3X^4uZQxkH9?gZ$h9 z<=j4TX4wlpNb_?$|Nb=}et(evUh}H+$~Bf;t|u3kZi1z*lKsNct&_BKY6@*<#l0u|9Yf9CtH2Ggtxpa-)FXK zQKMfzNet_Q%w|2M+jNbmxtDCJzkAIKua~S4HZl8Jl67dQ-cmH%Ole`;Tklrpt1YFQ zmE?+acKJB7g!_u~xV9gDU++Cs|B%1v$i21bOwR5*&ph6c`)U?`A8*iJwcPrVW9`TE z5(_=2x!LtATWk}5{)-v(Id_G5ey{VPfRw zTt1aEG-h=_8wb&<~Y_NQf-S|&au@XZEA4mRE2WQLIN2Kl(aR>uD`*(!L#d1WjochbxK-u_xkCWtW`o&+dH=(S~^P;S{&C@ ze`TObw(5Me{3`eH!7}%`U9z0w)f>I`Foto+NjY5YJ}<_GZ1);2w{&W?(yz07EM;pi ztxzrHEs1LJ5;e9v%eF|t)-dYuV557dyUIN^!(J+LPwzsHb4==|kj6sv^BYkcC)nmc z5aV#R`wzGs%P;BUa<-dBzR&SE8u{AZ*%to&C-pRaW(e!;nQsqnu zqaNUNL*5idQ)R5pY3eHu@m#%uTphwF_%t8Eeo=C_DDfeTY|k{TxI}gbF_KxQ-#DB@Kg>r~`LJN5$)>?ttvu`3SrI)qTy+%+yVi#4bpz7jun0 zQSV|VQoZ|0J)T``C5ffW-T!N_-hF=8iRos;$kyapbjG@_5hEG1siPxFzeVXi$sck& zRsB(GkVgKvG3t+UjDF;gws&qlv{|+QjA+j^6mfrS#0Zu*ZI6z*x;JbBlQ%ZNb|$>B zE;<%c?Ph0I@o}~I)s^tZO74y2kSD!CW2bCk&MK?WPA!a;T1s?Z#70l!_$BK%%?W9i z_M7UQC-vDQ9<7l#gEsf+U4<{2+a|TgJj_tfxxf6ZtoQ7qO}FDx+dFq1+92$>PN_xI zI@ev&Y-&$Jy-c-xm8aoKVTfvoq3w2GSE5TVoL*v(qm|`dqPFD^XGhzXY_DcpDUULL zc@4(=ITPfM=Fv;w5qNPz!;H7>o#TG#*_>wAu@lEEwk(YM4OcWqR>$kZqzo%$Soo~D z)G7PFEPl4t{Y~s!7w=s7*O%))i+T6+?mu-~rWMe8x1zW0ozX*sLT;cr=P}D>YSF#uFWB_DX+O@Z-{7O(74x0RN95JUH>>Ux z=U5zna|!(qdXC%BbCjXycxswF_l-+?x#cf?k6rXe^AI`ID$cvr&>z%qa2w{$>|%o< z{R6xW({;}Gs%{YyFf-(H@R&chMq7S1TG8P{)q?5poIWf4St)F(zw%nu4I+KBL05h8 z^#)sHKNIt3&GfbCSJrWx$e$QPf3d%(TST{m%bf?c-Q*!mOCvW-vU zde?G}Z93+DU-L`23f}2?*>81!=&X6U^<;+g@mU z=j(?`MV^nYZE&;m@n zxIEZ=(Q;mI@1I$|M99p!Y-J~({anKfud$1tYsi@@ySDzy=ZbQl6Tu9kYD&>!^=%FE3)Jp8Y)c(dXf#O86+NRQgCC?b;Lgi0To2 z%Rf4T5AJu`@C}TOAoiaQ+qUA98rwKuWWrWuE91LU+qPA0v2~7)4(+tz3;W()+nu$2 zHCz3CcQGB7m-p_#w$bHdAuMm=8`IaYz=pEDh#MFgx0R31;Ugiw^YQ_#_7WL8Fl#T~ z1F&80Eqj$MXZ0IWut?wi_LldGNqsP>H#B}r^t&Z|#e^t-sCVp^;0Ts0}34TRw_v=Yfs12#;d`wJ{tBjna?7@g7Iq?a|A52K&$wg8m^X z#L+uE7EF_5vC zeFjB4hK>Y7<-Ga!`+L*u5<@0TnmC-ljOp3~5$YY%(CTENUp0s2Q0ef8dlyWvqtn^3 z%hl=Q8`UpN))f;?Z`vq%~^YXF~bQ?cj$0;pVws_GaEWBxU-6@gSb{Gs4N zsO=pM&v!S=vrBp%!O-FPZgd9a+ZMv(V$!#OsuyCg<9-)e=lUI?aPaU#I$TgULYeJq0u3Kcx-HFA*{(nS@3mC=^`-QBUenYV;~&B)j+^s-a8b; zk2Je3v7&`jJT^KWPW!}M$>{h9R(j2xAGvtPykx?W>8#MboeX-4#An`9TnjBqobIg9 zZH>rKy4${x>ImX4AXd)_r`i8e@gwP;gDR5w&6>=)CN$)a^pA#zGvpd6-hmM;(<;(` zDIkj>{gOxgBUo}4>vN~sDHxi^MrqaWG|L@}jE4OKX}b0p^rvas0zr*#dt_qAqLy42RuiItFBYkjTT z=Ubnnv#qVAvDxX_LrWy5M?2Q8A3$SHt1#)QwB64WMk;cZpXs|vcU3h~YliN;{r37D zeS87_OqHU{Hwu)zE#WLT2s4cJ6t{Jo7TmD0zBCPib0{O&;5dSH{C$C8f0||~SGOh| z6(b#2M!F1#>ACXU>P38+GzX-|xfzk2Iai3QDo4*qV2<~G61YW1&v6be#q^*W_xO77 ziUQ3qrS;f&AcKB)K>Sc93zifN&vi1E+(XnLNBT!I>7@be>XS+Nc+D}B;)kkx{TXcn z*t7^28FRc$PhQG&BOsGLBKeMeEmd{%qQv2Cuc@e+KUH&l1atMG;jZJk+E!7O$$X9V zrL86p`-5}5N{sm>9GUAaeWR>&kGW)DT5dBM&BRzWTvMH{@+Kp7i4MG$G)^1tWI%M9 zXETb?@@9c}D=h=In>5huuX4w>t>u-OC^RIbL?hm7R(D zqFbF_2Ok;or>#39Sq}erWDre|wn-aJ+t@x^a=N>^I2zLLXh&}_G#Cg6M+VZ>KDgOY zsTpxfOnN39lGcg7?hP(7Bd$pI_`>a#Lg)ULQLG~}3ho~tn&U0_M3Tpj`1%54!GZL4 zAyJP+#XCli3{_9e@xJv{GeKHvwx(GN-lR$2HI81cTx4b{xIwgItS^|hE95w)JI3bv zUY)r}b@RtY`y+F{x0h6OCY`U}Oib$lp}%DB&?RTCmKzl~`h(%&BmTL*!Wh3C3|SFR z{4?UR0JaCkKDKFB3`eTY4u42pQELz4EYC6b2Bat)^HIH{=J%1M~Sb z5s^Y$JiA?-8xz`&=ir__ZC#z}$?D_kCX(IR;`Mo(omDyV`x7o>mv>-&$E&3F^KU=N_MHkF%l0g-3u* zjSarWW>341?pyBPFGTtHH;MdANNH`qMJ#Yty>)8^p0GE0yV@yVzPifls;VZRvt^(2 zb}~cwCid)Ky0+1|N6kO?lVsJ#PHa_vckT6f+d6z*dxSD>tteR(r^ngCC5jl&o=#Us zM^`(1ZHTUJR3RBHi$b1Q-RNy`?sah*yeeK>AVZ|G&L&Truhr%CI(NCeg6D4U^3evF zu04i=b-VEvKvNeAJa)cb1NeEuKOL?Xm(%Nt<(og0j~1e{qp_BkVysk+xXI<^>B7Ly zjy=0n@uHU0?6|`N6{7OSstamP%s6k0%Z1{NnKJA7F_Ne@?RBg(4R3!z1Z%F`B@n5+~aI%+hr`V_I<6ggbdOk9q(88TAiKE$N-9` ze0Y2)670cd=f2)Sybq0-o^UYG@9PWt2j~r}AbpisJ~E1nl2Blz&xbE#B7tGC>oz6f zlw{@ zRRfT}iR_bEr{+t) zns-{W`?t@#byBk))2zoe>jRqggl0XdSx;%!WPUGD@=oiIcjGT!Sz9eu%^J6?=cW@y zpHOEy>lfus9%cC9Tyf8d9IS1U^&pk<{MewDGx`0uFX#V$`?AZ-BV39MH>`-9$UnL0 zl=Z>9)46AI&SpQ9HE(`UZJ|9t7t$8B?Qi2{a^H!plk-<67FxeesTYr;F*dB2IAJ}R zcPjV6oYUE7vd$*!12fep&~mBW_?ypuD4EW5_CsoUQ=c^7V~yGmPC$PH`oY|jIj6E8 z%sQQ{tkdZO8}!QKrT=D~OQ#)bSi@F^Cob zsLl^;+!ymV2VO|sY8|LvfI6V+r#)5FegM#LEXj+(Z1(oM`3k0$v-5yyeyJZ8W=z*i zIE(XReR7s5J==tHIG?T&^drZVp3Bo|9M_LrQ#!8MU>}Wj`jKZ!x0=$eru0QTovxAe zW05I6pQqFHn||b*(iijeSbi6q(hGPx^~L&8U`oeTC+v@@q!(~qU5^kt^> zWv28(o=*LceiWM0m-F-qnaq}((u;UHjcNK(WJ+Jb(`_=DtuUppf`mxrOzK*BUoL)cHF-^3O zn-P(P9oT;%DxZzx4eV`!vpK$w{U}yB!MCti3|M2|G~g`uKMgpW{hk5mu!jvemqiRX zkKJLwR^~C_MeG&>&Sx78crjaKzy%D;)JKmjwuJqI0WW2LX28qX7Y(?O{hk3YXD1D~ zh(!!|1>0}HD_N5PU&AU4cokb^z^hq~0k2{IMFk;_EbMT0*?`xvCIvI}e^mn8aE^s- zV5^mM3w8kib(WMy>DROWW59OyZ3EuO{>Xqgv5y<@X7(WiE@QM$y*w;z3)^MDH?VR8 zzLBjk;G5WgMe91*SI+*o0avhZ8L*9g$$%Z~qXt}w#aN{^B(I8n(15F1lL6PT8w|LX z6&mnX_VZ|4B6-^w?Q13v3){~A+<@!Y9~f{6d(41$u*Ima6h(cg#tPUwDE}BFja%)+I8$-g+3Y+i!=*+RbaaRQKV_? zF9fDBp-9VOF9=L-DAKaorv#=kuSm;bj|xmTeqY~$%GnA?D_VU+?? zpIoG^VrvAZKDbCje=IQdxkcI<_J83xav}AxMcP{SZvs=FTBNOGy_6`9BAnA=!n9wU zJShDp6JBM)xh6a#Pe!;L=l|G*|6ai)|785@sQwk>j@0#!#6UH_z(S!K?QAGJ? ztkZ;Pk1Bak`YjS5Busm}$%F7l2@n!qWx|R(SgA^mzkRhoP_*G}OlA&)}vn<;#Pu|9!Mi}0fqKFHW-1^xkr zko!**LN4_~gx63Axi?b?xh)hzZV!c!d#}Lf5K=xbPzXOfMd3Ndo~H13bU#r#`HRAv z$!_GcS>P55;U62te@yrTdYTBIXY39NKY}%S1-@V4uTlv9%M^l7?V9AojzW}gJ%!_wSY zggz=?;!%G{c7KCH*!KepVc#nh%6vfXO~PK8FKQQbK8;7@w;>82VhmM}+i@Nt$$OeY z$omq7@Do2@kw@*A$(4X&V$Mt?udqA|ulX`pB zy7h9`>IJ@A;13Aw75IGucM9wjxJ%%j0`C=gyTJPdMq{S_L)$NKo50v;ZiwRB1-?UI zm%w)l+$8V;fl+z5yt@R(;KT6;1%AK4K7n@#>=$^Kz&!#t3*0MkgTQ?P-zsoG;6{Nl zNOJq#0uKnhM_?Gm(=k|b`+@@R7WkmREdqng`K@qD1)gzN;7h@9u!ok~VHJ2n9r5=d z9F)JpfuV}NK+pJqk1xi=DkuU={EkIv0cZ|`6<9zygqQ6)Ct3pL7=Z`XXz!lDkvQkg zP7>!dH+q_U-arKBM8cy(SY}-JkvDjc^gpL~ux6Heif&iy*nk?jD-db*PweRlxAp5% zPz_MV!3r)yPmLqK2`>W$4w0{;bRIPj#A^>>if@Gd4frltO^3La;K<#bM?*0~ahe;; zrKvP0IR&-w=rFI1dQGG6a`ABotLPbniFjSXcep~`2U zj(0BXc5sJ+J*>Bf-c9Q8;l;n+z)%$W`(ZE;mh>3IiyQi{KsY=au2z2QKY5X~2FAwl z@hD=NUCwsjFpu;`{CEWfac+;h%@-VV4TmB}qi|#_5RORHABgl0O3)j|!ptPA0WZAZ z6%@R0g16Orp~BP0d_I4`-xKr=2Znn?M-6Z&T+3RW`+d&F7GH~J&u*`;#bu0OC_vx7 za4-^RM=8K7gvry+-XSUgi&k)t z*4&2i;8344IyTzvoz1O2kJov)*6y;m+nemW?G1LXeY>mGzSrFztg*ZHcQ#dRBjCk< ztxkKp%kJFSQeEBEQd`y4Qe9==zq6&P%I-ys7cpMMcw8#5FB)7vv?Urq zMKT{e#qZd_DI($wnuZi*z@&I(u#CbuJ*P+$gP1_-kSU`0a4CNCu9;QHAu>8Iqe0T% z$LtX{U#}ZFF(YMsykZtirdeY(wmxCm>OLGSCyH3^lDyVMT7K?wOOduxTWwimS!-Em zxzQwM;g2VJ{bz{nM>T7)+#XJm`tbSS0>)WNR={(D1YxZ@#xw#o_%#D-q*lW?@vp;#U|b$?t!cMki6d@ zvub`L33xv-@g~8;B~kQ{^8UfZdmX$oQXme=`yVD=c20c%eaghMgV!yEA(Zltn|LP@ z@B${@kHD*sBhPK(*->%g@f;>zA9&MoRh{K~Tnei`LPhSS_b(Ez%WPX2& z2$lC#K4X=Vgi!LnW8(b)yl3L@zG~u~SR7v-ZU-3jeigi?IP&NogKFOlc(`RJu&TGdP`@8&=KU#jD5tYNY|brZ5Lf>GAK+Pm zQH}XA2wuE={Gmx6@qR}kN?o`e!S%{4{tDOIHeEFTU+VpWkSFyPqZgHFM3lcbncQbgT zhj`S7N!~6K50iKP?iBHI6ke@~hkGIHEu<5V=5SITJ*!gl(bpfd4?|~^_e*3-!0h{jG`jFnFjkoCkMDdC!`7KT`B!NR0A6Y2y79Jn26SiBaDD zCf=_U-V%l9H}MJvV)B+Myap4mSmDuBTjuvh6YnPQLP#gSke!mZ+QfSTyfVSVkQn9t z8o$-@_y%|v1g}WpyKo=|wDNqApUc%&vjPr^H( z@G6qHBp}w~$>&Y^?bMr-ZF~s+#*YnYfecstc>})-_ z=7pC_)``8BuWcrY*J6KkPqF2))ABMSyvAegX7+W{%$9w*$+Gg+qCst@iqX#DgbN8@ z{<_6_Y^9CZ6t`H!HFx(F=V1@-`r;D}|NFJV7b%A^U-lA=9{RrX#V=eg$r9FNH)nSj z8f+%AVMu-vRsrNvlnq)1wxlrmN!K*tpaD2SuR;N=1lh$ zTZP;oW5@3@cZk=L*=5A--^4CnBQ*Wpa=G(5v#;iwmI=ud-1f!7c6R3JhFr=e%hO|W zRh|C~ot0PBxm@V{$@0Qz?v`<#q=h`0Ovjs7(Lw&xHMG66(Z4LJVJX*;FEmuXpyVM( z&BNuSek=dUTf4H|ADdz41|~dj=Gk8Q+2Z`Xw1DV75nQ zFblXiqkHR$qvYozFU~7j&ZjS1*lE|jQ@yX(|9pu>M~A1%U$4J%qeu%)T?14g(7~y^ z*Pp(k)t~$0+_FPci^@WmzAMhrnAd}Q@O8O$_5bEKb2MXZ5zUrCWZub_+>gv}Ir_f6IMStGE2wrN^e9yz;H8|Ht0D zz(;kJ>%(gP}YC~|VNr~RIH?X_pt-kBNZZzhSq z?|i!rYd`CK_PgHouKU`1_GU|V4Vjnx%h^}X*{@9E+B=3;AWtTteJj#B^_SjuT=%*$ zvl(`E55;AE`Rpxk{`A~~{>}ad|H&&KBJHh12H0=P{M6aMzLl`V@NI}tN9e41?xq|nAwKwP$>_4{vGcYAiDE-l)^xu;lme>2Xg z?wzt`x{ei}ddmacyRE8UWj?xl6JnOQ4s6SIohUx}*2jSC{S=4(sNdi75#fPPzg0I- zjo6{#hgolbCECEVKVM1CH^l864yV&(J@@#FRnkvB}IYj+2VNr@I33LmoFw7;-9Rl{dj7U z?aII1Iq*36y={H4=uw=-KY5^y>U*O9%Rpz^GW);C^}T@DW5x5{`~ncw|IZ;bc&R4L z2&C{C#GPr$?tgSQ^#M7qAGBmblPMst8@P`c@b@FT`*8Mx#^2}Q@As!E{yu-Mb>ILP zcHgmnOPX~a#eN*v;j_-`LkaE0d9TmfzX#zyA6YSUu5Mr_5NW4c)`ePj)<@j!h-F)? z{p|=1TZ#LfbL9iufb3g4PBhixHb}ahlQOU07o9nx8mPya4l8 z^NExF%*u`#jv0@cj-B4~!0==?jDM%F{JS0)o=WrePM^zsf>Mq5$7!sfp8OjBhrh2I zm=4`%yuJM?2-mw_@LJ~`LoG`NV!q6N>Lb>p1yW!92S4=!k&l8)b9k;3Ty;uW`g;3) z(6QQ8fI32&d1*p3mF8;Key;g>zgnK<1Js|N@pbSX{rjkiR0Hln9Mu&nO{K0pCS9=} zu~cU&5js%rbOrVCRA;D%SL)1t{?>sKVr~o8UFzu_+myQNpes;QZlx=DP3iPgZ{Len zbu-2BR^|2QQbSjvryKd-T)J{wX8&x2OI$B(vqNi|-*S1c{nTIfRvOP*c@3M! zwPp8DMfhgw5|;_Q6UCE(s`@A4U%NNEKT*gEy(FWQCY{0@?-QX)w&Po7*TSB!rq0P~ zADZ%d8)hPL7cS)Gudx@ElvQoqRNv%n>)g5L;|GphxbG8L;7on}@r!fW%uJfIunPx{ zJou@HKL6U6zWV5suZiOud0E?sEMVDKT;?x1>xpGgoqCR~%IX}t8M0flI)*;XT7C8* ze>Tt2X%Rjv!c!uAN`y~{@G%jd6yd`nJR!p4B0MI-`$gC%!h`-r{(a*79ue*l;Z6~D z`isR`s|bA}Y!;zMgm(s*8%0d52&?=q|5|^EK&2vdiqIj#wIW$CqfU477# zD(pc0?D6-w{=gP}^)IYya(-`re5P?IIdk6G>Da+w$7ub?7F_FE;(FOj{rc(R*?#Kn zkWvec5-I+*{nSEO`Vv>+He#G8j`y26qX4taW4w(FhuzEAEBWbMs+ZSVS{cPNHb||O ztlhPKjy zJqd^@^a5jUzBkPJ8S6C%wO-Zp{+=|NYcEE7$JJ!jw(W_+f_TLAwr2NJu5W^;4z$v2 z1HHmNrB{&4f%3}+$%CZhlk2Al9i;UbA2E7ibDB%`MDrffywr6dg3Zd_3iWTK_m=Im z0v@|Y#NE1GU5!&e*Nd5kwPz~LaWSKyT6Ly{V&Z9z(b9)fvtqt@Tc_y}rM{+w@e|cg z)kjJjigPI;UAGi^S!Tu15+2?*WbI*@d1o_#>=*^8_jY(`%(-)bdhj#g<`13gnTPWi z5Pz&V$A2B?X7-=!q1sTuV=0$*l=itEs+~$4?WowjuON-PS$MKd^=M^snn4UgVgdUe*@bm3lH;L zw0V(>pPpym`ssO7kMSW|KQ)~x#s0|~=i_qy#R-9NRPT3dkB9b5u2sJGf8MB zzt~ZisSP^#teML8*@ocyYh+)jv=y}{{fbAe2h_^WVBTZxF;XkQ{8_2>vOU^sR|e`3 zT?^a9wX};c@>-Nl@nMt=8>ALM`6ynWF7k0bV(i}2&n)g?i*o%hz55cg$Hz_arl!p? z^Zf6!e$P$Ui*COCi@>OODZog(BbiuYw_fDzC)#5qXunVC~W=L?F)ph)K=}@A#Ur+2(~5$ zY*nl#TNSIx*2x-M$#(0e%D?vhRk4^_SSX8MmMoUbh1#3qTQO=}nQNFW?4>om-J9}^ zCsp=kJ!bpK>?EK0`}xej`7Y~S_CLfeI(b*|)8>m)E%8)adzg2H#&g_byl0ow{{a19 zn#&LO_SVDJ}z5Tc(=<+|k& zAutcPl5ddb0cW-X>>bQoH}CM%{u>~Bi{8%vLN%Gp=*W>cP&ku{Wrq}>aA(V zJJFB0NiV+pqJi#c#0^hl^{EG+ey-rX*H}i9Rt9-Vha$ZM>9zjARgmUr|Vwb6?FGPO+-zRcH8lt*82q_@lmCtLM%0`v@Nc-Eeh0ownd`EE8s1LnIlSEBt<<~`AGc;e(cy$R%%uMaauUVLEK$Y||M_aw4i ziC=i*{G>F0@q&nans;gW)Qd9j>3*8yA1;_N6gnLm>9yBQ=Ht5DSL)|kD$Y7TTo`K3 zUBCMgntNxeJDh>}^Oes}Q|Hg*-(*qd9m;G9tM;UlpJE<_*}jYBTRMi1gkb>wy~HrPEA+#p57UFJk^q>)cuot&e1;WqQI)|$}7{p_w7rO-NZ0&$I zUs?(1(^KY@@mX{D&cJL_!lbD)>Qkv6r}&jHS%el5nnf5~XDT)?Qr9Vqf14T{alScC zoh8v2#C%oQcU1B~_ASL-Dw8jgeHXrU^i-TH9yz7jKyBh}&sE@>=}G6n6OOY}fYG2cNcWGJX~_J_GtD1I?g^ zhBIkavfz#L3FyTVPhA)>X3_W;ocm4QuI7qz!M4`xR!cM+H-;Vmbo00E^4zZ%DO|vHaeNUhcT)M@h)&ZJ{+I_**U?KM5f~!Hf4p8~4bK9>%mpUU|zg-^F zS*tRp=eUfmv>Vnj!aqtK2(DFs-y?PeGlQ$u%N}|5VQ;bX)r;CLibT6mR;;p(&|OSB z7_=s%8t__R=Ya32dF!9~3}&1xW0BuzW$zwjvxeD813$~e95iW>IS^|K#xBMPk(lVG z@-w8pz;5RBMWyzkE%dnacLab)oXIU%L(nSr-bz)&*LN$1l>Z zwR2oMQ=2!b~+5Tl&+9F28$KGJOot^&7u)O*-Vt5VOukNVUXMSU8%_wg~! z-iKY<`zVaC_o4K6>TW@>Zr&ECn=1z>ujf+t^SdZQk>s|Ob^d+czx{4^;JJ}Y&w146MzrbOIY2%=v+V@m8P9e7V4Kn&Ci(g5 zrX`>EFE_YyT?s8DIgL^G{SfZ6;i=$eB7RdFgJ9u(F zNT0Sht%$&@w+*g!Xbm)cb~y-3$5mt2J#eYkMRFCjZRG(y@50i2)~6& zBXvYR0xkNATjLeG*o7+K+Cr`SsO_b>9G8-rGMC2wE%Hd`O1nydoDEi9{t|ZllszlV zvM|!fepPi$38Nz$^98&xYw#v$ra9}pG<9yP+zI46AN}?#X=y9OEJC?2i1=k2hS);P z%indf8*q1ro)I!+y3Q(h`<4oQwzP%fIyOkV63U3Qz;nHbrF{vrG*6$$=jp%dH(H_B zFbjJ+^dw$z#xAe@ts`dabl1rOR0%@tiiuKEmfX) zy-C0e1{f>yqy4Xh6X0@Z@mBPlt_NHdr7Su<)KdPNhygM3fAwRR0)kt5JYod=kdsjUyM}YyRWg*#6JWYBW1ir#8j7!-iowilpmE8rD)rXmly58hpl2$oT@gP{7Jkq zRBdb7F~%;@WI~q`hvSzqCH3ZR>K$Ux>OvM%s2pY?Nt>s$al+EI1;3s+ zQCXKvkWT4akpFlVsRoW1!pGZGd^>LflAMUDYU}F63~XFmB_%of@4f3sfU9)1KojV_RBN_^Es6m(3!_x$%cT_imbgB|y~oW89Cv$6^Fzpbsg+qZeb z4X|}|VA(SM-Hlol+zVuct)smKUs3I9nFwpfqAd8^acL14>yay{*tP{P@5EZulhxSb z!%2)?7e1khOE?xEIv>$_Ng3UNH{|XfJ3n&uwsFaXZLG6GyE|j(DN;Z7p5m#{tFB|6 z6{=+2EwOI(7UE9lGf z+~qfpcX~Fwc)qN##8Fy7Z)%TC>fN4Byv8|3Bcf2Ida9;2wnj>NrPJ7L(v37 zXy@(kPv6$mywew}t?^Ntp{=Lxn%bh6)>X9>P`#v6ss<_?Q9ib=rWg%@qi_yvuRZOLU~TmEn$b?iR97^hp*Of2@E8Zpz}51l2HCc`eJl%M3%(UK zmiqAk%vh>#$!+wEX%lGmv|*7k%4K@wQl^c7vGft?w{0lP$sd+EeN*e>)bt%y7FMIW>m08(iQ3gs;$21o^x_zVF zEY?*(t}#$uM!D<`se3Hyi(++b9lWc>6SMA&blE&Ry1n$^VWS6|h_R{$BQ?jms|%4r z>>X`u^mTZfJAG|iV(OTH)-iEPQ2SUoB&HL6UWm%tVN6^R>+yx#t12D+Q%1p#NUM1B zj+Rkw!H3h_waeYq+~wO6+b$&Fk$`$z`>vMUo>A^wUo{hy%8HdSPK7_;9Mk6B#8r+> z1=py?cAYO~D`cfg>hyQSYy~T;?`q%NJ?gzZeQi-J7plk7`O0SESkxFr^VrpLnE%(Eiy_>W0C&G^tS{c>njkAdmxQjF(@yz0|VM9k)~L5;Y-*VU5M*g)%r znEIe=M+bgeg^x?eY_Z0T4yqlKCMu~{$~2}v>BbMzVpN9o`=3!xGGky3S7GD7xTEiM zZ^rNOMw!2mKXn^V;1`PhLf$mPNzz_RWeoa;B zT5LQO$v>gt5pH*RffIT-&|gmz5mjkf={hIp29;LfK6q(GWnHa&v3$F_h;-MM)wpX) z964?>ICw|7yz>$>YX1byaTq zayzBJGCMmP)D2~h3b(VuQBdZ@Ex@9}0(W6aX_cGyEjMlys@(iniTp}vDX&^9J~5KJ za^-T|VK1twtD=0l^Rshva*EuJvJH+q$PD3|;JtsGDl0E|VYzf(cYA3~ zWwpDmLL|nm6(x(}EOnG|jUuMBqSjemT~`HPYoc=tWk^P=MWJ4pTUb-(xZTNV@Tz!h zfecX-t1T+6beB78Y8=JR8o_f_)w$_o(#{G^!Ma>{3ZSSC1s=R!sR8^t;h$<}nbT3@ z4Cb5Pln)f5qq;DUmtwF~wYbPx!{x%j+Ukm8S-q$wD^`D`6iJB68>}vF#c6T?s8@+fQ8Zix>zUIyDCZA^u zJz?deUnOR>wPR7z(cISL#xG;Kn_J!9W=~Tyr{l+W-JL$PuTlI|R_XXR>29H_zuCo2 znN9j%CI^1L{(p5+5B7&RO#COwH!$PgDbpvj1eRb(FeaER_%wzk-jZOkSQ0HsmPrZ8 zmMICn#)N&wg#E^Z1IC1d#)L!0gu}*!BSuS~(Q?#ixz}j9&uF>dXnDYBdC+M2gi-kh zoN81zP8>7tIcR*)z{WdmOH^rFjFyo3w)7e;`;3vK79(+ZS|g_nJ}u4 z&p2n5Y^mk8^c=JtN;n*UB(BeV)O7E7wMA+J>ahtY1vB;>j6W22*nGs)HxV|JOppy$ z)d>jkxk~t<=U~F2_``8W%zdV#lHccz?rXEc=q49Vk=127Xb@e!dlY$u`$AS*yM`!G+hkUHdU$*BY zw`YW395XtN>t^(fPu-CFWf$ymVE#CsYe_l%Jf8meu4U!<8s%TtH;haB{70}sE{FUH zCpyyqtqnYP^a%HaQr zX#ZBV0wC*9F#1+xFC9?)1k-t%OWgk2_0Y0F*uO9wHss|zG%`K*P&EvL* zBA3fn7&j4h)2ccJA?<-r)IOtJKkTq$y!%PHEGYenC=1yK`4iv+IsK&*kbW}KR1Z3@ z$KP1@OLDm@bA<7~-yr*a6Y@NfYt~gf{qbG1%K3k3g43VqJ%jxdQ2z2B&gYSSi1|A0 z;gpQm9?nG0S>?L;SKMS9?{P>@U%y^J(P)mASwU!K7eDk#m@xy>Vxtb5*kjP$lgDv+(B3$mJYFY{*U1yOoSwH(js%_D!sYR*m|1l4MBVj?I(d>#o}`mc z(#a?3oA5o6!I{6GPuT{lthE6_{%e{1?nIAK`e5Zt|{@f#Bs&9`)E{RxK<~>PA9)k zCr{;an&T)(s!l$S%W3>oj(Ixyd@iSXp>oXE$*0BNx-*laPflj_aC(qz=8sC&7LnmLz#@%SgzA&+@_Ofb9vAo**bX+mj}x`M<>taa(h63u1>y!%Y*H4 zg-)Kw##$I z3;6Xx`wMjPLM{*X=Y=|XkxpKulRLRQSbk2O+{NXo0spyl@?tKhXBL&CSSK&hU0wg)S2mPtYUkvCk zV;{x%M@KULOstaC2~2I&#HyG}VB(lC|6HxXMwY3;CYGwfW@gslIQC|+^MSs2_L2rC zuqQRx!j5WiB5Tp$Bvzuqlh`5+PG(6OJemD@2IWLKOl%5!TZ5;vUubX&8`R)w>?sYN z&K}a>8LUf#XEL`2&tf-g@HNb!!L!-x(^c!p-*ed08a$WXt-;r_S`EIAEz#gq_Wm?k z-#qq`2G3`YXz=yyhz46(g9fLuwHlnxuF>EH3?IV|9434)^JNWQ$UdpTi&(1$FJ=x6 z&SbMScnSN{)PQ>UXDNG5gKuERHFz1@sli!ntp+b=(=^z|{tz52p+B4bK!bDGaShI8 zts1<7t<&HVO2`rE(`vNtvO5PMmJ53{E<_z3%y2G_A&8r;V= zY4B0z(BOO7A`QNeP14}|*@fU{1N`*>`-KKS$iAb&pI~3s;A8Bd27i)m)!^G%r3QbB zUeVysvaf6K3HB)s{v6w-!JlWFH24dwK!Z21#TxuD zo2bQC!F-CgW2jp;;_P>rKM=0wcq;op0@E76$Wqw% z1+L(D8vBO8w{bk3oe;Q|;~8v+z_dqWWHXsZVA?k|Vt;0>z_e###Qup%U|N$Iu|M+f zn17Hxy&TVB&kDSsr0*q;=do7=Udr)&_7#B@ z{`Ksrz-PGJ%9;c&;y8`nD)2In)7cyiUclbNe1p=XJq07?FFz9aB*zQcrv>idcoAzC zSn=m#Rwyv7K`=XJb5%LY(a4st|HOQQ^wXN(i22L+1a9H{8`whv(;Cdkma!gz3pmbV zw+dXs@p3jpU|JIxnT`Ds^9|Ckq@T@xD6o>>9QKgFcFxab?E)+1w}O=mT*l>j>^gya zIbO*wW4;m8zlyyguu`5kvM&p~mGkr2T>|HEyqcA1_&2e+0^7O#X7+lrqF<@MYuIxF zH*xt|c2r=+Kew>~oxn$gILS*b=|!j=kriOWmb9D$$Y_%>!1SSi1C>`Ibi--}#c#@v(< z9LNTnW~^lE1vYbB#R`DwT*WqE8lqL4229tgcos0KWB?}s(-KLQ55qZgB>Y=o%Bw2> zF|bv_&jV*j_#42P624jVS7g(4BWk?BMI4*he1W?;HnVtv$%g61IQBM-gGz4GbYnbw zMPRzeFx{BIo)Vab+3DDLzE2}hWNjLp#BS5zNi0)?lUcIBO8S%81<}7%as5-+7s(iL zOo#98*5M`{uGQgU9bT)$nL2!p4o}wMzp2I`BzvfysR!Y6DnK|5_~#NP`EwE``9DdR zArXHmK78M{Qyh4W;>+n1s4(`<`*GukU>ClJ&S<*=Zuj5I# z85q@@q%Rp*I)x<$URMd{6Ye))M*!i|2L8L%q^}s*BEqK(td_zj4XhiX@gU7~5$-pz zJ_^5TVB{C${RZCF=z3}s#G|$sz(<1msf`#98+cna9?-?#r^EN^aGwqz)unUDfRP31 z{<8r)IEr0lKiN5*;$a`hu(wIX&lK_Xgc0ANi&ynS!3LO=4y{fG3Z z-=K6~r|>b@hk_w|3x&WhVID>Pzbrz!$He_-MhL&9PzXO&A*Ac>rx5(dD8%*eV;)O* zIy!=+#|`XJ5&ne2M-1%WDa3W}i1;fMx?l{}3lvVL5b|p&{J4S5rw}*7aw&Wkc2d}D zULU)>TH7dn$zw z7?_nplxrqJvj1lkB3~ylFH3sZ!0(}v{B4@2;re$dgx)_=i1aQ{2!B!gOxkE*hbg?n zz#gQq!oVJ)u*$%`L}9goeU-v>2KEgKyA15x6r%I`9)&e19}3H02ZdVcS%yA z=wDDTs6V0drLmLh3CA!>ZGXKa2R=q2%I`RZD9?C=q$hv_7kp8P=hJcE$(!P8aq4Lge{9`>pE z;QFQfs+h(D)!*d5hlM_U{7GFrw+s9Z5pO|A*Q@?2qj=b>##>1)?4$TOgujXUNFlB} zLm?{HWeWcZ_ES9ppXO^6UxtwU#Px$;LOiE|@p36Pu&so_zlTCx%>9FY^)V6uoCtp| z!a1ZL{Z9sk;N^?->P47I>7jpFMj`r_Yzk3cc@)C0`4plY)=&t$Rtdf2chX1sqI~Y9 z5OVHM#HW)S{gPTgHwhl+Lm%h4(Vr6UVW4SUq< zx!p*Q=L6SsKLD%sIZxy^q^?Xe5F>i>FyRsBtbkw4Ww?pLJG{f=~aJw&>^ToBLs zh*$08@sQhv9t%S9C)q{*sEsn-D)_3ux&AMU@_t6?_l!@7{siqeoLtQZ&%aCQH^>fd z4=~wJc#jBwOd;y|FDb-0`x^?;KV3#h^A3;oPNr{PKfwtDTIA=7_rzeQ+StRpAmx{U2n`5_3Z0R!8Z&1HG%)Cyl=wT zFL0cYW3cDfrwIIQfv*$zn*uKq7{+jZroi74c!|Kz2)tC_rv<)2;C~T#nZTz6&Jy^d zz{>^xPl0U$Ul2G)-~oYi1^$b`D+ESia(gkU;O+1i0d;@LK{K z1%6#%lfXX|7>$Cs@mAc%=B}=a=AP~n7kmG1< zDS};EmZz<$rMaZAw8-r&bl2e>s_rVh8F!uY4tKS4eVwzW*6q9+xaS+e<6Ul+pXqRjly-#+L{P8B04k59UI*>WtGr$)yh-usKE<`-DRZ}>)g~rqHs!C zWo1RR2N0fb`+rv)>37}tDD^sb>lV8g^nsmL1|fO zZ8V*pmLJ}2r4{SzN~=j@OnckLZjYL^+w zjnaitWC0Z3=iqhiwRMqtO5t}&d!UDjA{j>=y?#6V2pwW>!lx01__7mD5OlOOcQ=Ql zg_^eDOX#l7<`HuxL)sui6`aXM<~h2rk{lU| zNusbnq|K#mzKBX_Y8c6i=xhz8p%QOem%UWNOTWBpiyT?l(%yx_>e}7PC)vsbnm*Kp zc`aLx7o59yZf+LuX=lFWUd==lO&b*uql#J!BQSUugXgoCqm)s#6k`}G^EG5-R5x$m zfuhaGKzc2{2G-i#+SuB`8XGVV>cZq(IcuhAb*^-d(-Nnn%H4`8(cVba&ey1oQ_*Hr zTAaH|U6t;(hR({(rFi>%mm1@1>uT=oR?+6>?nbW)8atb*GB-99)Vk|xOYvn07*^24 zD<~rI8h*SOAI(s#7D}6#+wE!gH2B<CN38asD)baN3Lr>r41_`1Edo-I65DL=ZvK~A931;BI} zITkApV5eL0_w8_IduL5YbE9)7S2|LFL<`X|DDt8jH&QM0wQZ~2-OHSMFLq|sNpSZwxER z3oFS9Cs`HNIjh1tXH{6|tPJa%m0_K;GOTk}hILL@)AGVPCoimX^1?c2MOf#o2y4NL zu+GU1>zv%M&dFU7)(5#^{g#^>)(g40Vcn3M8`clGIbj`Wyq|Ky`za^9pK`+cDJQ(2!e=Wxyq~he`zbqz73}b}G-1vzwvID0YD>!9 zr8SP7c^S@(s*IwHbr}U2H5oTL%QJ3wRrywAU|*mpXBB}O{8R48sB&gFZYs;ott-pR zsVmFP$=G;PSx!zy4Pt5#Q-hdNr_+glH)LQxr{?xm8TZuGt}9$uq`(^iOUg1TYp}d@ zW;hER`59Q1=4a5?sq!_AQUNAB~B*b}w3q;QP@0RJ)kd z&*LNPKS!i0%kq#EEDOTzJL~z8_nb$t|DH96cG)s=%UYj^*ieqNT^;6}0 zif!uf7l+-V4sl7O?P)zd)Yfz;PRMO(Ju%Xj^ayU~?Pxvi>RZwJD@JZZk6?t}f*whW zxc#iBhuL}_K~s0LwcA!Psi6i?~%MIO`>9%>pY$uPfBGe`{-%7p;GqMo@M}?+^+&H7@A0Z}5w?LUQbvSF-`v6C z0*J*=PAE?_CdE%POgGLn&Nj?3%r#tVxXzGjm>-{R$S~j+Z46s?%z#Je86K^P`tXb2 zQpJla@(?CVR~yB-Psg((-V%aWtK*e`Qzh}}Sv)$5bUb=??--XT|EN6rEjwjLwGWTc z@#jWWs>-9^w97m^rXP~`W|EfI1Ku)K8A4Ux3pySi_tf}B<$Y1dI~7LXULEiCFuYnF z&w>I7W#4igkDf^m#haqz)q|HABENseZy#V%z|Vc)Z4AMq-?+*=KX~2{yr1fLCHQSh zcL?4yIv)KNxhVwiVI9wk0;mtc+ppvGf)^?u^iBaeAHM?cGUC(&kROFQ-cP15_E)-4 z9LPRDuG8^eNn!kXY#|QRt2fYSY=9ltd6%4JZdBAq4Eyvco)L(%5}Ux zJY*ZnFIFATABJ}k9gUoi{27ctU#_?BjE;8-ymwR*!azQByc07S-Xsz{RNkFB9{skl zCrAtEyH&@t<2RB+A$Zs5cq!K~{yeuzRnz?wIv_c}P2kaU$?BooRe*~{U;;AM) zuj6H3AKEVu=y>;o*C*+Nm>&%~-b`y~|J|tL)q@wRUYT{ghrz4jDJlP`>HZr1rzXGP zm4x6uqvPeJh0gEYI^Hqxj)l-yt>anKL+3YL$7=yER6q0=6pWmY7s1;bBHf?rc=iSI zyIh0y@AEp|LGVJQ+orv$`W zS;`mbs`aOLOXzv=JwhLvJ3sCRFVy@L?&9SkXzVn2aywVk)${Va(eX}!C%2Dq`Z9dc z={p%EFLi5l`c6d2o4GAIeaE8YCAUPUuMfOlwQ!`e(wB#&H9CC0LGYrf zFRVQ}eZAn_A4PtXJGAXGT)jFD-oYsJ%|Qnd4ew#_`l8U6(HWh-C%}uQJTkkY<2?c1 z@hI$DgGL!my3a+)TeBldeNpn(?2N8nodz$Oa$B=2N`2r(Q~!#3qU+aAN6A~ZJGy%H zEO^JFDBmLdI5QgFtKdab4{GmB_ZTxt2yjQ`C#xEP;lxX@PKX}pTYuXo`pWg;An*7%9k1pM}qvUxHL}%YS;6;<) z7LcN;SAPUAn*Ox+P;}{<4@XyS_k$OWeaT0nOZOOf(dbJ-rHY1k3_J`Cfg{}bYd#vC zeSP3Xldk37=y-im@+|j7sV_>N1%pR4{q70yqG?AnABfJr<6(I8E?af2K!r8)LG0UN z?*~68XZ!JIMqCR1=pAv1L=Z>!KP&eaz6ea$6VHObDjjbxc$tVN9<4Q0o?XX#3_QEw z5l7`^=y-2~NA{4uIEnW`lGeV<5-(oj{kx85eln;pLE?Q+$D0Wr<&V;(P_^%KI$o-z zFHz$4=y=N{9z+3sRXW}pi3e8%cuRG>GKrTg@sf1BO%iXi#QOt`C41GQ1-v-`l;0`% zQ}g?}j(1Sv(M>Lu_ahzeVTniOr}Dn3<2@_!uvH%5ozU@qBJr>V9^l=ho~wWrQ?~u!I%|tvX9C|_1}ISF9W=6!NXQ>fLE&H)q24GTPpF2biAj)vqDb18zkNw9q%XLsr7G}#Jd7R<$PS0cv%u}K*vk%52m|Z;vLoT z)_|wh7n{WUn2uK~@v}BOZ5xx;QhmobiDT^ z-fD^WkdBx9bkNT?Nj!Qtt(5^tN1w^!m7NIbk2NMqk|iB~A`XwO{E$5RroNaCHtxy*Y};yESWk9EA) zC7w&-eOJf344yhJ6id9X>Ui%<`bs3;0UdAVGs^Q3)ZR)ZUaO9`7d&dW#Jf%6)#-Ro zfk){PZ=J*=U&?;DEb+=D9<@E0x8~VkJ*bp;3v|3%@YH@|eFR>U#H)_L>y~&m5qJkB zUTp;4afwGhQ`@gTACF1A+avIvm3SK>@LrU78zb;um3VhV;Jq#JJ`#ak;(0?+)d zV7YCIz?&)Y?u@|8ka!=9z{`_(?g+dhiB}(iS1a*65qM1!uOR}jTjDiF;2o5BO%Zs< zC0=s`-eVGPa|GVA5^qZc-is2?8-e$##Pdbqy)E&!M&MnRc-tcI%-;^yzm^ERnG%os z#&GR7L*lhX;N?lY_6WQpiPsTdTXO*isM6E0TD<5qPx{Z(jsnlf>H}f!8hZ4n*J`lz0at@QzEoLlJn7 zNxZ`mc+X0_BN2EnO1!=ZyjLaO(FnY^CEmRec$X#KeGz!()4}?8e+1r4iT6MRUWUYb zFaj@6;(a0luSnt@i@>Xuc%O{GYm#`MioolZc%P2IJ1FsvN8lZoc%O;Ddraaz6oL1w z#QSUn-is3NLncyCL*&qv^0mUv%?z%vg7>)*o?Z!XSF_*0LW;Qi+$6$PKk znT9BtXZj&yznC?WhvggbXb9!UuYSWA%@5Usa_3xjeo;>Eq5am%*TFA{#UD7d(dknV-ky@gS4^7v6B(@h!7! zvWsQqp0)Py51VCHoITn1;eUPbAz{2TxSv_A9c-}PXZKnM?3X^3W<5z#Huy+ieP4r* zEx6sg)OD(Og(KY@%C#3Z?iAAkGRixPZV4Iiq_tKRb%Dl8@5jhsgY8NcYUSr z(WCW!IW9tqT^-MJA2l+Tb^d}Q0oEULz5L#!gwq$w?K@p?)7knyLuSHIeP3LrdC1ep z((}157P_*%Cku>cPkOWKC;QppuZAt`WPy3ee(CXPGlgGHdS5~8W8MLHGHz%Za{omA z)RMS*vwtc-pNw;_*V^y(@)}_E)+b#={krgBlEHt{^_Z6}d;V;d3qHbtq?VCtdpvS! zPmMz^EiTq$88BGk6~uMWCISwn9=`bAB=ZuNm0KL|VuOoNZk`;ouuqkcXH@;U#g;qS^d2yd$W7C_po;j)+0~n&-3>_-h1-s>4KTB zEp_F%PI8}2@t^F=EPCWMwgfZhXUF zodcV$<7r-tG~Wu5=5>DMs@cCmeM0_FpF-M}fKs(z$|;C@L|8nilmvHgz+VdDZKrsj z>t5H7-kX$IB0N>@e|Fg1Tkmsu>wR&)df&@lMU%CsYJd$cL|NRIvp|%E-StFqj%dwu z2B=l1FfUpgmDs0pt`#h{U|PDvRf7KEI?lC#qguBZ%rE9l4d^>voQNDyDqqP-3dBB9 ztXjvGee3Co?qdnJTISPJp5LAX<|<)OPptT*J0>mlvCurK9#Iv zY#w{p&i1iuVL3_Wf_s#erUtpQz?}hZFSDmATsUkaxnq&WF6sWge_S@}05 zY!4{sT1)Owe7ez>p~TdcHVv+H2L|L7A1lU}p-clVRTy3>N3Dm9p925I-y_wg(I=0({w^6aDQ;<>*mK7ngq4b6&PVo=}r zK_!hDyiCp~e{IT_nbmkqZ6$13@z8fMBFsPg@qw@Ii|3wY#|+0FMZQX1O1_oawi0t5 zQyRRUBFhx(7W;P%C>AG37N^})Ei}wV38-_b`0Z+chj|iaR4M60!{#$~l%Ar?;5WlQ z1G%$WtsMr@ zt4uASc(NlKc2J3!(+XWi>b+9b9AW&n8b`ziZKk=JQZDn5Ps`_nc2T+H4N-aI@O22j zLGsLF!^yph)ylur3!3;`&2rY{S8B#wzapC@wWgmr5=H-A@2hd$#=U3eRx4aK$i&Pj z*p_GvxQ5T*&CeK?nT8bYLzvH`!Bez)_;9_t?wN;}xL%sG74^~>=&EPwb4st};}*4r zOurc#;+GkQ;+9>D8Ne)|A=#sj{xpw^>!p#usFy}USG@u2f#iUO1l~K(Z7@Be*ue(F zkN-+PIR!2I1h-!;QDx=R%U3?jJ@EmL6rdCj__DFaQTjsF2h?T~FdwA)LaQmoS5z~; za`aKG-q!OT6!XJl^}cwY(l05qz5Caz{-$|eBHAUZ`uec3cbkh^rP3oPbv>9C_3hL? z=WA?!u3xd9W|I~^o2>Vp;j77SOF8(yH`~=$tT6R?xZqIR5zPaYwxjq^9UEjh)+FBi z{2CT4#l@rGp=`;ml;u}bIwlkPe+T(?@!@ZrJ+Tb&t&ozF`36t(#2bNS(Z1% z2g*{^KamEdqxwbd)5-Q=zfS!(V~a}@y^C*~R{W^hYo;EYU3+kDs=rKT#aSE63H-3`qnapQ+ z`wIR5ElK>Gbi@U8sBwtQL&3?8JCFJjS;9m#w-&ZjC-)J?b&MVg-&hTz8Tg_#bpOco^ z)AJ-Pt8gXD+%%MjFh^*}mNYCA8Yt{5DB&8eo4z2R;Z{Gb1N{99@$W)$eFpXGVis%_ z*U#fJ#exOXX9TWigBV9}{T%!|OI$xwx;{l*Phnqya{c1zCh2;rw`%>+`&N&s{wTE_ zvjD!5+Ljh4T7KMZX|6cl!(=v4ZzAhF^D4eshHII19<4kEGtl3?kanH8lIAJY1O6aQ z-O<4urEhAc>8$pd8 z$&|o)E46>Rn89?=d=~o@_lmg_jdwQ=Jv(efZ|cNq`z8D(`0TuoRd&c|Exi!?Xl2`H zsO7L=I$ujafjPa>Lso%9>+Mz2dihlGBuGoJUSEu>E4Q1()pplu>hY!ZGGF&(tsHvn z88+zUC7hHtN3gxTgpqiI3uqtEJ%Rd!8&U)_@{F|c8;;oa=4oWbds%zii9149k=2@oS7}1hg z=DD*ey0u{>eTKh7AGIxdyM22b-c@~*74MF*67;n+cUo8CRW#Ne9e6`dvo*(>*+8$1 zw64loVy$g&Z@I~e7mznLT0ffCv|^>F=}xA=tgOb>tF2jCT^%jHZoH73e*>t?n$?K7 zEp0ojS?!~EwN61@X<5-GeCepWYg1i8S>;B2>;T`CDZ*>}hJoTi=`3{$m)_1cMqocB~D&>j!WCL6oPXv1_fb z4KMWH)!w32Qc`r-KDXVS7`vZ42r_XLCn8op^UN*mg9uwD)AS<10~F zyK=LdI(_t7_bjfy33brtX&KeUHnKLW9aU}=7N|;Wjjdh27^!M%Z;X{D#b>d}A>OLr z)*U0m6kRs@LctDH&{!0}W_(j%2fiB-TWvP_LRK9<9#giVv}z1h+gf({IictEnxYsH{sS zNT(}uU3vd_7O4h~7`(^Z)UMrQ*`tJNj9Ex>BC4vbs}pmtacz~9q|MXen}}rbv6b=e zW_flgU7N3C=Xf_dP2#I2!sBAnH-Sk{#9+t$F0#(kw{>7vHjz$fYwq@Ko^S(f9UWM< zjDL5d76tbL8DZ;aZ}D_?b;V{iVT*c7!YjsDlm-8OFD(LNJ#qyV+qU3KSXgU%vKm`_ zIEisVhEHhX5>_@0#xA2f@JYMfW31jbE}5{6byjF!XAC_>>c`$wJQeyFcdWBQ+Zx?1 zv2Oc9tIdZUK)i9fGsgZ8sBeq)98}WGmyKiRnvNDv_vZG_)-iI8s@{eXY^;-r{Zc?J zhS+Ov^R%_|&D$6|1w(UJJALUs#(KND+dDm5Vzl<~#%L4N21WE2o4k@TkxjR!p{u*o z!*};%qg-tVvC-Dq9jhH+(q!xG?ungUq)pujDa5zGog3XT+B{Ni)oWLAbuB&;Tb}1G zzj17HGcr9JKK)vTPdMXF4c%gj$pWF<(}^!?#Arkm%2dl^wx2gruardWHtDXKjGF2g z?Y#Z{>D!u`clu(rH9l%HwDlC*x6+ ze4Bl^tLll-EamFf#G+!vVr8W0u<7n8kFHEY>!dj#-Oe2o-DBqpv8u8)v^9@%?zF#bN4upT^fBp*^_a_bDoMnubVwy0WNTfK8+(m5 zJeIVhb<}(PTAwP$j)iB1W_7bbJe4*EZqcPcv%l=st5#-Zk3|`bL3P>D?Hlc8v93(H z#z1u$<+3}Z?ikO0d9zWhj;(`twRmFIoslk^XGgaeP0-iq!6ss?D)UIqv2KtdQi#2y zZH>MTZ*!-wZA(lY6VN&)P6=us3x~vXqR$IaSv!o0D`GvqaC=pyqkqaM*b!+JZ{E=| z%3bqtn!9$no0_|PTVmUV1UwQ@Z)@MxlG`)Nee0`cf>K$rGRCR!=bK~N+?B`7$EJdF zYgN_QuJgrgg{)Lbo&M22SEnyhMSWNM=I&AN?L}0rdT1=lRoP4&JI!NP%WaD3A_3cG zUuWws&uAZE3|$V|l$1OEW8$*rR+>G>Y_p5Ef*8*YxlY=Nh}k?gs1f(~x>~Xt8)&@{ zQ~!4D=)kY48a<L}wHMNDZ$t+Tqit_r@^MCTUDkc?J~LcK7zu%^s$yOY!4Rq@yY z8KNduTU1)O=DUuMCH&|UzbArazlsTO! z-k>QXZqq_Uwdr<8S)FrjZXPO;Qjbt^xYJz@G_@MIh;+!$LMZo`1755u4f-|s}eC&Kqu$@h

y zR-~yO^j__P853Xj%V5WNm%UsLRQ3~@{{Qy;PqhD^o#67H==?98;Qa3u>6;Ew&p-bC z@HG>Ve|a8|kMt*E9`KLU2QHt0GO!{|^>_s*6EzlERU;5u`Fwoh$7DZj8SgPso{wQ^ zG%oWoE7DO9`tC--jGYrQ7q+TKAXMy_m^zRl+3{zb7tH8Bn0Ux?IN?ZqU))jiy{7xd zuaA~(d6L_*^B=;Nh6%Ps9y=EfGZA&qigeXuIZh^O?2_xlM66}3suK_@W9P(-;qrL(950WF8$0Ftna*t) z|1rXfbk!ppC;tfbGy1ij#b^n+$8YI1TJ{+&`;C?ZM$18?<&e>G*l3A%k3SxMsK?)U z?lVrrxFqlI)4YB>_xI)gDEjh_-8~(-?a{dd_gCT$nGc(ejNjbZigeYZ3@5aV2IOX)JdVq0&ZZo3I(a;o)7(-yFnVdyPvCOevr>)(o!r9Zw6~@l zXa$<<6S>^4is=jX8aYZ+gYh9t4aUf#!IO1(3fE8Nqa0IoayVaeJ%9#J=~)8SOEkLI?@fzeIFpQpp~b@+N6w(4*i*Z-udo~7yJ>0BPHkC@qN z(qF*k!TP*FC(q#WpuaF<*Id6)Cts+OFXD1q^D4(8oqREu)0$K{7VG4hT;8CH@tsp` z`b)UHA|PL)lP}fb8#o`a;f|f999D~Cg-)KQljrH=D|L944&SK5Xt|pFujcyu)a2P} zo%|*)?+M6n(#db;@`8Z;W}SSEPQHd+LYG9xM*NxBt?Z8i*K=%VzZ4h{aszusgN^Jt z4K}f_X|S1nMT6tmr!+X89n|0i)}g@`=F#9pR;$5DtXP95u_YRu%;stEWHwEMr!a#C zPi5~-p`0p*35D|$4W7nMY4CJ*zXs1>9U457RcY`nwn~GqVHp}co6XYTIn1EJbJ-s; z!I53^B5qLLnEzU7>j$p?4lsIQ zq^(^4HQ;rtA~MYV?WX07S^x9t?aWJT*UTja2xYza65Bpa0k0VgSWF34en%rp$#o@7+4qk zjRtqKK@Hx)9@F5R?5GCsV(l92WVIUH!&YnXZZ=oz(vk$1DiNnAu*xMRh$^KP?9jsr2tJr5X zcs;vYgR5Di2G_7s4X$N24X$IeH28M*H!LC5!@xGMa~iyny{y4^uy1H^0Xwe2A7Ohm z_@k^|gEujk2H(k+Y4FF`bPaa1VWVmtwefoPE6f+Dtv`!DBhG#-Fs+%5`0slHQ=eeO zjOptFKgzM0JuWb<8H_BB{lDzJ4PaEqbuT{mY9%c~fF!W_l3^vUv9Qr6k`M%Jtya5Q z83_rk_=rQYTCEneppVsRh2@yI!p2xQ*d{4$N$R#FbrL(ZQ{%*~otOvCbMn%ZB;dGh zUSqe)tDD#{O)(`zO=}S{piKy`HcZA{Z(ReEfFg!u=4DvYix2O-QsgkAS9)^EKv5oi`{wl>q#Ko|dUNO0y zVNIW#$&Cy@M)`K481OCRJoI;%-jg(b8Tl86aSWo8Tgl%t+)Z%_`8vZJC|*vUWY|XW zZR8IazK!DB$tM}cF@y>&e-Fdhhp42KY+zW+Zy9kjjAI5B#tU~ajAH~9dWzc_*5p@` z8yUtifC|t5nGCO>cqREY^q-hN4Of$YVOX1EN z@aK?U&(`vX%~pY$M}Ej~4#oN8d4_RVQlJ))#~7}ocrJ-BjNL?mI*)W1@C~GnVeF#| z)Emh%h99GNKAF#O3&jga2E&CEFC@QW{-&k3i2O6d#Wa2~`CkmbOmQK3mSHV_H<2$G z@DlQ@P(B4}9r+x?a~d_=w{67G>OJ{$4_(}xkfejvVGN1A@fPFvjQH zsL*HJoO*>mOX7JyhQs;uc>XU!p2G7cg?tUq9))0i%5f_=!$Emta8`k|56@3S+8F*@ z?O7Yo*xuzVhW$-h_y%_F!1E&5*&EI(bb8zH{5*l45Y8_Ug85e=(Ox`11N)`o`7gC+ z^qfgT=>4GQ0}!55qY$7F_3MN@hv#Pr)l+?u5NHNSjzb|!@C^JCJpZQ_pVOd_HHhz2 zXnHvt6oTzr4mb<;LwNoPo*|sT|9A$IQN9h%>R-Va1J6*{6?pz@7&GAcn=IWXmLAxR zrUU7Bp*%S6!Se!^9^j)a9P^O__krpp$ElE$cm{oKcm`fQJKv3Gu)_eJ^A!@oGuU~Y z#Y2%${NyY3P?;!hVP`0hJPf}>A=p3WtX1e(3Grrzcj7ru(e!U-`nM`%H-+$>-gdE26YK0uZ^D#o6z%%H16wiE+|(#Gy9@HH)1^avlY)@X6LUEEx%ANmLcD(X#NF$RET&zD{mL8PvBRy zT;NRghWn{MLj9q3fkvtY*V|eaVs2wriXdmQJ{kAGJ-&oIS`NFv!c_Xts$ge;Q^?~LC?xTJJa<^kR z$Q#2m-2YiTL--e2I4#%bv~~f@6Uzb5)P6#F)FU745oYK8?0g8$DwGQ?f6${E!$FTV zc%F|V8#seKsXp^qKEYnJ-2r=X`;;IL!rgd=dUh9{p`Ptz;o~g)AfBO~qQ7Fh^CXND7fmLKGg+69DT zIjU8xd?0)orVHn-cm}`i!ZY_T@Y~&p!O!-+`+^zUNlPqH&DM+m2KSF!wq|20B9_Lm+!gPmIN422b!2YyC* zU~kHM9>~athaL-_f5+OtOIkmmUe?+l9H*jxshJ9~;W0cQE{q42Ky0DZ{-Czriq6Y6v3gn+*RM!~ewapECT<41bQ{35K6w z_-70sVfgeujU=a390x7#?8wJ%;x&e4gP04F3nik1%|J;fEOhHN*QEzR2*S41bH^ z#~6N@;l~+1&hR0IPcZyhhEFp5`wYLr@TVF6Hp2%Q{+|qghT&Hkewg9!Fg(uicNyNp z@c&|XFT>wsc#PriGkhPzf6MR#44-0ngyA1BJjn158ICagBZePj_%y@!Gkk{OPci%& z!}l=!V}^$q{yT>6W%%zIhQ^52hksxg8hwg?!Z0+h6#s9AhoSP6!Fmv7u&Q<>)Q#Ix zkuq4#A?ojjb1%P&1pCT*g54uKd~}C4QicJrA@^_;wtn|h7%JOD_knMRB_d!c#zqKl z37W+i!rQ{p5Qt)7ov?Fx+enm&=?D%P!<}>uo{@+j?_p8i=wP@bI*NBjgdi8}q9TWB zw;MzKk?54WA#CdH5EwssJwg<`v2}1aH^9bb*yN3=)`DBiH^VCFk$#$qSQcrFJ2V>X zarXKL27-NPMAvS^jjllNV8?J+ltqJdJ5eExpv+6dY)LU zW^_j&5Ddp`j&Z>uw6TF69E#adjsT0%Qj8NW1u=ug2^FkmjNK7})mI|kU|=Ky`vyAw zeSHo7z^-^4^sz+oqNgR|Q4dIvj%3w%qMC=DeS^cnm=}Rn4OIfL8+Miyv(Xrg1hveX zDL`e4w>bLx1_La>6X+T49CZYC#VQa6#Y#;IH+ViWS=q#BO~Gh0&w;ydWVjdgaz_UH zH?k!4K!!mAuGWV%9?}~O?4rRtoP)3iUN8z-9=^AqHn%;LhYPL3O24EGmWc7~-X3J@ z?2u5|l!gPE0Tv3vVBPO2tTGeG-HQho&Z^g~dsTM#M>ICo_+p zvgTF{V)1N&x)c;J2p`t4uYI`R(bFFqpzeyw>LJu&jUl0d9x6rWXdX#P&QOmeh=;@k z=^-F!bI9+3GVNn}h*4S^JVZ#t5$KcB;32Uz^blQH9-;{fbi)>4!AN8xMK!`b3%Y2L8j z>uYft1Bl1j2urbnFJM(*AWj=VV`z@(m8N%3_YP?1{b5%mG7PHVB3C;iVW0TiVqaZn z8dGB$Q)L!Yx7swO)--0NX-tJ_j9J90Ri-i3rZJUfF}0?~sWmlDt*LQpOpQ}xYMdHV zsd1`IjZ=6)IPm>QK4L zREf$}rdm|4GFQX2C@O0cM41*-WvyvBRo0jmRAr56NmbUE+o{^zPSxgisy4S%wYi>R|wLOTiIliG&hXtbS%laT;C`_V2Y;D;WjBN%|uUF2RKL?11o)551kUpTtOABw^t zcq5E}0kN?xL)dT8%aH(!a1KN@B6fQlM}i|kgd+j%L9rt^9ERaBmBi(WQt_I~#9Lw# zF<6&Jd^mCyhhX|sx-Tk@17KWX661gg0wHS30K^wHj5my8Q4!(h_Q+s#FfiCB1Q{3& zBcZ+?Oi-JVu-iL5t-fZjV|TUPWpB4P+Sl6~>|XmSSF3%qyFIkh?%LYfSXqm}3;(n_ z?CmbQV@*p{)uxu}%1td*mG-S`S}H5;UI_6*h!;YdT`m{=yT!iA>+)`{wcqdUT<=`p zsKHeLJuUV&Z#%5YX?Ha^>g*k^jdgZhsIjwLOo4Hl zLl4u6olkLu$_&#R8jQ_NXjr>Nn|;6#c+}FTG#EDCqR&`}$>@PxkT!)8D$}Mf5{^KG zkpxa?Fs|rYSi)F6SQMYg5Mk^_!>9uX{fuS|7x+fu)SF<^g58C_ADauA8W@u!)e<3P zImU2LY|vr6LkJi7@?eclRiIip*)VmQLWnU;QSfj!l8V8Ym8bh7Au9ylB{CIPJgojBRHaDgDiL{nB=iDGxqHp-ck*J@G3$-EbMBl z#Dmu*^m`3Xk@BX7J*;1 z#178;jKnJgUT%!0%iAmQ)|l{yB%TL&&k6D%njRmQc$2`pQQ&d?ek9p>Hn=5F^@H=O zBzg0Im#4F0{!$?E>=KX5`(=i)+^T`+i6ig(5)Z%07wyOM`(=qYZo(Uvc!z;kA*9Ro zi%7gzfd{Wt^@FGDlXzWL?K=lf4ly$Kl;B@s0xTNF3e*iB~r( zemkBi@h$)_Uj29n3Rf)OwX?PNpFC-vj~__9r+~MWlik*eXF7eud7iKc>#CZb}? zIX&t+wC~0k)YH8c0=R69I|95YCkb&fFW0MmH_fSBhRizzygi(hNM2`hym8>|OGe%% zWBoAG?=bMjl8`rVb8>bW2VOGrtXq=P?-1~kk(akMIo_cpd3hgAQeKk0yt|W>mn1Lm zV@b+Ol9#tFNqN9a#{cGhJUMxXljP0&L~{P}M3OwaFFF051YR=j!Gf;j^gEg)uf$L2 zck_fDX7%?QN%HEulaqG}c*&G+dmuU9>q+vq_9RyxKLK7c%bGAOU%;Uwj(+H-T+=Q@_KrcE8la#OD4b3P;%*B0$wt9-m^2gaytjSWaNc+ zCD&h`1zs}p`udWy%Q@gBQy!!J$)!69ykwpaq65j<@9iXc+Xj=%r%(wC*C$3V)pv?=9fj zARKv^4(ByWJj=t{^B?l?nUM3!C0-BkN+2G2$l<)3CEh{cp+3liD4jQ3;vELw0>;Y{ zcsNgH$giMZw!nK!;^l(#;qy4Ai|KRy&Pcp%z#C&cOo#JMO1w9KhxSK#Fh!vA{!-$d z6?ibD*Ljahyi35dGI=mm*Lk=`fS6y)ffx^l;5x5g;^hMG2$KgxYn}H|iT9)+4~C>V zuT0`SBk=MC-fW5Y4S@$kLtWm_!Fgr?=Euvx;n8dR`63YkXhs$$HytTmN<-1Ve-6ruG zfoFqwOc&>GxxD!juLpQMABzRve?euQ0hk|A;I#uld4=%D<-IBKUKRAaN#OlJ;++zB zO9b9AiT672x*#6YwZR`x_YWjq^{2IYB;*wdyn7_x9^i5N6$`wNO1ymn?`DBlFYyin zkC(4q;N2?mUItzr#G`(<2)ua`?*j0;7;l-tQzTyJ!C1N7D)9bQF_v2o@Jg6GJahZ~ zjl??$JR9RJ7kGaq@ty%5x8H37@6RRPHw5180&kzhdl`7V{;m*sJ0;%hg1l0J_X&yj z2Jm=!lnXrgd78nWb05`ySApe$d~O%`xtW0%1)dG!kyk13iY4A*;PLXU5_s@)D}%gK zg1nUi??2&MtZ!!pUbVpc7m1hqSj-P<1m2G%UZKFN6?iX8ycGg(mB9Og#9J%yFyGvM z(A*jF(E>c~f2#%Fh{THmkNedcf%kEVw?~lo5rOBFcuxwvwE_=qDcboI@Qy+lmhYYL z$Mb=8UgY&X9<#F}0dJ4MYe>L5DDY5svvi*jc#R2o&j>tM0^Z94&z*pGO5imm;JqR6 zJPCMb1zvLk-X(!|R{~z{p;&pWPrxe_cr6KdD+FF^0^VAIw;=(qMc}n1;B6Cl?Fo2& z0uQEKP5ot$z=Nq&Q{F*=2UDb`ye9-+X9C_c0&i0S-pc|HrYcR-Jtgp93euGKhQQmJ zfOl5l!IYt?yh{QPrUFfQxu1#oA58I?@(KmswgkKt0uS3fv-V)Ez=NqaQ(lX}gDEsq z-Zp{Pm4MeL@capQdjwv00^UJ^7f8T+Lg4iz;5{Sof(dvp3%uV97z$+AZdj#G>xXyq-eyjlAo0%NN=8N+oNaW4<93i2+sXTbhMjpBl zJt9vNg6$(eFdh&5VOOYZu-wLu%IZ~hH7jdZ)z#W;6*Nryx3Z$5wid#wYAaU5368Fu z-*dIN6@^Pe9ZTRZcHlcEI5P1W6Q6opNHfXukn#G$%x3GD)eToA%0JfItYZpM$s&TW>mXKncZ|5k z2#s5faqsR`#>bFZ%h2~Is^W3OOTJZq{>!$@zxmx|WUb)gUE~DHEMYRodTlS&pT9T% zmZQidC-5HR+cp zSK+JAXM4zKec`@_%NKY5C9(a-FVJGV46)aMIY&1sS~#J+yO+#azqofU*h?vya|ZED zz!_kn`td^zSu`Yzg@l_tg|9qsp|bZjO#GDCe$6CnWl-X#7IHTpBQ{(3%e@s8!!jtg zqkF^0!%cZFSlr}<9c=Vy{v4J&+o)19|BUUCFB}+enEU3@UX);a1phq>b~y?bZM*RO zAq!_eauo7!dm!()=8pkV`p!8=HkQ6-S2tPFbei5hwgXD|=w3~SE`J@>B@@!W>7|23 zH!*p0$}-Q?pa0{oi7|3h$pbkP3dLWvX;_`8KabaK7cUPL?QOeI5}w#w^Z>C<_-);@ zJ*4;0v8V2gL~E9I`^R_oBR0N=k`vu|7@`TE5y1U ztvv?Twt%%?A&4|fTbKU|Y&=PAjO8_t@@F#s)?=KFB{lWlxAlATUQpdL;r>E;|C|;J zP45W3AFuKLT$(mTAu@i1$wQoX982B09LrnNCHz8`TeB;a=ZcEcVCS)kknPw+2rW+sC@b5o;yz+oD`%C$QiWv>Bh8Z0dhtX^#^EgcT`g`&P;?fd^>TWJ8ob_|TzN(ZO$Wpu-)=9b27uv$iR zc-y9imbR@v*XH%Uw#McSzAaVTK=*CKgCmhZa9g0;7wqr$b%O>`_$3h!Mni_TY33XR zg?fTvST|$cheV?u&?pcdS*L%m4PS3VkUtz4UKbjGf+eN*RF(EbLhzfe;ZiET2fQ%k@0-@m<*04x zAUNGLG~hzY1O3CH6p88?45UhuX0z1fFt{6xo+8CGS>?F$!3a2LDhgnG&>tO%1XH9S zmsaj}IXX9WxO^>Jn%h&Ws6ljj-#wvlDXqTS{ecvlBvDE<;j5Q1EuX-s`n4 zZZS!=)RQdtM*`O@-SSRHN0Y15=k090R#_KR5H43%xvM{X8gT`ubl+E7)!}>7*`maC zRY>w$xN7-u1fIUGYOTa1%l+ZdwMaHF7`fWbEX^*aTOJDUzS@<}ka+F2usD0@yM{^A z>UOQuFAu|0*|k(+AQ%m8zvc>*hr=*zx%$lw^TKj!1yrIuJlF>-N)4xGG*O=PBMGgL z=_m`j3M38!Q{8jL1efoCbuwVA=`RiRh2SE^1! zGflY9AH{`Z(_|Vhz8re6bSIJep#U$2)Jq=l4-C@j+Y}oGy5`|QTy`qOa)+aX5&w=9 zjXio(GznS`g77ajc|~C?n?8RxtW)i$YaORXIIjn(krs)jY6ci3mBXsmsnZLk@re*; zTSupBt1m^9M_gA~I>#NIu*_&{wXbzmdUG>1z4Feswic(y0q<(?B~wZU2(aST4yep2 z6~;AB*?b;TQjjZLrf!n%eUss-rfKHwgQs8K6Wkq2)ztX3)iC-gOzSqL%e{DkfTy7w za5$xW%7=U4wO=X*)YC8y=um!7XnP3WtNK&)l=A-Cq{1;$F*4F*luK`wr&lKNW#Tg+ zzRpdH?DUy}jjGDK2ZGa_`!O*K51!^TI2U95Jb-H-7)-bLzH}CBIq2U%IFLryp)ED+ zZ;;L;cEFw}>6G6anC4rF#6CnnF-fQXu;Ty>GNw69Pn-vw2uNoZP=5KAmdd)Tl1RC? zeP!9otC!R?U%|Y8(NNRTT-BCUrZZo|Jt=F<`~9JmHB6D{bf@%VHbz;g?sKV3Es0c> z4vK_N+4@&jrCwq=e3mqVo1dgXbc&y5VrD4klLhRnv^3~0rGQU=@ELhcX+=89APw#^ z5)Dmvve;Npd{mi&i5%Y{z=E2CIL zWE8x8q;HzD=4O(I@A35nheJD3+l1&A(Z!b!-qTk#I?Z|O_ss;Rva%+{snGA6Q(E1% z&&<=~;8a^K8m8+)DH|bcE-A^M?ss)^k!s?H2e(J3J-3%oG`CPX%2k_8OrPZRd3m{} zI!mA&w;Q;}Kiy9lbL z-uC8oF!9tV{)C1G_D>s^!^6WR{%!J9Xo1bZijwPwm86)v+5}h3ie5 zo4suvzD*lgVpLmJvQV7OjutABg*0#IbaixWY6n{zf~%Y&M5TFA@Efa~-WJDZ7o~w! z*=Gx=2v4lDvANCH>hgLWO)f9vx!X7SaQiOT21CKR-S8Da<0dHZ*!`LZ(EFHuI$SL- zhu0O$H+?Cu7owxXSxrkZR;ota=lrcC>7At*fdAC(`@~9ETd+4SSmTykH`fA$|*?y<^s`*xnqoGgI8L z!O_yzWGu1vEv>wS4AMY4d|%;fb#!_l15iAr{Ud$RQ1`vjpfAu1-$O%4cO(?t?&}Hp zciA)ZiO7Q2fKKPkRG}zB}K*lKe@f~am2lZZ{CfQ21nw?>_STn6z)@-ZQI>VY{otd3$ot-_VX75$AA5gO& zRI~S~*$=7N`_=4+RqMEFJ)l}2QLUd=tp`=>qpI~W)%rNB$d{`nMgJ|lN@>m$(p&-8 zj=A^mQy)`E7hGRieywAwb+2lDK(#)oTKB2ehg9o+)tYR6G3~3JCay4cwbR5^4zE1T zEB7VzAAWolE*j>3a$nX%nfomdXN+Hq^2JsCy5KL}J|+5d3#9kK{rSpmz5vqW2d?hp zn7e16<)MuIAI#oYp1zoOY)h_H-pi()_bYEpMBAes9CJUlFXJJ!yqVuwiB++x*0^o= zm8XyP<_9$8AHdhIyu9r^K{(?IqJqDv`*Iv}$*bS_u4Cra(M9yVYgzA#!4`rY5|l%F z${tq*pL+b6B^G8O?_GXEz_{|$=K#lAY=s!(RT>|YtV;12G#))bJ2Iqr3ysI#PCG18 ze5Qo6B%Dp}$5PdfY$@JKp=aW%vLiOXl%l!=7 zz0ZUP#{4>k`H&^3v9kOE7OJQVeMuBQ2|Hv@55e4cDa-3mo6AEDS#LqLV z-9MA;XBg{zftpMBK9t)1v&hF;Jl5#~bv9{c80&C>I)~ISJdff$Qp9jB#rfo3IP)VP zGNCU72!REFyLcqS?GkR3Fs_l!54^va12`kTQNluTlVXUc<+7UjFc_s5_&I(;V0lH7 z6CmVk4F7~-I|xu=!R-n>Z`0PYM~wDEjOCiMK}$EMi$D$4zQds%JL=4~BSHkdexV{8V5(a_sRa6iotELcltn;Axchjs`Sbl z(|fASVyae~#?+d|m>Q?b)Hs!VR@Nf$!auDJd%Mf- zSkqEfwW+1La#KrHrG4v~mdZ-I7ec%c;)RfAm&*nJZn1Cjy1bif?e}{-*E`oYYH$@m zPm8_H+YWQ)c2|R=&fekLSZBu<33YatqoH|s6|XWp2eisaEg`Mtav0WdDNL)~ERfql z6v)FwfqGb+)=d)S7AZV&@qRhXpb#%E)|xTdJXBPZhly(HVM4xn7*8faixw*5t(n$} zVdG`*A@(S_N-qN(@L)n{!$lP6Yl*W8RwX4Cagj`tsUwm#E4y`unv<2U6sYsm`N{%i zp|VI>tQ0CsvWgYEG6zIJt3i}(xF~=JwIq-40u|Z#41-5C{Mqn=9Ts-}lEmwT@LW!U zGv^(YcwG=zjR~-W^Kk5n!93l=0L15B&f6yO-U5uzi~La8#eYe>EQsK7Na5EF63+?| zm=}KVbeBuKZNPhxliwJj@Ty`x^)ld1JtfXP09V z?=X$zdO{(T#GGjtY=d7(mMz2bg} zJj7p+c+~z-HBk-Uq>%2Q8-a+8mn7nL( zcZIh???}800uNrc=)7ko-X%dl z?1#C$KahCU8)NyMCGgPKMEyE}w*bO0zc??#<@HFsKH%~E;xh;5wMe|Ez{?YO)e>(H z@Gu_J%@=q#OT2>u59hadx-#zxfj2(^?-_xI`8JdHvcOxIfOksZ;XIU?yf*~i;sm_2 z0BJpi=DCl!ZKM8C@~&cg z`1vObZN20WIWYtFg1}uwCWf-vo)Z?&F83ODrTg?GIa%VKXgdD(erVNYno3 z#@q)$;!V25{V0)1U;5jz-#%HW?SYZ)zVqw1xr^MEr*MadqsPdJ`JR(>CzuqMAG|~6sfWIKzzcEpbeEEu6VFcOb`jgNle0<2 zU#P`AoSevd4t5fG*r@B}rY!dygQlR}q(RsJG$7C%^;N09bnlW7?pt$L(F~@o`V{DN zG}E)*-QZpg`sSUipjNs}Qx@%X$*0-GpJW9QCzejIKJzmNf~0I@B={ffd{$Cggy zz#ciXaG#vpET`4mtfw<>n{{U9gmrWSw2)cA%hj*9j%7_`PN?U`i1j66gZ*z#kQ2)r zztHgJj}_Z*ei4R!n`XIhguRoj9s+f%?LzxdtZr37t}}Mopl)fq^oaiRo3>oIuk9Sk z`LVlXVkW+9K6iQMEu%e!hbPIQ9=$!qR>Sgcw)Hue^1qM2{kz9WY0jJTO0BQW@w89g za?V>pvz(@cIGwH{XNK?R2}g=hTUx{z7Xn(7xI3 zT=xxn?Z$RIyR7iFe||gboFy}N@$9Twq;P_qz&26aCF+KWd4O?Gr}|^)D^@6Tt+%Ly zb}(z=cF?DianVw|O@XwU#;BzV-EU6X4&Cbh)Yw-bpUBo)cCGc+?76nM$elrV1yViB zdzCJ3Jwp4lF=*3oa4&J!7xmH{SYSWABrb zxrd&doP9LcW*f@{%`!#JP>PdFiAhiet#<6S!kuyR6z9&Yr0<*!7GEk@98wwDKJ>3+ zw?QjudCy91P-1FLuCp=cnKbn*A?F)G)@&;4L9pjm$(}+PQG4#CWkl`y7jI5h2<0?I z^3ewOM|If~R$;S^&#CW`UU?Yx@w^CCtk$ z)c1eZg+6MXK;3THt3YiaML+9`d0)&v*xKMGUjIMa(<@vCKfC=}cBXs7q%JY1_7HU_)Cr<2u<3g-UEk9yIGkvwtX4Q@9Fh{w=vYK zP|}5q)~0(z@zr4AH;Te#>Xr*mrAA!AI6sL@#j3T*t9pG;ucUX_ymHsPzNgm*-Ocm^ z+L~`DHq8Yk`9n|A)rb~!N>dy+eNQiKb|P_kT;J0RW=-@52)^YLJR_vI zEfFNs0=d4Y*HpjcHsb3OV{e_NVo1H@>w9{oVnlp>PcP>nJR8Gc*B1$f2l1kJ^o)BYr6#v*SD=&%~%^UBekoD2K&2x-BH+H!ylODK5Ma6 zcSV`0UQ^W|JAJ0$yJB76(<>4P;_e@D?2cP*UEk9SH-#M>NnoYxdwM0d&-FdM*f%2Y z<45|&Vb}Nc8YsQTWF|PVt6ksI>k3ATF;n7#?kSm&HHy5xrgo?bl(-V#Xea(z!P z&0ntX=@r{8EY-scx+8>PKe7}zd^7=lf2`?E^u+3iQEFO@qU)R%gIwR!OW(oDpXwcs z*bbNF*Z1_oFR_KEY+7q{yBl^6yS}GaFv6RW>w9|984%4|4BLfq3#GIfXM442)6eOX ze0@(Z&CtW80o?g$>KI%sZ`cy#`kr3b_w<5!Q0f)e_w>4=_s-Y%^wKxI5?@#ATRC0d z)5~{#PcPiu?fRZxY@al7hp_+4_w)*v1@I@yDL=YE;+5@elzqj!gW;M|{D39PQ?R4c zmFs}(Zt(+_HBWMmekf~y=EIipj01^w`$_FiZMZ%aKkkQ% zhPlywGaj<;&we;-JoA9%k&I7YJzZ>E5jZzeU9OEyL_Kh&Tr3;wL)rVY9?l%M9LRX& zYVCq0mdyawBf2l=p&9$F4`+{O9mssd^688OyF#VUPwu9=?7n7xBGz5hCAnRaQdf6N zAWeQ8g^M`;;g}my*Uud#qzmHH-JaSY4SsMxxfcFv<4VB!TGpEniyj|_eooY31(eJ5 zcTc?XzE;#>?KRQ?*D2)(E|J&;f9bB5AEx&E!%zldyIlwNzuN7#4btQXY=J}D?Q8wa z<)(UEyS`NPQCJofZ1UmIW%D)G#Rlo~<68QPjVl4?4~ri4pv$!yuh<}Me!w!+*Gvzw zJw-hnuq$!qLzev+4`03Ul2~`Ibvq*3qv{&j!v^W{V;Nk;c`m;y{k~|6UaH4*cdWkh zXD+d?#cQ#zByXg0sXHLc&fJS1S;Sz-WiqfSwXFR3Rf?Y>$)6#`=ScB6Qv6Iw z{!A%8m&W6>xpw4A@v|g6oAP7!m@UQ6k#L@b^XdIK=cOI_QhWi8$GITwD3Idk(s*3Q zT|4H|c&u+6qrafvb8IZHd6K*vsJxiJ-XO)_DB<}MULfIx5?&Jye(2C+ zAsY=ikGKsupR6v63 zL>@5U#Uy0Fg{0MhZz5F&yo3}Q@KTatz&7$9=m_k{AVuU211=^t0w&O27c-3hg?s4E zWf=Vn_sE^h(1c;I0=r$j$uNd0#6!Mqz|G_-1HO$sX27?Tr~$7acN=gisW;#YLe?4ZDsr;{*O3_pyqf$w z-}r#qYYq831O5p4mI1G&`_iCo@leP*@~|QP4$^PHcM`7w*ON5{yqxY2tw}?94w7Yv zZy;xRBu&prUNhiE!`@*EagjeY#JiScM&4UNP`zkgpkV4tdhRpGiK? zF!rG;>XBo!v zUV*xh95&!ZWFN!zG=4GJ#W0SU3)Di=#xUlmK)s1nGmOvW1?m#Agkdecr6iMKEj=6g zH8d2cFSZ{AY7zM-11>h~DUEwR?*tw{5M#RhKpcBELwUx%=ManY>4cS7) zLmJB^=PS%VVb5iXzsmM*{*1Pl6vppC9yt49JpU0PN8zjjAN?Q)c&Hch!Ymx~D`G59 z#ME!#zG{Y%hjL{8A{I~mE)HM5U*=Q)h5O`m(H^J=kKcwE@`L`D^AsVw@%%I)V{leK zq3vyz^ZSHQ-T}5JGVC3_1bLs;_D;#qiw>-_P*J z82&wmH!?iN@D_&mGTh2=7sD+K`x!>(|A2dym%*o|!%=N7S$*sBu&-k{+&r*-Fwzfu zSPu>eJ9g73SD<%L4r>ezgQ$UEAl?nmgfZ>@h`)cz-rzJPxN&=E$4G>#(GlD!r)r2d zMh1tbsu>(gpk{E$OieAuR81NkQ&Uo7CoKIBKPVQrbcd|5?aB?@Mt{`5B@&7Tr-VY% z!#va*+A-koV-#<2pa*YbP$)Clrg#JB;Dq>l zz|+0r4f{va5WcN5b8SNyZb41Nz2g(@1|Pncc$|&!F&^$KZ?={BYSYcsSDS98zS?v% z^*Ynd)ay()Q?E1KOuf!@Gj&s?SDEgzzRGl$^;M=j&DWZyQ)_CRT2tfHm>Q?X)HpS! z#;Gwij;U(ZrpBo@HBPmuaaNidXQinID@~14Won!%Q{z;b8mG$CIF+V0s5G@frKt@n zE6i`IfV-mZ&}gv7+3SZct`A#Wr@ybS0amCXKGwc_ppEYf0<%3b7#$1@_UVjdX^R_#jF1xG2QD^UPZLG7mceuQDc9)}}d3P1t^L|R-ukCLi>-Pn0=qAMb zWBq^}Dm3^~l-RcKG>wZzu>M_FNABB&h)+8^|Hhlm0L65^~XtEeRw=U^ln94&3F zF54a^nK~j_v$9)fs5x2rN`X30ov$oV7AlLB#Y&;FB&%4lD|0}Eqob85*>F*yz&}YH zlQ2ht>ihgi;$0Xh}CcGmOuLLj* z$Ml2C+b8jGUUi$!is^^pVt!8nj;CKh;(1^mxG|2r7KwKdc=6J$k$7*L@NSiOjgY~3 z=`NIbnHVQ}Wxl@f0a@L*V~ zADs7VP)^hj=MP2wKn;4lE%8nPZ=WtLR=%%EJlwM#$K3qj@?MsBF9UBGC&8KP_Z5lv z7VvBWkIOqG@hngcdjuYrH!Sgbfd|8P{ouS#iT5(_+&U|!AI`tS|9bsZt=hLYoXX|h zB=Odo@McK7-N38o!r;v1orP;L-M<1JOxx%O=be&xxijMX!Lt%?JMgM>X|Z%+s?d<` z5#YtM3(hl&`u!8|U>Zt4xPILdZ$XZ+{o}kQiPvkwD`I}n6M7MN+($5sUl#%oOa^Zx zwBu#qt!3AE;=H+%Jmeh`h?qw_u+HE$*S7@}j@ORQV)A&pPXLdng>v}ytxO(<;c*mr z`?O2?FHcwI**%1eCBb_Vc;iX%Rx}fGFbUp^z)MD6{awlNz6ZQy((Qz~&SZEKz)Qw1 zT`f?)N#yq&@RG^zD9q(0!@~*fWO(DiOU4g!VNN(1-k~IU^T3&5dR0Hn{BIn1$&|-D zm;+5lzazjK(^J*z7(&_a7r-2EGWI(PykzuS0du~|@Lo)k*9e_VGWwlLlGh1y)XB(u zBS~HlbRNl+$J@Y5#x7Bq(@sX-B=C~S$Jo~7DKAyj1LW9fOX7rzZz&i z82&8qmj{0rfCOEYel+%I;m{n>_8oav_@D576CxFNO z>PCS#DDj>Vl5@V5_nFD zw@;8)Ebyu&-eKVNLKyn#GJ$uq#JeQOD@nl1-4V0P@&vp>fp=R1-U@+tdjj5Cfwv+7 zuSMXMCg5!ocx4HAeFCpM0dJ4M!~TKS582KK1zu$W-V*|^Dgo~qfwwXN?`469K4PZd zDS=m$fcJ*Lt4+W=EAUn&;9U}UbqRR6;LN;Uu1>%!6nHouHOub`fd`*EnDW*NJRBC9 z$!igK@cDu%Z=1k_&l*g5eF6_Y=P>2%5qR|pcn1ZZBLVLTf!C0L_l&^9Hp2sWwTY- z@X-FPtf;81t+m-ISJze7(eSRE-*dIN6@^Q}v`h5#F`X_n1R zHrtAer?tf4v~K3x%cVp}d7ytd1U{XL9hP8C(o{*J>s6*mSa3Hq2Pu_R9vm78j(~%v z!fJer#?(qHce@;&n>t*+mMzWgX%tO&d@iNcce_83Vv`s$A*FOJwwf*tMzM8(mSMVk z+3`Yu-yC9+<^D+Enx)IPD@)lvY*(IjK?UJ5bz8QjQX{V5lrH^h`_1sZDQfbPw+ahqg33aH>qR;gORJ<%+l;)y5*tp?&_=T$%e#huSMeQ zq3;?deJwgWYIl}(ntpj0p31JJ5e9DJtFXTd}+!67mwSHq&tb>NV<|pz2pJ^z+ehCFh)Nyj3S_G z9v%$r3Z}Y#4o3$g{v9bAd-VEK^w4ac$c$~%p#|ED5#Z8N15 z6*CjYHBZ@m-c-3l5~-V{d*5Vus%e^e`{3!9_XKx`QZ+R`Z8eO3>hpFsrlw|2L$To= zc7~aKp zcNBiLI=wQ9FEiC!&x!h`Wawj}HVf_^2u^eEC$ap%G@rrWNBUs8#rI9~>F|B^?;jjU zi(9gUu|mRI+MVOfON|*-_lZ9cU2N8_qMMr zTY2@8n&vB*#8n)NhMJD%sNm*mw?+>M{VTwejJEb49G0IAHpG#$GNu;WD zP$WEb^slT+y~J|9RdO0cr{v9`v9vTZl=H~~_ElOMbeB>nhYtxWR@c^)R-~g0(%>#5 z(a>}!izUlbiMqQ?bJ!hMb~^k;(>k>V#_eKL<#KfES^r417hbo80)Ci8OrPXbH+55W zPw^mwCJ+dPdxMeCz>bs}Mwglvqr{}A-t)=>uo_KJBlJ zVhxc|@b;0uX->hLNglq(*ApCuB?wdM&$>l)@wgX!)#xDzHWwdSFpOsB`e z4WePHER?blvgVSK{BX)fu%h_k!R^s$&+WA%N6-A@?fmxD1S?Tvq0Ocw0Nr{|PSc2PG?@v|Y7iNooXJ;%l*!u!49zS2N9ju%pD z-{Fxk{MIVqpYDfQl6%C&rlpDs;^oM4HZ#Ne}U%;LRJ_HnFYZwZvnukAaA? zJ6pUyug6j8Lxp2+ln1+a!mkfw@|n^Q;PW|Kz0F=9N)lwWHr7xP9=;-L&)b8tS zZgpY$H5C;VK;6>f*x++*a5S{I;1yt_v%%-|G`IV3-g4_!Cdx;DrAY4tDXs16*iS;M zYHG?>0mr+k9rNX@tEj51Z1g!=wm3eDYB1aIx8)GRio)sGAR3R_iLH?|7bn>IIl z+d6!kHn7B~woDupXS1V)N@O9;8#-Mb9h=(0)`s9JrwCDLUKISsDyO%_vDrmwU{&_n z0xH52>uhXp^R>FXUPqJ5%XsegO+H*9)wRJ;ux_`{(b2dG3Oshd<^l9RW}gmMi_774 z#qv#G%Il8c=x|okQskb|+Gxa$E-#H|3U+pEXcEQiu6=hiB*C0F<}TnlG3C51E*BJU zOqD6GNFfTnX|tnclWSd7H8_#xN8mWr=x$gx*5?Hip$zd`2<;uSZpHTIn4Ov8jt!2M zwkBhVwQp(VC1j8W(&49=zE(%42QmP~Q`$e$7Y%ja8x8sbz3@FWgmgzj!R@}Dkbeh$ zVHLt(C6*2h!k`3y80&+dsYHYQzTTj}CrIfL_?9seg8DU$pUi3vzu79H@qervAYJgQ z<}2GJ*gB?K_o~(hRO^GPb)RZ|NVV=)tq-f#an*W2wLYR+Kdo91s@6wU>tm|*aag$q zSF+&;u6ED`e^)b2Yr-_Gsx`xEv1VGctl3tpb%r&^Ix{=hI(vHgOq{0KPVHBo<~+z7 zKXTy0G57v`xIbqXT$|bW>gV^`*!cgYeDX4mo$rI1#Sh%ma#X;$`hgLv63&pYg^a-c zSUa`DBE@G)I7`CW61M7llws}9AUR~Spdaq}S7pE|nQOoqB-?;3P*h;w|iXONJ70QLJy|g`JU=b=<+JmTb7>32BD2BztdNCX_ zLopbWVpx2O;#myCB3l&0qG2>178s!z77(Er7R{m<7Biz57RRC(mH2>r#)QfO-43TO z1V0WTWqivGoY#f70Hh2T?kyFbq@blZCHyFWB=5Q(f9k8N49k&<= z9l`#=Xi!^DAGhS7w?aQ2j2dt4KmoD%{=wbBxVP?*Z)7X=Gs#n;HI)p~xA%<<_Zo%A z-w6c9A@BgRBNFzN^#r>|cKGP;Q0%4~EST=E@S)f%!Qay#8X*7IY+rB!xGlxov zztMV?<^}Q19%VlqOXHK9S-YAAO&1=x-jJ1EY5zdeN{`F%FSgH|hwE@*Th9;9n}7h3 zhwDSdlZWe!iM)2e;?p6nWrfFg;7{cB0FEc`OA-&;<9NJJOT4HFZ>PlDW5T32ZAMH-99Opp*a_|rR>}L2Ad0T;p_ahI>*^JjK@Zj;ols78y#5Gjq zbjJlAJpP!o-&x^i_zHD$m58g6gfsW$o=ZeLNJ zRKhQ0xo5d6+?RjzyUP~$3eQ-t<=uS>dDoHW3Xl^e0zNc(C$W@RPS;=ja{kRnkxx#L z6H5(@6~uO|{^D2i7whr!h4|BxM~LmE`ioEH&t>s>LM$20EU}y+MK-F->6L(P2QQO*yak1y^|FLwVN%- z!n_|kR#jZ^bgz5XA7E^@6#H+Q>5rCWE6 zAftZQQw>-;o0z;z%r#w{s_dTOou(Tq0ENar++&n(su=TYjf$s_^Hm9K7-pLgNxpxR*uRtl16RU;0 zxJ?4O)h$JpTDBrwbw->!4zI@c1>k0MdnAWPGb;HNCv}d_*bZeZP6}woquR{otFkp)NhwM2hAb?!Pk+`y9zW7qe8^ zK1-fM3nj8oHq@9KBeCe5?20h*-#G|)8hb{a0XNS0b$%(ZF zhURUnq%ib0xd+g^?Q27^9^f{^U7EKY8;bP+#X>yyw&#aFcn@H-aNC8+Zn+0|ANxB0 z3b zJ|gI<^;pV8+eFPojgTu|k_U!vXEtLskESp7QtTO!g~xg+*)L8{l0#ZQ^}VL~6I#o< z7h2Yr-Xn9+dw+i@kNdauw6p^H)LDA(rS)O;=l^WT*h_&|JQ%;Nr=0-&qxDt1)#pzK z3zb}+?uj{`lc5FB*PINE_2RSCVkMKsSs{$~T-a|VuHV>i$vxE^WtN^!9!+Pqo=(1! z#o}f_SgaRI+}4VH81JFp8sZv@Jz9KyP5Zfv5heBvc?&$T4=XE~ezk&+oSZz|CAJ?> z6WYlMV+(yJ$)aO|dz6Iz*TqpKVgGgUUgZPzUl;dIX`d6@6vqYGFyfig_g{Qe*{YWx z+T<~%Q^#8bt6CB$PdeBT+j5W+_wtp3uc3_b!ew(Qyn#8P(a znd~A~e`!rrU=$)hXAYjrfxfRm@B74Od(`^$r1hjW#+YcToUq!8gm%IT^4N0)Yk^=? zQ?yXinT7Bkc7`DpaSSJ?qD)-=1%Kw&Mm34+Rh)kFVyoiR%R#i^>B+4 zLwxekd(Mj+l`5Sfwt{GL&3`+T+jNFF3O)pFJ&tL;O0gbq7fO<~qZd1sMJ!%?I>RxM z<#Z#XRkrB*qj#4mUWPXd zxzX&Ac^Z4E_T~dHM!M%U)-O>X#TG&IY-|y-irCXi%x`QC!LzWp6ibCa{fSS6n(yB! zJrQb8e`SKK&%m=#RuO7fB7|yvT)a|Qqby{(#Am|zPlV8KL9M`N!ilB@;ICRAItD%0 zi(1ch(W&q;2(je|>0-{viNw!?@%yCj8~P-&6Z<5x^Caz)P6>Sy(MMAstWP>&=#wy= z*^rLbR=pzhNkkY~C2l|C^hp>0TH!sl=EY{Z;=RO9PRsxu796wcnl$9|-Z7(j#!gRY ztjXfGxwX+_y!N8>ok=G?W6yJkSTC%VmV(b27nkJUz{=e6_1QM`l}z{Umu%xDV_oCD zV@JoI8k-n@d(3vAWN+7j-n~Z;JheAt0%MSIo4e9Yj!^%i&z9Sbdg-gP)C&HSL+e7bv&|OP4!13(2-b4M`F3k4NWBRR%kRxOFDllWBr84H$ zJg$;G**@U5OmKZ3aDNlLQ8}a7$ONWCY$ajMQ$e@K)hg@$75m@Dc7^GAPOEVhn$$K&}6 zJ|AMgZvmg-_E3vH&Qi@P@(I1164vZ;0+S#HVmpIxHNY!spPrq6(0K^F!Lq zVcFNk@)7SB%ZI!dyWb|X{%GkYUDh)2vss74nNCq&fnYOHUallhp4BufAJJFuELvyq z)jI^4=&M`Lh~69X)oQ{1=&KcijyOw;r8a-!c29jsDN)Zb&y{8sh%~E!PeGbTpy%S~ zVKMxxdG6gsv1itkq4)D#xnB=Ro*Tao$MfBri};giRuSvHS-sOV-6;5~`d*pRD&XfQ z58DnsFZ%Co2EW9X*#Rvx`epsaQoYrujpO(PCnqNL#WMlQ`W(d>#lAMrhx(7Tt_O=J> z{z+Qqj}-B7di+*+4t=IKw!>`~mUn-!cKDn6+m&z@6SPI0y@UdvZ*B9D!#rpRNnk@Ptk<;7Y)vCq@$)erMyeI6|XCN1`EV2&a6 zSbIGK`p8(lN<5~*Hq~k~%(sERKjdMtSocClqva*I-yxUm!0ulQVG11U1xYF z%imm@_hqH;Tyj|4<(|x4S-Y}#*_hX4g4bBUYg}hmO|*by+kwFg;~TAwwqq)I)n#}R z&7L^A#~*qMW)|`MT+`f%uE!2fR^CL& zJ$Jd<=Kl9zpj7R^aT1226s2V58FKR?_d@-BLN46N?+PCeV;vW~37=*vP+iJnfH=ROV&*#`2=T!MDHJ`&(dVsvWY4|{u!9t!Ca7K zizZeG;htSu=o~2LWkUF8U>>Lb{JMrhq111k5NBd=h9MKYz-oAN3jOc0ya||pIZ-f0 zT5E$=JeWIt zubX&|Ld!Xp!6k>5cd%*=-iz}DXoWNRu{lMw!aGBE@>+00U12#>fBwh$u{lL;RNi*s zmqWFTwc11OS4;e7)D^zd+N=`jTl)p`v_yzz{(BI`^U*i$Kr+0%W-Vq0#o=PlF< zcELuTux*M>3x#;J=>h?ZHZ7pi@&ub&-Im?TitICv^EXnjnPEd)sPHU`XSC)e)AyM% zTb^UK)GYXE$&bF9gdZta)sGaKSMEoDGA%#Cx;zeZJWFsa5B^hJRHyq3^$zfun~V56 z6tqy=g&9NqJDe(3vno8!`-(>$tR={Hlk&UHWY}(J<#-#bTek}3>IvU$@B??(QXy7( zuY}|kFQ+w0u`OgV3+}>Ni5@b~z{OhUpj?;(gt|6M@DQzS;x#NAX4MkSGjpH7zK7SW zEVojYaat`?PGfHa&%*a9CCZtxrIWuvA5%&)&Jf#8&EFeVCluRaI4|10j1^9X9p}lu2-eMh*@8pOUIrwyTnF&@uilm%=t^}5&ugwM$5|Z#xBgrP& zkkvevJTO=vK>?%HHd?gQszqxpS|3EEg>yIDEqFcYfdVo8SEAd1lU|0q1^-3C4euz1!|kO@?hSD}=gZfKhZ( zJ^JU;(*An52hr9?SLnXERo~x%c^jJp<80t>Z<18F^UCzfhtbn!(w1kh$KP5lrN3ar zY)Xn-{L!0J^;(JRfoIlF(|2+elUfSJ)2FR?2cBE%ZBF}EuCfqj%L|Reu?sI6iS<<{CgzYpw#M&0(|};h&#C4anZd`n8jp z{J3a6^T$lzxR|1t&@0ildYB(}4D)Mp3tDzGKH0zHjwiSGc~==@QrML>y{4sCm?=xR zYmh!~fstKXvpuD~a84F6G+F%iaNk79KmS zU8!huqe(D(;qT2fxK*~EH<^_p=0DD(2s=9lSOpF}$AGy-i9Wx3&zm-YT5xQrIBVIu zp0y%&?*ohtFQ@2tC~h7kN42?tDJ}ZVinE!%yMoeM$iV*oXS~s5|Mq*lvBZC^P@lBv zFy^d?-m4Px21zl{{vg_>T?b%^v<~xoY+{M1Dg5d&mPi)Ys||Vg4v-Z79>qRyjS+jA zH5ip0d}(a6@OR0+?Cm3;nWqi&y#iciyT#JLYu|~U z4TF5YU{BI#hgvz}UJ%Ss?g-v4w6efE(vodh7TOs7x0KRRTLkZfWLyrGDzl1sn46$H(S7& z?%xdZ*YKGwSUOu<^6NA2RCciSBdUFygcm#{<`TzGMQ`dj6jG zFl&7Zzh8oDOIYjq9f4rAK6u&a*Oz?%eM6?*S1x#6vw5pt-?6UR=#GBWn{bAO_HII- z?hetX$3~=2|BckA|HnyXdREKONp*TbJ@3<qA1nK5;}9e5&u;$-VjnZiK*I z{Wh2l2KVVFC9$@<;NGswU==6+POVSJ>&4wE*ZBOZ)pzTeJ5n~VxND(L*JjYzr(4h5 z`ys7E)-xqS8C0Bo(!uA!9kdSJW{daNA-7zIme_*j zA(qymA#XNV;lHBOYEiI03hNMFcTa|ELaoi<^9;DAKABoq*#*oGrzp%}wKM73V&4&*1tPdm~9g!l%_3Yqz*X{K zd64bbFq8zYOyk`uXTF_(x39nbGB@kdu95LBn)@9)eGIf6cB{`km47RXyG=M}Fpqrt zFI)kaf80M)Jnf!X5Bli!d~FT$THJTAV{ViKQXvJmtRG4bQNc0Ydb^%%LnDW!IY zzAl0?urvqn47bDGaYHWRN`ohzhFppZ??j5R;f||)Fb@7l2|k6SOC}#y?L~e1?uynf zQ5W2$M0e!l;eX;num5|dzMd2Vas2r^x$^_H7bDoG)g)rVJz3l1Y?~0KfNo4)PZ;5USMDvCVgm6dI@UX z+&h2U|7gEf^DNMQasMEYJ^ucOSwP#XBY!@#fbEVm3$W#_gccV+GMB40+MZ9W?Q&0Y zfLPFL;h%2nZy+f%gnD0S6ni4>9-Wj40&}qucWFZ919NW$yBl%#FR=;9x?U4I*LcWxF`fAA{4}Z4{^eK3sqh;~{fA259>wKk_uI2-JzuA=i zXy>oIhCc0X+o2LI-5SnVImUa(?;#uIi*n=suUBECb z!4*n=^_8wro=eJ_%-L&@oOmBJwx+G__bBiYe-8PnaOztM~M_V+h@BQ=aywoW$iD{#9!+} z|2!X7DNQf_{nTml_i07Rhoh*)uZ$>QueO7!SsSR0#KIj1P><=eOkcS^s{SiqzP;~0 z?<&)6TeaTPa!|ERgu7nhNjeYg4$g=#kNI$CbW`u1g7^`{7kN{y4;4hy-zceXDNTx7 zaPmzHySGGNgM^y26lXxm&^Pu$A3JX_34RTG6Z@ulW=4w^iThg;ldZ4Qo3c!F^za zJYr2JDHCC3_3P-5=%^2iroZ5|TE0?1MhrG=#p)Y{No3KVhp~qyr0XD@kwa3acqVeC zrku_rv2$Fs+{od1%nICX{}A>}Zel+1rx!1zcg^*3YJXv=!FwHiHj3wb{km|@5%cw? zcTdoKVM#CW%;ajtecmfg%EC*Br%7?@!s)}4q`0Vs6NclYxafss#F~U2eDh5S>a% zo+^tc4(oMRT^!^49kp1i%dzEHo0Htg@z>>F`RcL)?I7L*yWk12^clUX-n*c7M0pC5 zhM$j1JM#`a&s>6a!+mf!+=t9RLp2QRaYHZg<0i%sdacUu!(glxVy6&(U67s)u|~q4 z)nR=jXn^b71j6p&^T*!#jCTf!dWJrkGmpPpcgOY0y+hZ}g}V$Cn>wJ-yWnGOQx22) zbcHk5Vv9YXjdEHZ*eXBMJU~voz^^LzStvE zUlAIHwf!NQcQKc6KIF$ph-Z>V%;^BJf+T^c&kzrh@=1L8R0gy=?*r!(uGK5>X)(M~ ze6f$re;&#>d0>JWpCyeub#u&_)2IIO=RbV}YY8U0mVkHLe=77jIQCo5G&??Kz0zMf z={~Qu^1nH(?X%rL_t~~Z$Hac^%PK{kQmjkRnU+ zz|ZVIEQL8`wEv0#$ELWs>ukvn;@FGVqVwTu=gW@6%mdM;?{X;{+$o+vdj_Fb(4U#b zJKdh)Fy85QfZgeaccnccoUPxL_O8cY21mR*;q4xTJnY>KPminQLCx+c@?oKIz?(@7 zhYhe3Ho>IYz9LAnh!rGp9`$|l{_o+By#IpdMc^s0UvK)lmK(HScR&li?m>nEBXx}F zW`V(9Yx383=oz^G#?eJRb1|E(sA&e!z+Y_|+!LU@Q2Xt0-_OepTUaSIuoQDfw0TsN zsZK~2@7}*g%b_qcLQU(1c)agYo1Il?@vKeLCk78_v$f+Tc%C++Qqv~DyhXQYq@jRX z#9R5xhLy}ptZU0SyR=>3w;OV}y7t`rWd1Yn`%91<D{Q`2HbyW(Q{ADbRjk&rQ2B$5xJS zi>NsJz9X7h1iR}kkW)AU&7&|L4}C6zE&pN8)26TOXoOm8+;IogS$Ln!Dr1!Ce$HnG z_kA22b~5_VuAAwKhLW~@XcpqMr}+4LbNx^8 z)pEJiRxUPj=ijQ+HfVgBY1B%68J8~3xT|SDTu^0=x$=_yXmXU_JHmY8y@ZRkbEpr|R_!UJrPMAp zEqUY_DCbxcdW69Lg{0#YJ~``uHwC*hmv3!8+sRS9D^dH$-K{IfQN@)g?vukR=+<&B4qC3U)L&DkmDtsmyBcrnzw3^^?K|MEpwCj+ z4yCVMt>jXGJwC0}O#HeV?t$kgFX2+z(O|IgvnOr6QQSXXtnVMwlwRINO#BK9uEVKt z7p8w)-T@=uYyoExT;sini^DbEX`CJC0jvprEx30KJt4;#@(vhFlcR;0hm6{F5Y{y^ z#|Y<>5Bs8&4-2R5@D`fZB~OI$9b@nv8TU4jIdKAGu_=nfukO<4&A7r%=98mrmz=el zhX~xW3QyscWnRkal9H|ttLZT#s;A_PWkb9tX{}Z}HfGIuRO<({+JQ6OnWfr#x0uI= z2;BFh<%mxOYGZ9?6iY>$2?wt019b|`I@U4%dEpW7Lj+qbUQhDtM=wLX?lFAl7rtEr z*Rk}KykU@Alkx_!j=Qp=eRVvP4QN1NN1MB&9bVYG+yrl|H6es=b#$6?GAy~K9(NOd z0VmUxM!)1?%FSG0s)0|HEH}Y>eH$B1*JL*>$#FDYOEj3C-na}tv60>d-*5p=U)T|U%5)xz8SFc zU(dKEFs{+vv$7CA@#E}GFVD_shOgPCJKT+3D_!l~&dwV;I^h%U74WH#if&gMe5)wk z-RWc>85-OCv^6-J*mp}aTHtdtb4;~!3YVMLI9;uE+j7iM9{5*SSj()boipdWK1y?5 zC!5jQ^bV+srC?)WN0ZaM1!`!g)7^nTT6!AH0Y5L34(|(Wb~WKgEgh}85_4l)mn%Z5 z;CpwG(nP;f79nNMZII=N>M}dG_Beaa^J7}96wS>}M|Tgr2s|>yscSRyp8^^~)#lb4 zT<&z*e48DO5q61?2`MEC$1h`A>dtQL9U{=`0v1!C9Hv8(W=Ch^1xwfL|7z5Q$~tEP z_Y=Q?^{;1Pa&H^&M(4{kCZ2mCavqWIT>f)~&62(lgB|rdpT5}*v$6~5e{;LD+tqx*4KTai zaM?2c-Hl!p)C*{Y+1=3!UytiL&u?P?a}{$e%7T7X1}_35J#zUKo40g2;cCF?NN;R) z!H)Q<+w?3sweU-KjIe{`aYGkMtar(@Ym@#?CePW$@;X&bBdfjjkTQWIfhN zME+7hFNVl#Zg=3fULB3F<{8o11Pskx9gWvJBi+^DckUcpB6RK1;)u|+1r(Vhs*Gi` z&d~th*mclV|Hu@O-VP$8t+P8)E5NA9+}RBu1CK;C)V1jgA^K;j$5y+Z8vl9nvCPfr z^vu#XpCgfax1$rj;~1gYFjJ;mPCwioK_fZ6+|S4@(v3D>N=AocwDR`Pr*Cd@;-^6) z(*Vxf46&YSUpgO`Y7n%1%w0_p8UoM5IbehN23NDI&e`UO&@AQit%*d%h{TnVro#+( zayi@Rm&GD5EeWg>=YXv}P3PGdg6JMQSFo!pb3?oHJlB3gnhu+>=hsVoj`ohRR^K|7 z1#8BSF?Y0&rH8OVwl~9F6z9_;hAxCHj_&iEn1|Ni(&!pX^INkT9b?)A*w=c;G7q>A zFxL9b8_P2D#w8JRb>)(bCF7UWd2YdkuDw_^)O9phxfz*bnXj&TT)Nkd9U@0KGlpJ3(qpm`eFgQD{Tzi zBBg+{Kg+V*oOH`rl))HOm!59d`7RbqWlA;rs>^v^b_diQ;n^>3Hk#Fub?^2850=xTJpB4VT}^JvYHZjb>|h`giCjV^bKv(weSC8Cb;X&n=%__dFPLn1oS zr-i6pJB*1dB0auPdv&Gff0vQJBN7!i_q3kp5_~YtT{qM!*y+$wrX^o?~Pef_3*15lP1ck*AkAX zPrBg|wFs3VKL2x`lgtQMLsgjRGkA6G&W>hyLhn5D7w~Z>Q+iQR@rKgE;=1DU{6au= zb@|oR#Z@(R<<%ts{m(VvCgl=%)KBMESC+1Xg{LC^5gHm%S65z840~uC%Ol zO)=&Al~z_%)s(KSSYN}R%x_m0q3)Wp>bh!ser6pS?B7xDXt)lZKlJN|&0B3}6^tn? zuP&{wLroypb(9z7P!;y-V%Xx#uc}#JSyxk9UX1DISS%KxZY;}RTUWd`zo4wR2w-7B zU7@|SvJTfRH*I37>gaQd^i0rFUb!+edud+IlH9DEoQ$Qwsa{`+`KrsaWMyU+)#aCM z%)biFV7~G1{p+qR%wNmrpZZB>W&2Mo=YFr>P+DD4RkwaEON?5}N*0QneBh3Kq89-`5DQRpXT6;_w!Zz!fT@G3BhH`P%?^u%h4N-OHhi>s^iONy%* z&sMpva3rW308Ui)dgyf-?-|s;$kRXzbOH>(TlJ)ZOAWM zU%WCa8!C}jkD%gEr`z(Osa1oEP)9{YS)o0@bS-$HT-#&Ty#S5N?`LLs{@VPqiW0HJ zDmRwvB_wDA?WnUnzs3$3fO?YN*3;VUYS`ZGtZQt6`=KGGq0{ATu4{5Rw%{FBE_^C6 zy}bi2O5D!&raE{srrX(8*Wz?EIVl|;zU%IELHjz7XJ)mIzgF5p)t};Jn;IzQAJ=W9 z4^5BrfAx^wXK+N($D9`t^`_WGZ+jL4Dp7Eagz*F;`-FM z9ctWdYTWH=+)g!amm0TQjk`lN^s9zDRl{AX;ft!_Zq;y)YWR|B__9jKBrZ>B@OwPc zOytspwCfQOuZPFs^QYgk^FpMZLGylL(zaZ{v{#LD+I)Rm zPSd`5XVfk%@$sqed>cz0r!qXUFZF-)%Edh=Y0D2 zfe*&JpE2nL0O1E>`uWqhsU6dA8lU>d+c7lSj%&xu4!#}af*tknH`e1Dwm1EF2pYW9 z4)Ukhsy~~46wzX6E#@Hf^r@#XUrq<4P( zg`rP1>`)E2sfOEC!%o$(OEv6P4dKqkipD9={5bJ8q$#zJaq;`Vf(?A%G+y&yKHrOJ z-_$$qW3&m%Tt7CzkAmsjcE;_B-5qmBbbr*H<2Og*ec`2cT-f=_TCm~#+W+}oi`7H= z_&3&lo(a;>4|p3jEq}wVxZSaL#Pmns8Fklq%@s|$5fI+>FJedMzla^y3up&FChmu_ z8Sgg1r;l@n@lK!bmli_$7kYeLPU}LreWO7&1Y9RNzqtua*T$u9;@4@W(6S%DwGzJG z*}|-M2Ic>3fAe|P)=579dj0?OJoD{){{L3nirgA3@AoROVZ8e|KK%n>*7ZoPLG$Sw z|9|@9UjF>G54MMT_#5kaCtv0dT!1p?+dZaVFn#>5y?7tk>3YoP_qUO3cf1c?xj;VP z*Q6e!HgxZlu0PcB>AmApC;wG#!FhMV^wEB){D06de4VYOehGIjJT~LCwy$yHxb7$M zKIr{_)CYXusm&S2w+#4e69bgNcYoYH)sO4o$AwzA=^H|;M3ns)BnGJZ<`;dKc&}f+r>3&+|~Pd`u2M8$5_u}O^}9u?55Xl;+~p1H2n+p zKp1N~`2I*6lg4kYgzpdR7w8(Aw_(l&vVp&jDuOZ}?{ZgZ{Tsh>=ldR98y)YykM9Qz zqstt7fm_FGZ=bJ!Rp5&Yu};jF$Lb4Q9ybLpkHh0t9wx}Yel*Z_A@$48j(@*w0fWYK zp2*ipZGUs-u;0I($tTuNB7B_)u+a%Pd4dBK&b7#N%Mp!#>Wo6JiK7bc$WvC{?G+T-vnvu z#}NFG?@d*&9iMXG$0^+RzYy~kzAUt7CH#G&?jt=cpRNCbZ}^hapRMLFAqpu0JmjM& zM3k$NT$SWeRF3sgJEA0cG?nM+Vz2=97jPKU$M&rqnp{VO#L)9GkJ=F<>5rvyEC=m~ zmE>^}Hc&oZ|7(Xql24#=yjIkX36eaX%5e=tJK`nzL@M{&JCVxmI-O{8T$9ocO|Bz+ z+6w)F*Jj!=Nzy-=%5i?A9g`*b6e`DSZS9yM$){5J$GVtImE=Y$$2qWe7$x~MD#vRD z?U*LX6Q~@o?X)97l24~{fBvRR@)=a_&)*D5ei4<=*VU7YB>7A#$9aNw%#`F8Q#sCO zwBuq)o=D}pbumelch-e=e5f=~TYomwvh=&!F;bpFBg7o2eZ4V6?+5$t_eK ztBZ+6l4nZtOi7+4;U$!x<%9nE(%LnhL&<;(mBSNz2`TqKnE$Ppp@~3Qj%XO$*olGuWwdKo-g47%J-LNfg~@K za1rI>y)4>MB*}{XC{j^E)5-PXp>PU$sw^O;l{@EpYsf1Tk{&hZmt0nmwDnH

b|26j0(cc# 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%0ArlG`$RA6x)sq1Ux!NCmz_ zy3%+Xw3xPCD?#gKJM|e4_R>6F-Y=kz$+V7g9p3CzmXktwcXkBcotcD(r{px}LFf6- zqo8Aoq~rSRbf%*mbUX<<7Qq=3@Fs&`dSG1Em<^{m;60>iZ?rT`mGte6H%;`}gn7!4 z!uNda@ROwQt3Q@qQ=y$Kg*2o|I^HvCNX~X!$iLkkdU*SNp|`gGE|j|?yVt+N-TUy4 z`+B3h^~#vQt>BxlX;-%V9I0&|4yJg)rZt;~h-Tg;IK^81*8Oo?7-U7V|gV zEPvH|X)9a;?|{j{1)WnbOnO)!C+>3MlUW-`!_}!G8B}tZ!HgtTZgI1#eF0@27b!5bL1DX?Z7!Si!o%m6mrh zi1iq;{q+rt4Q9JEJ!#N~qRw+fo$oC#Qgw=X(VQ0Bf}@s2Fbi9hfh%DbP7V^=q(KXH zQwBBa;=3!HtprzoT>eh_Ubm5rR&zRS_@%%uyZ+AbUA^zTYiKdq4S#pRTR50ilAJ9z zPs+QsmO|U+E-ZU^51GH}6hABH&Y@CL@lGZ%OUakv4O7lh-6wgNkH&l~l(PgvA!iAM z(hMIf^MNlU=-b!~n2An>HGs?kT&vnWR7Nre@l8z`u?{9vH+j%XU82uak9T%KT9dQ| zSJ#n)SJP*1s`Kt|$*ILy5}Vr8oVhQO!FhxDrY^~vIeTWtosct3XJ(w~z6;hBPyCr= z)`I<(kiuh0w$jqJV1LkJOCBnng!Z=>_75Dju=i~DZLwDOdk90n12jm>s`z7Y^9*i2 zdmE?g(Jg6NkPeniXO@&158ZC_zIl6_mw!n?j0@T$%sVpRyd;=;Owym!zRGz<`-OGY z4?8MnGrZ>gU2S^Jnx)UI_MSKR#0R^2EHCCbErTe@4nM zpEH>9-pPtas3S$4`>J3L1c3_X?26z>{>1|7U>=sMB{|At6E{M$;ltPCde|iA6;4QOe-VvKj_d3sU|Wy2I==FYWNHDMb22*}3+w%XBRA1m!#u3}=~(yI zyx-`a!E4v?nTMdheP~(Bzv4(h;Rop{%f_&8P7t!z@sLlHUv`l{GoFhm#&6ccHdj&ZMu;f-}y3V}th? zyU+*62vey({rQQ{EBV5JBJ+PrmAxXifeCz zdnepaA1J8(0o<>I`^f`~Yb`tO9IA!;l!4sZO1Q6s`wLFxGA*+Q{7lD;frpufsRM7Z z@RJ5|S?J^eKMQL)MHU91et7d>;HIjyfn<2E3f~!!N9f8Sj6oK@^TwUf&KG?ao)pAS zpVKfNS@`d7+z!tZcsqYIcgssd{g8%9zghEsRtVSMg0y$Bz!mbq(sIo7dbxz z<1;psXMN_%B0eVObwnA5(RIO>hECHjJ`TedAGz?o$7%b)mC1wJ6}g>_G_5#-(&w1C zu1AjZ`E3rZ7r$h)V_eVR_elqJ+2UhZHWs$VK^Fh+6tUsF63d8O^b#8}rZ}yG{F}yz zAIW=vAoz6Q6Pk0fQ~Tgx+b`ZCjuUU4>mas5Jiiadu=|`2NDaA~F8Nkzb~cSkA1lLphCA{d+7x&`%?x!x1Q4S(@rJj!xyLd$@Gg;EO#sDulVp-_9A9scw&78o*mg2FuNol z```_;S>}Vi$KJI~!*5B*V679MkT^4+MzHKI_M{(b^GrUp8}pd`%+RvTXNE4zbbG%G zbF9o$--Carz`s@qZH3SqY3Q{OdKnG9$!isC&F7iqIKFk@eKgt`d&-$dEsK)}V0Fiq z`LqS!032WQ{?Y6BY=G8nd^=`@)B9wcpOS@o3n2DXV`M^(Zk>lCjt>X8Y`P)acofDb zm6o@kvD9|r-C8IQd`o<2C7w6=_5eQZ^|r3BZ$-WWhMK$}sZOsa;+nbM4??@5ZJ5;~ zHjBU(9ee_3fs37kTaG~QccC*ycuUj2Ig>ph^tO*}kYrm2EpJy64c3}>by{()du83c zd#c_az&RA;9L5Q_@-`1fAhv@z7EB#T{a{y{W$psjhMxIgS9{TU6);o8Z=@jI1(x4j zb{^EMi_kAKbKlB}xzE9qBL`Rh_mPGR5&D(`XSm{9j+frDz_*EoQ_pLXAsYqn>gii4ErEj z&F+CS7WH^M?8L0=wQu5-OJCUEF>%V}#3`3?oCY{?%H<}1xU;XlAnF!m(N8Qh zhK3WTTo&iCIq=7@6g_`35&P^7dsd0%F>%Tz913UDR5TSF%{g((rE%=wFw@|MpdCG- z?oqUn5k=ys0=$3|uQ}kxJ=olyEeW2yz+vFMJ)SMT5pM80tP|)B_k`S=M!2;r*9wPI zCMMexr(BM7L5818nV9n6+W11q#3`5luq)&X_TWLJA9Fl3amrrC`P0AhOCVNRoxY?hn$fNxZf`15p+X6oVam{C^Wm5|C@;Aw|u*zRf% zv!hXYU83I;jAj-lPPv>oo-L$`2Q*^<1% z;!!Y^p2vhLre{(nUZZgg+z3CPP)b!lL31?fi>^7b2F5R)6J=V|HF3%%ZN^^q-Y`-( zsBw(*C=+UOLu;bvTymNdJnPbxCv>1Ms2mkjB>MS6)611koN@`zCD|eqr(A~pZgHNb zn@2zBFTqckD5?v3y?*#XLEQ*G1y%Y#b_^x|)~Pq>9}V>rr(8xiyS_}xj)oi!!%GoN zoO0Yk53cqaa?&}Ks+joS0E>EXB1j{yg?IFLf!{zn6$M2L&`KPZQ`g>zS+Q1#{ zqa5+1L4GZQo5~qC?1m#8$0Y9AJYsP1h^WdLJ9j7FnzU!E;unw7ycXhDj+dl>e$~QF)r{@Ct+%G_N!^>WFZs5l z{j?@-cFn-L*#>{3-4BWB=`>4ESI?NGN9-5pjFAn*`d9&Rj&*ww^SpYD@+>|J@R>K> z&;70AV0Y05rT+jnz*Ba|y6%Z}zj2)7$MNTQ=6|Dx@n1it<8RUa72^=U*an`b_P>62 z%B{(JlJ?>ZWNe;6Vj3QWILD(e64PLVjE_ee#OHu@jBGE~zcaM_$96m}#@|2A@wbd~ z{8i%+zc~I|o`m&2v^)LQNqek&)Aps_ma;$j(@D2mu1>FDZv$D?9>m<8={ ztoviJA9#b{8!D`u{-V7)IBMCllLXvM&I&<)VnuWmecfHzdQBTls(CNllI|CZyWfHc6}7<#CXhSMH}GweLS8GVj7l@QyRo_ zsDd;It{6U?V9zo8X*}FC%*v3h%-$~iyCLzE-mdQE$wD4?G`O< zx0ZIRmbOPrixsD6_ni>uc$a4e9{D^yk2^Z*a!EPZ}>s7d^nz42GJ23EXgTK*Ei&!4G-aD4%A@H0a}pNE$Z$A5Ftzr7W7k4#ThC z<8X&v$>iO?{i}cpu@D(+ek!Mi(>xMi- zkx!xWupytK$fr_yry-xJ$fr?xjUk_=$TO)Nzh={~OhrDO%5gPNzot_;KGitJ^2V=& zIhN}~77gFR#UxA7KZDBgt5*G*p~z=a`SV;%W-9V?sJ!2hpQFfUQ8|7+s9&=b`MFen zEf75Qu`kJQiEiu^n($FI}%>pVq1hsw8dF`1*t=TdovA)l+r=TZ4;Lq1QDpHJoZ zHK2Z-ugK?9d4P+_d_{f%m7g}`7btQYl}F0krpU9Ye7g}oTahnN@P!JtEBGR+Z-t@n zB1OKC$|LqzsK_s-a(v?J*TsrFhsq=6oukNesT@~c^eb19FQW3_b1_+@$S+a!U!uqt zQ+cGnTCB+Ps63MXJVl~l=IX)Tmt4NU-Q+Z_6U#!SW zl=w>&c`22barLBBkuRb0HbcHdk(W_9jw1A{Op!08@{L?fmMZdcDv#K=T#+xM@<{z# zrpT95dE|MqT#;W&<&pYxsUlyYgkPb^FH_`~De}vyJd(c475OKW_&=e@E2w;yVV?>` zUPA<(ZXMP5zixLT)Q)r!1E!4Ar=;&kFrzr2L%*f2AU?Rd5~U zN6M>CkzYaOiwu2NDDqVbuBZIS_@-WwHz;_ug4fXSUgLSUhRQb!7@w#3Yajj6x zNW+5VO;rA<5xz;0H!HY>@+0Gm7Dc{J!Rr;gLBSgpe5Hb~qVZ)K z>AQ-`XA2nZ^Q?g7@y69O{24=jwW7b3$|L=6t0KRK$|EzVYZUpl3U(>DO~G!e?`9)C zZbjZs<+#GEU+s$AqhK%P<4Ul8c@?>j$|LpJr^q`LyovH7t`%8%H`ugEtm zc#DF&$giRN@OmeikR;ew;v~bV;Fm;#A{j9hgmcLW2`?fKOZXD9SHg=)uY~i+Itk~K%OqSt3M5=eY!WUaA4WPqDF0&eD+!m7 zpGdfrJTBoS7%`Rh5N{hG*|5^g3hOSpynM8fOH5ecs+ zcT0E!xmm&+NvDLbByAGDiquH>YO++qt;80){glb0p@W%7LqhsjqZd@tE2;jfTx3HOsG3ExMS zO89;lMRS6#<`y_mn1SGtbG)wp~QZC_dk@F?|IMF2h1bJhs zn7(h5lM?<8IV#~N$=wn@Mm{Ow?~*nNe~&mNyp3EU;ipKZgr6oKOcB%bee$Y=kCWpP zK0zLk@DIps68<3xNcdk!vxJ`^0k~cHN^!=E;AmN{o$0Yn5`GSO> zCp#tlQ{tBJN#d073*-_B|BPfx_~+z9{Dhlb7P5o9CgD@$goFpk*ChNR*)QQ=kRA!Y zL|P>LOR`MDzasM`{A-dV;g`vqk;MUMkFSuQN%(s5EeXF$4oUbm@+k?QCLRfYlGI6f zCn=Edr^q=HzJdJrByKJ2k8dQum+*DuClcO8zA53G$ej|tnOra7TS%LPcN3?CZzYQ* zyoY2-crO{Uis{=&ekY3lj6ywpW)Xj&LDdj4pTgZ1Q_n5cq(aTxQ60sq>N#FN1>5S zlF2Z>bI{0i@)pczFuoSb&m!Mp*hcv?$juBtPvtX7GsFE9pFSMTiszDahF4QOkDP(|2kLu|;`7PR7!FW8 zpM0C)(-dDozREDJk!i$64l=x*;%xFY7%!qe@CNxRa)9ANit9<2gd0e`gjbVthH=eF zBWuVd4DX@g8_7YKkDz`%eQU{o!}tyHqg38R{)1tB)2xwZ@+!l6dA5+}8Lp-Lb>uOI zaT>0HRSz+Yk4cSeAiEj1QoNCDW*CwM@+(O$OV6_uUqzfueumaA&HisFkD5kgIvP!gA_Z-Oon$-ypntX5o7xF@U`SMhV}f`ksmUQ?JrBa zf;T4=eby3cg9fAq9ICyivhdD0rEIFIMne1*a+a zy%afrzf0fN7naX26?{y=4=MN_1>dgV zn-uI<@M;CGP_SLW$qGJgd^>^di;(Xs_#OpsSFlgPs}x+M;PVvxKM*IsF#dm6@Xr+d zxPlKU_$CE+DR_f|s}x+I;8_YzQt%(KGh!E}{}l!Qi-Nzc;71hvB?a$R@OA}nQSg-t zUZY@#f-h0djWLkhlK!MhdQr(mCg zHz>G9!37GwNWnO+;uq#0pQHT3=Zj!IvH&nXH`8-8vH)G1M#q)uxf=bZPFrFjQ_(*| zBW37btPvbHrBBfacAFRu^`pNH-9?db_?SaEJpQRXpULsLk9w&;=(QoKLclGpf^vW^N@7l;rLX0)&gI6=sdJr`h^;4M|YD(pU>&5 zG<}}JKrSg8fx*DNHAF6Tjb z)Te#N0&fn${jP;<2N(6;jPB(cIe_lD8o3|cPK`Xp+?Ua9*JwJ^-5U82@$*m)P$4iq z^U!?=(vL3a#qn7B)fzd3F6e&%-ODucZFD;{g5#TXyPp4aD33FUk3%^@c(nUf=z25~ zLKp0RJ-T53{pf-n???Aq(1&hFBR@npsF9b^?a}Bre%j-ZUk%dpEyyprM<8A3p0tog zbdTxfj_E_YY2UPvjp#zSR&+s5>lN6w9McEsMY|bxhIAt@9U{l^Te?FdThU#nkv+`4 z6Wy7bp8u;f@(5zc-}C4~IpsilwQpF+Vss&$h3I}=FQ4=k8tFhDyu zmmBKCc(f-h`aBx+;QR*l+>9>Rh1MIe2hA^(BdzC<&(~27`Ao)gfrnETx=<)sU(%}~ z9q3kS`)t3UFz=K^N*pJ-X1Y8qtM* zU@_+N6Re+u`qTzkdrWV)*giTDLpVF~pnl?f1nVoUZ%`j;eFM9;ArH#ShH@zPM#M*1 z{e*f+`5@0hIp`@z7vfuuF6i5id@$NhbV1)PbRquT=tBJSz(u_k%)f^D(|CYK+X3)y zK;CB7e?dEcA9;|^A#|age}pcybEwm9d{Z1L{cb?Sy7v$0OLOKgkFQoGdbX!@y zYhd-}9fOPCc z|BIkJ(f?8nzAOcIA!`RGn7zTZqCd2YEOg=dumD}ChqQd*IZ=uj>ct9h@p(~!E~Jy{ zg>dwF2H_SW55m#(LA^pgK4)mUAUw4Z2G0OF(i!KL*9;#-e$h_4M?)Z;~$#|L`mpd9qje1aaDUI?$Ix1NQk>4xw$pU`e- zKEeGQ>H&QZFny1r3;Lcy7xevvxi6v%>7xBVr0Wb|OxHW;f?jIJv*i!$dA9sfJ3_kV zVSLcpqaD+Kz}o3rR({+Lao9Z_!vil1UC0;J3;9@t81jep0`r08fcY2^zlD`c6D#NI z*tlvw>tDd7?Psz6yvO)9V!Xd%{Rp%RYDY-#OiUl7m*yYRyO^c3kfoFIz&?}*oh!{3 z*a!KjH>w>6hTCx}#sl&3`cLBnyX2!k#7pf0_F2L7()!-a>N~_w>)`@cpJ5z{_QdvE zfi9$n<`?oo>oe$U1Ak1P7hTY++MBj-h@ZC)%rB;o_PY?imW8Wldern&JFI5y9_mpe zhK~|2%?IeEc7pWLd;pKy57LG4V>+pR=pSghKp&O^uQ&MoRpm6j;7{utgrn^f!qIjP z^}hzg#|USpPxU`rI;40Yel`3eOb3)#F}g7Br*?q!+7JVu$|0S}h@n1XeM5WD@&X>U z7w~950($b12YP5Zf&Xm8b<97k>Emq}#L;mJ^b=Pxxfk6EHcpz&#$nLE(B~M`qtBrn z!W~BU1ga^y{$mEi1l-28tos`i#7V(O)u97JgTT1h7KfsDU7F?dxrTBp<4>`EKPU8B$N+L zjHE9C`=Sf_YS1l#aR|6t7UUD%On6?PJ00?i?zG4}jHVazP0JhXPwfkKru_%_^XCDz z3*?991M)+8;L>tf$>tZpr|k^%Q2W4hnbt>e%P{}oUe4SQb8ki$5`RC#k1>3L;Xk1J z3Y0JAAKZL&A$>F+h>w;txU_zK)uQ(+1*{(BvwVU-&1WIwfj`X;)DPOf{enHOpJVmd z$Ljsh**N0+Y+M3Hr0I9DdBf8d(vIothItLTT^b#ir2~)J1$YmjKVX_Kz&`jY!1FV)eh-hvH@Nh<0O4zp2l{S67y84enEO1spzlR=LC@>pq8?uUv>YMdi%<^vr0HA7(g!ZJ z)6ZDB_D0H;_Cw%L?EvFbYS#ec!?@Ij`eteRIRBtUPyb>z?uSJ%nxB6sx_mjqc}xzA zSXBNiCU0bTCX-*y@Hq^3Fr3Zsbqv46!o%c=>RZI*dl~)(lYg4wUow1vVK7=J+Uqk6 zL*=9Rc82FMeV=7`F2i>)42_QRKgaOzS@_R0{BI23$?y!uzl-7DG5OsLU&!QNVEA8| z{1C%~4Bx}>ZyEj~!?RfU!wkR7j^HHPnH_&mn{3d655c|XG!F!_B9FJSn7hEFs8 zQifk)xSU~FOr-W%#_(?#zLa5DT%__93`6Cm_%enIS$vl>44oa7e}dsR8LnXXBF3*| zcp<}83>Pq5&G27X_!@@KXL2XQ(3#TsRx0cEUwb30cnx1tG&t`Z%!~ezj z8yNmG!y6gCnDMV<_^(WU6~hAzw=!&F{A(DV&+xSj+ZlE-JcZ#lhBFy8)Y#MO5Bqxpj1cyFwzT-WeLa0)!H3=U z?g)4~Lp=fi^;}9Y=?tr(; zSBEIn7v#C?lzo-7>(Z6JfG_0t)cAXY7%$Vi34NisHZ)e&ITXL9=GBH@haXJlXmA9e zK44{_3G{6bhuofUWp8hfM@qTZ7t@%Yp5PA1w9n~fiab4mt-esW+2am0`Fi0f<%mC8 z1*%SyFC5w-o6pm}p~2M~?g>`+bO*b9VV_u-Oy~}U&80?c!vcnU9-n`!Z+IP{YM~&V zZhu!_Xn2g9eBlcAUN>6K59ap{lSV|kW!KSG6@xZh6kHdK z;tAEe$=BVpHCmiO5JCls#2r06EpU@$ql!weH>&oUo^1g|V}0dnT80sG={`_!ikB~3 z4HY@y>#B!Vs>*nKR{WuaWuMs9vV8+a&N+JNN1CzHs-P+$TWqA& zD!$cc%7BUj4Fns4oSCz=GChGTC^YcK=2fx+E^;(R^FL0K32L19LVo{5G>vo7rKas}ZSbzhC62|99Fqa>|{ZX=2qvWicJ#tk*H5Yhri zw6~~<)V<-~XzbNJH6bXTP&An?!CVLZflaX(V1u(WeBKRif7sa*!k)0EC!p9@PbQBO zG#Y$pw5)6*k6BhI=7Fm9O2vEEv!veVZK$he{T@r@$BQ)*d{{q@4Jk@GBO%V3wn$QZ z#zRG~|55bvj0ZNModfZdOC(5TU$_&-6?8Ci)*|Z(i5fSYKCNxw^$A zjp!7~u*ZQAF4CL&yphh`h+ANK^!5>zR=KXF*0H(;lG3uKNll9?9F`oJ;D#F26QTp& z-W}a^j15uuhG7^D9g?S~yPJ+<+k0W$W2gbwl?-`gMl#!8+yFHIvkf4vraLJT$dD6 z8bs^y2Rk8fAEdLccfGsI?}ZMov3E;l5QTIQ=i?TV2Ww1hR0CDo-skV~R#WwKP(bSa z?RI;U@47x;Z`f`JTXp%{NuaN*tHJFd-M(&5caV76U8`Hx)E1S&-G-LB21k>N4eoK| z7V-4=HudR!gTeFTgWW*Tb$EPT5$x`Ory{}z7tV0lU9*n{0l$^}4#%vzv=<+Z>{g$k z(BM$D#lZmc<2GV^9NSQdVIB_kL^c@Bin5d;2=^O4^w1?nvNsvYhK6Gd4E3nIVCGQI z4jp)4z6aHh1~+OnPK_FScpjDDY`CC@(1!^uID#6Vp+)e;-dArc5DXt1&`pR_#)vPk z?HHI5{k_eR*`-$yfN|)sUGQqIhk;<1&kbXohyw6*d#>yAheXf1<|chshK1i!*|gHp z;(~GooiLZ_>Dr21=FQU-EeP<@T27ovH)CgDgz5*WDFXE$L4X4%EmSI`fy%ON@OM{`?H2FJPX9ik2OaS8MT`Fx4_dN z9O{CRGmrqFq42h0ovRm0wWkB7)H^Gy)xObHYlT^Yg?+_ zL3g{q3zk=4RxYSlFdWB}Ul(v)xWhdXK4 zt4B=*G?j|L?bSomr5b2h(8K8yK~KBx#VoD^Fg9JI*Z|sbtkKuIp~nf005T{OA|85A zB85xQ8cHBm{C+4pdUFWl_& z^udr|huSI>Rlaaz!>VZEqqRIaY}7_2Q)p?rTy7uKO&2_Oak+sA*c04Qs$dCrg-S_d zWlM{rX|=0mRb8V2YFp|89X%oFm(W^Rk;$5Mb*=`#C)Cs1!;mBB-vqrVXoMw9*QQX= zC9YE1mzA4JmY7P4%_QZ^OeJNek`hx%p{c}7uym=Z1Z^DE1WSv|BxR zm>Oq^sd1K=8fS^AaZHm|YHFNPQ{$AH8mGk6I3=bjC@D70X-TnZR!fRa^IBqR?UEwX z+?EuXX1AosJimqJ87?%>aiM7nib}BA6 zwNvp@Q#%zeHMLXmQgb_%nJ2!?+)icYb}BQslexYn=5|_QZl@*Yb}BWuQ>nR~O3m$5 zVs57r^L&+<+o{CdPUeA%&FxfdZl_{%I~AGRsmR<;Mdo%YG`CZsxt$8lvs`FyCsRq$ zGE+MhEi<)K(K1sz6_uOXsi@r4PDSOWb}CwGYNw*5rgkb?YHFvVrRLT!H%3_uk-449 z%&Fy5K;}UZ_mBa{TZl_{%I~AMTso303Mdo&b z1t^ozSy7R>or=uuWS*@;b2}B9+o`aKT<;6@G*niTZC$X~RE4W;mBt4Fc6&>0gR8E& za%-vGVQ;k8*jL%B?9KM2jt2XBXQRKw?%3E;Q&fha8UAUgv^P5JmCNgki`Uhc7Okr< zF0yZ2USCvXZw8-c@M#90I)}pn|8B6aYj!lRFSFm!+_I{ARgDgp0<5jKuW4?qtajKP zRh8xTCdb-xdt;NMx!mrktg72u3~P$fmPF0JNibh8#Z^51s=}X7*Yy1P;$jmZIytovG%D?R3po@`pnmO>lhK3zL@mqE1xMC9=PPAf1&_h>gNgm zeBsjs0H&WM`1AF*o#2{$ju3qX+3fQKWaH-y>Zb|*eEGA42-a6X{Q0;XA$*SD&yVsc zf*)pme8Fv)Erm}I^c8IR^8?*)M62HN%e6>7ieot()`!)lZdilFj~!sSIJ(5BMbX8u zSge0o!7CZn7v(btw&WgJ7?T1ROU+SZ;j5_d@dHyMeE7h8q;)h&cVroD_y-RxaD*a< zG(L3TJX}APK5`HR(jtqZ2*O2{SE9%wA2t{oBOf(TFI;M-3;Y7YMg9ns7xx8!V}U>7 zhl~6MGOx_~3OAR>=pWcpHgCop;(HAv8Yo8b?Stq){B40Dg@X0yRX(CAR{PVF%!0sT z9DbZ&DC6GnVS?&MzZOtEBa6WiK6|@hP~{I1RBu_W^oap35E^tzLO(u`MZ$*%h5$Ps z{i6fL3j`6(I?MRjK%w%N{_H~o6Dd?Qe7kHeH9iMX9Ydr=rG?yDp$itzjVc(Snx+R)y4U+G>}}4FQc~SHI(Le1WAg4Na~cdhDlm_ z>U2w%Hd8y-GTU;VWsYU8Wu9ez>H>@1g4?sg+B31>zE4^3tMN%0bf9I1U zgw@#nm9Rf2YUR9ExJNF(lG#nU!aE55GdT%du5YfwdjMo@0*~u^KV6O&K3$I*@AC=| ze)>TwqUd{6;lU^9^fz#v%H#cxfI?zCi-w+QVRwliWJ@v;K9!_jEl!RL*X4ximvZ3u%D3B#cy^3{T|9lCQFvCUU@g3o0GIRH6<(_~dVRrtQpJ2c1-#NI@%|b7Mcz9Q4t_>t zTs+cM5(O*TqTTa$cFjTLBH+8-@25XzyY^ z`hkaSlV4ol35E9&@b+;MxSaQCg||DC(BEuxD(79T@J<46BPR*^mMJ_t?zen&@Lp4R+ky9f6dvx=Czfy5xzXeOqQZL#cok9f-K_9tLgySUzikSy0(dK; z=&Mn9J56}S3hznawMEf)fx?>&`-YZA;k^q5E!w3XcsWscFDSe)@G7G4zNhdWH{pF% z;k^&MX!T&P!o&St8>7S8L&{|J4%SRS+IMb~#q;cYbGeNW*X0$#Ly^eep6z>Ai?9SW}y_T#lhvCGv8uMv3B z;&mvzJAt<%ioODccM5p$XfQ4?FTHkW$o3lqo@THj_cIlJuLG}M;BkGpf0S4rh4Tq{ zP~dUhuPMBjfwx=WaeY1|eXSQn(u8!b?`cI}8}KTk=<8Q_{lJUX&TEx;UjiO95#!?V z-lFJx2YBTMEAl+gQS{~5#B+Be`LHUyjV8P;O1%4k*U1wF@pJoKrSRTaKc;5$}*giP#ePw?1GvHYbZIN<=Ed!){{0eyRXf-ab z4}R(@@y-D6q``{V4}Rh-@t(Xm`uM6*;XMQoqiFpB{N!HJ_d4(vM~QcV!pqE++d0n% z{4`tA*9yEvfFV@FVF%(o5$?|`6>*Q-|*UJgXMJqizg>MZH&S9m;q z-&1(AFClb~N3N2``xS+U#*5Z(>{EE9z`K?!1DD6URpH$UJow+Zc)VK_-U%Q@tIt;| zyg?Iv$CUEO$Rl(w4<0d3ANFBldE^7HiIc$PyayG1yMT9j6yDv8$3-WA$McAO{QeH$ zVf%u|4ZWTL9-hU-FMhjE(TBV)q2goO@%j|w@$?pMj?^)fa~?D=;~xFXfVUHG*k#6h z40yXZ30yN?@fP{{X2$zA@Z!-|)^xz>7!U z!k+ke55~z`7>uuc?+4yNZe(!H>|A_Ze7qk5FC2%yvQT{a{WkF8(YL5KzVi4c@Zu?t ze28>+9Qk+*c=6~f?u(E2Se(3K=wRcC_pvy6#oOY`@3-UREr*9zJofuO@Zu@o;vI43 zH%?yh^>ONplUMx7INJyC;wiT(=$zxR-?PArN1yXk@$sIGljpoaUe`10H+}}Zc+$7} z#`t(Yi<7q+B8|s>FUHARe^Y$<{Vnj~$?vr{$H)6E@Nmq&2s}_}TxRiJzb8I@{{_5w^xd#GKAr}djYr=e;O#PUVQ#KVCemcH!#D3t#li&0M@$vQpFP?G9oX^Bp9`^z-p7hPXJwAQ+ z$H`mx+4$mp5P0!C2j_rM;;Dc4#>rc7M||<#4ZL{lH|ulprSFSz^5%a&K7IGc$y<15 zeD(gDz>CMu#dpQmKE4UOc-mXp-SWDCS^xJ#;Keh4yZj6BmD~5@KsVtjV_74V>oF)lMZw|^%dP4vBCXs;1AbOkY|OzQib;@@X#N5xOT&N=PJC%frs%R4>_FoPP!cLGr+Sk z9=w_}c+V=l*9BgxzX1F5qov`eq2cKS3b^ z)wo^<9#7v)frsCxh`bdi_4f-{zUK(M&nmp#z=Lf`X+4-F@VpA|&KDwfK3CusE4-%! z9@?AR@6S+a#q_-nJR8U{edh_hrxafD&-C|E$eSbZ_A0y;z{B{EH&@_oP-Fg zczAB3Xup?$$IIhlfrsCDiM)@1SIhJvpVz-XK_@KoYEDJs%@ugRR(QLC$IESzzIGh&z-v`_Vc->l9P53)z^hPr4+y*hftRoFUIJbt z(}#Mw{qWpL(SG(9Bl##2cz=WdBCj5JHm0vw;611Cx&(bC0`EHt?@r+H{FVy5uPD4{ zfXDN(MBv?`@MiuZQV+@mUQpq+0FT$_r2_9-g?9jWyq+Q-#I#+lRCtdA&jvCqw`K6h zd5aa^OTe4Wc*_M|hQd1|=(|+ly#<3Au{<(fis)M*@J=c`yTH3l;C)BotpJ`4r;4P;8~fz3W2vl;q4UStrU2b3h%HGZ1iXHbqg~bry!8q%{HsVkz;?&$GaPLq+2u~)aXYUScyJ_=#CrgE z+|Eq`Z<4}03A|2_WBQr}-Uk+0U+J$S`dS3u?-X7u@VK4V3A`UEyfE;1KGqAoe^Pk6 zfye9f27w1#cuV;`An3bN;KA1967MkZc)hwx;K7#k67PNB*+7nVxmw`CR{auh=F5@% zwhFu@3U4v+cz&-Dc(4V&q;CcA3PFzXUMuh>DZDNrUYEc-1NUM(+6_Ej58MI|ie2J8 z3cL#N!+6`_kJrEF;9k^s26#Ll9)b5Ah4&Hg%E1ryc?BLU14#NxUx}2jPvGrVcq@R% zR-Wh?nCkF2$fwwmXFXOdH{o5CVH&5W*7K67~ z;O&pWTOsg19fMad@D9Y_wFk@e1jKSL}@cual?|{HN5`%YG;2n*@dsN^(7K8Vc!24DV-bsP? zcnscYf%ilV-Wh@S?HIg|1Rl;2%%1xhzm3$tCu8vD3A|%5c#8$zcVqBY2)ysb;MEJf zr(*D01>Vy!cwGYT`!RSs1>W%(yaNL7L=4_xf%k(LyhjDz4`cA25_ta-gLhKkJrjd> zTHyUC2Jei(do~8|BZ2qh7`%*sjnu!N#Nf>nc+bV)Ef#ps$Kb6Hct4H7s~31DWAIu9 z9=swlZEsxy4_>X9@^%WmpU2=G5O}9z@D2;Sff&3;1>TD>cuxtuU&P>@6nHPi;GGtD zzl^~x9qf4#MxjGB}ES*Eb!!L|*0}3AyZo;XI4Z3vx*VoY{CS2jHR{FSdb)E4(A< z>&@>eC@NiAzNDmVY56jntYWw~*MvHA485p( z-%9+Kq?A%82j2f?5sR}t_o`FppH9zhIF)wV|Kh*CX?dr!vZ}hq;api;my=t2%6fWo zZpEpL+)tdEl6(0nd+vsT%LW(cUUsT5cg3mF+{S_BgS&F8Pi399yaRT~sU6stIjwwp zP7P=x?-UkQv#YqIbP42w+>=`j8h7Vja%x}hqEiQQb5Grsn?G>z;FohRK6PL2!c$+% zy?DSrNRCJU&teO%j4mU@g^ak4QO2c-Y)OMQ$+pQdC zyY&Mrz;-LZc9(+f)(k8I+f^C1Tghx!P2(;otYTM@ZalDE5w+bSuw5?LE(dIvH?Rfw3Wk6aPZCC9tcEO+RtMR%FYe z+uqp9igIl&Jw08^ZE$9b$78#?)LXK|?Y)NRFfY%uY?&=DuQvz>9l&8b^hCg3Tb>8} zHU;`@c|9Z87pH1nU42a}oV5_{ZCzJYzhFV?P zMmPE0?LM!IZcDT&ztfgix4_oApn7@1Djyv9wslDXSR4PUt6N!WS{Ez;7BFzvqXNF` z5#GSAM+Il!^=L$a3ox~LJy6j`kOHoxz|-C9Pmn5ak0()@^qry-lS3b#x0;}Y>ADK= zD5pNCpou7e4mh6(&g@K30=c#Vr=zlEU6aFAzoD)%u?dw_7j$j&2lHt2?QnY%Y?4?p z(TK+`V|qS)VeB3L{&sJ)x~RpZ*wToyz#a08Tf7DAjHu?8hVja}kObkjq}W;dkC!5z zz+sQ%Lz_zU1@<*nnHh=31H6CL*i6a<4XZ5jLShSkCXY6VP0L9nL_ z4x{ev8jsYBMp<;=8Iw2(O!Sj0qPSoa9F_-%1i14&U4FPpu<6Vr8o!A34R%K_qkXVT z`;JjoUoa+_C>ZUm;A+k&S_;*VzNKg^eWQ>ST-FG8CA#f1tp$Eq_k%5?LkYIOp+1o4 zF{q%KP8&zhG{G)+7*DSpCDU;A1@HtL?I;pI72w5?c+CNKprv91OXDL>hFniw%`G(v zt*g8gpn3_nSPeKFRz3y2-UK}YM_?RCL%}vUTHfXBb|+|*a`x0DqGBXsW~A#VfNwT@ z-R-V+c$Yo$VM%nII0nSmxg)D{Cb~z@6l_*i&>rxOaP22%(&1(7C>o{!&ej=a^08)!7MfDJOx(KDJ+Y;uQ3I53Z0g*rVWd@B)KeOIx^J*rKh+Z}*O#t5hBvGafn z0i#*OsJ~!CeNp+CL{iY)Sdw2dc2SM+70lU-hMJD%sw}@~H1pN#O;}CtcKZ|7F@?e- zUDA)(7OsPhrx{Pqz9aVRNN58b$=&4Suf$=EDL{&M| zRe(oILKF0R+^~o^dYTj6Acvb zK5Hg0mXak2j)i{ToY3a3AFew(6`ZD)tA^z|f5K+SdRJd>pDos>SuSc9vn}p#9 zXbCDqJa>JBgUke^hN>u_zp!%!Lp>ev`@0e5FX|7jY`j`elb4ws{$vKo-fRoUF^ zXlijaG_M30`CS9PohpGJ@^OB1W8G!2@KhuIgob*!Tn$wY&_jV59tR>^X?@))2jxbT zHo|-Gy47pewTOYm*VQ$syQRL_)m&Ry^05n8Zlq4^1|Yxq8e9a{f5dbF&WG@ zk$3;xwAGcX#r#t{aaL(0V1sbKZhc+znkLt})hsfaT2``9oOPA;R3r1LTixPlYFgI_ zwwAn$t3`;3=0(8+7FRddSFU$Z8d#NmwtxxYk+sy+t#LItnwu+EI+_{J*|^Tt*yLz- ztd4dKUYSux4N5bnhfQDoCX>!y%Dw`dVeAAcmMj=)l~LAmqI1d>k(8O zYIJ8MG___h5$X`Xh0xzI8&+(ri`bbZymEDA{hF0>i8XF$;3Xt!1MTpAg{z^mr4}*( z#go_F*A@1+?+E)`o=*548hqMAeqV>n>vwO$FRc9dtHiuO4@^q%hp;aAnM&B#?dtTo zy*^5ZAK!&TerR7K_=&9E@wc*{y|?PGsyJjn#`VCKz3;*A+8f^^2kS}JpUJdGODqmJRzSF`TZthZ^_{hIaDn)QHY{fuV4U9)~xgYyOSpF`7s z&%nQJ@MjihT7u%7Nn_Lhv4K-L(xGrV!PQ_RkuG#0!4yM6 zD4xMEB$Q&v0F}>X_#6n74?T81y!Q_I+wsG3k`MiD*xe3pC%+5%y7Ilg_P$Ln`Wp(8 z4<7z}Pdgo@Z1RPhV7k@o>ko^VxHpO0ck(7y?OF+=Yg{GLz`u5gg>7JsnLQA;0g1ctou ztlSg|xRvN`?x3|+Nfr8(|P)cT`oD+nXF~%k4NaE4Mo;tLnBE zM@skOR0Fl%8FeN~6@d!K>!RID>|rwMI(hB*j1^ zbxK;pBrQF4x+P1Sshw+?Z8^^}$1>M4&oV!CfyHi_1}dP!5K9`|WMS74*M<8GA{qM& zyh`Ek487C;;oW*UK#^wyU>A6}M-yI$;7{b$09Z^V`afLXE`=8a9`g9w$H)&j4$Hk0i2tEK;#Kv% z6Q@3JMf7-EAP$}fjP7ON9RUyM(v34_GT|P}a}xaVYhShg+{*wD43GB1=O8|xMBYK* zVR+=B+>F;R@G!g??})%lkHI@3@bG!e^{IPdodO>2VaG3CZt7lGchwMbmtZK)LpO;K zV@R`TrF@n==M@w$E3paJ+4jOJE-fw9cgH&WURc}L(bOAzVO5aJNbrdi=Tv8g4R?r2 zc9P@sj=hnc(T|86_q8o@W;+Y%?os`1|<|dr!Z-MC$em9HfInvM+|lNwz|7q z`kMuaCi978r>&E8RvgoJUHULPjfKm6dO>G@=k(5fD{WLWIsU;L!@~z5{1iwJId1Db z;kO;lhA_|jbDalQ2A{?>XE>+Ul1^LO6!^D|{@dS{(LdNmY&JK^cDwI$|IR)6zU=m# z&RzbTqq&_Ab?)~kznf{n@VpGsg>Kk*Q1%731bVgwXxjCdD~$B7GV-mbe=Ve+93Ofk zTE1CW|Lmif)3yG6D>I))d+7eVHtYU(Y?l2`F#iGSFXo?Y*7KjfS=5-tobG^-_vQn#eD4AqUU4(7BwFyw&*q) z*n&0@!w?oGeOQy5RSR$}U8+?Aist^wjsO8sjcstN@V>v;H9xF|lh`ah^Wc?9GFP8e?)b zyo)j4Oe?_!X&%wUu3i2>-nPG^!01j|3HhzWupU?_Ej^ZrUAyS&M9c<6_vTg*-lW1G9-;yYQ_ww}P^} zo8jHlJ+W)oS*IHnD40{O1e` zwGn@^&EUvpCXv#i+Ye3b+7&TF0bkLY*tLs)GpE!**Tk+}E?QqEcI}Gn2R163GDtg) zCAj0GJ7E|*U?r+Mm9>tFQH(T?ia`>(J+E$!iCw!~)DXtzR};H-DRWxcJks7^6T5c# zLcAN9*tLr;59zf<+7OIeD52fB{)G$M`fBtvPwd(i^;4qA6h$m=*z{v!*RF|OyVw>j z1rxh=1$#cmO2WjhUB33y#)aEmRL;0zw+0(zwZZ*p z#|^vn7*`?ORnFMCJNee6J!2LBc;;P<8|^Tbb|25U#WJrLhcXxApZ9+-{_!mP|EqD2 zcbywgyHDgDIvKc}@Hd{%w|pAE{%pteNS6~gD`FS!30W;*+zF}zFlIo%EJT)TRE`no zm!`;*6r4=?6`T$`CCU0ys64XwR*E7|RdAYutqPu`;B*B~rt#qbM8760@(d+C8H#+0 zf~P8Ynu0SGJe}kV_QpLZ=So;3uuYYr;&RkY$ban zJc)!QoK8Fvo=lo04EB)l6p}CDsbr3Xr;#)XXOa(ueXf#Vx60K5#yvH~JxeXH1LYh+ zZo%CuB|Mw_!4k2Lg`7uDN_Y-=Ou}=?AqmeTH%Rz=;+61xa)pF1AcYdPky#SXCLcwT z1Esrw{F{VllIJ9RA^B$s+sWM$K8F-SeZVNNP2!%L=QE6LFiX=&GQ&8)!96$s6YP!r z3W}4-ZyClmmZhbT=NQJ$I!j9>-;!_|`I3aKWFN!2{z+u3Bu^(khOtd$X_Lu1hV}R| zh(qE}A%zU<`lgb3l6)GOB*`<$U!c4(KYDtnlf7`yujwG$&H=cHH!1jP0cU}{LBW*@ z&Qow?e_G6+o)%8QJxp=mx%9P!?v26ko(JWRBwb3_~TN z7z%^xFJO2s!%(PHp3QI(!wVQLX7~bzOBl8>T*`0`!%G;>Ww?xCFba)-DZ>{tyo_Pk zSdYq=GmOR=!Je;8P6zBV4hP}&1dV-Q4L^4XHh5*5!!l2Qz(33nw&z?AyL-cKswx|f zCJKjocBtN-kPo+j750@i-%OUp8{XcGNyIHd1s_bH=+zVO4Wm&%mFV|u5d(&XX-6L= zP-uITuh$m_|8TDycx4n{e<17&h5CY00>M%ZJ>I@9U(1f5k3`?**2rKGUY&vF^)2r9 zE+3J+t91i<+SfF@AeNp`G01Bjm5r`$cUM=Bhog>=4@1^8tzYkGa=~7?)wQmoh(`nL zncpP9$}0eV?0sxY%z`W_G?kbMN|%~SOn1dCEiwyJV!HWmiRtdUCBlQ|&|S*DLf0S&cpoZwvHmmB z8y}l5$^K*Pef%Ii>Tvv%3V(RPBb98Vcltjt{G-=r;a`z=0B{AB=>KruSAZn)PJ$T6 zV*G+34ZZr{Uy=7F;5I7J|Ka-F07YIc037r1i}Ut_zsTDS0LM1`;_-$R-eD77tHOKS zgjc8VaDEUize^R~nr6AFTmTy69=wY`nFZY$NNj1ylvI- zrSH#i@_K6G)Au&;;>qt8M|}F;0A4)$HaX+d_iw<9N1tb9bbU`k8A4Szu0i0nr4RyJ zw$t{W3~na;-4B1b_c*^QVD1OgB61P@VI4r875+XAeF2hWG9 z?4t2f*8C*0uSqmnOzwE0mV1M^Of1ud;)9zg7p_PAmL)b?> zKmsx=J%D?#4@sN~Mbj0a2RWI1@A|+lg8{q2LtJ-s?_2rTH_9V>^#^wO`HuguW=~=} z{+H8q?Weo<7ap_N$U(oeEufz zgP@I{Wne$H=Kb{Rrm$4_I)u{OfbVmSSb133M_IU^_O7i+VVSbR3; zx*;10K0Ta^^+9KE%uY7gjv-qco_HYhjk6U3q&t)5irJNxINDV#hZ9{Q=lL#vegN7f zGh08!;lyK^Pv^ZgRE?TvIWKVjX2`b77O3d59((%Dp<7-UBD=6|Ug|7%4h+?t$aTWA z_4vCi7F*!NX6rG+>hJUPlmlKf!R}ikGW`^Qp*J+A_HGxkwpnaJct#gKaoZ6*5h4@L zf*=R+U(3O1@UM1oT7S|(VoN?qvQzFzy(8_8srOm$um$Kj1dy8jTaq6>xYEAB@64em zQA|2g2$qUmG0%nwR2XL@^kruowV|HbV`g^pyY&QXqQz!wJI~hER&48s^bWRp;e?7c z@6QUhxrwdcJ;^rc21dJPYiqaI`rCIyz1>II2ejR=c~U`?~jV+8|( zfW{;mSYUP6@K_gAG$tX58uMyNo2I5sT1}Hy^JpbaevNGtZEKr8lK!Ag+qA#**G*r< zrVq7h>EqY@&zYIKd+&uy>`xy3e|}y*d*^;<&OLMH%$b=pb1!!)_a3!k8=UG%{=&!K z>6#=YxMjU)IhE&rxHVDeD*oup@0|Yd#-0b?>56~-l;snYTi-zLiG?1g$M#9Gk3aP5 z?Kbn&X}4-$qD`S~AeTF%wzWdo)}K)tqcy^i*64~@Bk`vmWV#2p8aggzS$|r2?ju{( zmR@{%lC}8U9ZlJO#r4i6%2nH@@ZO@mXoV9!Q<(K8m^~+Y-W+rzKll7>>Kneq(Zipd%iTHt_uGrzB~Kr_h7Cnh6ib zlyRGd<3H2YJ6W%;t|C_2lcsXS{y+(D3b(pWPXZR6yQ4n5iFBy$4e|#a&!{b(i1dM# z=T1d>PSJ~rok8?n`PF7FG{nc3F#uY9#vyURKI zVtFQeOt{J0=o=ZEyy(xik8yUF_XR1syf271)aX~gaW{CU5;bMe*YC#KR4?xfa(Q2n zi~S7yFdaJU-`VB}>ed|iFI$)L9m7FiXaAQnzq~KVrG5qYqQ_RLbLm1jIE zU+l|rd0&v`$nGdv!64R0TeCOR-rhVOb<*nV2y7bRjHCNBj2h$d+n!@HzQl$v(|I!+ zn*(?;W+fbv@AeGpw4+s(HQJkL;H#QD$EFaYUX%`ek#zJbp6}Sfzhp7mxm?~C`AQUyzZQM_k?)fRS4(>7IZ>Ox3S zWp!=I`nrnI<*w$Y{m{xtSeIF82IqHqUl4co%97f;!AoKzQ}ge;{fJs6qqOq&zt8{j zz95(P1sSqojEG^3gufsC`knSm{g>8mhvqrbpH9@uJ0g=r6R|~fL#r=1Dr!-)Z5dVW zZKKWp^1dLK_XTNgd!OgYs;xKF4bghDF7FF+d0&unXFl8QByX{EH2cHL`-1!nU-OK% z+ROWbv^V3Y23nTnjI=j%d0&v>-b2z`;N^Wm8ZPe(;%&{+@7f_A6_3=YL9eeGa^O}t zq8UW?*cctIBi&0er9@;N;aL}FetBPz$o3uHU|>YeBEtCcz95(P1u=O+EIQJ%<|wwN zP+!AoZwj=HtV#0SH6r{++TwMacZ`PQ?QNSnTD*;;($Na#^X2E!5T0|sye|k>wBe!l z&@JKez96_YszV18r$A#?4w%ILc<obz8e4*Ao!nbhMkyco;PO0;!f%<>+; zO=3uvu`Ih*?_-^}R_`vMcgtSdng_pShQHD7bF^h&#Pa{YvoVqO8;6>L2WA`?T&1#FW#oFR*He0+c!Il`8WSeN~l5Ka&w!388-Lh?uY}+f_ z_Q|&4Hl?C(#;FHg*W+)r?Mth8_#j>a{gnl ze{G+qu=*dLK5x8zobj+dZTnw5PVJw@IrYHp9k35--xI&rwlD6U*!?m0TJN*mk3Eq) zrL{J}owB1aaZLI}vIX_njTeO}JNLxxjolY>k9EK0UM5e+I+SPU7|Ek;BUDcpGcJwP zW{KMVne1ge`{(h_Um54}bANbj=K@q_^}uaTuq|}z+XBYb<8QQm6$SH9kMWd4+a6Y- zKx5q=w0!~jY-(Si>P8K(iBqrWTd-%|Tdu+M^;JEV4cKD9Rs)WKWysGJ$s)#(9?Q~6 zK7Pa+(&Jb<>5m_AhIE_Zew!gZo~1{}j(9_Q0!vp^_K;vmPh{z|uELK*Lwb?{PcYz# z20Y1t?FKyAfRhb4g~?N{iUTQz^eHU;u}Jz9L;6$$o@T()4S0qD&t&{*{N=|?L;4j4 zJj;Mn+5OS_PBo;@X6ZDR@?*9keGW^fwGMvFF{ICB=`{B7W3C}xVd>FvTQQ`kv2hL5;&|y3Loj!^#4%(mY9UV@FAM0=m zd{>93z%d=33eV~AH29+o!tsl#(%f)39G zNrx3UZ&gcA_K*grbT}OfHJJA6yGny4+@&r_hgZT`OO&64U%Y=)hZn#rI=m2`)Zwe) zJ{?{JK^@M7bvnElR_JgRr0Z}t*mT$lf0VWI<-i*{yac|i!?|!shv&mRI=mEGbT|)c zba)vQ=x{#F)!_n&(c$IrE-k`|LxK-LpAN5pFX`|#@VE|t5NMwj^^o8y*rLPNLX{4? zAWw(gkgCIlfLjno4%{6S-iaU@U5nxSI$VOEq2&je#bo(PIEo=%tN7D+ZPVb{*xyhV z)ThyYhcNakS<#@PLV1?lX*d}l~!-;T%z+4{OA5({Me@ubxjD8}_5}16sWO))K2~0kIvTTR{ z!S+by<9IUsPGIVvljUT1Q(zi1ljRh6O<)=$ljSM!6@kfLOO~g?7X(%qo(7NW(x<~c z0(1Fiz)pc_OiY$%LY=@g1|`c^K)JwN{#j5UFxPJ?I0U9KFIk=qvji??cn(YwnDd(p z7J+$vEASU9FF%c0$#NRJD=;rlI?z5x>OuQ4-k|~v3AY=t&wy_*V7CD~4Vd;uP!Hm- z-4BxXo20r@584ls?c4Yn0NmOT5}u4=vhjo`_#Pbzm_DEIQvmrCB6d;uS+S2KV$w&# zp(uT_pd&w+=o!C#eE-OVgSf38#>=|^swlh_pq4_c1kxMPXHbZZjr2|-mofBL#-n30x;|nZWe|7YOVX_!@y51YRz1qrfW#ZW6dqU^E_(GF&Y1Hi1h7-Yzh9j*NbXz}E@fDR8C0I|VKhc)h?M z5EvU9%Wnl%;w9|Yd3{A)M~yGK1t($LBr>wYCSu)Qo($8*cj`W#6yfW*zNG3pUvyti z9$Af>a+U|$jkE?r-4395qh>ohO&%Dl+0IUzV32;ZLHedZySKf)tuerM2o;-;Vm9hF zcp6sfHlk4?`j>{bP+*s@*xTW)YSR~6!?t~AONX}s7B?XoEN;Y?=JCT~u-F@FsoTEE zSLgS6n|vX*$0z38p>7t+wX~+Krpg=gwy4Rd&5CW!NaStr@C2H1*H2AKk>A_e>T70N zr49TTi`J$pZ{sakX=+TPw^hB?ZySo_sK`jY2zn8v-a@dZrc48kA|k~Qf?%w>u_LhE zH$<8@7}-Y^Wgw((o~XiNUqsnz&Wy~hR)NX(rmfqWn=8DuLn(4HZgDE2BHNoH*4jf; z$#$xzi`(|JuFmW8HU#Qgd@YT^owR#s6gP)*quZWd(zd7trdx~_m~JszV7kRz>&sbYiQnM~Ex!-`=5QIp((;VTnksiuNk&PbJ3phkWKDiX zRdq>CenyGAuxxvd+Wl$A2{uNH?wXCyYFDprVvRjpbVFJKkuh1N9Nh0Cjj?ARcJQHr zJIZZ{UcTM;FAYVJjcid~96Z!LzeN@_45 z|3YxmjwPy4s$U^Ugij$*WQdFS6KX=lMNuP0V8G<=$ms3rtAC;L-(yeTKAF!OW6>?9 zBNu-TcEwMa%#LFQI-DM{d7Ma&>^u3ifv(Gh?lA)$PESF>pL(eI1|_|GCy}6BCBo1u zu4@c*cEsfBtA|SGHqezL#;HQ&Q0W#M=$ z^%wO}=}HZB|3sXs5@D#)(Hf*S-zzLb)6F-~Q^_Vb2L#LJ_-ar>bI%NpDzhI`?e7jBfy=|a7jC2`8@WW*r9lzI* zu3kfjkR7iY_$`Xz>n|#)S`ON~S}Wg;NHW(mjB5L$x=Ymh0%gjdTyFnPRBQ zM{|5Fzgp~&aA_lQsC3j;wRBG+-B9_K8tB4EM}3=msQjp{YWYox8@l}-Mj|a;InoVf z2L}Y5nokqbsd-VHdi`MoogeA$)D(pBqT^mchvvzS-xulaUgdWcrmFW4;Q-Qg(S%TqIp*$wl%*y4|X97@En~;kh_|=aBAV_|blg7en`Zr0co}`I^ztE{5Mb zNOv*({J4I&=OXg`JO4YqQyy6%gh+k>6t#grFt9rj|%(RGn@ zfa~BF#qT2N0M~{0UqpHLUnHHq_TuF0M!KQ&cPBO!bxb6&lJL1ecLKm|c#V%Xz=}We zkD8G#9z*qb44(r~JdHm%)G<06hLr}oXOWKLi4KRR2;DUXx)+enA?V^XbPEl1Z)x%+ zz9b)o$p*ULYw{(zRXTc>sx8Mk4ILIcLU$IgwRHc`&?Rcl* zDHun3Nx`2g-xu*(oA07}KK>Hj6b;=W16?uFksgR{CjL}@_u;jcUwM6$E>%N^k0o?; zwMeI69PyitKb2n-UTgVv)JOTzb32s|%}qzQTSGTjLsx8|+oPdVG<3NJx(76LX&SnD z2D*olPPNnd!_Ymcp}T4rx)(Hbj$!CdYUmaWL-&S;Zs9O=zt+%QJq+DB4c($)=&atT zUNVQFo1&pxJPciihAwLux?Bxi_AqqC8an4NbhR2f^50eaGulCuhHl9)bR8NxvNc1)c){Mu_?bP8ajN$ZAzD+p}Te%x?ByNYZ$s>4V`-!x>^lg;V^Vf8akY^ zn3khMLq~n1S^e(O(BTxrl7LZkt<=!bSYpASdc1&i{j!Rpe(_|C($am> z2k_~*!E_R*3#uv0TLADCgUCVYbl{ge#5a2uw`D1c;>=x^zjR67vit%?$wsW6o!QxW zd3lPGpO>4L&*JM7?kFkuNRrBlWOPL4UBvqzlUP~|wQuq|o|2xB)V;Vfj=3((bE-RV zE3?!5CAEs*m8#Ukam7F1Vf~@&!hEMJ_WTaMEQDlxdDDLCaGW???MxCBX|vP)RWoR> zblPKH@jHsOoU$~W@I4y-ks`4#xb^(jAlZc4Q*I{QOPwHZ=nTFPLrHI4eD-j7muP{TVqr{09rqz6r`77|+a8|8QG9lRVRe zRX^l(iL$`)t5EMBajsCY0^L&g!z_nedh=NsVmuEIoVF-ElB1$mc3j{0!LXER>66m- z44h6`7M3%Y_Qj?LJl3;kvPlBhF{hudPY#?(>Dm9}!1m=Q~!lgXCw8= zfxj@yzo*!Bl%+^X_i;*lkIZtMi@DqSfL&XZJt!%!>lBn^sQ5UvE!Txtoffr(Xjw16 z^N%}K`;pSR22P|%>8`V1b0*XVS4y6Tkf-E`LF@Qhwrhi}2WxO8DF5h}86`w0?JrtA zXi@cKOSWFTYM6Wjw;o&CwdYDun(G2$=Sw<4Jfh!cE zkMSt}!}SOEAHGw~kF1bdN*q#6^HiP&o71D#?rlAeI~+aAemK|Vvh`G+mTZWR34DyO z%R@Gw{o;d1WAOgzX?|87`Qd;XwR*4RFr>jlub-0aOsBHlBhOP)ht?@+<0{mK>%vP;RU1}n6FP0^ zOF_M&K4v;A(=YoE`wx0QHn0dt&+lxpW4lZOr9n?SfziI!ABR2VygRs@(J}z)9dsD(L#bNWehFK-y$W= z7iFB}xcLXacn3~zv`yK#apS7hb2lzrwy|I(P|Z-SEyP;;Tbf#D`9fyB9sb!+Pji^= z-|3Gx(fxn*gYwg1YUX>G?%4Y6eqM(s`=ufI#Iamn?2l#T?unF)+qHV;W3VR7%pspOdl=i?bZ~Kv5huTl=db@qW zt!W*BTfH4bHCdFA?*0wdg8JvWaK)NLbqrJ9WGR*Bs=cw1ILFr4`(v2Q-w`saV;sqR z8hh_JY?0GEsUFM6($SB#vau!UVd?3FG(Hwgz<$L3;se+RZ}Hef|D1Hx{<7NhKRA%& zlAcaVa7-t5jhyqLYzhm_7^Q4P(C_f zb7%A6;!0<7FaU4|ho^lKnl4Of#g5dEu_WtLE#9KVE8qVmSt&BzgY^vu` z&(8-OU7$#8RFe)Dc^0BK3*B7fR?mtal38M-3Lihwm$~Os@8{ZzN<2{~F#vfEyf^3l zRc3FJV(0BR5XZd7}53!mn_q6tbSRx~=E;)srR6^IW~^YQ1l-{Jj511GX+U zHX)xk2cSN?6HfmFx*XPCepTg|*;jcknMoOk9x-~rXPey9A~ImFhj%(r!Z!!33gyFF z2Pj|Y2ON#D^`7pEHI~HI1InlS<5}zdB(_fKMJ&oAtR-sOA9I-Oe zt>+)un#5Xk<+)D>;il&XYJq&6b?8%YPiLL*bSTD!cV$B5xhH~f!?fn@A>7XU(R7=5VoO2b7>H{Ol0Mmc!b|Ag%|yD#VZ zdwUeeSvZ}9O9{92ReIviBuHEnGrDISa2(U(d}dQe9W{L)ByT#ABnsXyIi%jo(-RZ3 z?^_L$guXMo!x+Z*Id4-G*m!55wQuWfY3z#b zk4v0!z(#&|;#bbVBun3n17w4Jqsa?-c>z;lj`+oG1dZ62SCRHY>?4D_#B$~TC zU&cG)dh55W@l0oZL>2c5P&zI#IBrLYr*}{5zRQ!u%FJb)E@VtW86iC9?e~{6PMMBc zu^pR?VfO8CS_0d#1iZ#J0|!yA*faRwZ>;s)?U`_7J(EM5CW$mEV_Yw!af)e=+KQ%i zOX2wjPB|LtSOazCxyR6Ir#^aTp$*&hV{Fd+z}5-Oc5FSwN!aOE$}eYca8pq)pAoa#&a! zH_!fK&C-KJO+DTUHYd2-lW+k4G30lNkk~!#(ZmBbS7LXy=jW#qQ+WMeiynS#_j3dD zVfumRuvJmpO^>wQbkTOxf!Z8;_IO6m9?$66;~71Bw4VnD6l@9IbOrJq5{JgP{ECH`Jd$?Vl=oq%O}( zXf^YCAICn9EN}g>sbZdar{EInd2}E(D2L_w4-b^G{u~}z?vZg^d&W;(IR~kidIOYP zdHy#sXKbRi$9gEY#XU!E<&rTP<u4Mfgt!hv$@O(hIAo|I(te^W6o~3TbRw?btfuzaO zVd#EgAjxSxlPgd5sJ0R7`Cv~y&RV&D!As|4yn7iBes3m=d6kW`G` zBF~G~pLQIL^IY5WmCjwA1)ZvlPxkXM`GmvP=kz4pkFuprW&A(hKPSx74m#o@X?$LK zZ@)cEbtI!TJv?AblOpvR>zRn-FxIKE153|mrXigNKf1omL;nW8OwYLZGU|LN!I2!9 z@2~B%g%cfVy;B`keOb&>*_tKVD9wTn`?Gt^eA(W+m5N|cI^&Qlo04;aOwbZTknBf6-SldmX7@Sa3Qb-bTrqbG?yK))3!EXwC~ z*1~+>qP@aLOLE*0S&Pc)O>pe$tH8CW+n9&;JS(5-@sgwk!fSOMv!2aGpS3dh#z1xk z$rTg6GJSW%JAQbeV4n4SRq)OYN0*aH?U`$Hoxk^mEv(Wy7$!TGh zPn>6-r)E`whp%g%9QZ0OJ3Qb2aM%)F&Gh+fKj&!sV(ENIp;a^M`I~|k9C0Zhx!dxn zt&>Vj>uQfNQ*G(x5M zF?wxfI8ua|^$hM?Ztmyf5c&Qwz3O$9BRAsxccJ%BBMCkUxNvClEHPpe|E;^Yevj^Q z6`pwh^;2ML--XhKNXr^mxB^FG1oJkT2f@cq@-p3Gq~PVH z^%7Y*f--$hw587&%1rZAUd}jdHR`J1j=sF`B!`Q&q6g6nlDeC&Vr9iPlrWjDXtaus zRBsHNW6us^Jh$O!wLl%MdLAA~kjSPJq{?%D+stRo^E~%ytal1}q^c(07??6yU9CTf z*Pxt1$tmybt;9)oSbn~nmFPG9my-V$L;kPe9P%V9W%kygv>W5OMpG(YiW`|6hx)Om z*<3}nWxHd0A6Y;J+A$pW-=EzRpb>O3Z=3h_AHM&@pC?F94*b&&X(tC@^2q_~WbT8{ zkz>xxk+=^Y=lO7tBvydlKq^}i(n=7Cv9cJeq`i~-;}?4;9DifLD&buJ!W_vVS{ddf z%{YefC>7|W%2cR7i1SqT@Od}UkW5x-YIuH_q?nVB(p#kT>FAYDFXhzN4x&aou~RNK z7nO%2D??U^j|Kz3CB4y{-J+cREww~`XxpY5M`7lv_jKzZdAMdvcH7>E&t>sRMAUBM zC*xZ7L%i+KdbZZbx}Eu0;>iG7Z9KEucxJWS=bGoq(^!oit=39o0rT$O7_b}c_B7fp z3!0k-;1+|fg^&cIbn z@*8M$acmvVOS_KA@e4+0^va4^S|4%DIO2Z@*Qm$~qPD8?{|0)1aLXyb&85bCnQ=Oi zjwJ`~6Q1&)MD6gg{~6S(>+BY1w&+3DV4K7F49)?fb^0jdVD1IZV^Zxi^#XUY`-^Ec zO?ahnJmBHJ5Y?RP?BhB(;q9s113X&zhd1GPXX>lZmuAVmVfnE;o(`s z?ufrBw5iMBUGEIi(tOOH{9oG_m*H9hJtrow*ebkYOSd)R6;DC0cq)3u zD^GXDNgt2Vc*Pds72kx~BmL%hRQ-}aTqSx}w5sF0Z(S+uOFMSa)0HHA7eI0(u=N>g zKYvJ5-(#V8izzEBn_sqw zY$zS2m2qB_&HJmgy|{)lr}Ue+I?Z}3r1;oCl4R|+9y!d{n;8WtL_sr1W$P5i;pb>c z%GQS4=iQFwh^*Dr<66xVx6TV#aR%vU_h`&}s115XYf(<=WVOEt=`rEN*`M5ScOmrIU#?C~^nbMQLSN$SB>#-HiT;~X z6YJslS$r}_Pkeamh>g6rlI>C7BcUgW^lnIQTC767y4CYk{cr2j#9JkNjv)6*=x?Ln zqIpBb#;EZPl}<;<+ZhNQ>O2y9yYo~iZRdh^@6JHG`o;=>+lk&2iBaz`ywgHY>8ze9 zqSvwG+hWv*((}aWo&)%1&I9#aF7_th+3AzjCp?(q<>m4yGJAfOl)fsI5K3LOsy;D2p*|-Jh^6#|&`gYxF=j!S zDDWyY6=SRzqc9qZNft5FBQX;NpNWyX5-}zQ?}{Os`h@y~(5eu%YWk1Bp^u2%k#(=& z%k)0mX-jY==>)E{hhyF?!CL&LgiprkIeTp7>G!gO-WTdE!VX$e6Ec6_hkX?u77wJy zhD-fj8x9mo*p`DUt5a?M?!xn^<$-=`ZTF$aLT}5?^_1c}fuJO?F~1cppH`BvCq~~Q zrklpVnE-g60SRHtBa&k6wj9>StLsqnaShPN*8tJ;;`84v9_tY`HV%3Eg0^nrb|sFU z@xVj;`XD|v@uzGyBb}|M^mLc)^#N;FJR4&R@X1RY8(}5o zNgNrTz~}N-Pl~25QQvH^i?`j-gYnOBSbyL;`@PBP2pW9@j=lXB8AH{#@e)Mqezsoi z)%g3M^fsYNlO$*sg;W}~518bcg1z6gK|JVPI<;5jecmJZW=E2z{MaHP>#TI8%+LCT zW*q%zU=K2l`(jtdh0|u2Zls>ZhOvL{Z%M^B1q;u;nVUA1oDB&8Dk#w)UmIIVhf?pk4fD|DyE7BY2;SXhC^Zj5s)7uA^~cE^6EU%+F6vyqCPA ztX^qxOs~Ay(rZ~P^;#ES)t8$V&vLhV9Gyxi(CG~w={yuV)%kX4!Opbyz)o-bXWOsx zV(;9wXJAJ6o`IPMPY$FWO+KJBq_E zzdDP=8Dy2}^XxXfHA0^BjgfbC2bk|Q&7pQeNk6q>T zy}f%GyUOfKyDgtxIr_Y}6|k#$eF~drcj1#CepQ7t5PsF`n9{ce-{Ik-hQ9|6#LYT8 z>q-S4Wi`+Z2kaQvl^UJd4ZKJ;G8M;N^=$~1X9{vs`^9>^D|Xh?v*I+Iu;)Aw<-_|J z>W3x?ebPuxekR4KZ;tRcY9@M?ve?604i?INye(^~XK6T4KVnX;zC)vWAM_Th@W8K3 zVm9rZox`kC=}~68H}W)Y-G6$MS_{3sgEFSYgzH6bX2%iZp~Ao5o7Xhj@#jJcz6I+F zmi8Py-*rb)@6q#chaJzZJ7)K#gs+-yJ(FOYKl{bmbHugvj6L?nxzi&lh-2(HlZl%R zNC}t^nYgwcA8l)%sV{JInXJG!7_uzZK6FeWm_QGa)irhW@SRA$74==)X z7MwS9$8^VbYh}!2GOl4VZtL3?KDdkCSbZDMDfTpcZ*Yp;i|48KLwKHMe;d!!?Fzn! zl?3&8o&X2&JQ2cpo&*ZsWrun^Pln3VGi|Q)yylmOwtHKVCbUSji7vecZxeL!zl&|A?sv_eP z@o7pSo~J7k=8=Mamcawbf%F}aftd=h1rCoiHwIEhQKgM}O ze$Rw6_$^g@>k3isftBcwVcL>@-g@@q>X7Y>Y@<2>m#v4cpMKYdZ$Q`*t?%06OIa@r z$7b~(!?h=R|5(nVkyP%Mvf}$*MohVtUigrN?<25y8ON-fJn?62vgJsS&tkAOEBLnf zQHCTor{HHe{-@unz9;o?iy}Q7v**f(a5go`)9smqZ1bZ<+&ejovyJ7e5doSmq;_XE+XTbD=(d~Op3*` zbrSldtZwjm-F_FoORsbR!@Q3sJz5`q{gk|g*7)Xm3h})@uJaE>e00fE+W9p0@ui*5 z;G0C~udcK)Y!moG|Nc(=&ksyF(=XwFj-ZPMMQts?wpRSg;c~@YU7-*RH2Xrz(#6?% z%C;bWu+pbE6-NVo8BNJ^E>LRQ+M1Uu_~pvRM&+j5rX@?gO&fv3%*@7u0wpuEJ=lzU z4Y&L7V~=gE?Mh}N#%*rhrewAiE#FYo*5uou?nO)&{%s8#wly@jb!N6T1zIzA487C+ zhQhUF<;5HDt85+Z8`c((}b-W0?rZ?Lib8uo$C9c`gol+4O( z{B;Cce3%vt`2wwt&D)xMqg#fS247QMV_WN{z~;q%+|)i@*^pkeJnK4Npt)}Q(k#?F z{fde<2x&H?ry~_oP(A-I_MEK=M#VLdzPz{X` zGar54bVPY&`L=HJZ9@Yci3-@{^LA_t`9?@Um0Oml#9h0#x}>iB`m(B#6;#JMt9eHt zn8}*&CU4^it7N#GSjJ;lFkVhy2lWpB`*t5`bwgH@L6?y%v%I0kamzPLYz<#iTQOcm z*NC9GT$1C-{r8hd6>!ktJ=UVO?;On@Wk^%SEXTuCv)V)GdyQ$Uq%5<%!N7QA+t?Nw z>u#16m-5XD1h;Jfs?Xx~(eW`+{p$ z09OEU-6=G}`j4=09cdp_!e`a^btANRq{?dKuHx$2%9^^0+`5Wo zqg$H6`DN8sR+bl)y75U3Jz^S>CXL&J;f5?DG$IOSs^lZKo;R4UCX10pyd&hLyuUOfVHhJZGvYk5@ZqtqrJ=3?pK4#aTQW3H@&V~_?xoqB3GdNUg_u=k zHMIIJaqVYV(eYvIC@LlkcjO#p_RXVNu_S*>TkB{Rff{7%CVX?^QXKN(t9Y}w;}RY7 z;raU;FY&3w@a&s&8oi_11X{eUILWxgY5MSGpoM_ZtYYGyb$z)re@rsTs;OGCc*)ph zb%~E)-oI*?>R74r7CT3?TO{VR>8EV=}4Iz@yentU$F_|cJ8={IC`8%x~m&3`-nVW ziP{FspfM2i`$B=%%_FLq2-i_jN|gJ^Tiyse`dr6s?l3B<80qna$*VHG^tX%*#uj0` zXKmM>rSue)EVncm9t6 zqhsJqT9q{}*9AswhRki2T>r#iO}G(|hOx+E|7%wl z47F{-|HQk*@(uZqbxLM&aml)}qLR9j3U?8rx;l4FO-XfaT}91Ggwg+Npr=zy@L&2= z`kJb;YjEMISo<$DETXQiqOb({Fkrl&91)didD(R(j5f-&3ZH|Qt*%^KtG!wKxVo5l z*Ou4R)s(uObtG`~iE>-R7W_ZMD1Usq#-FUBFhvzLWi@rg3DZ>`6~#*#i_)4Be8lIj zu3cMIS6fz5LisPv&dx^C>&xA%>q=I;3(HIJ5nypqVO>#aSydgaTdrR(SkZ#b z=#3Sc>$U63YAUPi)~*(rF=<83Vs)0e%Na)zQ?|Ocq`G=-73x|Sol~TRB(z!;>Ww)? zHRbMgC5#NUDqdS4LDbA@i_0qODoSc<+$&3J1f8d9ZCzD$NlnRWUB!Al_!dC%TCDKs z{oDfBeL_FgCFLdVnv!U_*+cnACAzDNa#<}#YgLbnOKMoU5U{p-^-3*!VI@lnZY;wr zgz-kr1uZ8kTupgN307}ZltGVaF^Q~cox6N($u&8-XhhtO&~TX2J#K7jHK-!up?w#E zKVyz)v8pVpXCb(IwY$7>rM||huCGvQNXHGiOF@Ucf9KlGG_ zNJoO{nxrA`XRK5{0B-#Jdm(<5s1QGCQ@9fU7y1VL-3YJ}aWU@aUa}UzQ-;54j4Q-F zkTER9xH3#HtHB@MUygV+;?O`+vJrZr?K=Wp_zqUv{!#^;n1( z<5~A4%UI`6?N>d>4n*C%Q$j0KZbw{?zp-q8FEJTz+hf^F7C1KfYjwcezsTR65?qyX z+nDG;E5mjycVWt|J+XUZ_F3<->>sPPNPV|@Jd4UNOxdv~ey?p`+&!`TWA3%yXSp9G zai?smOmL^{C`=p^y(p?c7|y|8)IN()ird|Z7*~(K(YDbf%tJkBe5=RbXy>V|k9-`b zOzI<8_J6QG6x6?ZxbUJdW&0l6-nf0S_r&bC-fOvUtlEsW-SYmMjh)zkmW^5e`R^cu zqE-fm2p*QDG!CT&Kmi}4!Iw7PIHT|~zd>a}jeUaKDCN4x(} zFc0-`;l+5h5v`B)3d-Tev2DEk>+$gKX>Oz*uP`51*ET}(C(tNvbtl#%(OB9&Nx+mX%Ed5?>{+|;0k5{|2k8}Ry(~b4qORN9! zwm&{rj_taKwhwTj{>Nj^qxI{lKI-u|+I_IL-p9l4^0AESf!}R4n^)W{Z)X#W6gc_K zZ@v2M?|k=rC1c~aX!S#~j&-}#u7_#noMU1e+BQLDACESnEq^-G|JbbuYTF~}z8-(0 z-5#|%ufqJsL+9FZKQKn+rg@rrd>=0i<;K;omDmC7!j+z}sRwPlr{@J@-R`w^Fomsu zb&mNOoK}WXrh{G4dGr|7gVq+wFR91hShm4D%#Y@Xk@bUdkYT*mV70m@pST`>qpkb# z$Wv?QD_C0_`}J;Zf0K)P9_#)_o4;!u^4E^@e9dm`#(8c1ceApOZ+jmv8ywF%(Apne zkEi{UJ&b4m)Yp!6{#yTQ6??w3b5Gpf*nKhgSod4*W$Wf0yU+vMIY!UgwD$1banOgh zPpJJj@V~;SgTj=t_W`x_K>fp5+oghes>i38U5?MQwei-2cHO>^+2eNYeBf4fa#WAX z8f_mylE`$L)&+L3T<^f=1*E1^|QJe+vj}Rc}y+lUyr}hZkJlUcVd2qHIy-tLF+@3 zJY)I(p0@lnZy%5HYweD%$9lZf=ASdp`O}y+*5%jQ0KG#w9yXwrf!9G~TnMfkqj&hU zcEH!o$M$)eHhwx-%u^tP@JAVbstRD06 zLNh-KR*d2NNKu8rkdKApz1ZM&D8<;lx2>JS=Q4dn+N3+BwH9Szue^=9ZH|YZrnOC% zUKfb;$CLE%T^v?8^WGs129V%Wi1Sqf#QJoZr58rhWkb4!rPKfW@WWzAx3YA42FDMp zAw7nr7put-V@QuR;5bH4_0NwuL%NNn(=%Uw*bM3M2Ap8Pi3Xfxz!MC3q5)4bV7mcN zHsE9fPBGvqtUUCtDLogXt; zx}rk-&q1;udgqZJJY7WqGY$98G~CbAKNY!wr$-=MVUTB*0jC=9Yy+NSz;g{)G2k=< zPB-9r2ApBQR~qnq1HQ_D9R|F>fEP0T(K9W6EHtEF&C(BA)%2@b`d2lW>WAJ9;|EVy z5&f4ZrPCTcKNcDIXBzU)G^8(P>GX_&ABzp?SuCBNiSQ%KkezG~dJ#*Hmbb`|UTnZ6jJ_(uuf&keCbdMo@ zr2&^RdYS|9qtuXIX27c$ebj$n#nPko$I~BB*#S?FK)BApuiStu4DweP(pMXBr2$tN z@EXRC)>-(m#*kiZz%>S3Yrtz6Kbk-AW33^5odI8O!0Qe81_Qp)fNwJ34FjZV6Oo;7;vKjHyN;x=_Bg@_zdZrSUUYrAU`%4(l;BhpV8C*bn?S*NDshAu|KDy z1%DR&FZ_K1-^y?cbP2qh;Z|rD7$MS2(4fOIl`WNuN}Ul!;|4f9ZrUi z>2L~k=77$^=4q`})doDSdA;d$^W9nOG#I(#Lx>F|80)#0mPi4Hs93LRbm z|1(pShV-)#-qGQ!;WZsz1fSL6OxUBti=jz}vtXqTXTw|_cEY)+GmQD?z-v0Z1U{$3 zxv*b{mx51+^Pob9m%$Pp&WD*gTmXNYt}Xv^__Ypy0AAJM74VD>UjrZ0;Sa(N9ljQB z)?pVE>98BJb+`~xb+`yDI$R9DnWmMu1iqug9_Z2GmGFoTm%=t3E`#+tyb7+-;p-qn zhsz;Ohb!RSsaknf!}oN!5}wxKD)_JtuYucjxEg#qTmv2*u7#_0crDD(;dO9<7O%u% zf$QN%I=mjfsKYqk>F|wkuMXb?%{sgR*6Q#^xK@X6hO2bA4kqbvJ^Up_m5$n*7k;I~ z4e*~j+z2o0a1(q%hkfvf4sU|Hb$Bzh>aZVf(BS|)A9a>curu#{R^TfUNjRPzKup)v zjS;>Fu?w&1-FCt|5MPJaG^7%4L|lQ_G$kTjiFl0$FGsu+olwMTeh+Y8`$G@^!c!X6x{0LDu2VK|eiw5r+ha z;WZsT0zEqXG(4ii&%muZ{4CV#@N-b2!=HzRI{XE&>u?90pP))Z`Z@|f)8QUCuEWp6 zlRErGxL1c?fL0xT5o&b!KOkR+zXY>&_$82a_!ztso$R1|+u(H_{xUqT!(V}q>+n}$ zw+_DyULAe~JUVwVcwL8IgXeYlbvU5IJK#1Q{ysG5@PEQe9qxri zI@|}7b@&HxAzmxb58=Ob_zgIr!#{$jboj?`pAP>7f;!v@>vVW0tkB_IkgmhGf=!2a z!yl<57Ka44!H;yf4Zfnox5FVFz60*j;Vx*=;X9#5hwp*{9ljgp>hK_Q?LJ%B3(-pBa(fzbWFXJfqbAicil_3^h6*!mSIQX2vv<5HZ zDEd)>X&8_p9&Qzw+0IUl-WH@D=csz~olR z=#|_rFqbD4whHWG>9b*pz&yXXFinRQ_#eEH^5^Mk@GF72{?g%9fq8!O;Gn=~{jwnz9U6!}kTIHDnpr zlMn0YGhv^=-(~VFhD`#~ny?I6P$uxtSb8?32~2CgGC1J^DuVK-HC`F#W8W7z%;=ZE z5rH=_oD25}Oz%$0uoO0{_cMNZP$}?2M!yV}3hZY%A7%;sEW-ux51j8%{w{`>!*2zy zW%vW|9f7(2SHN=uqZ%>)YoH(JCv<-m!zJ)NfwLL*z!wF6iQ$!SqreX^yb9uV^cC<2 zoL>+>Ucam1b%DRn=quqfXc&}^W{vsZ2=@!z&G1doDsU;o8{m3@F+lo_;MU=rVS&KB zJasTxmtGHlMgN`hfUfywBZ-z3txJ_C>;`ioqoPnIV_tiTxzPlE4>_D;{#ljX_qC4ti!PKIht zdrg+-z{f>>=CSk-!cKv67`_(j1?Km=phRGjH(7Q=j=-G^7s4EYseY2>B8U+f%?@!f z91!|i!Eh<;5E#{t>1A-O4qpfJ1-7yDa(Gtghv#1f4++fWT?1VLbA439W`VgpHBc%r zwU1=E7BU5XgyFStg}}QRUIzoh9(aD&!%uX0J-jF|*;}%F16+taivpO8b^MM2ziz-M z4EU%9C*%Ex4EP}f-fO@+40w|PuQT9P23%mknFc)5fNci+2bxHVgXDkBfR7vSvj+Tt z0pDW4l?LoI;K>I39!-oj@|-o`pBV5f2K;FQ-ebU940yc(uQ1^G20YP#-?pgIl05-@ z-GHAq;0FxYYrv}vIM;wD8}J#-Q#~mE9~;xGzh=OnGvEgec!vRRGT=1^yv%^FFkp)TpHqd!kmUV^0l#9vpEcme4ETNnZa3hY z4cKGA%MAD`1IFPaa*({(-9`?=n&Lq^VjA}n{vxq&CsRnvMHHq}_$LXUz;aB}u!Pqo z^r$erOM*NR7K(7S2j|ewK-2RCG*TMh z685Fyj|UWu*YB_N;u6ptZ|XB0j!!V@A4Q}}=c10tk(1C^iZJt3E7EEwJ=@YhAX z#tJ$2OYGg* z5-cWu6J+*%?*#O)Hi�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

>A@oNFSVQ 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 =>E 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

    ` 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 fK2(7_@~Q|qluYBY$H~Me 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�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

    g?m`T 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

    }_K{sTw^J|rI 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 literal 3774356 zcmeFa3w&Hxc`v$VBw4a-$FiM=lNd)<tXqoCdJZd#u_quWM*U=FddI(Mw%g` znaMnCnbOuKPT~NCl*8=_ZCVlz?S+=xlZ0?C=>;5mD5M<9&n|EZy>R1mN}B|?_c|eM z)s{B*|9xw%z1Q9|Bipi*QjU~t&;B0kTi;siTi<%Gz2VMyF_HfH*6w!aUylLGck|!& z_WqsQcI{-IL#;wI_XzO?;e7sTR)~vyJp11(-tgxSekeSPkMRDu{H8q(pFS_%sHgGB z5Abh*#j$3#<&XUY0uaaqsj9}!F3&$(H#L_N(nz9t+G z>S^;&+w(7-qWRzGS-Nsg)P3H0NGx4^ekSvvb@mZ)#h>pT6s^@|n%4xg1b+$k2HH#ZO3?s#6*eDdR> z&3r!dh-kZl&#E0sQTKW18)8+x=X+letLAxDzvZl``^5K%)$={S`;1uq20d#IeqYS{ zeB`89L(i9^d#3zJ%wRT#LBm=Z_y1*IeMacK5Kj;8SiB*UtBR^@OxW|A=SW(ttM`01B-Yh?{&uZccbU&yVj)rYdE)cpEm!DS-}Vi$pr_I= z)?e)NhqsIMKa5`Rx#{*N#m~(1=bslhxt{hFS#iN<@33fJ$n$FlMEixFZ_bMLi+DCH z8xoiFgb#=fwVwMAi4B+fJU=To(DT}3*3)tG55;9avnNGIt>^!ERCHY8bF=6YH{ZVY z;-3$l5I4J@Z=}V|^!#(b^>l7JFMbxEjX!@-Echv9#m38hp8XrK@u%#$rTuyFW<0lE zvrbe!qrm-JKL0H(ZvA)kbRBwLSkDvh6oA%sxPf}DpXWGSW3wSo) zxK7l3!gq?z#3eGgpfpu4m_`zap&XdqV75^6lEsU4J8X zUGDSItk`wxg!Syc;h5kj_!F_a_LG?09~u~q9ZnTXnS4$ta3-IuWK*N@nUuyThDf=X z$xYWp?#+}%EH)4xi6!zgGx=O>CN+~N9PN+o1pDBqe>_+kj^~ouRG^q5v4o1G$|LdF zP$qY8Nnv7%ndDHWl*s3DsYF>LGdT#CL1M+!bf#2J72R+oRfLi@_CB9eMlp5YP`n(s z7)k{ENiE(R%SB%Z5G#S`U9F;#SjBeTyW zQneINq=`x<+1t0PPC%yas3Ma2lKBO5Wj8H4JDxw1Duz;rQ&}^`*=#-mSXDBaKb3Oc ztWZc!g3WFy#Y$5}N2Qg8Ohj2_4bvoKsd#U=RM0t_tQ|C&DZ*j6B1+ z^D{>7f!i!)%EW38vYQ&%$>P}5KpCESvQkc&YK|9EQ>kJxl_d455)n?#x6{! z%0I~z7}ixCu_BgWT=Nij)SzkWLW!Z~!^U95@oY7tX=*NNCYj2WsT7RzwLB=4&p3=G zQwpW1nbAd7kj}*jYh&QAG@Ev`ZrI^)5t-)G1%9+1gZ3-cblYdMyiz`U7`B=$rb?wC zB~>>Qpq5m#F`7yxQ_{~fHcQzltF3H1xlrNFs5vlg5U3%pF48id9g=D~F zK|)r$FF~q-Fcc2!=xj-{*-@}CRbi_70T!#-5s=6_ye`H_b%6j?vp|413k0CfR*}f( zO6Ax)QpLP_4Nr>5$apMKOu>vIndw}d8gPkIO&Za48%6K3HG)&l=fWv+0aQ(t7vO-J zA&j1MekM{z&k1cVdkH7KW@v}cr1;oj@{9DA^qMVmYfG;MbXd{dCoky)$wf*G_t9(y z4Qd9suUd|b!g94UYGc*dLH4wCiesh9By|T1@nn*QAf;3;Nku{Wp-Pr!3NZ~r-SB~! zFYF%*Mk6ub*a%hFF^o%GLkq@H4|E#k;zKi;k(D2;XpRGD^HFT?VV@{b7^}Fky2$~9 zZUm@VApHqKYKNjyLVU<$oel+ZKabz- zG$;_IZ!)8nROwHgc0zpVf#ggkH$YuT)E*>FV&SbRa|H8w0_rOGE~JGnXud zGC~=ceVMo%mnwmp#G_P>LSgJUhO(%1&Nwv6j>E(t4qrxT?82LIyGTK#dsb>?Q7o-A z#-SCO7T72SDa684_?ht+i}|AeFdAmU`KCB~3o$A@v}Yw4H{r>RtG5~X8%T^zO}QOp#|`JyeV9&c%E%9V_y%{pGp%*2aF6++?883?5bPo)aLAI+3lQ2jY%{W|Q1F)PYPwPiL|O!82aW7tlgvc)qV5Q*}H=OxmK?M{P<; z$dVaOWXPS+Sh7;0o}z)~X~V?5sWSOGSP_~UC&y4Kn=13n8pieH=Iy{km6@5N4!G=O z7(QZkPVG>^+<{JEqvHlS-UV@Beh3c46&ijqdH zwkkC9VAIC)W`?2n70KqywX%e!(Q4tx`1(Z0ySBxrRXv$6{5!a0Hvpzm!}40 zpAOTT)oG?Et9h#BpcHs10u5koAua~D1R4eeFgsJhG=7X*ymmRn!X1 zRCj3_0jn|w?LSYap@zEbpSlK-Bbjm{?TX06J2m8b!L=Gwo{mbbil@pxY`im@CUP(i z^yHFo5(y&=k6WKgXBCsGxk&bU1b5XL*uqlp~!bbaNGv!DwGc~1FA4nm{ zQQpMn)9r#@v{roggrh3I?PXDe z%5x3ck+|{XBWmHKS1~E*Z5W{GDr|I(vZWHQ&RywC)QXDA$!G>vUC!hx`AR8F{g)c} zr~^L~9>)mFp;$B%LYKHqR!8M2S4>P<$}(o1F(AlzVkVT&7if=ztN~^y(9ziGWkQoe zG4VD6XkMkbi|Eu|5^L+jb%8oy399Lt>A`5wjMPo`lZQ<3N}QEx%rkr>Y;RUkr2WNu zp3;tjd8j6;cG>CkOg<=Sf~wPQ`!nPma%P&wMOOSn74(kC$(Tq?qsf|JB7t#M%l$>5 z$V&~-N~2towB#yM6kSDA$o$GwJ6AKTvwrL^j@OHu3GSGw#|3X~3bZ|}1Dl~{O)Vb` zr6wyhn4ol}IG@7tWG25qj^;O+*A#T=rR}H{0^(LfJ$gmwoMs;BRS$S*-Hj*do#?%^ z0U?t>i&}>vq!)lt*Jv$8dtNQq&fj_hsQu#JeLaT!G*Q(4B2#CoBy|Gq!>oM17%8BR z)J~Yq;E<9|WLTt(4KAmc&t_AwE39RL7BX}xU}(aPm8Bi&hPednGf8CS6gD+9!a}2e zGK0>FEEyY3(|*L``9Jb=au2{;B82S~=WKT}Re<1!9T z2=R`Q3DAr70cO%99)*dq7j1Q2>p#TZN&OASzKEfLzdMWo9yk4JNwlr!rS61SzQX zG+@&~tOi+$v^%_-1Bv894P>%#-EJ)ROH^2Jk_K4v!Y&rBXPUtE)e34gaEeTMVYl_Q zkOMT)S(c@UG;n|#a1FLdntDctOh(jW1io$n9ni@@twVj!uj9qWIgIyYG43z=D%j(b zD+l9=P`qHHZI^CwvOi@ACP&I0Q2}Hx6aBg&-dz>V?@yyoAEF%{#4gFoe$WS=;H?oR zsYr|5HiJP@OS}dqgcW8i)1(SnX*N>2f#uG#6)mlG8==Xf4yUA^G?`LMQ&^7N%t21V z2y5Y0&%{ofwo1$Xq*BTReQ9ojos#4lJoSY!+;NhqnW+^8;o-&$*ebv~_RLVO%_+8O zx_ha+^EQR+f5_2iCnEZ@j$JwmM-2t-zEB`CxfT~Tb5hSobD3KuD4=CA9Jj;Y_JPj9 zYLm2wf|E~@r%zh##;|WFBHcQIdC7yJ0lc@B&& z^TnhnP}^nYB(=W5DHrHy$_tL1FZgC`X5UN*QzNRwQ=mbC-Aw?fvdiR9^+h=^lEB-5s%QKvbCq9*to0v9Mlg-5BfoLqM!uCe za8k-twUQ}1Ln(pm0%coarNY5f9hnZ!JID0!M;nqOEUh)xma11C+*IDdV(285my?Iw zF;eoS^DqI{#$q=*PMXP|NaqzD%j9qYm`xo>BvOU4jdf;-#B;AEnwd$V(}x`6tw?hD zNFm43%|;gvO6ut4@{H9lW>e1gCE_u3UX5KT4pac^Qo@NLAM3zy;W{v?m1i8buegP4 zlr7xE*xPCx;fdKIp$9TvnvrT)VJ*cp##Ri>ZY4CzR>Hzqf;7ewWbS_G$yRa0ltdB&M`j>+QEd{s8)AjplRwhY^n;FxSQTayaNyDkj7sEvk#I=I}X zVVb!agzVgit5m3|LaE?Xf$ExlOk=?{#rRs9iOIwaJ#sm+RJF=ypJ2j{ zQq>(%i$YL&khYn+CgTVfcbt15Orqx8sG`_qpk&H<2lR0%HHe5O%Yty2lm; zeKhLop}SI)dXY zT3a3AQPF*pn%G!7Gi{umhc?d6IuoaJ$Hu8uTB+52s+c2g$WqBL!YTQ+it56r0VCnmdS%Mdf_HoYr$Myg^8% z4|HAHPBSnFmKgw7Wd^l(T-uXmKtt#t;lQ5q?)c&Ltub_yF$S84 z!(O9z?+aj$(c42wf+I*$1sTM~VpRxo961k78XSkL4w7`9ebT&DXlwldDsVMCtokG~ z81HlB5=+)^!nC8Hgzko(YDa0zOXh=rDh_iM*$PA_PpHn<5?Dnuq-k0RvkEyrLMdZm zyfxP#CwFZMIS`B#N^U&+8Z2A#W+R)OM&nvBhsH$MkB$oVMeEF>2^agFhjR7OrF@)& zY$VMfyHlr0H4~_awbH0aHIk_)HB)NPsuIfyq%{IH|1UF5h0u6yey}A_)X;dJJV|UF z6qX^mg~JF}2etCjO)z9)dk30Ui<3757!3+rHY3$4fsCp8*oH1P7;{wa7qDbfNSZ^k zr^+<5>_ZTp60NPotPgcKjFNV8xC`5$)+}$EUaQD$YB+UYje@u7HOt;fb`?K`fWLG& z2P_~Y?yXU_x=E$RRZawR4l2O(Lm7t))E#VIHABf2d7acQNgLJ{0e_DBpT6O{$p^MXZ$=MXH$|gI1NK8g9teU;7fnK;&U;n2Bw>#Lq{xtE?InwO-175S$RT z`=leZBiHSlq}!-LFf?#EBrw-;NKBbkiRalkt~fy3b(5&IEU*rTQHD+qcQG2&nk8w| zYZazVty!K8<1x(T&>0_`2hd036fi~Ob&1zb1uR$z!?r|;$2}EjYT$#- zLs*alyd45Sy}mtjqNmKpFm}$1o*_SqfSRCOxdgg4=fu`J%o>FB-Hch}D zq5W+fF64?RL-}Lx{tAhsjG&#Rx)< z*OSSwU@eO54>-zp`%Nz04$yG|-bf7wT>_!Iu`DO6D)U>AjtB@VD!i-6%53Ny*oq2N zE^SO}CW~fdiXayvsB#g5HNnC{q&gTqk`f^w&Aci{UWKrFKu$hxF%-%%`=fA_KU}NG zUI|A&%h+^7sJ(D0346N3jiP?7FKuO_3gGJPs6h5=xr_~>NdtSLOYy0>6a{HxbL@K~ zntMu&aJ47Eh=MAlau3a*)dVYwV~9^UUA%a8doz_)@DRushajNPY}m1|-9ZAo7i+KL z$iRWvfG-pa1xN3WKv*O?;JZ6kFuT6O!Gm>itf5&$AFIGrK%1gE&hyMJh9>;cv9aiI ztWeA+Xgyg+j|Nb0#l(3px+w$8JG_G&ELixVLtxlKsd2#2-VWZ)hly8AZ@}l#+9Fo- zcyU$})mA@LY%7RgZau|r_(?UZ?IP(ZwtbltE`YHE251Ha&AKw#K^%j!iHJB$rD5$D zsl7?iipuaR7A^u4vDKnUQCof_n@SZ(Gv5^Ux!FMqw4u?MIJYR4v$OUL)+3pjBSY0v zPA-#7pqK{Zl_YYG7ti%drM(RbIq$>t60OrB!fLuj&|@PbDB5dY=;46X^q{$Li{;*w z9aNKe%8N)2#B?k^Dbs`_v!jvN3~xUwRLWeZ6)uy*>XZ{_SiN&l$Wq`wP~EBm5xRyf z)Gt`Ldm0T@laANmN00g0>(Vt`N?{}hE8Z|Kdp{YnCn{Gsk=csP#*q&-k=Ckm6#K!< zip4>AXR=YPqP#D`3{N>pMH#hLp`-S~5##q$&p`!2Q*2doChD3#7>$HudZt&Gt(yB& z?T%!rVDE@r{i{I@lnY~p!aNMDEepc5?mT=-ww!<#9KeCXT#3TY8(l@N4b+YZ&dnd* z7xYnMP8UH1vBAAo$_&1GiMLs%=E(t@DOjyi z%|x(Xgoxlcy>%&qfv`j<2DpJhrih(o1`lvlvrUweOV@f}mn4tbN=bWVR<}jgBEKZw zheYeQlKrNWZIKig7CPxXHD$--L@qUp&5vb_{@^GA`3kz;qqOXq#U&sU6|BO5ixMO6 z+LAC7_h(ad*kv%E&k~1?8Ai7j&7=cITk1lo+;lnZ#MAvS7;rdvqm&~K%tTHe2zFtW zZity`Dtx?j8)_vC5~`9Bxi?c#dc$mSB;Fs^Jr7=OnivR29SGZZDYqpTrD}RKChZ>| zbBW-KCc^>0Q|?4GIyUM+jYWKcy|SN|&C`V^Vlo?-H$)Ek2PgK%LSu?d=k+zBs2qqM z+9Fvt5v>Sz-}3p6e(XCO@izNz$SiE<#cjvC;4p82)GZqW` z_x0|0_r)_uhBFt#yd9Fm2O#$yz1tF#BLhJ>e=%4d@7=B7L5zMfXz1wPx$(f^!+tmO zSmZFF`V~L-5*2Q{A#*=+jv05DjD*dM_w}jUKDhzrxa1lM%Z#_Y+v~f@^n!%LE2zBihUxu3fVx>Uqf9hbHBTNy8cH?E7 zigjQ)v+IPwMg#PXoWd-_hYBMDKHZ;Dxlc6$1U*DBuo>A@S;2LO!C)!Q?nR|19g!%D zk=5o=gMo@7Ex7B#U@PZyxLHCDFD%9~C7JqT$XjcUC^`_{>&JxxGDo^lIb;p*>y3?J9&Udokm1QW z+@qP|y1oZMEzAB?L2T{Y3?{>wh%ZyUn2)>Jo4}t28Ejqy}%K4)4C&_;-x< zV>f?tm(HeO;P80wcG7@0tCdRQdDMvU!+!rReeG6oJklTY`wxfjMkg7$`i{#L5$lmc zisgK1JG+VC_~FpId;NZ2um3PdF)hv z8OV9K&}hUGm^Z{$K7YEdEaHN!Bl+UJe)zITZw&v>%U#BHzdX)hp{=N`-?jwi{m~JD z1s}~Nl+@n-Tq$12V9G+?8Jr$JOf5*w1ol%lWYC<+z3KJSxSbeh;)#pkyOpc>RmnXj)t36-awz`nYqp`QAr`T~boV67H=XLXBB z4LR=+lN~*nBs}+^1dtil_8*B+O`f9L4W2@1H&4B2IyVPV!~TKs*d!kj8aN!!WYuyA zqt%iUzauV866X_`n9xV|D5Q#zS`*2dhnz1$@Zj27cX?~os*c-tIsTojO@w=L_w%*ldYZZ(t zmKLFB$;TqHr5=Gt#}P=7fvL_SAQKRd2?}e<5h&;yr~8=cHB;g>)=Vx==>!IqAIk)o z)W9V+q&cB@{A9oODKsV}os3i%4vnfy1mb{HhY}oG0nME->gGr;C5p!y5);8zX*LOf zDg*IGeR~tXqy({ERFgpQI0=>97|#F7;B+sgeskyyi;+nPmMAyx zneb0=$4{XR0nE5b+Bhx#Ame#XE`p1>)#4uTDgfSe)i7+&!0P#7GG}?qi|!xw z_Rt7u3cD`Tu|y1~n0tHTlRfAZ$3PyVJ&PXRisGy zWh_F&2pgYFO*sg|7?;o;b98eVZcHo;@r}6oZ>iX0#UTN9U`!d4UMSBXU`A1tYhHss9#`{gPpP4l}|Q?|1$R@+W= z#pvxk;OG!8?o(kpk2LGjO2vhrMtBNJz4C=*k=w)Mw%^!C-!vL=&T%Nk7365gs0cWa`C&A?NI z@6oMfWGFah!ss)N_+q}1A&jr+j$(Bp7U|J=s-!j0)VN}0$6!1X&tLGr>P1dg*vi0UoIevvFm$#&#rzj$ z%zq#n>@iE35O6){I2fkDNH?O-jc`~G1?hKl?2c_WQRE@_j>F1`Ic7L+!VQF?x^M~9 z#ZT`lBk5HYzka3T$}Tx7e~AMIf`ig(`yle1a5B%a!UJmuijCeE93ZRV%LZ%|+l>HG82HKWH%Tysd3qYRNeHE_OIadR9!Nlst95dA zQ-M}6>r1Yyf9K9!eaRXQVjeCdDRsG!kTk{7D}T_xPR_(*l@g(1#aRbfHo-n8wJ!!L zU3A|&7WT`RQS}>8zvJ?^Pc!r>hCap62L_|9>NP!yfp@qi1HYpV|4tK67R#$>yx?JZ z5)17d889bMY|0i7F7Gd7?b!qiA9dnUs18*DI~?dl1gm+DL^8&a4DRAm1T3s}Khxx? z*B4Dpa#G@xxF$urD8_IrY|hXyR@YYs?2Cr2>{8-*l7YAL6y>%|=7*8A|PxE%5}tNx;1pbl@J z+SQ-xnM&4hNEcu=Dl%3^v{$GhmE98QGBju{#%hqKK(ud>VveZWv!LAM_FetG$wYrW z|| zOc3cE)@7M68;!IKMH-d%V)NRTs5nS2u02kw8Aye7Nm6PN(QU7UQx-_C)fQ)ArNI%% zwgNrnfL(5Cu7Rcjxzb#QkP@h?p{5BzWhjZw!o@tbH4ILra50(#pstgi*JYLruDjvo zNC}m6^;2M=!nw~-jy_)yL=jLeWK1EIq7H6=_Tgtr1u`TBs*EBEeGY);wy4p*hY)gR zQ;*9TrSx{ARb!IT6!SEdE3$e61tHh2v+y9f4Ril3E9-yI^fnqD z8M;XrY~*dqA$8(1RIa4cTV({-fun!ubR?LNRq5){VFSK=TQ6e&}Z7nKvb zl;b?4M$-iM#rX;_jXdmRazf=|mhU{|@a1AIF+-aTEC^TJSrAUPQ+6p@IZyT50>}{) zP-bsBP%QFtgv1P`61eW4UA64V>Mrqq30i$(1>3GlA(Vw{s1&Z`s5lX&La8>LW&nX4 zn1~MhN25XCKy)k|8_6W5u)STerjNvju?mt-RrAAdFUzA@`bCoCN^XeNdT~-HQFfl$JLJb_HFYEBWh!ifJG(NLoFrfS|$V0tT zD^4RU@<&F!2PWU8E1a7&TGOWMkuzyJ`2+`2HaWn#*v=ANI+< zkIk~3QP>JoOQn*z4URUSQ0j0AM`0*`B&T~^j6j^|ex#CBNXsF)DGqPtCemqH30?%=ou>>u&R z;H7mi0x`)nSJ>)gP{Q|Q zRaMfIOlg!THi)hzZre%g;A)Sn97=#o!FHcWArLo~Yb!W!DsS$#(e|pV!l{~TLAHZb zD93(O3rE9VYnQ5pMNQ&Cp@HCfr(j(rEzl&QpGEyMMKd?DI#7-vYGbP%N^giA3h zojW4~ZyO6ks0M?hCWw;t4aaB=&T<1rv!-#f$DkWKjg?z*$(_(X3?)KWVFhYowELAl zQYg_@;X#yLa0D0?T(VB@0b}}j!yZvLTwm=Ke z?w=910YR2_`-Yd1GPT2|OBal`89`t+Ra(m0u0q0e>8op0#ngS$Tt48z2LlYXfgnw7 z<$yp_s9In|r2Rj=>LMyzIf~(yDiCFOk+DD&Te)NC!dbl=*fX>;C~{E1#!yAm5gP0& zVvV8RhHA8NE;fX1WrlRixtq8eCZvT;VsnM|twxZ#@-4g50&L^6Fis29Xx_^aPE8Nx z)y^wTfGO4LCm3XBQ5%F>;%FL->WVxmEjQd7DJx(b1r1&Js63B&Rf#EM)6xm7kuhY5 zehlb}*xGA%7PSbsRa(My7t%tISw->PyL-{&uN4h!Z9ei5{^pPL=tl79$an}F`ZC$% zKw&TyM=3^A$N||Hm_*F^P2w;RzHd^CK8gmZCSg2+ui?}oNs0Fv;fBVdI7Y+ja059U z#f7u+$qYWKh0l|rQG`piS#VGed7Da7b#&9_4_PY&GH+@sld!vr_=FWpjf_mtre^z{ zwssEC7b-L50dl?J)O~!72-ytrR?~3{hC1d@#ekYtk0x7yx>QwZOgiUWI5KMKY9mno zX*~l2C7FN$fs>OFE>4=};X`&7D`6afeMFeLN){w$u0~wwgC}JQv zmA8a2p@uQ2%x1D_2+~R@E+#qczzk$&6SHD0Hsp-f+EhjM;u37;oto*1zyS>A@m)D- z2Sx6WTM{K$C;24|Y4cOeJGMWxZ9Cl_a3D75kNWlJRSa~zSO|_=ZInTnxy4$f`)is^d_ouSniq-y6~nLlMqv*K92 ztWl20C;p~{<30p;3WGF3sICW=-4&+>ck2RIdpn)fahPDOVl9tH>JeZhGgz3b$_<)d ziHwE^V0hTQzCV?jPV@0LXM~DN&8$@mIWQ6#nh0gEIt6R0Cc`(3#B-2OM|bNOM7Uh4 zZxC#D184}UWYdQstB}zHaQV{|8BYz@mm7^2Q9F4s%ip4K7n6O3p))^dBkBZQ%aBB~ z%Ue{PbnItCn&nsST-ss0yEg@Apf1d)Maun>C7^=8K)iphjiX4YkEPA*9+k z99eg2QKgDD52AgikGR_c8A%N}6jg1#(N8f#%5?(Fz2I=bSk7+kOcvSelAlU*Mv>qh zh$b(mHn1OOj9r{ekP8L|e{!m%;&kT|rGO4f)K**0&gAKUn=>9XQ}t6K+py}K!iSgW zgOlpOjG-P8+)WrMMtB%O5l+_?y(Y+8Eb0(3ps7XS(UuweY^}Iex82|)Ozd!e;~6;v}0a}-t` z3L0N*{3SI2cd6wX6H|)S(s;eW8L^N9Rdj2b%@jP3)->?rDHt9q2-vcC4c13w4Cq<4t!MbF2v(W?!(RaM%Y+ zm2->|-isr9vWGzf3aUG>tihu+3KtFxe0jZ*b#|!ah(dh+cOyeU@3A^0$qTzZa5`=kakwoy31@JPy1bGjS z1>1~xGqE(m8_3}LDpm`o;EI>0uO*RRbyx0p5 zivkdotx3T~S;#O`J#tf%+Xn$-cwD@s@@bV$<3NGKLh(4EK>&_EV()u=q{sgX!ZlvZI3 zKHQd!v)}0=1{3d*d)H`z3{h$24PH7Wt~d>BC1QJGGb2K`R8CRU~$H7m88;x3WEH)R5yYc3waoR0qtT@YV09_cQ zYFRZ+)u>v8Bk;dYc~H^bIAH`a*9u%gct;A2VlXh_tt)kx)?uT*YzA!R;+i8l7RNZ+ z4dkI}jW14_WPgSO{IH+L9vKxlt}Jv(*)*W0sw zJAUwYsP$L;p@7HZ5&F*~x`Yi0@snGb($vpCU7|%a@f)q+;L4?3`HuF1@JKs>xQndV zzI|)Yj&@n$+k4x)c$Oa(VpDq*SIXVd9xu)$67BEoPj1^DPreI#u?XCT%~_E)F@9x;x5N;aV-**s^AFSX!#_X0n zZbsU2q;HEfn9>&5{8UC=@p7<~uM`uhgUXx_%CaZW$~eT8Ou>mJ?|S1SOHz^xmAiZ} ziq!0uk^Zey1)$=EMCmS`7oi(?+P92t!$VVkpy3;snOq`UNv1BKAKi&W{sz<1Thr}Z zf*tJ#JA8L^-<`tduEX2Akze%qd5zH_>LJ7wdc&9;l4K2Z2mAxkiLgHw+8-QuusJB**&~_47EU=`X?4+z9PZM%x1`FH zE4IG#DI)bkh;I6T)dGWct3G}tI&%3E3}M^)0{vH9pq5`%(JnD296h=85DUoV?ott6 z;!=u}LUiNusRe|>hh;C(HaRj1)}1LFzQodUgx#?KbyWplc*q4*FIHMb%)z^9R^u{M zz@CN7)a8cnE)?KjFWE|TI#>si(Ty$d=sA|M3lLT#Ayc#@Pp;loS8RMY&hVj)O~tn) zc)a3_w?5y3!^w8CZZs9lNF1G?+I=x1x-TGzy2ACNA?gLAVWvv8AZj1WSyzrLWOoLg z8Z^m8XWSMw=khfMp?hAr)LEskj@Fi|sogNR3vg7qJFP+$As5eKn-yk$of2V&7+7OF zkrR!%XRW#Bc8`(LptZMdde1#z78>TyHsgFtyKz7ijhU#61)9rIL+TgGn-3xN* zK($-ag$M7Jw~U*q(NQ4<#w)3+!73$`6lV^_BGIACm0LPxhp0pdu6hkbi(Aql~Idq8ynKDj4-UXOV@wd#fJ%}E29#B()-GY!t5DZ zG1+`yb^@s@aAnjYN!>K1c7?@tN5;2p-S$QZmE(;ol7*ab)^x|#-YcUkzI<@$f@oLC zrH3k(Rd4^2@`6Gw+;?+mqZ@t6QDc&KW?SFF5-Y>f1Q5O&ms>yuAnlcq1-D*?4Bfj_ zb6S^`D3>g1Cwq49*uJIb^787kii)Rk7nmvzYZaC3)n2->NGX?BR#L`7GlC|`FFgw= zRJUU-;Y!F@c(tw8XTcpW7L~{paA*VjnirTXEBs|9$(D0D<-6c6k<1J3PhDn07Vgtn z2OZp+J-no<<`gl7<0=a*R!fc25!%CmZ|z($LETvL>YJ5A_RC0|r5MS>8r(wlP z#)L zOZzfnNBUxFrNY{qa1i?rbjbxraY03RVjLOGB2^@~q}&84g}NMUj!0-=pP$)~$7)@H z5}_51(#^ml{zznCuRo&r0^<|0@vuLF`>+_JvMCV2Lc!1kO4|-Ei{Io5`$PVLh~LgL zUOCY5MZ=?enVT(+x273;=zJElQ zheH~qW5ETNP~aQTKC-ASxWm1inZ!F@ujyBs1}8TBpL9P2h5Q^k``h z4t-Vtd%UpsiM~2XB~o%IjAv_$F{P;J=c^NiVOwo^-$sg5U-VC*f8Xe2oE5sCNpp%G)4( z_@(z|1#iVKg(cd3WbvXQXqdf24C?U_7&}6W6B?_3j`bf`3K^I>-H;19yb_`X)mCy%V9n-p&Je zgnD~BBfvy}i2y@4=-}V|op5H6eLFgTITF3wclVG4cLE#^b&ipL?(`21?CK;Rva8cS zFc`$)Eo7FJZ&%1j2SO;hcnTK~2+ts1eX!IWqS4$pCYmfrELqV!veetUWR+*N_iFET zp6fj~cy9Ep^Q`xFcsf0+AOJ=nJWKI%m1nhSBEZ!Ddn-sLGwlUzG}!g~4j11pz+djP z8MTbfijT~a{{9g>RFCwZ=DQgP%|o=c8-+NH-z9ij@KC&Mc&^7obwmHX1imp1;8)9| z3^4h2-Xg@bCK`N%0$%|?{P)|~1NjRYz^@L1=|fr#lbbHFn^HUXo!I_cYu{zxZhWnn zwq0JtzRT~%IYMjSC2q46h0onGDmur`zrOv|w7Bi$sX}_$_ZrWAr9qs#zu`AC9~ktU z*%85jk+_-e(s<}?_N9&i|w*Jpv zc*%Rdq2X%$dCr{>&pk|Bg|wLK9Dgb;fN9Mfd-#hl74~>GwC#0s6uwB5J+FQ|?0o{^ zPRY#C`H=wF7!>E86T$SVxpv{{T6;>g7xogDC;0p!`GySs-1Q@#Tb@~eE-f~Q%_mQN zXRh(N<=+#hJmce*DXGZI858z8-HqaeS`h(DAvO z+mFwApF2L+@Z8%DwI2V=Z++s>ErpKwC*Jp0hramI`MoPQc!%x$xgC1!{M^-I?7XL` z@yyt358c=NIBC%`d_2AB*%OB{fwmrk#m0swy8=C5Gq<(jz;;G51gAWuIs z*V*p5&3n4%3m%ln!|USyzx`Hwq2~*_d{#a~xpUjdb%Eo7AEiC*qVr^cY%P;+VOv`@ zcXN+tbL(lcvcLb<%jpjeww&^`BdyKvn!Ea+S8f>Qk`X9zPy7FOhD&IPIQO9V{3}aW zK0denk>#hBZfMzXyzsTcvQLY*P->~vJ?+cSJ=naf@^V_Vi%n}!Eq|rW+j@FU`m?XR z{?@gp?jJmPYHc96-up_Y_q8*7*6oUW+n3Lw^0t5JMaq{gFVBs6Zn-XSGVpqr@3h!( zM@alyL*Rd=N7lEn?(sCN>fCe7J?B2S{QGll&pqb%oN0np?OFH8;H#>pyu5m=swqDT zAV-(Zt|Q%spPF5F{ONI-rboGKUV;1k*l^(JQ+EUg7=MUrR!iGl7pxGezNP83V9uVv z7hjtDusC`;(+;aZ(O5{yj*Xq-IUR~9(ifYg6fBoVefv$k~7`-nM zFPw>|uWI*DxWe~ed_L3u)YxmD`CiL81`1d^z5H;!ipCPTT&6&#fEr-1;S| zQ=L?&GSWwQJyw0Xg?+?hs863oeHwdhS+VVj9#x-~ock)*rzM-bryHK!6*&Jzs#P9U zQeuPTYZh0ZYHDw8&!nk_{fMlfFygGQeB$Cq}%Q?)aX^#3$CS{I7O-U&92zI{Pb0u*PU9q zxoz`W#q&_#8pX3aASJawwdd8Ny(_4mzn)32M9G~%$&o&f%yo#@yBbl_$9tQYo@UQ_ zY_5apq;DG<8rZMzo-uLr7Xts1{yu60QrR!IEc+gO&=S;(CI98&2a#XvP;T#B_xmWf z-x+-L6m08$yUzI}Z6ySYf?hB7RH`~&+ z`}ESTyH1b27P)UTr{!qc1L`qQc7bvyQu)r_jf(P#r->#$CjGI1<)coud>(#_a^r=2 zu48MSMQ%U>m+f_L6B`C!Z7WbNvSiQ6IHmE~IU#;`u0b?)e)Yv?=e+9uxfgq`2c^w( z?33%h#_wK!|8kWr>O7`jvP;oP{W^o&PDzWsmC;b$As*k}_Eemw^gxCMw8I(@T@^dG>2iCR4 zn~=v{;y)h$@5e=ZTjhOoH;YF&)k}?3qc)+=pNv2MqG`jVH~m5P*sqQ}9M}}_22i)# zgH#uGh|MdYul8+Un7it^kHWVtVc+&BeA{Q)QqF&z>UC2Gwf*AOhMUIDuV@`Rzp`cN z=40o7bnJzf8qPPp^iu1JmY06+=R`w0)oG;h0mzcda4jVGeeq=- zL_ap?dHfMrl4sMhGq9*aqw*8&&uV-3980Hvk8R%rTl`2G5@WJgfmAH>&0e*6+3A&= z;TJdish-95y!tPbktbwbB-1^nqm+uw`!fw3H}!W&2Z3LiGKzDxiqj)>nmV3rJO%nO%AGxkmF?r> zX3T3GxgokFt$wI4XT+u!va*kRKPXe^5o=ECocl;dWFFZoWjx2$Bj3MWe(oFMYOWdApSmXSr!R{yOMKU?IR7i2rcIjfg_k_%4>lY;cu=&R zKeiIRzw^H$noo<)rmofKcZ&1NTd!(s6Ae#h)mPWUEZ~JRGA*Lh(%Ez8Y0=)aX&H3( zoNsDqUb<9x+M#7Tv}}i#?OWGQ2Slg$k=}RpP|Pm_zi9^WE*^b;N}sr;kLlvq{HbY z=mVlo+`jC47>hJ`(P#O;AErLb2T>=2>z+WJNcyP_K7SlFqS15fYWU2hCeIbZjOa`^Dzvq~mfg`nKf%Pr(1{5!0&}F-a|HoaEU^S|ZG@=hiRn8sd6*yKnt^ zpYN@{CQ(~IX=&!D(AJOAqWfjkC;Rf;+G8|&r1aOLoqYJIbZdsv*9h;59AR#P_q@6> z?xoha##oZtzAue72bKrUqwNtbvL=KE|L_T^-v*4_RxX9zHZ^ZLc0PWbYU}fjfB)K# zU;D8*H0#~qIk%_fJlDiMuYRlVNfoM)ZkyYPvCP_2-p%6tmyb1JRO8vOY%}#q*21&j z+$PR{@t8P&=d&OEM-Tc~%TbrMoo++fHEj5W(=uk!wdefp$A9arx8t{hkMoE@bX`q- zon`1@E%SDK%)%}Q)`M18w0b)}5^QG+6kUv6N;TNq@gapB{;X*4I@{Rs0V}L6v9aSp z3u{Yk>^K&Dyh>tY$1hsg@0{_p_s+I#+H!j7raMl*^=w;5#VH5+ie+sb_c^hwZ(GN^ zgN?7O=DKfc+}4pY@ZUWBpI-dG;Kx>-E~J-i5OW*bp61@2ClgK|d-##PkDetjxAqkI zzrQ{6_8$qc{1i%N!#iHQFWrJZ$42qc**&jr7#x==?69 zfi+UEanAEd?riex+t0rKB3VTPTgBLGQ^j3o`L;D|dgqxqjqL9bn;K6&F^kdV>7}e6 zOX2Z@lE`hUe1C3k?c+~D@79cG!y|j|IBWM)?@Oc4gZPO9TDPy*Fi?>FjOAxke_H9< z{;aKOA+2-c*u#I8{?3cfz~}Dy!#(S6`ln-aGG#4iDGl=7dshDLAusyzYCmAM>Thhgmiz9W zcCn$o(9nI|>89=*PR9%Xd!eC&S_O=8xmB?H^w*vekBVE!m-9&X{>F~U!V`tFg%@93 zqTU)i{)g#b_r4W%_!`vVlki-grLq?PX~)m0_H6l<(eLfywqa;pA&uJHEY3Y7mUL_g z$a#W8Pc7+q;w?R_WzSQRQ*7`Q((8O@VRIeCt$DkiC0;oi>G`aiD!P8>m8RA`fla4L z`$ow4y_*_eS?-Z_=%#;q|Eq=cK!D^q#xF~UsXQK%F~fEXzw^p+FNKr+h~If-nRwsR z|KmlH*}yWNc#EWv#P4uU$nhS{S<3QBA6pXe+)CxMA|OYo%lfW;LbaKW@>$v2M&9vt zPkTE?XNL-1t&bP}sz4=!zCD*rW5;t3%Q*zm#bt9V@zcn7?tVmwKeyfZ{=J^zHV;_n zqun$UO9#5;j4W1+uKa243r4$muDdkfacbV+U~K^~7wP3eYwG~`0uG)op6kX5b$#6H z5)Oi0TA6HFJl8ExHPa#T#dF=4W;~9w;Wds!U&tX;hhIF`?Kspv&v|fT=eFg54fYEh z$EH)?=B~K9A{NheW1osX3f`@co6ycgXI0Uswk?jTQ-z9I4t;hQ05L=eo`QKbus|&9#n;r}U|53{1?>3*W2kkYafCg{vZk zES~GeHaFbJSFgZSE-jwxHf~kBKwd4L>&DjAi}D7_xU6I1i|4v8bfKSNdW+|}Yu|Zj zWRY>4TAv=g^!CdTvfy(^h78^HT|C$AXmmJ-7SDArp6j+RFEuJMpS`osV=uTKy5uah zA1TEw@Twal@WQ*pEM(z6%@KU@Tz6F$*qJ|z=eo_|fy^7%3Gu?>xo+IEOc$$|+2c4k zed#@qx}p}(b-RYFoKuVEx=j;YJlCB{E}rXNJlDN=u6yxZ_s`I|ZgU>I<`y6vLR@vt zDjbVmg=5kBw@n-q;#llA`~O+uOqjPwUF<)H!1y};8u$wqn}zqiSFK)w!`aQAW^Z#t zOJhq@%aWGnmX?;KEv+rfnwPg+)qKp`eB9goK5z5=-sThD<_EmZ4|7Y<#%k{oW6GN^8Vd z{`jk3d;U+p{!Jkcf#;3ZX{}ZWzog&5n)jS&cmSG2*8I{Tz?T+(%Q0`uac|4}ye;>8 zTTXae9`Lq2=xv!VPudZO{yT)1fi=H;!ux<{s+BTgaG9Te2!CmMTzc8`AP)WaBwhyA zymxR-`NZ-EmOa?|(9)AF4>!Mm$%mTW(YodrRrw4qd(+D&E%iFl_&~#hD4{ncejG5e z{{9JXgKG|-So%QAgUt^uIob4Z)`>9%?+<@bJHl z9%bk;fO_2YK;wfA4?%|%Oyo_n4cZp0|7P(rh`PJvfu;u=A8I)HZ($$*3Li)I(fYvB z2U{L$KDp%KruR2~py5rkk1m}V`27t$sKdIhyodeCSHC&9>~8k3-#i5R8|_m}eLjWw zT;-FHI(_YVX!WMlP}}@TTZ#wt*k1)-z+N=3jO|t9A%{Z?sK(5OL_g-iC+QlZQ&dE! z$|L{0F8K{i2aEb^aM2r?p4McX$a3n}#Pp&?Z*tL>F#UFmzQjduX8IwE-t3~cFr5Y? z@~_23U&?gql*_-RE_y4|se>y2T3z&IOs9^c{9ERtFK7DWnv9cZ&h)QfI&~!E-wGG~ zDyCD%NB&*qqOWASeGk)0rrY@~>C_33f0C{tx+#jvcgjMvarmqO6a9S#O!`yhmVYw* z4oiO-{!Rm?@YLXFerNhuar__AWUy0QGw1EwJK5d8(fEe8B8z~sf-6#aR? zG|1HO9|9(SwpP)94>0|a33VR(&S3BT#@lRG=AbmE7vktgJeANNpEI#9aJHOLsPci)}(W_wc$zEKsaKh6spX9~umrp5}e2`aMEA$g*lZ~(TE)ic* z@F9kq#ghuAHhHzTMSNVr)CRBiE)^e8Ftxd>y{)3GU}|GmdzXo&lo{%8HS*wf4d9pH zAG_f1x!^x>!C!E}pLW6Os5xUv{;#{}54qqYF8E#-{4N(9bisC8CDXIXMSqJ6raMmc zAL(ag58rXR3&hsPwgg9Jp`lDQN3uzKU8kS|2+NPFY5=z`xC$qy_n zgvb&d>Ev`E{91w^7h(r~DWBegDg6=Ohk&Pe!NT!=l77QNjN+HVoy0Gt<7xT@ z-#66n_vsgf@S1|D;98-_a{7G~cgfDLB%tw_%h{Q`eN!CzAFtMrTfZS&$6`MwLk6psBD zM=;1Zm#d2Q27b`yA}Sh`XxD(Kb+5?|1QC>7qVxHkLwZe|Bu3RegmFU za3k`K^k|`9=t1?0;Ppg*ygD5R2oJeQ`b9bl_$B_^>Gv0L&nW%ASEk$hE6T4OlYY_* zd)hKWUUcvV$_&x=XE4ZlOF$I?t zJfL7yI+i!6;EIBy3WgCdJ)+ zsW6(FR)JLfHmNo~b)S(DnmKh}9p>o_ZmlmyQbpW!?usBKX-;eg2dkZ!#7xr8J_iZq zH4>iosZOvo%&89GOW}$@SD-{QGpXWe9v@FXiYwmb#qOD{__7A><(G%p zVl%0kMB!+EY^T_|kjvgF_)Gzp%HZqFsbVo->@(iw>ttnWDpedf9M5Fqli3uI!~TKs z*i1Z|%_kz|IIjJ7;xsfxiHXJd=5x|>CV$ugLvMjw*kh4$zMx*>#j*(X`37RRl-|ff z3q|&<0bP6wmPJDa?Sp26_-3}`9GjXdrIb|8UgjSl<)Iwq z9rY>O>xSv8N7=r+E@eku%C@?cp1PEJg#Mj%DgAXRz4a*D>SoTix|y@BZszpW&78iv znbTJ{bNcFLPH){j=&hRvy}bgq7S9eQ2a?I6n2FDhP8P?eq!XZ89s@BuNd{XWUo5$$ z{|V<&;rIxqWz@NNVWN^r;u3mMi03N$U7?Xh8jDxWyTd~E?)a(v1Vh+=&o1Y880Kl; zjJ8d_!V~CrEwi<%P0MU`wp-NvxN+3_D4c4?Y{;f5k7El^2+2{^Ze_OWw#LzBnP~09 zY@BMVOhgSPM;m4Es`kmkaNA@-&UQ(o%{EEn9PLqNtGg|_a2uq*q0yNXooF2|?MoUL zu`Li^e6hZ%fllkCep6$u>#G_oA%efEL9>z<|4ofsymJ0x2}02yjWIsMZ}Oi;^}fQz zcNX}yibg-0@9)s($NxNML3kP)ETE@4bLAB(VN8-_tHW z8q?lsaoPI)x{I$L=}Ok%`(+p3qu_g{24BX-7sA+$#y$E^>vxZf?*IrVG!uR`AFb<9 za9tkX2jOH5KKc%j$(L-B^8uPw%cHpflW#c$rwO6{G~eF=Hu=ghqc3PC{A#|xbn*4H z2oXZw=s(SO#>MyER?MFuZ}gw$d)CGG$O<7oshRMr`JQm`^6j`SW{EyN>Q7=E=p3zEx zd(6dm0(>uY+5)wVT|m*hE`sE4xz43IwY;}0c{(dT1-|Pv6Mi+{t$5e6iF^utAEg)d zr)h4!$Q?o)(@glS$M-Gpnf6?d@0~v*dRTzDT~e?s3+)dh-4feBZu^bo`$KPCryn zUTpB<%J(0@_u56od(J246*X(!c!w^I?_1!znDTum=9eyp?=Qjkm{tzITE9Wm%T)&c zSU|Ry{lGnlr%^q7RQ;tnN&5RB_~44HKZO=ny;O+b24C6Yvg4&WWgUjdSHpqrfsan& z9aB9VZySE;n{7++tN)^yf9e82`cWE4zZN`8U3~8aAK{6Q;?aDsAdo5VguzF?N%Q@8 z7vBfLw^qp`9?ka^7vCqr*RJ@`BwBob;Nts=A#aJn_YoK0_YM7;4Ziod_y{ipAs#9h<9s?g4GV!f3`0jJ_P00CY;=9`5n{@Gg8+?xd zM|{^9d~i>Wc$53={JYlRqj08vA2s-{H~4OL@qGn+ly4ON#(DU@ZSbv|hwq05-&^M4 zd(GfmKM!Byep|nr=Ha{A;A@|UuhZb$Fb`k9!PhYl-;lvad8_TuozGE&uX7&0q`|jw z9=@`{cgs9{Ck#IF@%8lksKH0}UytvT2H&Q6_?|KNZkvbiD+b@@dHB9<@ZCNS-wzGG zE%WfbX7FvDhp!P%NY{_ooYb8GKYn8}R7Ae(*W><46kmE|c#w?-1gf z)DWpZxFr6gU+@(aDBcsV`whs%jP(V`i}(g)-?rWz_yXj`d;_u^;MlEiK;DZLDctFP z%Kfx`j&6F#m!-aFQrbTEz9)b1a$^Wz=?M|t`=q4zeC~eWm-v4$*Z!RN=%2pqIY`uo zCwm;BO-b{;lZHQ2_sAz^=oWb@(>Lu7c`M4r`{NhykDoUO z_{_}W{qe3F;5k1RerfxHZ~inF$koN7m#NC){qc#5zY~4&{`iZ}E8e_xWsGwso{LYb z=6m6l&bX%i%BW>s_z8h9cG&KP-?eNAS#axR$k1Kq#rxwI z?~iwWw}mgkjaSNPy3RTgFX!d3?UMX{wT#QWquim-f;(QUmUaL8rB`HU_{&U^rN?C^ zXYu}c%d2)zRkGOy7OVEm-PSejS4>cM{z$fOcJ_+O+qQkd^7zj6g(~B?u>Fb%!Pqu~ z#iHQW?n`$uNryV!rN#T>E9T|hDti|1kDuL=PiAskj$H6lKkVTb+`r<`i}%NyCb)Qi z{Nnxb(b(es@r(DzFWw*jGk$-(wGSsD4q;o<8+`#HZD-YgwAGmJGXKz|` zRq+s>H#)ultHep$d-Wfcu_{+wFTHmSZq0a8^4iql2G-%1Wmqe(6oo;eVC# zUQB0kCXsk!zJalrw~Kjux!+M)w4p^CTC|~y`{vM3LtW8*C+l~D4gmiD?7a(oRMoXV zzRt-cnLL0Y;Sn%|NfelW@F*6C|7{;SmxZDdABP zwn=!jgp(wkEa5Q{9xLH-5*{z%6bVm&d_#RiVSP*zFrFMM;3#ZmN5dhGX%m6YA^w&?kA-^#Y=vF{ z$3Yv%v{3!atGlcO^`}>DDij*QWyv3Da-1^^0(W z4lpEKDPj6;w0;qNstzzDJWj%f;<0lOh@7@sV@mV!(9gp)Jj8Q8Q53|taNNqnHXgQX zzrT;?zvxWELeTHi<2yLLlZRbAT*t$19KZsy@89@35vUTL@T z^E`|Ad7gHTt2j>QcrM2o9M9tze_T#QSLbu=;JAR}X&mFZF=PT2jm-ELa(p?*cy0@$ zXL7uVWBidZkOj%kPNJkL|5 zqt1$}8t`n$I&agu4u2OOvB^*5)S_!V{tkBFr5Ii1VaJ2Ec)Gnc?JfQ$Iax(}u_xeZ z^tVV7@!-w?)W0M3Z8R+S~L~YgxT@@UvL; z%A@lU*%^w02HJUeTx+yzBrf6nR;>Efkv#&VBY6ZypVlLgZsrlI+VK&!6JK$wZd>Z@ z>8fjHC;5gBdc^~OTU+t%H<*K;r)}t7;D~K>&Q1X&i|?dY>U?UTbi9+T^;_$bzR<0hoin68$q43 zJKs_2sBx4ymN<$Wb&mO^RgSA&HU2zD>5BT2oOuN5@K2S~QB&%0F09PWU0#`=v%E4l z$FX8zWloNx4rA&trVe8&N=r-e?=_C)b)|Jz&vV>TSHGlqNr?vMBP_3URO5lsrH;}f zXMrQqnX$u$^zbMjYM9}u;f*s)6B;OwmWFUKR_N=(B&mBGMleqn>IQ{0dT$txjKC)| z3EifiQs_E|Me^=*SUet+%g5iftQ!qMlde>vbIpw1Ddz|sRg2x~YD2fm$rvTqAV!(i zAkre$pvjQ?$sAE@c=O=@AIHo8o(vy0YnwBFV)T5Hio=d&95a5)l@kIv#T z^5L>0BA-X%D>UI-Eb-y8BBDI{wu&*|a^$0Z68%ClyT(X-wHO2sM4HDl@6M0P%-~A?h z^bH?lzPn8L@+7|9CVaH#VU)MWgpc+gzp{h_ef^f3;5UQSNi>%65mV6_nJdXLw_kRx^SBz zbWiw;xDRnN-SEqdZ~U~#=Vi+B?mA1pQ)kK7i5YCsmBY|Xzki-3-)A$=t{i_mOTH%D zcj-C{{eFFxd`obj=WOH+oF!i#?gO2Tysw`n-(|QjbT;ztIZM7M+=n_FdF#)T@7P)L zHQ;{N+2s4$S@M3IkuPf$uNa(HQyM20pTfuHTyypU=QY>2*H(7N}8P zz`#fI9i8v%5?_yjFTucv@1Y9vdJTMu20r?xs4?F@1K$V(UxUQA)4(^W`2LRf#&Yx<_>v5KzmoW#G4LfD_~@C6QQkoV-xvcQ zJ!>)Yy=34so@0BP#5ZW*8)uN$DDk~v;2Uq?!)2?~s8Hrxd1q#|?ZqRWRiPd>*Fz9}exNd^Q6g4%w!Bb^{*{#io4O2EOdm z@D&>PaELXPS7YGIJq@4Rz=w~_Oyva(eAEZ%en4$L3jgU>FY=wlF;Bm+yJZ*ktwz2M ze2(}i4S@X8`6xubfF3{Ab((W_TfCu@c60LQ&&w-VuwZ_!-JZ?P)7AdwWM|KthX?Ey zJDVP4!n1KGnWO?uIl3ulQICa zEQbm|-0n%(Lo(exKRPj4=_`7P$+N!oNUF7DhHC-K&)t(*qDuk%I3Au$i#BLNb>m%1 zI-ScK*q`c3cBw9J4@`Uh#3b0tQds2ofTg58aJ z+DhVG6Id>u3GSZlJ-Wt$1A+Z@Jur2QD|IF-TM`lb-nu3*HYCJN@7$n z=HMSvZ!1b1h_hSmn%pRG_e`0TQlgb=^9`EBOczNcE!`*;byRn1I?f&Q*4I)Or{1=_ zvBz>EDlx{cqOPK5?jEBQvLnf9WO6P`Y%FCqo12bu6qKN%PNd0^)NvV!!B{)VwP0)_ z&|P#Q#A`Wx#ZY!*4pdj!Pg`7Adi#i(w^4m$XFnGx8$DG;TSf&FYhFu*>0<_B(__+? z_Z+QX){{JGLdg_gg1gDL#Qmu6F83dNKXWhZ868Z_o={Sex-3AcQR}GtP^(D}nEKc; zr{yuO^_;g9$HS=>j7bc}6h@)`R7+7AYR1YQOEA&?lYNj;ecX~5eL1G?O*~c430J4|`*#Dr0-KJy%J z+@BgfH8E(ZS>E%j)av6&iP2~|;uduT2{Ka$GF`y~knz|)#lAT>8}1Fx0wpuykZsE5;H+%;{J!9mc9^m+__!@a zYlrsW0pzn2UsC2j4<%zN?Bz2?yNXUG0%`EqBVv1@79QAdtAwd`-_GDH+lc8YRKIhT zLGn+yssF^OtD*-fWx9{*-P&aLjY@}%UgQl+eGjGL_X-w6I`Jg;z|36(fim0TBwv!> zwqH5sOjM60j=4V=cksCr>L|-#Me6pa9xOWfn(e@lk7QG-A$PRh-BEOMB-4{l?IxLY zA;-Y%qo=Ch4&L9txxd%-+aSQ^w`rD28A!@Z zIUGL_gd(R`mM)&4mbB+4YBf*vSM}jv7HV3^smCV?|q|DKSs6&2qzn#3}o`ejv zn;rh+-k=v?%0id=AZhuxBg5_aM^j-`S8)nyAB_n^u5Euz`<97 z)`O!Sh{LnRV{M9kTN>=N`J#5-+xN|&&35mG&jpiglU){;Q~AEajfEdJ*N(5Cd`I`Q z{_>s?PfmALe|RcDaTb_32)nif9iXOrI$+9(iV+Wu+C`Kh_bW%EcfE2n>U(hy&UE1^ z=W7pRevm;lnD)kz!Vep2l?t#QIx?u4m)RGo17Hu7S+LHY3O=44)%#TNNwD@(9I@H< zC-R=&I$%4{n`(C}tcKKbK)ZCDL1mV5Oij<}r5pnX_?Uq*dr|5nm(?D_QkL%{?g~r=={W)7 zrCw{H%jt>>oLZ5IJlx;VKq5zsRiN(-5aBD zghUUUJ7@5SXGA~igYJoal4>)K@r_KkxSSo?zTQol=*gwd3CxqRT}_!-5&KXguUW89 z{;2Q7D@QH1n4MU&2`bjF`o!U*@k-nm$$o=J-VQE0IO2rGy8FFRwm$r4L+{A;Dc``H zI$#s*wD+;`@znPt_$}b|E>1iYti#?-T8)P5Xxur~(OB0=tfN@0qf}Q6tAXr&ke(js zP0i$WlZ#_{tWY-!r)#w$*R;xO+RbZPId*7mg>`s+M+q{u`qp`kwI0|%mU(8XD=CyB zaA0%K4|~YpruQlv3O6Xnz;5p)ztjCVKE#Wyfcr7E9n`krcAOWDaqV(dmLCpg?xFfv zQciytYk#Y%kN3xA_Q0`1h&u*0qPUi3yQgD*P9^S`GMZw3g&wG+C!XksmxDIgfxYa4 z#J#}>Y*X;>u0pK+lY4^?W$z8{wpaf-rEqWXao8Jta?jr2!-2iQJ+{5UuM}2(_)1|- z@!sHL*#|Mr*8m(lg0l;E1jqI72repoIaq@Cm4)PadxHURr@b6(0mZ%}=!482(jdpD zT)v~}`QR3qf#W^Q=))OO!kegd)S;m5pn5DSxiB>`7!{b=b9>R>-x$ZrmhC$j>?_<8 z+)>yYyc@#@@ZT={_YnTuU3gD6$<6ku=}{S$?&rI2>$YSRb;qtRS%1g+=htJa{4zix zpZL-qkA7{zI7~SJ_+3U1%1ImMZOU(V7;n^^{O#8jne`& zyZqwX7*;d(zUjO_W9>4VzVl$5N77d!%<|MEeQRwrmqeu_J!ll8uStk8QL$5Lq$V%hz#d0VDuM*2p*4R4=A``Pwu+P;@#VcJGx+qN`nqpML*N~-hz z-oRUO2HxKoc(<7FYW-z2j)y6CP%S<|J*DmN(Q!{a!FtOt(p+dBuO-*iXA3`UTRWL) zn_ix}&$BUV`qaUkA?lMLbM~QFVHBJ?7|+JP@f9mvu@6yA47tJn>{FpWGM@F3I0nZn zGg*x%45_}Iw?t)*8Gv*pJ#I=<$E%y{eXI_rjo>4#IG&Sj=%OBp`n6c}BdS|yI%Csf*fy*JtSIZt*d+&g?ZuB}Z4G|o85mt~trQD1wDlDPxDSRY>~R4d|q zFRcs3u)HT!_Tq?V_l?7TrgxK)X&Eg1@GH)-ENAqGo2U%0qpy%3z8uVk-8e4q2vz~L z?n-zAXH72$YvGxo1^bMvVOKB)sVne)DfR?4?j6B7HNZwqDyvaXEH{piHG5*Q2Cch( zgK|<`V^M>VE=`9v=SZdlQ8X>^E~EwaIw=1$?w60+>h}iAckT@??q&JhA?Ksw++(nN zbhlpWw}UAMX++);oP?UD+I9pd+jj)hvUNJy==oqD=osfHXn#!uJIz*elqQ^;*s-2x zBo6cjt8Bf&O4jeD`!)x0w}Q_x^?b0OMQiM`VGnD^9#+Vw&rlZuoC`(svj1|em6hF{ z7L{pvt?rNL%cb2inkOt%hD{ZZ{< zE%jn81$G3lbz@BxhHFZbhhFJ|spJ8?y{{di=@puJs5qmi8Blz==KqNUN;;&+p#QJ( zyt+wS$N%++vEE77g8g>#Y3^;WI43cw={~@fMLt-W&xLJ0%ce|E8;F~3O{eui^dPM% zDlzV|L)Iac#X)+}$#@_=j~{^(waS{%j8@Gk>QIo!VY6co@TN10YDVBLB5<`KP*1V{Fcx@{20JJJd=iw-Rsx_wjeK4oUwp!4JeHN8SxTg@9H z?K*8#4xbHYU%n--Yh9Tx^$RTBlo_t^6=f&0YY3(LURsql1dKn5@zbarC_b17JGE4L zns_0NWypDQx?*9ydepAyeyp#1s1^Y9xjOmI)XHermVUdBRzCeWhWEK1FS4Mn`HG#{ zjOvT}pt(va$7mI>V1MB}IZqkS{<&w{`A|y-MHf39fU%d zHTuoBgF6q#O`{h6R?t=h15w9{V`GlRj{n;YN>=pX^{I~*eel|GHtR-;CHk0UY~r-c zUUe#R1EI{45x!{m=lZtxZr`wZZ3@NPC?4$P%O`|T%rVQj^5v9+Gwq3GV?y!e%aYwB z365E8$8kS`nVJ2`-hUZd_;$3g!fbG`jcQBt^5<9So`UUcfMyN$zQ>Ca27lk9OdmPe zxIKM4+9&A`eP8K&gw3X+*orc{5G4#ux$~Xvk8Fo~@!L{Urfh$w?-4fY(2AVe@ZX(d zmVzU@2Quw%CRfE>UVU7(X8IJrocQLb#c>W=ne%n|*x7wsixLmfd?P8C zh%0nuRP-RyAp1ELa|@JJq&`^m-fP*R^$*Dd+$Vq;V+SYC$Q+oQQJePKQ}_e8nIjJ4 z+&OVK?vrdORSxx~;2u#>J=j=MoBB}EiQkeJ&^(&?KF*hH2R6^5^yI{?2ep)LB z3T?bTXCDpXzQGGSdvU~ilkFSCcVla?r_!EdyfQ=YC3=HVd$#tz&>OqiwOPTQ1bT^E zuWOp!9e6KzPvM6*q+?jk_8A7KSJC447G(~^%+7pm{|DvmQ{RZ0HRZLZ@ov|^cR%>( z)=6)~&$;Y1>^b)IVq3DX-e6C#t7cEIyKqmiC$J~D(TzPwr@IPW zLuD*SEKRUlq18KDMzoFgeKW1U|F;s$+O?JD6KkIL1CAZG1A9`*u2!^#&@M?3s|%_L zE&aE|^u9Btk12--Y30AeJ~7ZA+<_afD*~!Lyk9_bhH;gLkH%eX_dV!>%kisfy@NPb zQ;z*by9Qz}pYW#LHv>!C2b(99^BUAS4nEa;+2chqzp?wmF!zF`X4W=b;**66CGIpn{SDlu8r=A8I2u3 z^8N^=tIUF&5JBT|= zxVxl$??A8yzKLz*OE{-Id^Bmw=YlHaxC+p3e{$sDQ-vqD6h%EkCHNuh-v)6lVzdkO zw}Jh4_7exT#ApkA4)2nWxZh8J$ zw*;O|98w;KoqfY)0X!Q$H6Hh8aPL#lmueRGjPXD6l~dJs^^c?VOwT0OMBK;FcDLFp zGkl-Nc~8>xw875@ud_v=?v^<>4+7>sijCz_J?hLaq464(0)Z1e_9yMy!A&pO& zqsJdUn!tR8_JTDUq%SXz%K#iFwhT=1UFIM8Chx~nlUeVL`>UL@B6V}o@z>D0i5{2E zo%kjUAb+%aEPCt>Hz>1d)v6>C=igs*m+s~%Y2G#)=WTkP{lUj=)_ePdPugPdO?V>y zUK~ddJ#34@zk9H?eZ}1$e5|HF__aNlTU^4fms~${DLa*+&kQXdI)E#YZw9UCC%IV1 z@#rfGD^Vfe!S(roN$=xi6*N5eBZ{sgm+Ou3o5Wid)9dBOL#xxgsPBruxDZP`*3wcbxhVuLGA3WzB1Bz7N|TH z=XU98i#B)3^g+w!)S@0`=(3?JhV(tgOkdm}tsZ9C;`@tE#)9r47FG&MVe}g%1IuD3 zt(EDvLDZGmK&!1PxE*oIn&*9CE8UJ(N?Ehn5To)s()`a*N05*iH)zYWvpQMA>Lj1l zYKp6JAFYaJ*;cG^8YCsMxch=`d$`8g^CzKAxH_gVDWmm#GpK|Lt`Id|%{vlDjX{qX zJ*ou%jvTcN|Bf2fh<}quwK09RF@0>@M;4(zRHyf`{%g`;{m=-8za7LkfUqAXdr)o1 zhH9I|unxdDK2d~?rG%Z|#;0uG#vTx+Xe+@PL-?e6Ac<-H_F&=3H67nNxk%A1ORZL~ z3+h9Y57}7F43`r#WaK-Bep)D4F@cw)89(9u?cj~5!%8d{J&__$`^piTqv43Oe?-AH zoL}^R01c@FF;qVLWfc||?HbaEJ>t!jinu9pzIfVIRHAU7dD%*J`lLa84qy7gYt?_Y zL>HcXbghkzxyt?O{ZaQ@?tc$==+ImnX-xlRP|b#noX|R*<$!zGNylL9pAHSN(Vdx3 z7%y?&U7U`qDC@(tBemy)TMH+~% z-a0~ddXs4=)Gf1{HZ$AWKMKe3u{eq(fA8?o(X0)#8S%-IW%+C!?%tTUlxAk}nezvu z-=fxQ$&Ajl92zl{fH9*oi_il$)=p>s#8&KVE~m}mR6d7OaF6nSd{(Dq{`F9J{#4HA zPm6I}R3Y2905zv^>hMw9l##oJ%6@%BlVTkN`nK_@Kf0raw3vS$QgCLL?K_o@^Px4P zAKzK_Jm(GNh;*3pI<6&N5307;gE98rw4t*93_bIs`FRZ02g=pT`$gwwR^H83t2a_l zIb(e%xIsJoy#p21d{HZQhiFy`p6REss601?!LQFy;`|7OlW`mg)W4!8V%9 z;wlaEK`Rzy`qnH?cO4A2;A%kIaoLHh*v*?pqr~XJDO}RzLn^y-J{y*p$#$WV4o&yb zvv7UyDHESOWcSjOYvayS%%GNk!=E93WQ4t^za6Rm$4zTXS$P!uoxwPGX0k1F1DjD- zS664!Wu>dBscFg@-GXFIn3;snNny$gw5EMc%04O=J|k+hWzkCT_#N1juc3aw$Oki~ z9MWQ_j*|AJ-?=AsXIY%UH*ug4AG;8jrZ3e5X*QW_=I$VQMd;J)32>RMEH=w>XwMqT z^@U(&Z=?TII$2xGbt21^r2Xm07=aIvi_*w^uO2yd#HjI4na27Yh+1{w$+$*^_0r;e z*tUOsWx5ZavfHC(Bn(<{9ZhRtT+5$~^3a--^(O-s_MUH&WjSfA#?#7aKL=;`KJ}QA1peDr)~BIWk11nlWi&2F z+q-jbRB`SVpJ^K$nK^Ed>{j^U^jsUOB@4EDisA233?xW+l!U2{_4+pUk%9fQv3{-W z{SO>v4p0v`q6zCeJJS_6Qym;J^D~37L-z(3*%hq+d)aK`a?}Oqx*wiMn*0bGDF-m# z{tmvcvzhqtZ@!(pFx|%_VQ)BjATHC&YCmv5_kw`I3+~0;@69MXo_mOqHZmL+e!pdy z-{89~RXd(y{TYogXvOq&?YT{+kNUPf)VF<@k*@8Y*m*0-NT;17dKX0BNfK>yC%)Y= zQtvz2oWi})imT7K%&CKk7>>C+qJ31b$ag_+_OJm`uxwIEckJ&Xj=S z8e>lxum)htVpn#B^JHH(*=A28t*DOQLA+6ew2yJ+KI>2vj>C=q>8^6@Gox{)4!B3J zm4eDJi0|jnjEU-t($=|f-tC(1qFuD(W$v;On0o4M$vg$_jv%IV>KZ^x6W?zKcb4IN zV<>Kja@6|iuQyVDjs6piUyp;?&mZ~$&PX z-Gp(g+t%4OG-!6S zH{fk+zVgy#+Kibt1=d|zOdquFnO&7XXH@{BJb|XpEB$TwjqCO89XHu$SLflsE`O^R zX@L%}zpbfdU9OI6-E*_he)O-ncqJFNG9!b& zo5a4I)YRJP$9ll8DB*{!_zn9wl6LRy#`-tjX3-%w>rg#Rv5J4hTL4+EQfK}0+R}!~ zYbt8YDeP%-VI^Sf5FEyWM#s&$7 z+q_&Ceh=ilN@9>=xFvx)9Mq|08~FLBJdftZl;#<;qIBUb{sm2dchAd>zl!?eXgCIPl$h@p{gi+TSvtdk(Rn(Wp z$F3I1;yg0TkCPl6lC_VOhO`e++oZn6K*&0+T>V425mm|3sq`(-GjI&+?sOG~5!yU$ z?VVkoCY(nY9UtAWv%TpiuVmg%{6Z^!otyFcJeq%Fm}R`@JPn@4&aMs*o3t^0U3~^R zy4p3{(oI%Jm-c~49q7YLadmBd>57J`P!i&li8`*WudZvT%5SKee~#=~_0`pt#pTY5 zr42M^B|B(eG1N5V_j)#U^#Y3_+He~hbcZLFxO5nKBt8G+SK+70zPdiP(?{I1kcLA!Qh^+PgReqehd$jg&W?=@SoOyM?%6MirV;6JQ+*#6+ zk_ zm^XKJ_J!H%f~sm=m!Gdj&fP*RZK$fWS?&2sxv;v@G&x^G&?m3Yy<*vivORbJH!h6* zO&(mqd=fIwzu6Ag=e#FgOjMIU;PZC)+g6`vu|nxDut;G!7gE18O>1pG-)hzpUtmFS zQ+pj9$$p;p)RTvH56`Kou__ITShcQ2TV!8=jL!89&E8J`>hrZ}NSTnJtoHRSxjovF z{gY6Ppgt;{=DrasK@sTFR;MgR+^KX$D)&Y)p?KEEHzEe z&tuLIPK%p%oh`GQ8fgx7o_6S57r=+WO`h}al*0lp(2Wg(E@+tR!sp)SY*qSp%vlff z=afT4XUEFIN5Zx1Iy>?4O#2#q0N=^>uV>?y?Huh9{%JTu`{L``$Y|(A-sUXYZr6mI zPWTy;W_jE2Sy2goHlwbtw6?yXs;&%Sy|cEgv>rDnt7z*n58oUpDJi|WqPVo7uBPHj zTvF<=w8~k`u<@xgi)d)5Dk?>}49N0mz|%9StXNXYc*9a_aId;zY4!4YV`Af;bV+!d zxxJB$85YNN#)yW7;;Ooex&}&!u(+t9xV)mKfi?wJtiXu!IxG%qR=>Qafj*Kz`OVGF z&PLKTmCmINrAwVfm8G~n%Q&xgRxU5SGB+O?G@iQUHKb=lL3VCVPDz8a@*3y0ln*a! zc)wkbVFlHr^TV7~hWq7LSJYM4HY{JtrL*jH)0fs(I4hY+$h7s9bq)C4huVhX>ZPuV zvIbX0W$BeGGiWQfz1iQ^us*keKdA`4o3Ik!JJ4&cVrhM8ZSC?JG&B>*GpWec>XSn% zpo}jQW_d$RZE0QUQlVB|E__f> zvK(tWoL;MbmW~^t*W_FKQb?S?won} zI76?EkZ)gCfsx!>!w!SK6IQ6Mva}Qhg%d}3!k{Zt?9}Xu?#4{)a#E{7gHUSY!x3%k zUr&bZDr{A5N9R&!Wp$ZYKQ-4>>GdH4MUyiC{Wz23}*V5&0+|cE1X!79` zRE%lt@OxJ^H2XcP={c33UN@QD){Zk;dKaew-v;RNw(?IV5vc?FmkvL+tvR3Q>pygi z-|!0$(^OPEJuwACPL0yzjNEugCgU^2MdDM=lFt%>5A=L5qAmvY|KGT!!%GbptHVff z$m7O;r|^nmucple_2!XDBOn%Hl~^@4%4)GjTVpQt!_{`oL%+)LrYQNAE$UX~+W2I6 z;YY;@B^0rO6xJNW0j&pj(Ho zhw;vteDfB|)~Idj9m;jgE-(JLC}AyG=EWbok$$oDNepSDowIr=^0XWBBpXnDShvP* zi@77Z&$2!0POOtl;-8fUJuKK*ur7*{JGYG3nz$|Dj`+T~?bbVE?~1uQ+L_$4G(Ner zDEYHgD=+=zr#~x72*?pA%Z>joWqr}nx0gCkIxqcF~9DA>tTPZe&ePaWy3u)@G#|ZNsb)T0oUn|A zRMnTrhmCa|kNS{K7rWgU^ZYdG`v1!L$*!^fx74R`KKKl4yL{brx3ZGj?T=pkxhny? zaCTRkP!YPL){MkU(YAKzn2#1e7M=d{GxrLOnDuu9F#RNdoRA zgf(-A0ZorCNq=e_Q?_BAIIq;!^LHz_WFf;iX|0HVFTFmss1G0G(2O{!xf0Oo7#1bC zC~zbFVvje4n1_Dd$mVIo*80xmHWgcLPf-H4Wc-V*qDO1BwARL%t{VkhY&~b`N@7TR zM25ATE4iE6CimQ;gxchrFHKz<=ib*boj$uIdaGqy)Ezi$LGM}~pZr-(s~=;PRwsWJ zdEEH#V%sVO^UyEaUgSPjcd2~Ju4j%Ro-k~ztL3Nz_V)if>|k8e?hx&Ot9`9E$JGn= zJ=nZ-|1C`@yHx)BY5U3l_WVDMxuG5XP`{?(jiDc1b}8HDr&0D#BTu_-Yz%M2e-ZYL zF3Ff+EPE>I;l_U#dmJ+6>AFODj=_BNi@try$G%HaUSofj5zf2n(-?Obviw7H-Rm!9 z+qPrg`n3aZ$me6X#%zne!_pVE9p^?E=f-~*+yBVV^^5$kD0!ptx#A_!!LBQSq3}HM zZiROImz>{NZ|zmBn^o&=s`Yl&x<$2aRju1p>m91KPql7Wt#_){yHx8A)%rQrdbeu5 z2RD+8ZShjIf8%rA&#<*c_m=praoenS#P-E(kG|7#SJWl*1!KRk3hUxh_6x?mC;ngF zrtQwESXJw=cN?sU){z(H@3_@tnrG}q%9Glg8~>esA9vy9BtJX1JY&zxw#IRe_E(CN zZ{4C);|OzJ`N#IEv76P{+tk?G)z~d+>{c~)n;Lt%zHAoeqhBxLjmfj6HTdGl`r^~> z>s%avJKY}o#qx10+QE(g&feds?$6!!cFaS+R^ZLK%x5oF**^_?pDxc&@*OSX*pZL+ zzLevZasJf8>iW{ppNu*z{*-hu_IF!Y9o($FFM;=N{CBb2oY4liu>3cM_Zd&4!^LWE zryEZ{jXXce_GTPg9!J}nysNWn)fvZ@PwqWUV;@k1I#p`V#V?8P8SU{9vqyyYIEs@y z+ApC!jP0=mbu#Q>org`%eQxQ%JoT#=Z-jN_c4ZS=YvZ#KH`30nZ#Z{d?3jmsg`OvE zRq#@k!$t(ag%v-s#(> zv@>r!4;{|E4rCpKc5#W`8BWBq>(`~46Mq_c8f{JO?bEQeaaU=eIL_uXAH0xp=G^;uWB$^!{Yx^& z81p~-@?ZLW9_n{4#$G1%dv5%9vFCHNucu#6;f>iIn_72iezRa~dxfY^=r;?_A>Dk#;NZ0$+RwarkBB-HJauElzMF?P9lSqYq5O{G7?R($nFaYm#rhBz=m} z7A3=N!S)dFca`VyKI*yeXBhh$@)I}yyV&+O=2>uw@;p-;pm!wxf&V_he~_-YH}`H{ z8z^%lxRlnQryRqtThhXD7C3S0vj$9Bi&&Ac3O&eAb9n7iC3=*EEfS8FaEydwC2W;& zoP^^goFL&u36Eg<(|E64BP9ArMyGb9T_Yv>C`PA!T2WRl7z@^dv^7 zy=v`BlIY129wXtg5+29ojnT!yIEg-9!YPbD>?tV{eS$=vAkimE_%aEnN_dil)0q75 zd^Js?PiFKNL*#Fi_uqw=(8mHY(}T|REO^BI5GU-KpUTt;uv#lc*OK9A8?gy{1m`g}$Yk16vd zdI6({`~L!ozCcR9K%y^XbXxmr*FuSYg(Uw9iN1)@!{uKj(XV85nu}`Jl@k3kjJ{YW z!)GM=Rg7L4qF*J^3mJV&h+Zhsos9l|i0+i=MU1{XL@$!)#S$)I{11otOC)+JqX$Ct zQi<+j^l*KG}TU#OE|u|!|O=r4!pOC)+Fqt6J@ zDLq#0nY^$+ESKn4OZXZIuaNMyOdkElUAwN8=+`lNnofr67=4-n(|qXt zC_O@>TPz~h5y16K-nLN0^-_K-8GT2HzEYy!z~~=`=r>688yS6Ks600^`V0dmed!DY z?b7Hv0%&0A!~IKxB;U>G?oa}^ME6MPJrcc9!c7uxmatdCt0eiWB>HLz`y_s!ME6U0 z4dV~Dzcmv5CW(HNL~mjAzL0%dBzh~OKNF(2O7u2H5095^61|<#!~W4O(F2Sg?(YH; zeJ!KYZw0k$twir&blMx%t`3Rb$>?GGbV~FtMyF?}+SMh|*D-py{jQVf-HaY?U)>UY zJ)>Wzi-+~l${Xj0Sf(i02&*}!CWxyMSjsUaiNf{Gd;u$PnSfQW2sjFkP6}m)=`HXx z0Y}3(1snrA1sn?j0b602fa4%f!0|9%zzLuTI1&C5?#xl25%7wDN5XdmJPN)lU>ocZ z@Mu^k;3Q}ka57X2cnr)J@K{I@@HmJT@Ob#^Wk&m@!0Q5@0N)qzMEHV$FN0eJoC-|> zo&?1LPJ>wjo(z`>*bX0uC&OsJbT};F3>Xmb6u4i&4(Jl_RJc*V)1XGcmqVd|GhvQ^ zr^7@6&wwZa&x8{bjP{!azZURpcv`@7;PV2`g3SWX29JPqphCd8kR{+em?+?U_%Ow& z&s;bx;Cb+ZfagQMfD7Ou0pt8wzzgAe0bc=&1-uC63iwJGCE(A%hvSX z1>6kX0`|hy0$v641iTuO1?+?4NyhyB@LK_|ftLk*6MRR&E%2CtTVaQQ+hCJ`+o4&& z0jLo0T9_x`4wxd~PKXk47rc!}nCe#)tb+pr?uM@lcs-m7FYYnfiBo^#nD%TG9Ip={ zrh6SfhnQGsjzjb(5$wkMW{$r=L>%i2Ilc>VA!3>{5q~e@Er<&^ZbkeYVsZnbdnr9$ zG(W)IO<2q^#VMFmmVmzmV+8y#d^CzUwM&6p;B5ha8D0?Z9(Y2)kHFmm{t9#o_)%CP z;K$%f0e=-T1pGCK74X;LFZ41GzZ7^JUKQ}I@Ld5v0lNkKBy1M&H(-^3_rekZe-p9= z{GTvZz~6$8M(Em*ef!~U0q=ts1pE{{Dd1kXN5J2PE&)Fc*9v$)d`7_Efhhw1E?5Qp z4E#0GsNb{js(`---xcupVYh&vgWCkW8CDDU08|S22aqG+0T?IXgYZ9exC*}%cpioX z{6qMWfd31g6z~ghkAQy!T>^d)t`qQWaFu|63=RRm1aSiX3A`U(9AbU`6kZeX&)^vW zzYJdz@GEeefPW6F1^f%B6!0MA3ix&yFW^J)ahz@~@~>Cn_X2(mUKH@_@C^a~5_Sss zSFldNzlQ4s{03Yl;5We`;NL*JfVaTksAJ=o0>6dV1^gB~E8xTMuz-IDw+r}f@CkSb zss#Ld$QAHAFkZlafRAH!ZOC5l!aD-q3O^R`A7QV6{{;66_y}|h_&vB@z(=7_z<-9R z0zL-u0{#p9Eyk$dU*UBDzYpIN@HY6efd2+t1biI)0zLst1$+|n1$+lg6mTDafVab+ zqK*3939ktFX85*%?}7&fyaR3(@aMoQ;JaaofbW4E0q=zI0=^giMFSbX6!<*+LBRLH zPXv5F^b2?sJRsozfSU#U05l5t3s5fLT`)($55gD$KLj6z_QuHHz6c9&eT~C0RN_As z?*ceqCQQSI3dL|E#}6}H0>vB$7%qib9Is&51<4$jGh7CzaK20OX#7`kzWpnXY0p-L z3iv+93mIMvdpLfX;U%z>;~5NBf{$Y=mI_s{LZB~&g&fneSA}Xw<@iR1Yv3cC|B^l~ zhL^!x0yaGPLi4WyZdz>oH zx8LHJ&QMcvKl3?`x3T=Lhus|SV0b0m%JIhx-vG@V(;lLVr(#^iF?Gu-?jKI%*v+sT zPT~BQ^4I7dc$Z_Xe2wtDfScf90XIXBfW5GSV@=*FC=lqYVXQ#+!AYFIQvOw>P$0ZE6!L1x?_G*V!9Bcj=fF&H$o|_75p@8E# zEPV$|_m9K-!4%CDYb3%tTH>64^J!?!rr(#OE(Ic{e3Sm+S=tx(5t zFQdo7T!B9xCUC6fp8!!DQ-6@8Cc^vJut=X<7#;z?;F#>6q>hAVIIdxM6nvdybZ?~F z;BJl|Vt6#H=lF4klVFv=pA5?cJO&mBcq~lh7~LG@kAql_vDqUY4}Zh`CeoMuGf7Q> zUkP{u9N-v}A$=k|$Zr94}&cCj1@un@HbP49|i$IYu^=KO4Ry;5l%=fV1Fsj-O)u+0ewX z<}W$0gkxIPC8@cP!?9MLJV@nOtG|2*rfB-KF#fslHpkSylhk?eBFBjg&xfZt*6dXP zy9N3J*u=3`9}D3If&U7qO%g7b@N5Z>mGJ*i$ILIv{|^%Wk%ae1xKF|X z2{#zYPWe^0_+lkfu)zC*%mCA?C? zOC{`-@JtC$l5m2APwIukkjnR}grAe}mn3|Lgg-0cRtaA#;iVETk}$P1{UZIQ>HtH+ zIQ)e!!qkuJ7hywjf$Ba9iSfTsfcm5Ob`|DPcq2YH!Z7V83KVjzhm=3jX?!yB5r2G( zs>wq+qzB2nn!+Xco*jiQmF3@M)FkMZRcU!vus*3isRqhkPR z%T)U050l?ZALX=Pa0Lfu;Us2e+Jibi@H_?AaJ7ySSqk4eCaus)!kpD6T_EPwF z%{pndXc)ZGZc^Dk8_8qk`?Z8uU3xc(n>IVMyuTpb+(Xi^894`-&8==cm`-EJ|m{e<8=DC&lY}B7`*TG+4SK zl|J7D@m0LO{3_%UZdKX-WBd&&yhzxi!bcR=BOjV59%p`q7?M6EJS^v7C52dDH58(r z^*kPvL)vnlAKHQW8-~m-Xa^b(;;#+UX?!L7uyS3;_4RT+eVRYSBX$$t8WnsPQhqHI zqFw@c0#+- z7ll^N$LxxO2>GWj-^fS#Q+{?HF5-Mlf6Tv|izl->>+`1lmdF>RB>6pDr zRn70wZd4DH&lU_R{~3g_|Dg2o%_?+Ii0yVKg*d1^Od;Bt>>0mQW&JYYcL<}L;~0{h ze^7|+IY{9LN~j#!oUeq3ET3vx@nQOx6|H|l%=!h)Z#Sh!d3z{C|9OmK-43k(YUKSC zE=KE-PW=V*heB2JKTOZ^b#uF*oRwToIhU*3(}Fl2?MeQThUH=PgnH@rcMu)zQ$!)! zhx8}DmncNNU&fI1Rf&#rY!o8B;0*DpoSs7b9lRZOs=)dW#H1g^yEz}z8}o^wc+7|C zh54{{f%UJ`nLKPSq(9aFVhXX|w^4|E&rpc{+`lQrdS?3tDA&sS3*8>9pFsJ0k&ntZ zhWN2R3s8vii;$l}>TgI+BZZjHMhekCXnsNM@^uU;{TmcwJ-kIB`pFQ5*ggwUUK*xn z^@w3N;Y!UvDf|kje}{+TFkSp&v@eE~j`}?cDgQL|^PL?314Ggy6DuYj$J2ZYE6`6k zzJ)?8&n^tpaJ>6Z3XvXz^GcGFK_SYmrx3?CAIH5MKh5zw7*amRF{Ez@)OqH-c_IvG1+Gag(!#BAJUsSUl)bwm#iK!)cMGds2*55M*gb_ zV}30ZV*NkO!{71nV+_guG$EmUtQ3#_G>$?{KaYov6kD66k@(^3@IJ83*whU6n9STQtv-meweTBmsAhrCsYpK z;WfP9L%AbK4%P$pZ{!zDE|!b=1^Vr~6p!`5+Ep>m3wiz2@~{O%(l0>a|0tpPm~JQX zQ=*&Mnd*b`XZm6OpFy04{Sf&-g=Ak!pUC+f6rz5t-@<;E=rrGLqY(Y-W(rZyJ1Io^ z{hY4rlZlw*ksp&iYKe~aAb+8Fx>OuDEEFD6nE$J9^7$opPK6ZzYek#a{EF8nc3v;@ z_Aiigu*|f-%>b)^I{7Bp!J*TUvT^)d`y8A z6#iKOT4$-axN}p8jis5w|5o6B3WL}WQizMl-4uSPwObV%>0^XX;1gg9U&Hx2g>T~% zSPK88z|#~SR^S;5f2Y6;6b^FxeFya=dyVJ#d5*_%yqx1P9AlvwKQ0!1l

    uOF8c5 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%0Dk|I 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⁡4dvtg2IbJG_*%*j?V+_QevFDAqvFR>KJL4f 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

    j_iwVcmH&pV)nT~g$LEB@ENd{WMWs0Qj)|1 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%0A6!^=Cj3!yw5Rns#?x#F}cUuSE(UzREy6sgtV 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Ν6(_H0eOK2+59p`!cozOg@^l>*$LjcWUG9t% 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⪙p%~- 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

    )5j31>Bv6q5ovFkvZ;-N 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%0AMv33=3Y{8;;# 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

    I%r09qkvKH#yVyNo?E!2Vws)*l;R?x=1G zGH76$Di>j0qXjRM04BOmf&Spp>h%Lln(u9GLX_v+mAn2rhpN_}7=*@2 zhw)sfuB@&HE1-y;S(j|uMxIv!o)Ln~;m$7Y)N`b7rBUalWK+$0d^Z8@Oy8~oTMc<$ zXCCqcr)%3Jos?MaK9Z(#OC<-QMwfP+swx%hBtAHD>^oS)?V)>lzz5>a+r_1#^~AnF zEyL;sG3f5LEw*I^7fG->^CQQ$VBMPCR%Tyz&A>TehpvGg`#y1>6d1n`Qq?=^|6+T2 zE%{cAJZM`kEt5`NGt4DD(2L-XJavsN$2Rc|FwF9}mMiVXlbiTg=kKe41si?~>;6CQ zJ$cRGNxjz)b6nrZbKQ|*?)pY96Ei8!xf*%61a>OHCX`_1{95>{Pzj#5-7o!6!ke`3 zq7=VOm0$&x;Fr+YkCk?(@z*!5rV`Z6-@n9+^ld0Zs`U4v?IJdhG>6h_-nnL&^U60h z$bZFSjA^83+L|)(ABHH_u5}5aIiK`D9%$+kd9%2>%)HFFVzu8h-u&=MjEf%oNu^1M z;J2MU=0|)f_9%WC_o%vZ;TQeO{44xOMJ$E~vAu)sb8K4p#pGj~ z1BXHRm}`N-cO2f)2I~}?B#rR3XIMjNah9)7{0A`ngpaxn9L}G&T#=eQ-RDRvDVHw3 z3o(j-p{@5Zuyz~d%R_a(@e97mr9DF!&SS}N9yfg}53Fj`NU;X_i(z(Qx%B&YMUZ30 zaDM-Z{LBk(_?%O@m}SHnmQQ6!|HMEsS5dC1YM$4>09QEVGFT~Gh(`8x-mPlh)??0c z;?6^##T=8a1j^4v-$i zQ)O`h8S@scWoRuzKI1i3!4_36j*2ShACD>*mb30PPYxB(dV^RmlhbaBC#Q~#jZwM! zTUZitoVVcrQ>UE2Wsh?47H#*M)%!d&V`cit9>j^(L@P^9h7N~Hs{`XptK<{4()-PEtTl%U$-bW~;2zJ2jZvdw(fYDxBqwbH z7Hmyb4Xk0zqCr$&tjG|Dm#|0B6Qiu)G#8mPQEU>$X0QNV)8}Gyj45^F9kD^Ii#A#M;oV>Pc1pYQ!L}N`UK~YTY!vr}cG%QtaBT6uVV4&0DWv6r`S@ zImd)o5RaJVE>m!1up);+W}!RUi`#OTzzR;|UT7ZvPYa**0pa1^2G64G;qUAMYH`hz zRO&|GkZRGq5>Bf7L&N)Ds^x&4!~6rEIWb1H>d|-|$$Y}5wo`(;c~$d|TT{;wCaTbP z8u7QTUBoQwOFI7^Ckyh3wqzdGT@3A?=bcM6bNTL5k)Scx0kL(e_9Q{vA0qiM%%S#yk}eTn(z1IxS`FN48H`dj$J2oYk$+X>H1`^X0>ckhCs⪚pDO#dWH(< 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�-N|_#Bnu7%+UCxH42p$uxYc#+>lm&yZ@NycWp<; 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�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 z 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 QQ4Cy6q~GgH?U(I;0B|I)00000 diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/TOOLCHAIN_GCC_ARM/libublox-odin-w2-driver.a b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/TOOLCHAIN_GCC_ARM/libublox-odin-w2-driver.a index cf5b8af77135b27cb4e804b32b709d1f7be9e817..999e79afebf641bdca9de142657902cd3cbad909 100644 GIT binary patch delta 289860 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

      wt&0EChh`Dk<)^dG) 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¬HxI6|Xm(PKBJRAHR;x8~N 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�&Q-hcj7Yww&rCoxXuQ0k7o5 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

      1iR+rVytje#eXuQ3l**gXaR#i0H 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∋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ƿhE0i>Cykuo%2wPgLR=7A&U*Ss$v@2`t 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�%=rO_mSpi2<-vt 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ν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%0Aqa-lZ+sr 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

      MtX)4>9`G=4iooshI=RAC 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

      < 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%0A4Sb4*9un=v|1~W=H!_XnkG41C%)oo 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 ^I*f5Z{$8TWlC@RDthX#!3;sSoNKJAYXrPLg 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 IQp# zaV0W*D^Uy+mz!VuTiv-$w;PH0N?uF{KLe_}h$F4|+A><5;i?}TFej;BmnisVUUQ$ zZY*(ywRsVA4yuNcg2j!9Np2z$liMUBjCC>*#up;O=%x_S$*8(IP`;SBMm2%89V6|y zW;^bkw+0B+_BxS#2`7WTXZxzY()2WBjKQdx_b#2rwq-jy<#F-~s?O6)8qn3kvh8ac zI^^Lhn@SzauasFN()b(8*aMss3KS62nTDNorIkbJKyBT@Xu+)-dphY&@Uh=nf4dpk56|G^xV*T zeP46PQ*#OOWRmwQ@ZCQEd0+olN#)im)IJMBewnXWNUKi~ErG7vLL+y^PwJ zk~db@BvXB-fo~x4e&mohz8`sq!8efl&c&o`*H^72ebjde`0x(h>q_sBpF8BKwWtqy z?}Kk3`mM!A!`5$#E8%ESTSH%)L^+@EEv3sT>-tywefqN**Pb>5%u=(?+^Er&9l$@zEgMFnVsEPv2l-i zaOEjuO^cv{EJ%zs#IKuY+_p|sHA`mvM zM1)QA^51{(JlIo&{WGWcpE3R~*m{2}w&54vFaB%i%XMB6{&L-a^^DlJS^VUHr?ZmyVxJ{5Q*#i|N8l9fk^y~GpX%h@r&oifg;I&dhO&_uHSf2 zB>l?SJgi>)>^ysiX#QKL_qPmu`r0v~`M+_tXuVII>Gb-A7v3mZ{O?ci|3#p-Fujeb zPR>XbKRc&v7s+QjZ+K56^L%b`3XodiROeFaGwK5%#S3r_S>(5E*AWSI!U__S0)8zjR&SUu5w7X^sDE zlQ&%a+vnAf3U3?y``LLQU9|Zp&&>Etk=bwSZ=d@g6q)*L8`jG!@K3buHLvlU^}J~N zKRdnuo4~SGr;9V5-d|GKS;r~oF_gb%LhZ)TO_St^hSn;#- z$Zpa8h?oEVZ_WrGJxjO3X(WL{r z%&Dln@5Rfe7&7O))&=*yaK)pB{Iq>)j9lG2BUtY0ozefkpQ=CXnv|2H9$NeV<>hy4 ze5&2-zJ%JVO!b(%OBZR>8qEUoaLBEH56&`U+sUDiw(BnoD`G;{=RSO?cY?4VCr&T4 zQI`l3m?E+rLE=gqbBW+4`e1R5Lm$#aA0jq5^lonx1Gl)vVG!CxA1dy3=)=ST2M-r- zY90cNMg%|8JV5av@xA8ZigySR9>bDY0=E$TdX5{lpt5pY#k@H)CQq7QId0a($>p8q zR7%6sx%c`ne+XG0_UN&M{M_s=+1-2OcFsA!OXt)nbLOQMjXFojw5N?ZMvh$jv=JMT zGo)x#>bZ+5=TDwhnIrc+ZN!_Mb7b`PfF8;H2aFlgZ$Rm}B}01WrFQDC>40;J`t{C} zds?|i%hLH#t!g(sV}u&L(>wJ)r+7gB(ZkLyJr4z~wBLx~1BVPM9XMpzfZpTME6Xp* znNvP}cIl;^OBvJoGb>9c&6z!A`qb=caR+85&6$@i0t=JKrD0w5CS$+PF%FLNf(T`+mUWaY(_$z}5w%$scavgeKXBqLkykMEcT*wZh% z6ToO2lt=d0gaSa`k&q(5+J~B#0JdG9JslAJxtk_y54EGo(N|k4wk)bESXuo*3X5KF zokf#}g8}PDzS4uT%7n85RP=Gx4}$$~8+{2=lE~7g4;}_6YZ>1Sur@fn86fYCu5AHD zA>kD62?@^z?0-A5B_MiVbOvBa7o#;{L^Oqat}>Nym7BstABV&t{I!RvD(cWak+N&t zserk?lqW?U+o!>z=q>!0`|C}yJr`u|(*ebRybW$<)7)nQIzqMW$<|hu<_$L5TUTq}3F>KG zEx8~S&LspzmcaNda)>1;mi7JO0)5w8$43YGuItyCA-?On!EU$jdcx+YP~Uak2_x8d zJ>kUwzuVNIZok`x4JPf4d1no@0zVWwWVj_LkquuN0oL_M9kY37jj?F(mJP0YTY@ff>t+?RC2!<(x0JZ*4<(?7+&$dQpw)H#Pa!eB>*KEkupCgn?n@>N zS6yVqjVi&s-k9pv#$9A#QG1Wiq<)(_3fFs1x^z@<)kPk^$)tt4PQ4?FB}ZM?O^asH zO&gKL(tT)s`XIo_qQrqTm~eJ43wp@YC^xBIc)xOe9eE3ZvJz!CoY&iv;5aAd`(x*g4vY|Dk|p8 zn?JccXa3~M`IX9(-*(z%a^)|$&6zxVVY}2$ohs%{o<4ih%mw9>d;6N{vK!;`{cZNz zqXEsN>FL}H9aY2`r6Hb5)n<2^lj`%q?kL0sd1F`C|EE!AZh;)ResD|K{=SqHS+OiS zKyLUUqWk)o(#)D^Xe>_my?uf-k2rl4jGtfZqAY;pXixs z-kv3wP+pTI({>mMvgC?RAsc5KA?7|P?l2NIt~NZz0eR@V&{$bNFf3r>-X{Er;V}8TB(pxDwvh|Zd)gU zSoEkJJP$r8R*1JXKMa0OGa+{4j??}F@UO6Nvb)xwpdS2o&0PqnQ@jwVkkdXMoJS%~ zL&S*IVeb)3 z9Xv>^0#}1v%Y$&SNgEIh+{tYY2NB|K@EdT0SL+Bp27Uq&%l^7)ehp2wT(xZaPsgbJfaDYY{H|Oa8DB+4el7^$B1UO z2)K}<6bDZf**1=+$083rpZ7~0v7)CWCFJ4t*Qp-4DS&o5AxAgSO%@_(0rK zp9k+b^zFn6@cB0VcMg3A;fCMUHhqjgEJm=CSENC(+Gfz+VUQzwfM0<^AmMWxn z{b}eouw7P1tf~b*j`ANXLXiE}+YF-pw}bbnxAM@gPlY}c_1@=UJBNK=(H*?PrY~~n zi$n?dUQ5sV7b`Aw81xgnKJnCs9FunH796JG>YI`o6Y_2AplnfdhF9Qq+*H~2&} z?YjMo6%RQK&KA#t_d#D^9kJq&Lw}BF0M9_%?$h(0+xf@PXW8^8!8_Xc_dfraewP@b zve<4AiV{Bzory1iSbq(m{Ya4xe$uAz;Lx8ddV+UEXXSIx2-J{=Z`?2Y|}sKaDSl+FS&(IKLdCb2I)2jZ#x`ZBt8Y7ZPS14 z&|fTEXoNP~^x^(SiMOm&v;eQS=`*PJh3^t&q6-8jMl`+@^>TPHNt_LyZ`1Rh+WBbc zyW8{^gZHxWDd2@RJ_p>}-zKPnz<0PrT$AoHPONh1U;3EUGamMz4dn#BFBj0QZUyA>c@ArZ)HioIO6r4RjEKzNag$IS?jK1n1y2 zU-NA6TfwnhP3a54BXH~6Yxg6-yP=6+q4j0pkNbHGG;_Z=trs0-Om+1w&8@vO%GhYu zcA64(*pT<$6&fbLNXT-_2V;T~<&itvxaA!?+eFDDpLcWD_KGux8}jZA`QdU)yaCPh zs3`f;^e9-bOAeQPuMY^5FU1>o)>bDNN#^f!g}=`g{ytau`&{AgbA@W6`S-a(JWR^@ z|7ET)CdwEdj#?OZn0vCa9BLMr1bddT)Ra`nbRU=Q5jGgRW zE;-d&gg7KCDxCb;il84X11teth(}IqlF81S>AE6(aKmRpT5}W6d`t4$rIO$ ztm&J^8;R#Dr{~(7xvJ{0MQ z+Te=Z278+2g7HR5Ui7nNc45#`#y_gTh5z9Vg(suanObep+V#C#$QQ;NoVKhA%4%ba z6NaZP#ho&*)JRK0k_3L!2R8)TA`rxcUQ%jwV^%bED~(DcE;T56MVbA+(MeZ=9@rC&JEVRTiQ(LQEu!_VaV%Z$R9 zyr0YCCmNFtAupe33}zyqnP_CY?!g@YcN2|N$Ps3?_w-;fZE11ftA!^EI-eers)BBv zW|f&B(M=esQK%Lnr-DV|2_wYGOoxs>S#`6nDg@c*R@qm2+;k%mTj@*Ur@>)E2aX(g zfhtmoC(MvInOkl|xS)_nCK(yYqWYJeN-U#ksZ0yY4g9u{v&xO4R;nx)A8HI7CAqt+ zzOa><6@R$Be5u^XEQ%gnk=oE`u?7v$>8ybI!jnt#P7h}3Zq!wuN-qgTF0?NV^z$|^kWt)5mTvPur^!2fe>F_7CP8?jy#y|C2NL+nj&BO6@N z7~~qXewd4?7dC6QhyiGt7&%mg?4UzYHm%*YF}VsM~YQ!V-Z^;&FPc8X^N2{b3RTEkuOX!+TrITT1;^~Vu^|Wp-Td@T=ikNid~Xl z8#&du$LQGNP>`*9vbSlhYXQQTu9=Fe{B)Yp!3&cf$n3OYsBCQlTKOtQvV*O82~bT` z)FFGW1S41I(wE1BD?-pt+9j%IIfLx6k4{|2M*>3LG~M{FWyQswPlXBiP1c-Dv2FY;-@0?@tS6z28J0o`f7~0tG(F!X^641 z#tL`Iz=zOX#mToXF%nT9zP-dKN!yJEXU8cNC>5i+8i8ir%!;dbWeuqh$hxF{i<~yo zNQu6#VQ)>siEtHVWOv6-^7@&oQav@(=xkgdPt7z2Mdib2cT3(0nsk)IXDO3E%rY*) zv`|%DD6-S|VjOl~X*V&7))wwi7=VEtbbuZT7nca)CA#Li1z2)|zysKVj9eNq(c#QEL zbhK#=>vPl|ox-X})j1nkmmO|?)c#|nX`me4j&P)3b=y%{t?KO_%HH#hBrj?Xep8$w z8NPxVta^`D{+bsoe%|W_TlFukF4oedV10rC2JhgqTV6#_<}!eb7dv3X>|PVy#JBZ`Mp!VH4dqQMcs6f)zcPD^V&w+ z{nNV(FDrsojv{Tb9$XRA(AYfL^Q6&v9UITn_QsXJAAM~GiqujzWIs-9Y{+;k>4tLG zJSCT_7aBqAktjd$n9sHFup2NA8L0xDVqHzeAfb-aLqaB04D#GB(nRa#;`G@qrrlVa z^a?Q}Bj9_pON;5TCyc1bdb{L?;vk1bk{FeI^ux206NTqd`h_-n(WORYQkcW)nquRS z2S46MC4VU^E;X9TluM1Uz%DnfTv;P?E;Z6Mf6K?4+nwJu-RAs5IpN(_&1Lm7o`5`; z;Yu`x_2)7ST;RVjAWk)f_2)E^WvhB5cwI(--P1Fk4s>=?DPj*6WBmJWM3VQkfLuU3gYV+>J#?#NK$4m%)oiF*YQ^ z_YTB+tR+*T7QgVx`&uiO#D41mk3hXfT<{4t>j4lZUEmiExGy9kfPO@{A4o(*RXr=h z<5ltl)`};*Q6%sf83!DWBEsQ$L^vEngfHh4pAh0ABJ9Q!5y3Lzy+V`|VLzETK!_6CYM8swu5nY#9$cr69TuK~*7J~?fml5w2;&S5ISkFPs!mXyt#V_8QEZew?xM=+CmB8i ze1-zV_*vq)SaC)~344*4g$KYy*u6@G-D^bLr`L%nd2bUD!FP$cHSZA-yAOzPcZ`Vp z_8}1^_6s8HPpBu!F!-7Rr1)>dNkV)>%oO4~A|mo5kwx6V2@hOExCaQzj2PGbiP@+n+U_hO3U?pk{X!HGai6?gRYnH`h$x~1i2*1##3&(3h{)1& ziLe_@MA1Eu7%#+yM2`^Th_EXq?n3P#!k=;?ZpBn0ZrwEEe2h_uamfD)UZ9Xv62nm& zi146_2oL^1ga=m;5rHK{cyuLk5mqA-lZ04BOc3Ia#7LBSBHXPf!hQo0Rca$KQHYy~ z2`GPCcmW4$K^X$Ll^k{LHexdrbRurWUE1z$;z}fzhyc;es)neRh{F0Xu^k#yA_`d@ z5&l0xM1-CuBAjQ4ldnao=f%TVV@X_tQcrvY>o$q&g?NRCEdDcbqY!TpBZPR1C{g-} z$hijM4MH3xB0w&+6gQ#t8}jA7Lng}lYIN=qmj_LiyTe@J^4)bgZn+6G8@ca4e!^8z zthYF}YH7&T!OMb{2d)TM=~``?i({{N@~NkvdG|)1L*ZFF#EgsGeU z5F9RZM#cuo$sf0BCWnoT4Uq#j#p#fmUlPJ>+5PJ zH?)nIDvxJ0i;&N+X&Wt9AM;e2x8rB`YU5Iw`)=oSnYF8@<=Wisvbyx;Jp%OI{j}EY zmMd?GtCU*}!6a`tBs5USWCaM>zxCni~vMV^>8aNP9lLQg@t8l2saT;f8M3q*0R3wFnmhjTy zE-k3jSg(DCGoAn9;RN;I&wtt zAQ5);lp}(#k;CqNjb21G!UL`_H`A?^N5OEs*uZ zR@TCC6OGTG!3(O9<-{w|Gy|DKUyxsg91aKKR(AxlP#2O{;rd z2J)pSe46hfzZwzL{8_DkN%JFG|GwrX8mWS1=)8c8Kr;Dq-2ZefD9{FdG#{=EP%AW_ zN4^3LkH#m7NZBhI8#I1FT#eom154hja3JkciO87@%{x=?MHY3}g5eav!C1{_YOL1C zHT7n5G(_ac>Rm*5ct4O?-9U^%mJ{(4EFcPqpJXu_lQk9s>3%rSTW|{+8YbQ-)bJDf-!DIWEKJ$U^Wqb#CRfpt5pzp3sJ54I$*&TbNPp)sEb{b`wIBrdjRpxsc9gM-gBey1@Aqfs^-p}>M|=*7r)p(zE@zCGm#ush|5 z@Ngok;ArZRBjbp$n`fa{RBOQ+jhlg??NPePk;2{NNXh+LUq_AzJPBk3ULr>XUeWsZ zG@jJ>6OcI>i4iva^AHh%WMF75?myqFFf-7k5>qj4Mnxos(?G_!KM@Y5Xq=~U6)-db zos#C8HSPp5z`dFu05ZbQYyKCF$B15dd{P^HrxhXalmRAaOb61#T+NHgQ7s1onKPq_ zi11kI5#fnMxL>SsmBvjPcL5pky*RxzJfIaX0U6K{a%5G5mVX9h;rfY)fC8FX0fiIc zJ_8uq7HvC_eF9(nV4sjrOh;KDwz1ytFw@ZXleb3BHbeb4Q!oIb0G-PiAOjc&WFeYH z+>UNk<4%na0-2?Cn%8S=(D;SMfJDoEB9JX>hUT3$7AE5UGXQ)kPlO@mW3^(Y#>+Hb zukm(`4{AK9@d%IujANSrpfNNF{=)y}8nZPP0vVxUUM-lQaV8NFsnUF@=4&*+S>rB^ z`+yAiY0cl%cueCr8bi@SN$>6>yr zExcxc={o{=8K4hbS#rfqfg_(U=iumO{eI^I03=FH{Ns0lnv6%Tsd@VlVv(BlRMY9` z5Y;p}dQvqFj#gC7dPktps%h>>;yG&aQO!Q1U01Wo=)~0IF!~fV`HQAoP0phw#5AOu zj6_jK%E>R%Pa?)4%gHZRbA;$qtyfM&8Kzn(pM+aMoPtIJeK{&8`eWh@{m5b_hB)N2 zg+LuwQ>5v{dHNB?eAGYkg+ib$KoQ5Fkhnqj5U^rMgE`q9Sz9!{wsRPygQ6cbA2zqobN!q&EH(6z8M!z#xrz1S(x{Kt^fNRC{XkcVh|V2Vr)gscKG^OY%9&?7L#Nnss@ zrBh|}E(HD8sj`kjPcI0+nrc~AOp~4<2q#cjJ%hIUE$>gwme-Mo%#m|zV1Lyd`7ZhTIdVTa*6HNz2T!c9_#Z2z zm;9Cr%YDLJ`7(LtT#Ij+D^m`D-#gceX^VMs4ta-pipxIR+lI^M4#Xy#ciT``Oq%8YEJkW-q7nK z2f@(5`41N!U9IyoUIek7;)5)G1U31dS0tZLT1~pL2;##l|AD9Jd@|eGdaA4qUhu2g zaK)$(eB}zc|M1X6%uAnuw%l(KB>wKdrgegv1xB~2k0Afoz9?{^FG)d`?eeJ+{kGt~ z!-dxw`QYtnGVe5uiQxJ0U&MLy{hAb{l#eY)5L z&Z%tc2(lh;X@+^(46zH!IGcfbZlw)e=)CxRD#NCK*?-L($P!1ubN#X)@uB~k`u5@* z@Lqly)~ouj(Z#vY+eM;O4)zO!L^GCBe+05cCiobe-uHzMnz-=gl0MK+wCM*q+;De)E9_l;Ogmwi+63D&l2CWaTlJTa01?UxbXZqj2*H*I2>xzgm;%Mx8$T0 zl{OL2Zo(Hf;TxLp-LiCR^PHl0nuxz>!cRBh5g1nb4#qB7zJu7L^=%@)unC_n|B#=N zBKsdq@W`F{8T_`-_5QGBgpwU&H2rRx!@S1D18TTRwy6u1-=%X zV@SF`2OLy2IOOMpb0F%ozZ4w5viy8wAj<5AHoQvj-aT2 z3miY`{1N^F{0XJA^gn@r1f8Y zx}TdGY<_HD4YPe^vf~;HhoQ|?|3lP&wUigX+$gvH+vPvMwj{syKi21w%~N^wWb_1C zcy(%XdD$H;6TKJc`MJK<7gjK^z$g<3rbW~|T%k3<;9?!j@2F`sHQiRkK>`l^KvUCg z=jv%S%pj?0HH=DDeuemoWE;-vN3SYlxo3Lafvz7AABMcOi<^AI4A^ z@ARXfO!lw+v7mWbqUtUVNN-Vp9v>s7le$?RqtAIZ5tVp(18kC=>m26x`8rvwM) z%OzVPGlMRI4=))TcehSA+ZD(|5Sg6{Y64C^C{ zy7)BX`q;vGxsP1y*Sy<@b6YxYWBSUYe$AA=HaCa+%DjA^Zy)!y#bA7)T;kWvF0{Eh zS||_sH7D$v@*W)#c)e$C=yo14#zWpshhw;%1Aihi=p zuc_{5bMsX{xyP?@^|z&`s=qY4`FvYp*ZkODj`V9HFuCf_x1|H*HosA{J#aumY{pv$FoxPOZ)EgEm!WVjA`lh|fi%^sHQaM@Fo?vyB;NeMukR zk$qxNv%v1%I(O@CeMdGjvo-|NdPX2B7}kuAG~#{Vkq!2LB|i=teuQ)xO>kH|MyLu3 z9)Qz8>%9)R7EKPD9=wmj#r2|-Vf`#6e*nBU8dNrAa*Mc8_ zU%^4W=ArQHXtH`tp&YaZA7NUJI6dS~OdjPp`PJ2anqRAU2p2)Bqfqfsaf#+3ibslS z#nC`nDU4FfwApZu#>oJ7z<^!RD9s-SzYo`in!gTSh7&!JvgcIhr^u0F&A$Wx3fByf z{)Hm)-{TssoZ_5xdcxbnde}k(&MJM1Rv+!IGQg`r;-Qw-%6jT6=m9!AUw~JDSK>t1 zsO)dU^?GzaK79>%Gx*<8>pADMwmBBsX#NSfw;v3uwII}mzAx44HW*+g_;j3HK~LTr z*DvB8!kyyhfp3I8Zx!`(!7oPuz6eS1C60~&7g>G<+u1q-v%t&XA8#rBTLvz}8u^{zQQ#}I{vaogpRgHx z0E7MDz7+lh9%17tm@Emi@j`I7jhBNT2KPnaO7J&q`mNyi*!26o5Zq-mcn^HP?H>OP ze7TLAL5NVg)xk1_3E+RjEo5~f&jg=@GUF>ly}(~YnRr<1hk!qhq04QWdnZ7!9?|WH zB+~zJUGzzq(0WjFd`v(c z{qY~)ulC{_FqXioml0~U=22vO49Wr{Gzfa!Qq}N~j{(Q+_VY4uWRjnAH7AemI1Nl% zEdk$>rXHUv|JG@}GUD4$PC-Z$?ry?En{Yf%aCjKrghw>tkxq{Nl*LAy2YjC3{5)eb z!F8yOhezBCjttU=M?7fL^8vs!;LJ_y@Q8YcK3TjAj!LEulz)%-$YIb*d<#Ba8>j(u zqi>izP8Ct$H8y>sL!U0%f}gbMa~=8&(HHzXOONmo0WOsF9eeZ>8TQ`isXQ2)7wL>+oQpcmq7rrf+cQ2a7Mkx!Beh zz$u4*s0c={w9}^Nnq__enSx;=1%kV623g9$^3H{EOgC_@&b1DYD0Jvc#0c;MHa*ug z`wkaI5mUjrn%6qeol|e6pAi_1HRD+1ZZqIwXW!vMi!Q-Gv+3FJ*!foIkK6Qjf`4t} zHQ=Xg{1I^P4>rM*5cpdLl=>IR_2Cj1SPhY{<$#`xs&7O0Y#ko)fx~{R_!>NbU7&{qf-ZU>i|S%*h8EOs6aeRrEa9=w;0dt3SMC$oH>y2o~d zZ0HBt9CUNo&liKhFSF@O9QuV~0{AkUe!4?np*YXXwT>I>qI>S;pvSAhZ_x`-yl8)zt*N_gzWqz^lNPT?;Y+psR-HiVUfr|Wv|*_ zY%l?V?{MLZfP9yrV{4zpBRVc;J(9!B{QwSf3WF!%j}$c%;2479X=wE=kQ>cx@Uap**dI3=wqBl zD1!ZWHvQQS_q)YK;2~K)7alR$p|24Oz+jduX5<073;y*+4Q$K^v{cX z_@2s1n?bF^;GlR0{6NRX2;!?T{=+3+5=X(4JNZN&@u@>!FTMxQ%x=^NM*FUrgRh8q zzNfO(X24Qv=P7Wo!lrKreyxpn0bgU|y}>uw_#p7>ZG0rS?{MKG5_j|K8+L;-7&OoE znRvt{4hMf0e*nM2roY;u|BKiN{yI7kI?w;2Ac)9Nc%f#7C-Ovg;-E1vdL_4*O5U z9`ItD{t>(0i;0sLAedn@c-?M*xvmeu*V*)6I`qfIX>d;$UlcvU?H`ge%TJ0V@EJCJ zYnvYH@xB&aAb8tm(A#F>(GBEmVjSx(_ho5XaE0$ zxCw&WZ3dk4^Bpd1pzr|rqc%OOshvL#eVtAJ9Qczq{wnyhHvSH{b)f!p&XH3rc7xAh zaImY-$Rob>JD|O31jixEImM+8kBA2M9WH#6B@KMIP2a(x4>HaIA4k2_|9Hdzhe3#O z9{4ny2c-^us4)k8u}#0op$|7!f-ke_ImPEYT=*Ewt>Di>ulqlbxW{4OF&+bd+vdSD z4t(F}S@6=L>SagAsV92|wI~f8B(K_~#0&1UB3!3m@O?X)oKBo!ii*~+)5pJB!up;2y+Qguy34fsp|Fj7=l6>A<9;Pk=EdMGpfA^a0{9IW>0N1YuX+&nGCUlk4Q_zJ z9kvMEM-Mw&nZ^K~0iTZ1`fJ+$P4Kqx&=-Mk!Joibc&yfkV@l!=1=f5W-M0X5iLo#r z#>EJXYxqLndJL{7Xa|G9N5Da(=3~ISAp)Gvpa;{zuYo;hk;(aJaxQ+sai)R%X7G!9 zV63G1J>XmL^Tp@>3Gnqk&UuYDA?Swy_!Ea7oB%&R-+Dkw9*aqmOS&}Pf_C5+BS2pS z`ho8U@2TCFfg5eDM+bDj5Zn#VIjcy1HTXO5uNWNfe|yAs2%;hIW!dB4>k*+Vw1c<6 zQxKuqsz8ridrV$ovF2VcSvix4~G#jr6ciH%H@aK?#0Cmqj;xza+L|`!6RYssC zZr*bUFir>11^hbOJw6-!26*5r6XU^8BTKK<_SN9A;MKkeg5LrA1kHDWe~bV*m%{Ms zz{?Op58G7=UW4E+craS?6X4gu0J*I6Q7L$)jeF{gKr8U&h%oOV-RFT{gWtIGH9rsh z9q6ZNJ`?;j^fNSH3O=M8mTd7`Nc7-O5J=qMr?tUvEFSj`Hd}{bXD!jUG!JLz+HHf) zh~V10e~b-t)gByWZVQkjZ;DB%{p0!OD$noh%YR>A{`>m!-`AJ_zP|kT_2vJ6t}jP- z7Ix;XvarY;I!|Tx{Hpn>ov^5UT=98BhV_?gj|Mc8*fY!0`&XOSdhf*Np1rN~b`oNG zF1DM(vYQpR)od+})*qzzNedSnS;6{y^gfx{Fe~}(4>8g9SnLBLH9+mKv9vhV;a`BD z%eZ=Rr}Zs+xV1KLNmgG&&kBxncp4zghVtY$Wx?HM`*`Kl87MZWS#-CV?2R}>AV$5B z8Ys$>KmU;18g+iG`vVxYLBfEpE{=4#2!!8emU+lPv<)QVvky~6T}|i5Jhp_yI$SUz zW>&D3E#7HX9$3-+5P9Hv?9>ARSX+ouRBEsaa(VGN4iAD=a*7=J8Y}{;{rQ62$Cd-h z?L@HJKFcW=X~x1vNqd@#v?7~`5^O?|w|_#T8D;X&J!Whuvelb>58`=J7Cr8Xm9AZ8 zc~Ah?Q|yqlcA4qiG->TFbG$iWbnS^<=95NLSAAc0pQ;cj5VcS5Hrp9AJF&-12G&N^ zm~|#E4&85hqC;}=kTzcAJ}N(W%IqHJV-`%5632 z!iqKJ_tdmYl+&L!e=xBr*3@UrtlG8sX9TC#XR&C?1J9aeVf?N>qxN{sa+&*_IUr%G z+VP47| zv9*7H$sBDo3w0EeKw+d6&6|~cymm^x*~`ElXVtZTI%EbI7-e_*_@@yo@X^M1PL=F_ z=hWz}2{$*}oVW$M?6`3oo_fWMahYOg?cvwWx7D4heZ$p1_oZD(x z)lru={>98T4%a^U7juhIayoHe1(O(1@5(H#I-U4ag{#5TS0b~kc&_G;#nEq$ubLzF zC4G~ae=5GB+gv+)yrysHrE_N`fAZn@D!P~Vy=k`Z&W!#XyGaDp2d6TNpM|eM`l|G} zCxkb_b0WZ9JTOgI8?afoLdL&kcF%kcu7gq+RXqoHpVw4X)hXNdczwgNt*W9<=DlMk z$dzxInFVz4eht3iS?|`)Tn!;jJ-|1!@C<3?9>mGNzh%bYQv~5}n=MuO zC`BQ9zh>)z0PKk8i+YGJ>d-Yty`3ZK&QcVN-=dFwbn>cPmZH?rRn0r5ycw8rUe!H` zcUQzH{H$Vh)oqEb=iXG497_4jxud-hY@55XCR_)ISihHVNC3j33Z57Y_RMfVL zK`2=LtcE8A^;i$RFwAU>;@qP1kTJ-q9yg}A~ zV0O9yFC+A+J7KK)(;L#G_fbb z701lv2zvlwa!oVr6t(Y|8AW~lF*6|qdgZe`4tBQPT170-iiH0^3~X`wmCHzZ;+Pq~ zu|7RgR)1)^)36ysmfF<;OK))jnriBODsbV#j)sR|?=3WuA%!YcxoUq2Bo9cFi zxQB#qX9wqXKp~drDf@re2{yE29xDHOGJU)$N@hjaA@b#Upq1zT|H#hh7J;#mh)p6s zTcPia-1Ctcd!gTVC{wYbRHd7Sjk{2|{LzLSxoZ8{cC7GwsdxI|P7`5r$-ZuBy}8YW zDl*o8{~dxK{_Dmvrmp<^RJdhc%fRMdcaw;> z7}l;M@P9fvKH-8mt1SlRFnp#Mky39A&Lv{jvx*3h{y;<)UO_~@FCp$Vuv88QK2g4$ zc)+k;L3+**es+lx}JDB7GMxDDSSN;nar(3#Q0VsQhqxzLhmYq zVPXK+^w<vm-zUPu4~e*?pAb=2J|~7?*&;E~ zdhLkw@?VoLM;`o*7brP@C$7}1?+dVei2NE%p%S}da+%cv`O67q&e5vR_zcHgArD5T z5x3y|FygI-^%Wl^gx~kzeMlhYAx=ajv;}c3@}Hlw=hxm+iMUZ|#GWVyL>OigH{yv0 zF&~K~O8pi9ioW{X5A4)iUpH9qM6u`>(C#Lrjfg6777=#p^FO%H{7{MTcEl7sFOZT! zM5JUW5m|K(5kGB8h?@;-ml32;eg0>wVeKx0l#ZkRHpALow!i-|k*ZX>9xUUC$oD~a(a2E@IF zSV2U9D~UVxt|R@B%jB?EyNtkIlA~JUJqYAKN-wUJLnKNCh(xIvBQdIR*g-^Lypwo0 z{3c=^o?mMcdr%vQH3t9G2dM5N4pC`P`iHfiU&rA_FOL!j;Gva)@RGRr34sB#fA$26E^>A?`NB=S1Y}7sLmJ z_)=wMZ+!Mx8~&XLkG>V zDCkO#wx8GAA)>)j zU+Ox6(y#gZ#IF!n;@5`wn23mcMnq12X|n#Kvp7is23mh3-fW0d#5)Y}JrR}sC*ngK zlmbzC1Bg!=BAAG}8bbUV8cQOoPy`YF;&%d)Z-`jp6NX42K4l2*3@yGzoLvZC{9uS= z3Xrmv#J{6P5mEQjwY;_BxGO}|O>BFo?AsB4L@gnHVu)Pp=3bC0Xs)=ZwmJ-qaE+@kM3Stua2%?G2SpLWhq+ksZ0j(#( za09W0AvO}jOmTyj-$-m}h?|HJrr1J64s9nQXZ}P)soz0_e|Hj746&2=CTbB8g>VmX ztJe^m&k*QoYKd_0AQ6LrhluEYA0xs+9T9f>iLDKBfcPG&6R{1d6H%Dr1!7x693;ML zhj2jOK8DDk;1H^n zRpWK6p0DBS#8saQsy&=@s_0Uiik`Fcn zrZDk78#*ENbxtS-QZN+NjfhVFY$7}wPDGB3AdWIb3GpyGBO==T^N8o6`Vo&BVk{Az z%tgfWQ4NV78e#$wEo2$-LJZM}C-K9?s})m;7oi#wkE0rDIbRzW7aMAC9`U6i=4p8) zu@u#k__2Y#ih&4V5wQ%_l88~p6qw|xetF+=8;#5Oi zOEgTehB)02Yl#7-*hrjXh)u*FF_t5u@ZCa0VctqaVZN1!!hAasofzM9XU^VDWdDCJ zFHoxY5K*dYi1Q3_AMsmMOCmgcn23ShV?=mRN5rk!Pn?hHNIZq=NQC`!#QRYViLmDv z9%x@rTxf_x#0J#=*LiU_e(4aa4Dkl>Z-#h_c&{PeCN4I_JH)RHag=xusweR>L;RKa zjv+oI-i2yPyaK%)5nopLoQQzGAXXdVOX6umd`0wLX^5|R5pD|ZWzHpdN(2h=tR5|)sF~|@`%@9EJ(zdu7HSvNH^ji(c2Nf!7m;n zZb@GvZbc#SI#k0z(HcMWP!B11zz~Cp@OTJuts#aI17*>VW~F>CHXS?Z#kk|;`DzC` zZrAqC-=bpV^MC50w#f?*9u4cF*vn*fc0vU=&I^~}MtirM{aTM;dAc?Bi>v!IB3>>? zfJfNJt(82sJhf65x-)||?uPA(HW8JwMM4LUJlzZyY7f5+8}O|YwGUk?!>co0G2Det z@ANjn1*$fp^PFfEE}wT{tG;Gg2&Ye3Xt=yEz|}=Q&^*0THk=dTmLY+zFY#nUZtL1E zp*AYW^I>EKx#7Df>C%Kl&Ru{L&hk=^ADvi!^TXWZ1`B-F! zIJu}V;@>bbG`#kq7Ow6tYfHP7J}$K_UMaW5OUvjmle_mNa;;fW?B&I=3zxdD4p|nw zJZMGW>Ht@}+FMdw_XNt3L*P^4hPZeca9$vCj9Ui&^ik*L^1`7|Y+V){FI!$6rmt?D z&+YSi28PRhZC#P_y|ZDW?m*uxd}!#;v7Sn~YEwvpERFL_mHTS&E%A}E6weI7To~}0T3hmPzD|%68CW>EA zSCYF@E9O~g8NaV{oO^+m&A0O5INT6URb zhx!xaMpvVX$rW+{-mxrgFr1S~dhH z#k*H&=}IersCyG)+}CQ^H7X(-w`K;(k|I~Ad$pGT(Ms^_{sD3BHClF^a=&TO&>%Us z*cI+xr{!zqiK}9L`&PD<6;nc+c`^GZ%yfKdjEJB5)kHMlP2~^^?)}2cu}W&$y+5oT9(RroP2OicZy67#f&n7PBWg)lK= zhq*Li=IaPyW)7Fa#7tawBK~0>MVK%uBzD3-VzG`0ri)ZW2Iz?N*AeNbBa(`ts)|XG z`YxU@d+Uh6*9>~pN=F2D`msO;G@cyc@OLXWyyDNsQ2f@Z<5U5^5^|D;$Qu3_Vg&djh@3xaLNQw7Z zxcB4_TE9hT*GJp&r$Z>RX95xOaxLGiaW4@O*+)G_ZJ!a5;O{tur-H*m#xMwjBL*C& zF^dR&MCNsb6UNQCDHh|Mu~MnpsN3XlPPrtuq%d{#v{ck1)< zB2Ej^HMZB-8OS}~x@*qeGMUmVHQ%NA0nLwV9)lW1e^WJP0z)y?pfV_Lw^+n6YD{H%?MHsNdHPRz0pQAPRn8WX9!0J&1I57W#V)#jFn;9|{}X;hnC z!fvzXJAk2RR%ZPI%^PUtS#?O<(!J8W2qZ}T8MnuZLp&a(#X?+0dINh6m!ctGRxKt|*>%^NhHqWm`ej*YY;#wyAPdB_n^ zs>UqJhojdcA|bsfufzQ>gxQU;DoIJ?3ccIbblD8H^!^aUSw84hcEuDb-X$PC1N25^~Q-LI}x{dPGMg zX*%%8u_Q?hNghca#M?X~w_ z>spj|$14XS>^D*l`>jOS?V=pv3Ju5kKOu?>f>&wK9ry281lW)JHxU8-z(_n{Ckjsy z%%B|hb%nPQ>>%<^!g~w$6Xb3+kpTo8E`mJ4xq{0C*9dMF+yP{QyM!MR{8{jV=)?T5 z!(|pv#8s69WI-|ovw;B$y3+uLy+x5DID~R^IAesHeLs=#RLYm)wUWpekVC#m_%gv& zlq2D_!nX?Uq#X9U>5qXKF#Cl9&3>W4OJW!nCsi+K_6>!;uJBfZ9e|9mI}zu+FXcGr zIiep#InMcT;Zp@?#o_!j;9LnhzNIyawLqUKqf(M z<4RtZh>RzRysGdf+&7epR#YINY~kFXl#Q>i@cuwHzCpsr2u`FN;ieGLzfTwWLP2h1 z%J>VYhuubUWN14%Y9z2r3=Rt(rvip2iHPuw$gc`UCpZx%0%?~-gk6fr>kGCP>_|QA z%toikNMDincQBxai-0?xM&f;S9yxM2P2_VaM@}~qE1=bjo*SI9&p$=PU6UJ|MmE6B z40l8htttUo@($$P@P=4;UvdoT1{yie{}5435XDq-WMCFK5`Kk<2-k~ztH`&Le}^7X zb_X}lw+%J^&uL%|k7721Y&;SiCiGcfol2;Ps{-5OB=abkK82L6X zFJb|1!y=z6xI~bvm}y@ixKZ#&!ApYJ)|2}N<7RQndyD_4lCb)!h*sTE4ZWTG~)`)(y**6ps9}z=-UyNLfVK|Tp)*(mZ zY9*Z8dQv}Ga4r!EyZ~eZOUaSIOF&Ztf;%aP9ajOl8vZQk!T61aejp9w z$zfO?NV{}F`ds5cg}&A}Q0XG_-h%y!Wzb&$8Gg9PR|pnR{yDDyts>z5o{@VjbwIe; z-xCIBgkPc_oZEOZBN>971i5`D%#CztG6d=c^$dO~Z zMDw)4kc)Bz;69&3Zu3d3A=pSTTd=#}eS*V)d@#usK2dPGL0tcHX@DMTF%dV9rDCu~ z@O{yLNJJmMn{s5dQ1pi>M?Y~=_!;sZc%~G7nH-lX-w`n5+(Da|2#gGD!kcp*;F#3l2@EiSY#cDh z9YoPpu#aGl;6TBtK$c(`Fmk1(RuDhI;8pbd$+uYQD3BRHPR>&*`fGxb)o}eY0~ys| zfSfl0lHV;jP%u|;3Xl;_1v0`H$YH-$^cw|tQ4YI3K-%pW`Ehcjb4K{JY5_-(l;T9x z63ELh8_100P>zWDQI3d)iF^V%ZX)x5ybNCzu*n`~Mm^V2(2=K#sGB z-B1HWjPZI4zgzfl;p2o)0W$nFa$E(ofu4@I>5!vWZBiZj#)uaf`2u=Ua=d}cCVw5D z3Oi8H6rYJG*lww=>sec(0W8;M=I!5!ImCz1m?_5?a7lm% zFJX{L#RznzHOQGx=&je@%c4*=Qo9Tong;04O@gvFWN4A1@J13aiCf;1ol)+a8*{56qx z70eMFNImRE3ZEc2jdCRLBM~pC;_Cu&Dk>3iRn#X&VVptaRZ*AMKQ4#f6yS20N5s{z z6xi$;oEmc6RMrT8U-)id6uQzwls}8_0hFVS@cR!VjwIsd)d)y^J0fbhBju>!E+X$+ zkJmp828ke7aH8Ne!MTEq1z!?eEx1u|JCHSVNceGb)`;*+f}AQ!yXXK9P}OyS%t)4C zN5SsYqhxmo?o&x&Lcft9H)_<+Z<<+9z43!NhDun-iIe-o|27% zf%=(_V2$9Ih7MmwEQ855g8P9yB?rk-g%^p4h^`PlJu#Xk`td%1h(~d{JoLn(^%LVT z!~=4S*ouh3ZEqr<|0X&IYL(zo!5WQ?f$AhURdB7~1;NZFj@?MXB|z5X3c_pIM!w0TR4G0TR4QdX zm&svoH+S?^fh=JS;f=^qLi*)nW6TlxK*3zW$%51AkBhJZt)0^)MCP8w)@gd#`P z?jVQV9>K$cCj?Ic89p)#|1nuA5y;a$lQt`9K=E5e94h0}>>baRPlOKX8FP@sSUlxVXEwhG@)j)eD% z{D8<0iTpVEd$?+Z|0;M%@R}e!7V>hVr$V*~dMM;&NY8|xY^)l|^d~O5D<)PiYjU$s z-!#CRAGil|lofvWIp5G#KWD=g)nB&q8))XIo7HaNv>Re(^qR$Nk>taXbK*$nqd(Vy zp(e~4w6er;vdV5eaz#FY8)D!$$-K5z`f8@X;<^q4y(ykR48BEC6^q%Q#5fG$hzXXu zmsk!xDzO44WfLpnE>5hB$=SpzxGIU&Fgcr;>deI8OydX1YvR^JtYvZAJu{OSr7;tL zhXSyW2hW@oG_ce|M2xslJgm;cWNsp!q)<$(rLxp0B5sN(u9?6)nuv+JV~F_HKbF`U z-2*WjlfH@VFzK7v!BUS9J7U%;u@ja`Fn!LSok&4f%myc7xIdYQ;r(Mo4C|*5d!a26 zd!yeW{?k(V#5*ybA>L)F$BCE@JB@g+#f4^Oy6be}1G4UJ0A`buKZx1nCdR?I`Y0G` zap9O*=ro&%+xZ+K2FY`Yqbz4(-WUuc$j4z?D{(v?u!xuh`V0}1J{J-vV-`Ab3OYz) zp2hWFX8qG*BF06}b?3o!XXXXxQa(@q6vmFkIauOEd>Z2w;(SZJNW@jOjQFgjmJ=7@ z0g0$B{q)tCLE))R^L|0kpVPFmkI&nm=ws7Few>$g`TZD3r(is@ln zUPfE+>Al0F(>yUN_4!rMJ-Slo5BH{r&0NV(IQrN+M4G?B(fzW4y91_s{t`a)1MUfk zFduMRyL8W)54aOxy64&l+yF1#GkPQU|4aAeZ*=&DjokGw-D7WZ;>+E{z5dcYd7GT@ zzi;9Wf9V#cD7N?4@=V;!ZT-@%S=u7~Ycu!qOZUWV(aV|B>07viU%F?}7AJJnR_@!E z?x_qcuxeRbxmjPjXW3RgKNnS3Z5y}fOZPO`rm<;by659<+?X%j^W`>eJ?^cAecQ1c zU%IE)hfdx$eaJod(mkJls7JGGoj&5ud+DCOA34F#e8m0sP}Yx})W>euZL`21->$cf zLG%$H>-pprKX&4K;$wY`{8{0cFV?UHc-#(0|JV+lPd;adQ&(tE`^f#DIQ(&7OH{@) zdU+>Q#`RD1Xi!h=PDed;r`|^O0)3w9Yddw^&7fuV{LY~HpXvudJ@Y?x68q~@{WjGx zx?vZn^LA;g71Z-~ar?-0Pr1)@FY=n7>3!rYKGVy|*MFvuy@9%Dx?7(ozh$=`{Rs5C zck8zQ06(%@$E|_B-{*QhdG6;r|84L~pX+1f;d`9AdTftw*cyBea5ePyUY$>#xYyCo z+^hGIKL^gbtX8N~+kiJH)XU$+nJv_#N#8Bh=SlbJZKN&s>9+3~8kY^ad7n<5jKIzI z>j%KCj(UD~l=XxC`faK|+wZ8`f1$0m;J1I_@Xx-`y}+%nb$$<+=N!<>sUCj7QJ*-V z&y!yeKKx7FwjKE7FP%pD`4xpW>Wsd`PEufWly z4Z^o5Og`!epFXPZqwqR~FN!e!TfK(D9#bJq`_^f(bHCNsD14E^r6P>|m>yZ@3PKU7B_s$u5>wCSK!uu)QBEqbby6hVezC~fDlllSl z=bp_c^?ejxr*O|nr@eIjL9d~($CD7|{NNh7x{J4@MJ zKkBy~*;2~d%z*4mY?;f;J?AHVhQg;Q9R8D2aTk8lt>1+3TMF${PTQSyO3$UR!AuCB zI;EGtg$5gaS|6n_KwGi!kARR?%>{E~){Kbjk_A^Rvq4a)A2b?k2w)bmD zW7k6Z7Nw`p=ws8owLE8)zMsPD6izs6+LQMeNZ+Eg$81Rd66u(8N?)h+MM|fhGZ&Nh zFGzd54e41*W6nDT&O5L4i9>>yC|&cLlZVZLSx9;6RmG;Q0v57I4^-cRWU3&Se0A^WOQ>Qhdd!D;{w1d>E--q-prB8|U8l*2$+GYWyWiLCY?(xe?Ph8-w>3Qa|6FBUO(z_@qe?=dgh%*je z=^60nujq!8z^^JjjJ(2Cr_c)^*g(NcS51rdR{sn8tSy9~@n245t%l%k3O4@bB--$r z(yJ(Fd(BDoT?j5yu>G1-u$!+d-Q`&bZoBRT*$TlD3JR}l>+Q1T_1YIQ{J!c6bAWV8 zMqG8z%}U2D@}_%lQ#>%ldv3;J zowJlaZec`=(cV)QUc^<^`JZ64Hy}m#f~;W}9(2Nec*4WDw~ocpuQLyNz=-;z8l;r` z8a8R(tZ|FRjb-oPCRvTMS~zmE5#`(p= zmCVY1V-OBwZfk}I4a4!wXLhh!hDaF!9?jHGcmS;{5q1L~fV$W$d?0uPGRVg&+T+1Q z`6A5YuHm!6yCFOuGB80pTD`^yU~me^0Gk*9&+vCh1P8&J#+x;fMt>HZ8^=V8J>3jE zSe{{>@HKFdibwHzqHhcSHeU7h5&i%;_wIR@_5tP)f}bGBmI$5(FNX-b3g>j~1XS5B z;h%xOhYa%3m>K>K{2p*VN|SR1_+W&ef?6Q20Q|lpp0q^Y6ue<&Omqbg(0~h}e*p;^ z3<5`H&4VBHW}Py)(4?rC_qdI912v+{CQD;PfHR6k5h+=xp}CLR$oJ49&=3)RB5pR zBSBokIPf=6B`{OEce$nbF(VOynRhn6gnu1mv zGc0rlXPA|r{ayOgj^3n?8mOZ#L%@m3!3ey? zxn&L2Rq^0Iy7ZMp^!3ex%S7}W!SIbk^qHz1_>7nmJsaVS7$<#5qt$INnC&v?13u5i z?*(7z;)B40KQES>uu-}74@2LCP2T*X)sztXCTb4&k8tc?Y{10>!5=q?eHA>zygH*a zTCEAu!?PfG6Ld_@FIw#g(YI7zg4^g9g8HK&`c~=}@W9st(6b$;a!)$Y;pVG zDalq}?}Kx$S5VIkx%n38 zb6xtK;Nx6;Ur2o2)u8|)a2piCpf37mcLHwy6ZDxb{jVVr_B17S>n&We+g?L+i;sNUf5Rf@w0)IA{vebq4V zP9+9vY>57DH5Gh=OaD}eK1VG9PpVp+fO4}7vq&lBY4 z&7jY7>Dz>aA7;*vTi*lvWkGw6F8YQ97_NqZ?+6+|KRQG|Qssl6bm?b>=yTN)@cJpi zB1Ef~L-b?RJK*C*j}b|<+8AOmPVENY=!)RW5dC=dJ-8>eB!M#_`U&b9cyy}XxHvK? ze4^P&J0n&9Og7o9@oAZ=qn`ttqB`S#Gc{G$1q5DXYTG_Z!E=t727(i}OB`U5axH?BI|32TJkrrTBtU{G}4k z4OHNYqC{Z$XQlYJrTCdr+*f@6cfKVhmg2Qa@sbUsn>zvSaT)N=I@HCPL9T!b{>Y!y zqr=0i1zsy9E-1yfmg0NC6VOLBLlp5i^L$>p8BME`aISNj1I~VudX8IST)aAX0?u?J zM;}m)Aovu$biCyRXbH~kZh{eT!PFlvJ`Q|2`luO_0M|ivMux@+p95YIdbTEJU^(~) z(BCJV3#e{}p7%=ZJ`}A!f}j@!8Dg*xd^viFbm2wdwZVG}KLh@#%l7}!s!dRK6g?MKH2^m?#*3#H1dq53hJgQo2!d5Q5xh34kY|l0ngjkgI9m|;tKeQ2 ze;0fu_%PA`j~mJ4JltO=##(K3&6VD&UhE~auH8y+JFg!3b-fDjtxSHz($Q<+(qhz; zjU)7^y|+c{ZrkAN*Y6K+th@H|Y}Lsln@8wEe|VI>@4bu&oz>gp*U5|QaQ&b7uw?!G z<4IL@*F|=O?mM!1v@WcW5v7-|j*QUj-|{BuNsH`Ay|PxVvU<iR8#E42 z%81q1C@XurXNOK&9A92zJ$$%cv9L+3?*6tnO5f>8go#E3cP);O)kmLg5}{{!68(Db zZ20%+`?fbu=l1bLSk1M6acTuUp%3!a&660ZGlstf#VZuI`W zx6a>t>-@d9&fk0M{Jpo%-+Sx)-?_KW?u*{2GB<9U)A9kAUowoX=z^~6;^43U-`=uc6^b^*M{@mFlZ)ld;af8~-KfPUR)9&;WDsPzC4kXk9 za_;1k-@oA|Olf)jPwy>ZihEJ`^@TsZ{k?G!6ZBn|y{#LRKa8kT77WcU$g1wY;!RsH zV`jmub`jiR#wCrPfX@T_vXj5nyDod12X1E||4ar-^I!4A&3yDyiiZdZpx@A@@R_T1q|>avSn;j=WBB!k**Z)l((E49KE%p$se#aqcAS6X`0Rd1`n@jR6>=TexmQk(*fM?uS@ zpy9dTI1%8f+sPk`-Y%3*U+pwfn1q*|iquaHxy-? z6RLf21)~OTh$!z;-5Zk2yHvlFO#kzmw}wBV&`GrTq(61dJ0JVu$HtN^;|hxtE=AyV^QS&2#cuqIrB)X-T^qB-Z2X*5e(QeP$ZH?|+;>Q#ew|Lv;De(1*dXxDatN*!O2X;K?sP+r&f+KK-} z!z)vi{p+MOQ&^)@^B} zZX0W*IW0ILo3%f@=z6EEXoW+NSKv^UF`&?r^5r;14i-?o;a&C3PnLxfu=U8LX#DqY zExHxEtre&SbxIYr2C|(JB16)TxU-^XhS{lhTzLPgdTp3p9ygUw!|a+7ah(Q~S$mE* z-ao?ZHUYJDlFFD|$dcW>?_z;f-&1(8z*E2JK9%B;YarM^m0T4;Ny$|almxGeAP-&@ zL0)oIs8q;Q4y&k1k@f#eV!C#?of^QMYTH^9z^af2+*OYw~_DA_uJ?R%-T@1V5g zwo)u9?jM4Z|D`5^CjWC)Jm_?C#ThHPBL~AWW4)!53d)$R{}=Vv*wupvgZ`h+lKxkO zU9p_Xn^Dqz1cU0m5q3uF+e}`Z=6p*boZF(^hOyoDyEvrT(6zVP>IC*EOD`NzQ0}}H z8zDI#fuTb=j&7Pq+I8!eFS1sKtzZgqMPVzme~mVmixVO^9x4toKhho;80$)PMB%`K zM8qBJx(6ceM2>os8z5OLZCn?9&o4iNIaPU>sg^ zxfk1+c&*gDJ8>UxROBR^Bt;4a*@|R?#VnCo8Mev5*2yZPTww-wVD!ujUomy<(2mhN zqqp(DKg-`je;sA_Y`a-nU9iYor(Dm-lolJ5IlWb+lQs(F+2>8M)%+q4{?668(RRf^ zevu6_#c5H-!~!2*#QiJBN;?Zi=gxGA%*u!?t~Jj-hQ8B;?sG$EyST{3p|wB8u9DT* zWFoUDDHT0APOycK?zL|S?zthj9vXwjRTAc6fvO+7ue$oWfG1<>Wd3bC+0lE8V|Pwe zFbjHLj17OeJBkNSGylv=t;kk)Q(60BO2<;!_;5<8;J3uuOTrUR=i6TwB;Tulh_(Nb zz_CiMV^(|_-0ZjShvO;S5VPbY^|%~NDNII_C6ZfZpjaYVb}2E>iLykt{RS)F4W+O! zeCTuRl>)17)V`jjBbaxoCTpsU zO2^B)c};&XhC6X7sd{}(jCmMx28*4CJ4xpo;^YO{x-fXz8SAu)#TOoLSS2xpjROz3 z1h-BNHDIlUO177>@Qn}E+&88veUFmJF05)?z2m zr|bQ6uC1-FCfF5wXBMBI;M0Q|wya&v;`0-f;;e=|ILt@HovSkXU@Hh(>QRaIJ-CiO zPqZ;LPoGb;E0n{aF*p==J$qCuXJa*!Zc)x|0C=dJU1hL&;%|$wUT{>w_XU`WQG6$L zc*%X#;lVqV!-BU^hgp*|&hABRt3y3ceJ>7)#PhrTWmF#xG81(!~c6}io1goyAS=r9D0@!^JTg>^n31g|P=8|Mf zL++RYE&p(vy;57(74NaY7M1b&8YGZ^HO>DAF zBNF#}VH>G4AGIpz5moFcZfF_TA|U}qu;GX`(`+7zzpl*}?My4f%grb8@5Y=vnRJ;K zr*&h7%|@HWWi_=C(aEbic~mD|u_~@(L=!BW?XCdGgXxsoHu1)70`1~5IK>ENyktj3 zzf-*6exaa7;!DD`MJM@SCY-ZcYG2Xf?E{NrEVXxIsgwJ^Q)v^-l2zHX50e?U*a-Bo zU*q~Y-q2%aS&4f1FELU2Y&AP3P+eA99(JZua-$^kfg4|8@ih{2rQn8%*hp4TVn$p7 zIqc1(CFm=VH^B@SBEsRDFE-b}3P>XCQi%BMj4zvJIVWypUBfx5A_%VyubV$nnA4~o2*A4`P& zI3jZKFwu`mG(==9K-{HNo;gC7mQMjb6VD)`ik~7P;<-dbG@po)E+nE#H4&%kIU>&2 z3&bPXwS(9NPRWRvOzR z;sHz!CL*De#5+s&BRoTnb9bKjsq8RIM6=%47$lPKG3$IW&l+)(BSV#m_oI~)aVew_5n*-F*C0M%*7=$p z-Rg?G9uW(Cj#7rq7=v-(|MDG5QPSi_Eq-<`VleKmkf}m58qMIuRw}0s@xE zM?}Qf1I_GqT88*DE*~N?3?FvbXbD#h5q9xJ^hOE9v$%SQu&X5c%ETAZ&WWdS{&8nE zy+m~};7SE9;HXK&#a^3;2H2yh$mb@Z0RUvZNlBEaoLWP~2=X@3_H_IDFkqK_e-L)Sor zeSaeCA0)zl2od%}iErTELA;3bKavM;;xZ!^;pRbv;W*-3vY+7vTxR5N<1!;2#ZX-A zFz&!CHl^~2zstUc?_oDj@^7&rkl3014cFn`LjH&BYgiE-_dE*zjmwXC3@ckq0G&TQ ze3C)izvB^+O1K)7HsWx_^8QRc} z({{BggY}pBR($f5w%8D-%oAbLeNWnRy`J2Jah(#zcS(3``^P&z(QTh8JKT(?q6^*S z%Z*JRrTzJ3;`PD1BNKJ=C&C6hJMTQ-*pAmH7nYSRX;PZliTWt_KkCQ5gK&kK@_3&x z8JnnQ4UEE$KhK88mkCU>?&fYiYp0iSN~Ra=ZBbtTUc0v0GNqi}Zg~eUO05#@nc~&+ z>vgT<^KP&b9?@GGmLKkHwqi~iHai+?t=Dav*RG%^&b6>{(zLSC@#smA?qqXrOv)2< zza89bC@w9A_eJVVp72T8T8V~-b7t?MASHEU>o~atwjCYvf!3JJ+d)TEV~i*AM!Wl z4pQ^WhU>yMcC`MaY(+`hn6!@tHM`2}&$cV-TdH8sC==qowm3%{?&pS0?d%kN*ZU~4 zIr?o6_V6(qB8_W-vrtkiogaYlvIpbK>07D=W8p3>y5d;uk7Po46N8DHio3Ia!dQK^ ze))JkxEk8&IqYT?u>tD`P&m)O_2?$$gIl*`>vLn8`U0`$2Ce9M9k(S#?@Q6dcxNFK zy)Gq^$2g;LPn0tn_rNHH@`|#@NhQ2@BFBKJE)jt;i5Sl`Ay$>ea2ThwB2PBsXROSs zY{tLJQ^6TcdoT#@N`vzFL#*axtXWSdBh7j{8Hq%HRs(u+CQQzRo89h29Eo9I7x1QO zW>l^sF_i2h`XPe2k;8QuBA5XIBUnfU5?V%t{1uU}75=X9_2fusH#rh26n>eA@Ej5{ zJX<{DttvcCcse=4cjw)jh8$5vVg%by42KElz=sjeCL#dGA>?}mc~__WS3%x9smBWk zgLqqD^t`3eZj2y%Zt|Dd)$?G3;C{g~L`0P6MaFRNNdwZZH979;U4;)L#}IuSISMkF z90i#{3`0#)j&N%Qw^NRL*G}PqLvp~aD{06rD2d!eg_t7PNU(z-_f@2x+aeMt3(gf> zCdf?#spsZ@#6yCo91N(dA}EVe(I7>zi6D2LqkJTgHNj0$$QKK~BFJ@1lz%9=NARFv zk>CYEE;DL&JI;S54!HA1J0n0V6&xZsgLQ(+0^w~}Ef&6k92ws#e81p1%8}uV!r8Gf!LouWKxQNp z7@(q+C^`yqa}>%40ckj1c%I-w!Pf-W3+@y=B=|Fs89pbRF6P-NlYoprErQoS4w{Le zogg<)iNq~5M{qb1kxZc;t$ZpuuIuUK2){&d73Js;)(HPlkejGbeo**1aLducgQed-(@U%{j9&nZDHwf+y z$iWdBpsI_6Ul6<|7>0hI8AuXL6U-3I6l^DW2aq*3P&k(yF#K%6WrBefa=_hHXs}&y zx8PAhZl*##H&G$dH6$?w$b`6dfHl&D95s?9`rhO}q2`275S-y)K)pl*^kCdog%Pe5 z+$gx4deqDzAWsSB{L_wiL}I*P3XoM^2iR;JS~oeWyou<$kmHggp4iY{=aJJw}g6|4)4-k#(o?L^U4u%96JDq#e31s4l)FOtYlQRT$FxVZ@5FZ!PaFADO-naPM?8j#_enXN;R z0ka1Q66z=hcMFaboFF($a0!ql;#MP!xInN_@Pwe*N(B0pc*m|KkOl5ej<(aATZgdm z+#v=zg2MQ!Xe7JOfDx8QNXi-M5}PJ(7f4`iT;@J@og1q0lEya;9qE)`rM z_#u#X2ZSFMJWlx@yg?BCIgyu7gd8QU17u0-lcS)G$dREA4hB>|5sW0la14-!<3&DQ zGCof%CBQr?7!1hObc0eU65;k$tRvV#kXwN; zz;K`^#aaICNyV!n$`O7s?UtZXksroQiX8E6ATB{$0#g1VIpl{017>Rw2>2Yx8VCc@ zpsHY9An$%Hh4&;b!6+HX2>XhBq~H|6xq@b^5X84i_(mXWj?2SwHw~y=RBXoeO2rOb zujE^BQz8EXIVInU+ba1XynH1`gcn5~mh5n|r3mD8gtr##35-050f_Lag0l?b+$<2m z62X@QR|ysfZV>!XaF^hI!IQu!)Xa}S*38c$_f&D@Hjwggps8W<0M1=q5ey=3!+S(3 zU^tG5Q^Ku7c%8pS`~)=vWI~6?VRusakHUWjGJ&#q=BIrPAmioMA+&EqM90(#7~o}e zpBVHPgIwY+^jspJCGy20UkhXg3PiqUJ0BBO_dpCaOMi(?9Aq%1HB8OtIfd`oT} z!W?xJK_?o5cNN1vfiyjzvt3*HpJ>1Xn>5MH8~ROM1);WBJ2hcQFGIPw3|*2yLm*| zEhfTlH4z!z6~F-vcT)hvgG3k}CBpDmA`I4ROx%V?E+8XZD)Kdg1%e+^{}~D=-f9Tf3PXDvJ1in2T& z+vEP(w(Zd=L$mC%j+9!6Y~5`DX70n4G2U4Ir?F4Jc(*+x(A#8d+y%{t z%nHQ2aBhhAV97J_Ui9U}`^^_T^ZgM0f%#roh4>)O9dWRHRUeA`Ir&5KRec0%f;`uJ z$Wwa#7l{=EkHG5{g%h23Zv6UOn>-+2-1Fs&`!wfW9KVRwqkaaelQ;{@or$xZmxKIZ z)sTE1ItAha_#`GS#9)HB2=DKRi_w7q0%{39YEtlm^EQ#+eOiz&H(&eBXPleKU&WVMC9Danu5w^06X^bw|PAIP_VG=xr6 zY{pkp;uhy^quPqkJ>=W;T)63t$cv@d1>DzlYX79lVe9?qq+)c{zhctDCZqbtijUs2 z?RCQj@SkYI>+VM_;i1q$Ut$NeC;h<0#??IoJLvq^t@66?uNc2)NC$oPy@Yh)wiOT> zFT4|AoRg+g6XVi62L?F~cMlD69PR??aMyQe5Gqyg`>b+;UiM6eA6v#-VP$LSHCDA~ zea}Grxqm{kKkRojhNN)awpTg0$sDgIac=~ ze@?h>oa3su+&JTJ&NE}2fH#W%htw^7+1ZX_Kz6fiF(cAF!(KP0>7o7J>pojo8Y+X?LEQapH6Vx_5MeA z&qp11z5O25ZN|o=dx{=){PmuD)XBk6Y}-!%ypK+F{8;`m(ec+?W|A&^$(Qb#G|6$; z`_v@emQHEQO?Dji)|~95_rheyVejh6#@V5#_G6C2-WHEJZejuS$GiD4$Gqtj$6xO) zQyfRHo2EGadOx4yoPc%#76%KpMMnoI3G7odoe*R z=zqR-VTE)v~4;m%Y|9?Oy}q8c#SLdz(DrI6r>p3CCmaM^8A- zq1klDV{galPU$|F?s)9|OnCN_j>q1fPdfUKpL9I-ehK91?>fWr*qbxM;a|*fJobJ! z!-@ZnnU2TaK{FlwH!~fVy}v+C&(Qs58K1qrTy#l}zemr{v$XNsdv%r*Wb9MMZ?EU^ zryPFyDaUbdDM1T&DMqv8(%9yn;KH9{q_wLFbhz>u>Y~ zIKNBdAA4u>3&-Ecu_JOrye)=0Tl6+>*iiSXRkgPFjo;O}`D5*-R$!n6ci{YW+$_wG z(OLMoG%bXOIWv?XvyC2p_J9vYI(GyQ{OCOoJ_)yjBS3QGR1HXWZcpUs!`18H+Z}yC zp^sJ%;Uw6@ z4oCtQz@G=t5ndKI#amH-!78i=zONE$L?YzprLRy!v&8-Z@ar{7PSGRaZ>He+*LE^A z2mEH7G9(i)IeZ<07LLI1ZQyNO{3!T8T%4{BKdWYDNf`S$L|hqqREps>z$@0oahSuK zgFlP0O7Il(bJQ;w!>r&~h&Avq1l3Ty42fVKIDf71pWY&ugYQKnFDn&y# z{8O=au9|T59rzX`7>w_N=vjl7Dq|d_J`}?*dJ;i8TI)B+-gMz~{8tWqr|?|xZYc2- z;nTt6kRcAVn4u-$v4}87`0L<*Mwc{Ve&-q+g@L;0_k%wLJvSpU5uAYFpAZBi{1yCr z1ZXXKRwZ2>1@+~?Zw3#BuLZsrS4~jg9GotLP|GI%TfynDC#dIlvjIH+2xANeLNEfy zK|T%~BiLd-4IH&^=3uhK{{nvk^_eE&Uj=^^RgQLP;(HUk#9@WmtFebLiF{OCmi+Pzqs0?R1_~@`C&f0ssx@?94Jav579R&)kdOKBj}g7>~9XS zZ=$+@Un-VGsoVKRC-|d(&Hmu6B7%}A^-zdDOHBkn;?h4JqHn1dfY;?EWPZ3Ehv-|W zRp0|%`T$+y1%F;#?H__Kav6LUqR&=`!TEjC`9-PkLiFv_ui)!l`YR#&4(46=o)Ucp zl~7z7K74iLXI^DT>AWtnNr6tPC0I*zGr{EAhgf$}y}`%0^!J45yQ*Q}CtUimA^Ps- z+i)7XrC|I|x%C0e5a-9@J}!fo-3D+iRscTBrT-vA-$(5N|InrXB1C_OIu3rxr9bV` z!$DqObs2)P=-Gog^cGhh>+5b64?fJLuN6ro16_J1=;r(yKE$Pe7<{;kPXW(0+;omn>PZNKKQH=! zcC?NGrBSB2@@uB^i&8I!*bh{1f%9WxP+!tKS%ZVrPUw%g^!tM0nLhnt9)qAi?)Je5 zP6Z8&ewexpzR0Eb7B@JCAFdL>kGS-#5jRhUzR0DoDdA1|z1Z!EC3YJ$g~3UT;DQ-y zEdj{AcnQ=UJd1-N^NTXwl$+lPeJhu~A9%Kl(*+?uxta74MU?9jV*+DLhWJg+`C*KV z0NnIG$XP-+e+v4^F8xCA;LoeZnfToLSD-&pA(%cg@McJW@oE!z2aJiGpHo6N-vNCm zm!94agFi3!yJC&H_1{82&t-4CItSDD;uRWaGF)~USjE>YYh<#D18;{hv-68ml|uAW zR2}doE`8$=eV%F$e$l1x3LZ=!2~1Tv5bWmQ#{8TTyZM9Ab4T}}ek6GC=fz_jOYGK9 zfu3JQoFA^T5c}y$MSlv);IFvCo}=;+e_J48QAeG1;+rQaW-pRJCAPjl%{ zhv?_3D{#cGUUM1P#l0M>e4a`K=hu&52CIbV7pQvRYhC(gA^L@?BRIc~1jF|T(JxZ> z2O#K&C%d2lTeX{WF33Qael++H7pMQn;LnTKqC5p|{VeGD@xu8XltSnOK-^J1Y`Bk(hhfzfkfQ1Itf@0ianJf_qjJw`1J(U&cyFRNBS{|e)0 z`B?)6Apth355YIPGO#;DzgZmtKk3qQrc?0eRa@0X@SaVAk|^iBgix>g(9D3E2)&a& zGEk{_bixvDS9QSqHZ6&O=iJSkK%e8%w+8R$;+?<;x_EE!;LnQ{RlEwIA11OW)jz}_ zwp5kHs&OHDzj`u+$Eg=xoa2@)rT9MGV0v`5z}Zq_t9Vf4yiBT4if5MMZAx)Y%nJUP z?6^|=u}~gRGeQMwRVlvF#d-L-i!*_eQJs_F)1~z0t)=9M_T~6Te(-6G4{RX>zv$_;N&exA4co^Kr~s z{fuumcsJ<#h+cy~j|BPJm-?5$tKlWZ1YU0xybXbdppyjn2>e?Y-w$335vGg&1o%IY z;bp?FgAc$3^uF)}87H%C$6@hpatJT0YJvaIn6GzxI5}z#L9ZsxM_Oj64fsstmM@dY zyMyy3GM5dI|Br5>9Y2s2=GfI@+O&D#;Q_rL7&%bUTXdH>c6ykn#z0+^m{ES+eHF`m z;?b>od&JH2@J04}dUdT@QF_Yz@D9BqxlDQeSIZg^`s>wjz8-f_(K-zbiRJ7x1Z zUHmDpTYlW`YT5qZr|0V5zO!4l^q=MPfM z`?DQpC99R!JEgL#+^vNvuby|-uAX@5J*rd0 z^HLdwX}~M=!)I)K9A2TnJ!3bEa{`o6Wm2+oAIp8SAVX)IwXw{8g}(DF-QldzGtU~I zNP5dz8*8tOi?}cqY2w$Z=j;Q>p8n&U-A>8yom}?opZIaY9a*+Ah|(;9^@1w<4>1uVAnWf8aCPS^KOMPf_pWQ$MJbT>3O| zg{hGFKLj#PxzSciBFjr=B*)j;zuR$EGP^@2tenu}Lf)8O?ZcB0JsR1*OE36mObt)_iOt`fi5K8sjkf0h z51W4cE#J7a`)?V-n_VPTTXHn$s$J`bj8`qrc%6)-ePQWu>9tqwiq;Ul>#AMl2J4h! z>zgtvnPNu%W#4MuuY3Px-xbp+Shc8V+MCrJzdX5s$u7@M@od z$-n=QxiRgxFd|4reCpD)PCdA{IZIm5G`FG$v>uG{Z<5jYip+X<7em+!^j z=J~N1l?vlBdKAWIj4n*bxVJDdV?<#UXfpGw;&12tRQw&7pN7AW<=4dDSMt;GcT@gZ zy+7PH!dj%WBYf2{+i@UajGhtU%f;NG8Tv|uFVkwE>qh#Tlw7vyR((A;(g%l3yvkD6 z{SfK<(8C*Gm9oC7`qLO+Z)P8)Yk0AAW_e$9kd&?b(BfMw1+RD$EKPr3-j`83Ip-OIibNHEdp2NvG zIeo&4aI`P4Mou5ANY%*Edn)+a2dpdp2jFT4UGvnA5aaKL^D4GXp<3l%S?+YW-=D=O zV~hMLi>{pe)pNz)KhY&utD;vXn(j`eTCjJRZ}is!9}-_h0QcU*to zQu()pAGTMOI~@@hZtSW3^#|L#3L}W;lYDjc$4S1-%5d0+3dX;n(?b<>e^^E@Kj1GH z3y+Bym^lBuR9#$M14|KK4K3_$1_E1fxWKtlfj@nlCC8nYl zQoNE!oZlq6y>y@FXg#k&Y-K&KvM<8x#ja&-l6{rwXL4I*UwI>FSjAVlZD?H<`+f8l zmmRrq^5!~lmtD6`_N5`dvZh7pwFmrRC4X*5(9$W0YfZ}(#kk=#e|$qcoM>7656NYD z=!FVpie|GlQI$#Z>TTERBt*M%6V8GrAq(YocIPPU(mt<6op1zj>S}ZqU&|gr=J<0g zz6uPrQNP9iV2ER!k8p2^(9t4A#OOrII_%7A!%IO>9Q1<8+}il#zP60Omxq>E`ae#| z^6z3E(g&;hG6G$V^Dwiz0@w?NRzsFS<=CjpZ;zhEHc#*tE*2&x^>tXJd z^)RC>y2!)VQ49}>7$;UI-fo%KuJmPBoBVD|@zWM|Y_*)VD*Y|v$c77P8q#30<*Z5R zZJ8Iy-0=Kn%HhJL74ZSQyCptmnHS1T@K$nU7;_4 zFV2xb4h2X6X`2N469-t1w@A!&97sOK!YvLzB=`^!`r*U}#f#)vON}N+M#d3uab`g> z0~5(%KZ!UPWh0KWR36i3jvuE0IhsZsis_L=c1>Ye@ z0KOV$LjNYhej^d~n}{g>X5u3jK84|jf_+THIAm*ePgy(>2`3P7 zq7#YZ;eeM2yUN7dEaRJqtv{9gE=$!Q4uluKnmj;@;GArQDeQHK2w0DZ1n}r!5@<-A zf_b^b;g;il5_T=bu9evRgP4bJ*F;o(J0iZB+(NwHQXPp?&6SDvkB>UY96mZ)rV`i! zQ3=M?XfNV)bAgzP9;X}Y-7M8t^e6-dWad&fivajthUXTi6;*AqQcU2%L|k1%h_g&{ zG9Q6ZnW%pRKtnbGa0QtFs67(^?Z`C!2}GPTbO~nSHY$xDWE}UDxO|@=M*`D{xHO(5 zW@DN(5%JF@B17|uuwO`oy+->p-Zd9fFb_^yiS2Q@5D{=05dmK&BH(L81bm&i05dd* zXw|EUuz!mPy8#BhAI zB*MOshy?Z#anbK5cEY3>BJBS|L;^>Mu>Y0_`y%2JEGi(PKl$ENWovxar=SHqRua)` zoFYPgo*0G8huBKoPcFs$BXZbZCgME(MMPUt9{f+iw{Bt@+8?nVyrB~NSt^qF5~3s` zqk&i+;JP<%D9hpUAs=L^a>Q3L4W5V$R1$e*;u~1eK#WFOM6}3MB6=-6=b1K=PDG2X zEqddH66w?@$Bm>R@j=voV;;1`^mZZ=Zcbc_ua-m@wjrV?Yez(m+Y<}WfQbm#iHL~1 z2sd6R-$j=~j?bq(iRdN!)NMH%^BYcA;R)I56A|iZ=hzMULcEnXd?0~aGMEq-ri2rRO;wd2R#3E2& zfX7viRe=I64Bcf5^;ywN35#Umqf&S zh=_Qqk6>yb#e3JV-E;2IJAfn@{Hrfeb# zQU(~{O@y9Ra4u8~5mo6YmPMh7Wl$+ZRBc6K4@)HzF+}6!4`w)xh!WQ%BEuO(WcViH zU_59Ly_Tv+tcAW`^zd~UFax{B6f{70PDF|RK}3nNi6~KfVmlOuh}&#uB1+JehywH= zM&M3M#O3=>A}-&)M08m95K(~pi0DxtAfg}xZKTf<45k1j7)C@1Mi5bgk;EuVjUv{^ zfLP??h;-2B_*e6riIp z%jb~uXUNe8%pxIVgwtv`lwC|j311+>?q9@emRc(ORU&F|1ras)1`##2M)YqJQ3G@r zsnU?acX)s$kn4!JU2=UMJuG}ctbqp%;aiD__#+}Brk_bhY}W7L6znEP_`O6FXg?AC z#TUfdc)lPu#65tBQ)*T>-GTf6F$z$^JK99E{pyzB2Mi!VwR<@6DOhX_W@gGTgv7ET6qK!mrV>25yTM@VL2iK zR5W@^RU#r>W#SN>e}`|FE_^02VqJU#-$RyuKek4~x_OztDP<}wgF!pELJoVvH{E{H zI|Gh_Jze2>x9aK^6W0AJ%a`TT^Z#j12~1^rZKSk9dlmZZyf zL4Hk0XI(cL$E(Xh_Zo{maC@Ke=F z-uocT55Pk-Go66D06ZZ-Mn}!ltzPgI{qYXHFUk*h&G5i%VVQg{Un1g~V*FO8*0@RB zNVj>vWqF-h6D8=^t!cczvkU(0%x4Csj!5i-0wmvpEDgm`x z!-I3byB4B>m*}c`V@G&cp4X>ow8s;sm-kF47dFg$)syh3?)EJlN&CNPR8{Zk1QVR) za(YKioKbUB_UTKb~(;5&U~^}z(5UebTH1O2fp6Z!|L zZfIYhUswDNPMC}O;=TNVjfrFR=(|w6_iRE7F|NEX-G$GcC%%VC?%lp*T`>t!nR>o{ zH>&;NEwBqZm5$dnCncCd>gS%Um7>FbY&3S!u0~-tJa6Bw=ilQSrE_Cy)b#c93{9Az zYvsUOIP)FR79B5Y-jl7*Kb{bD(_BmE4vI_;)Nt0v)6oonbTq^3m0prDcu*ePKck7b z{h=2$4rp+1S03Cv&}k`8eOYUbJ~@RPeKDd`9`wNoqCDt(ai~1#iO|O=5B@YEB5)Sb zQ$fFepRbxVNPj};tbYImUN=vXDiZI=7Q?F9GH0KVW{|HDz7ZISZf2|SU4j^$s%9(A zAX7!&YH^IGnypgYgh55#j+?vK{YsAh^_uWV3mh-$;(-Ash`!h)jIPfhZflAefQ{jN zh$kNpjJyZ8B9Sj6$0O)Y;RncZ%R5f&gFhZ8Jf94i4&J&N%m6anI1bWj$mg3#+@kWt zfX^=sz{eCu_yQ4k20o5Z&Zh}Rz_B&Mb8OA<(Lj?BIl|QtUSE(y-$N!3}o>pO~Dun9<$8dorY6IK1&RF6Q*4OIU-(9M8v#zGK0IQN4Pyi*d3%C37izp zweHL)KNC|Q<^x9!1n9Gw2k}5E>Ii00js&uaNT9dK2MUg-992wT&XE``OeNyFnN2-1 zGLMM(=;N6gSs{EqIU3k@B5%@#qBulBTRg!L5z$G?5z#5pbL~4L;jyFDf&F+g7cB}%1$mtL@g7!=R|uPvIQOU+ofJ!z&47ggg z4}Fz0iO|m#{S%^JPL7PN6uw??i{Ku?_koP(FcI-^Rcog6HTAe6r@aAFk{_tRCAmxm zO2)-Mi3x&fKp$Q$Gl_VNawy-22A-U^h#dAsf&&CcQIBxbiD<(0>esO2s@FbrvMx{; zM}%j@;``wcLmrDq3$0UUMB!`Z&CLb^+2u0#|HTU zd_t2CM!Lf1k)tzr888z0SVfNhVJ>E!_Ys;Ck<Ls zR(gM=F-RlAAe#t-Rz&E#645I`=T}BFLiFQ^xvJZ!@J0b#mmQ*hpNMFVi`hvcqT$lj z4DO9G`a~jKawK`u@0LtkeO`Db|bAV+J(rK)MyU9gC9 z*!7R$BLKw+2%LAIE1%ffcz-+d(6CE@g$#h+So+e@o=aB~KNCD7`YPd0w87NVb&c3e zupN*IcNE??ASXjaF+%th!8w9Us7FJ;OgJ6D7%?5ch{u3!(5qVsWQk9SoQ_>>+Try_ z?=5i_zPYhgs%|3PWWy?IzTz`!+%Ej&w}jL&pUwo zAEi%luYk;P3NR80XOiQRHxZsoj==duJON#ZC>fW$rhT#SDMb9_tt7h9Wk5vbEhD1g z-$Cq!=7tzRgM0udjNqskoDhRbBJ|&h{(_)8-qgr|j9kt0H`#Z5c*^fErK z$xZGjhkc^(G{GhTQRIlA9XTTED7=SYU%~#=cSVCmL`KIEkK2RL9Kk09mm0+W2{_>!#|9!wQbt5cb`ep+eL!YFFX9b6MLBYQmWYhAlZ_b< z1JW)*Fhej`u#kw176~ubJb+rx6XbjrkU5`2M9!a}91*S(+#tA3a1W3ff1ikqR}hi$ zlSE|vERf+Z2&N`Mjtpl2DQ`v2c`97}n*qB5xhq7G7z`5RD&Pz-2gs7oC8E__Ch~QH zdqiI$yi)Kx%JK7EMMOC6xy1PVzyMFuM34()0{KK3_7Hi0!7+kdC7gD1gfAk8{R_gk z2<{O)Mm_9L2tQ4ZAEfV+`TQf`B~f@WqQVR%2&M`)1G4GOAx5DcAl`_lgosPp1ITa# zg>$uW@=4@qisupCc=;!yDb}lu;}*S87x$m{ZUYs#1>1>G>>@(GU*ufYf?HFa0($4h_hE>L`VK_A&~zs@z?%>e!$Sj!*WuGUAc7KNeSEeMQ}O(Yd=U{> zX9Y0@qbwrdLd5@_!nqu|51G)bkRyQ;Kp(o112H^7Nt1}U z0!@gxq z;v^D+Ax2=$6#gLWNb`>fQhJt0{pB_B_e@RF`P$^k+zjY+=>@OUM9Ft@F*}68L9*_ z{3+qz37)4M?*qRIzbxnt;Mw%yd(sbN1c~H$PE&}eY@Cs;A4}2a3wER&8S6(x#`=qV zl;9M>If9FT%-A!+R|p2yQGpC>62UfdWMC%|8Q4ecgkL$)A16mdp9%k(99QnF$g4zt znH-lm42=*A79*G_m~Jp&H4{MrkR|CVe4y}QL?l=&@=4_AZJz9_Zzn>><(R9+lgO5-ma(tZf;pos6{PBs7Ey+{=k^q+MUZVSyhsn}~?7jEKs;L-YrUDA-}jQLw-<+8K&J3kg6$~pj+aj1y~u0f zosNiz2U3m<3?WAbCIBN5-y(8U%4NdWkt6;MoRJXJ7LFqirscxx8kksJ+EAuvEiFH!WP0uc=pK1r}tlP+z(^}l_5Nf9QIsS%bAbI ziHPpIE|lMh`7A(QnSO#p1d9cy3qH~m&%eG$B3KFJo6HNsHwbPM+%0%e@R(qw;90?6 z1vx0n_@e|91=9ta1>_`Ou!~@C!2v*4vSET_L_QVBD>Z|1T!}d%Um&9_SSZk|&U(%}y8IO7!`{3q;>r_#n}b5MC_$ z8N#0+!i8fYACo*&Uld#$FOZE z6Zv-8#At_^Lc=-rNKsFD&m+Dqdl>CS*2(wjshWBQJGwP6oS>)oTWWK3Y((HgJ^K-p zWKljUKh~2A^(62D@?+X<3KbdS8RRFlpNO85-Ie?^%etBPg`V-MXEJvq|A(G0s%Ivn zcIlbOs5E*8GA^N>c#PU=sY9*&jn(GkU)Ykqwjq$lLfCgU79wkPKml}F@?j^@t z`5>ZS-Sb*}BlT!&e^LPRDMwS5fiHFF%J_> ziI}BWLTo1$K7srWa8#a;p1*cKae_d z36lu7{HeL$SuxK9KQYhj(4>WD3|Weumz)=Ho`cN3f?_RkO)vuOX%nh1)uQc1s>|AL!WI8B3?|HK!Q{nSQ zU-rD&kZIrZW(S}fSD6i&Ze68fH#st$M^>2)nZ8=3R&NF$w%TmSG-hAS=VOvbmarHkjR+CTuYJFE{AjnVdgvuq>Y{H*jF*`N6Hkty@ z+-P=cdIEeFuCwn|vr|*uSB?JZSItgMFA7iDWHxDP2CUw>Y27BhRg-i3CbQR6>&<$v zCg)9?jZx{Jvtk{a&4x`MZ8k;hvPJLMfd%|w6ZHM3*W1>qC7nH`&E zZ!=f)`)y{&ray#_eckNX^x*5Za{lzX-nPl<+HMk=vEA(1v|zg_)0ORNXaVwGtK4jZ zwX9riC0}1|^w;e$dp0%SVXDvi9cIs_9l~3`VfJjg=?$q~Z#Jz5PnSIK?u3y*Ufv>EDGzFLU_j>^U(i&k2*}@{S^Ldk6L{{w*A_xQrANE zHf59cn$X|xRTC(zH5{CakBHPjLsF-ySZl>_Mcg%HP@{Srr z;S~yBct_2qWuyIS6NR_Uf$)a?#&Y9+b(zBFDcrT+)QzlnRqvM|{E@=^ca3n(yJ{tc zogRj8n+Vems2?bNio%=&#&X30)p0$9UsAa7fT_;cy{8sZ*y0fgo4;p-E8kOJP#B$L-4c>K7?WS-rg@+EBbUJ^iVqSr8GlhLVG}rjphiVXo zS13I7p&B|Jx9yPHMA>bRK{ob~+B*rC_{T%)GKJ4mc;%3}9OFMyy*EPGaV=Jzc<3YL z*otZ8TUKQG!w=&%!>_jubAIuWTD2By(cF0$Zwd|7s@{p|&Xwnwr$n=3Sp0e8W8}nd z>LK~H^#XmvhYcQn|9w|C4YTbSR_>_dYT2f(8tQN~b|&YSKd~;nsUuv!6R19p+VK%l zh`<52$~mfkQTG|<>O z?diPKrf(3Uud5xH52%t(?UMs3bjh$PZN?abt3F)tB*XZO@y*s!k2N+#pJq)5$NP*N z9_=A-=d+>1`%Sfe0nT%RJPEmfI!IvRf-Bk!z#O$XzDKh9rQ7v!eP0XFM_BKMaG!C> z55|v6__<9V2YFQu?sTe4BO0f+Oyv!fgLYV_t@OIdN*s-L<3CZyUpJR9zC?jmyWr z8a~T$ZAsf}OWIyr()QYtw%3-ly|$$7|K^gm_)Uw98j;q#I4yf%mpg9h)m1J2Dy)u* ztL5m--@8cvrqxwD-sqMTKvx?2^z_fYn;4;eRdp8}Uo)&m=mI5zL=({y z8B1)8;cz0}Gino|OeCT!j&BMale>-xJ>~;xU*h`2c6ylr{l1a`8enYKQ_)_>srv{K zR(r%ZCFaUr=jbbJMUDv3L#k7SO7{us?mx)UiK(YSA`MM+Pah&d|F3?>DIg-S?$JZ8 z(4&X9ln&b87`R?rrJJL$0zZuanQi*^hJ4!E8?EaX z(spN~lU4OOkq{q;F-rY53eX3>RrK!czyFR;s$MPFrI#4Teo$n=!i%atM6P;XGDZ!! zb$h=)E&a~^EmXm{{MzcFJ}qONYg_PJ6dOACg(fja4Zi96M0JQ}nK|l@OW54Iuq8iC z6V<>~ZDJiQRp-6k64lQ%_@E`fLlaepjZm~wE#HMhu2vMaVxL2zy2KEzxRZOL%24K< zUv#~A-kKeViE7GfeXhUsbRIrwt@<#qj_Dt*O-$c0L@v7&MNyna(fkNA zhS!=gZP?8yn(1x$MJk$8ZP?)`nxEU4*bbE;nLPG9CaPn%qlnY;%=hXgknn?O1x~2h zGaJOKjDFxR;3=27+>Ddr|NMzN!JXH-ZR^%8mE)amb;4Wc=HAd&t^Uo^ zDE10J3(%b8T4{hRYfyQg+iN$)&_?xf?#e@Q&M#aHvf%kQF8`Z=PJEQ`OJX7#q!GfG z0RIa94C^5D%fZLuqhg8hRp8vnvM!K%##0+@Seo!R*~GMg;Is(d1#%-slvoG&7}y6K zuD6>175p_ccBh1+aBKou7PvLwQkQw+5$ZuM-CYpO${@5@* zyrBhry1vCXQqUj`oGWu6POV3$z10&{Jy^o7;P|Jv^JW75Ko)~{6?qg78-xq5!q)wf%7&tz82>^kVhmGX%@A@d6MQHvvw8E(cnPuRmuA!S_Y0w zAjt5Q9btW9`pL%88tL_>7BMn?_^it|y$ioI(YPYVf@(|`H|s`; zfP3~{&(@(jkk70GRjp65ZiGJ9rZ1#@wZ5)iwrPw_KPW_>V%-P6uv#DRSyMv{Qmse9 zdsNGO*23y@UZFJWIq=VLpUvU3)`jTPt=GZN+Vs0a^cmJi;CkT{Mu6#J*6|R7OueYl zKHfxq_^cm7^jS47d8G9R^xV8UXz#90oEdIn)doLi)2G_>0T=39a|q~m8jK*%X5hkV zCO3m$StXI-xE2^)l2x)#j_hU zSbEg}`aH8Fk7!+ZjR~!EQF=w5BA@zfS!|LwU$3uI7O5_Q1={IbwM@V9Fan>h;CB8` zq(yfvB{%X$KTMGth(TAqMoo!+_hTYHYkG*j(0UB~kWH_b znvwjtu&U1U&?m81NFS!ecD^2Z`kdk5uY%9o8j?T{U1BlN`aRGW*do+R#V|My7uJ$F z0sSJI{;QDqdRtZCbV@S^n(k^n(syB-D=%vQ;rOctdc_u@F6=Oz2E89mtvO7I?7T7b z2{wHz@FW{=4<0;R*anOBQ|noNUV$DkDA2FhhO?Em^V^~CYSRw{?{4EG!F$>G1n?po zp9bE~#!JEJS!L2k2IfOB&}Og%Jb1XQJ9Uoj`qd%&=o&u@(bj7r`WWj#2(M**VYo@3 zx8`3q19DgJB@*Z4@ill_4c@v2ztP57S9{qwR9&@fS7tZ#8&ib#rP`zpe()slmI{;M^BJcp&!y>w!>#^;8YMx(0u(2Ip!3 z!Go9M!y5c#4Sp(wNkk2{#`HyO{l?B)k81~w1D_y#L@*x$DuxQ z5rONFj|}1cz&nE%2_FJp3yoa5@Uh@6ZJcWf+z!r98^-rI_`Rs#{DLA^;1f|Vgpae< zLBOp9dx^mg@RyMwre5d(72u1(`Le_a{tnKAO-U@?gMJjw-{M$)N#E3NVBZHOPaaq@ z>HcvehfkS2@V;RqM>M~Gve^;t?G0{^Dv5C?ySN$LycqW#4sHflvMVO#^$jWO9O{Rs zqidDF5$m21eys=mS`YZO9`I{D;MaP+uiWGCPyo0n%$7*b;hW(+q| zaa-HVtZYX`AmtzG@ZIkBYW<}!t$LR>t3_|MW`O&4M~1pEz}+HoPNCl02fgm z_(ruF=>Ci2iSok(-F2Lm5Vy;vcb1wv+}+$UQ*9gWZtWPR z&J1^7pKx2{;EVHrdjp%o^r(>Jt@8RK+)H&VYUe2T_1Ipga+JGH^r*@m_{Is#y6Xty zSMJg7FLm^1N4wj))b-=to5HV@eP6a&eKy|Rvf)3z;YKqJi6^$Z7a#xqO&B*j!fZ6IaHKt4SZ&nhN431zeN*z^u@Tj|r%GP8 zGW8xf7Gpbwssg2sw0Re5TPH4LSOv4LWc4}1vpo-4S-mQj zap{k&?iCZSn_uSC+tkb{ta~oZx8s5z_iRg-grhjyGN7=5RiyXlq1;MV&)?@B)+)2o zg?zt%A*o>fg_I$d-VVo8tKLb*p8Tz4v2J*dEW6-k%KqeU9S+rEf;$N_9=lI)&%evI zS;y7U6^^Lbw=S`tS6g|qTvir$jKPX`_J1x%aPN_>!Lgm{FzzJ1sR_nys{e5Z8T2DL zul@^7TRnNdI|I9zL{?(YHMO*y%^bTf`mRNBB3vdNa$-K68a|*37sJ#A+$g`p&y7y=o}FVohNp+te=Qp%lbDF z_7{kSdSP%~v;QE+mDYXW&*J*C%bzvHNko;`v-)sJqsU5{W%v zLX6alLhFL?lbLo6h{!-Xu{UZz5g)dVhwih~K_{!)Ea=}t7fQ0Ym z2@)PcM8a^K)Dev$B4IuC5ch5zIUbSm#9CM_g@{}C0C6E|HxajxE1vQe{)vbyQA$Mo z4-=8WxkTK$`9Q4ag9=H(%VvCtC0s;)FRnWAHSFp`T!2TPsPH5bQPo!xUqtODzJh8% z91Ib08+P>}{uyN;4n-2g*KzTPkHe(_{!BXOuTg-UzfPU4=Xe2%$mZK+xi0~D}RjBPm6i|-_;Y$9Ed?dya^`PGl40uR@FD1a& zL|mDF5^)Po6Vd8?L)?m|fVc{NCS8`vHYKRU{}#K8L}cK1;sh*^LEMS| z0Vn>f!qY%3!Baqd15E&NHJ%3I8ax=pNvP<=Ex7$eBoIf0U2P)l5{c9BR1lL<4T$s6 zkwjdAr-FzplR;dC{-H)Z*^D0p;vD?05Vy;;P(*-VFBq!WIgWAa#FW&;@`~y11y1Fz ziYU|DP=i|Z!bAd2NqDdibXeIsy*&C)?gXdf85R3zRXl|;SYG+GKefDPsk@!ak!5V2f7m_Q(M3)Cv~7Y~SRCmtZ~lmTN0=j14ShKB zIu+3`Ue?1N_i}oIS}-5RS*pRH{3KO6%M-5ZEpWeVpPrBrh&4a0&IB_>gzEzNQ7C7e znHu7Z2O&p$j(^&B%u7TwjP}BEqM6k85F!f88DYB7oIdkY>qO&|MmdZ#h-eG4h%qwQ z>8z!eJnl{p41+MQpZOK@;T}u}_pLQ;zYovlK5|@gA1a3r&vjkmv!)M^;n-p^Tu0G! zz?6D6B-9TQJ)eIco|<_?#KXtbw;YceA1fao8$K=!aEKfc^0CP4k2art5mr4RzG^BV z?O6F}R~Jam%0$k(;ltzDmxzpvAmTS;29S2M$YIAJ#=L%b)R%~0yBO%DkzsI9_+inX zCZdJ9DDul9$BU(om`f!y;vT{|Vn?o5Mn(p>GBPv3%{M6LmKJ#d2)2lTdsg^fK*B^M zq?bfSNluZYe*8*AiMS(#4=)ULiQu_FMx0NMh`SJR>jn~&(L@vRqcsOeySe1BfRn!Xg&Y9_2#9!AMa$svD&h%5385tU{?kP+zxf{~Hal;hG~5cwr?$kXw3 zFnl%<;q!=yw<9ob3T_cO>eLWV04Hclr%-?#JwrrBRuK^~7x-laWkh7)sOY(lFC$FF z<41ia5&A+R!rcjEMhB21LwY%0*v%qGxVhBNz!eKnfSjzO00B0TBfxGV0vsSB0N3AT zfRp5~KQDSd_sn>TU^WrAq$`niK=>pgGWH0N>C7WXI)P;(SRsO4MBLkhLA|bBFJtLx>7(#^oQX=fui~a-=B~C+&mp2o2CmMVseyM>@yc%=7nae$Hq8u4K zLEMDE;a+GX_@L9sw6A^xoAP1(Mb#d#+ zk?>_A;*G)Ek}t3jO(;)Ll6)c*qlhnK88;&8zyc!bzzf1R5ue0UAo2=0!!&ODZmE-4HB5LaOLa9^7&tcl2d^zF_4HWF@v}Y zZ(l$LTtbe3T$Yv3HJ4@O6*@+Q-B}>*z9WYnzeafrxGXSB&XICw3fcv7*ta9TggO<6 zTu?BF0z|lgn25?HhI@!>&=eC_qmlw6OL1lJ^Gv=#a4C@TqvWtZBXTZMO1V1$a>UC4 zZf8B*0wOA7W`GK0U=VRW?m2M@-kJnY5jW$v8|{DOY$Ob12|19>h&X`leA5hEJ5%v~ zPkx;lsAi?(05xkr2d0^zUg{I+Ed=LpgL3Bh<5g+XWOw;nPrI*oI(}2e#(x+s`D4E z>%dE@MJzmG+t*Qpr>FRxxA#*+mLUtj4=}!rQ|{rM!c6BQ_ZSzms(XwxvNh1?9~@|$ zk>?9{-m9IF9dYWbHg)Q#Ay<%-$L}=`$$x>44#+8kv_rC^nQEB_n=LoPS$L4~Nq&8h z@yyE_YUJusCGwo{HXdkVj4Ne4Kv=zGk|cSRPQ?wqF!EdimGCecghfC%5d$Hj4i?Y zbm`T|`NweMksLk3>W^{7oEVJdtOQF@Cdqy5hQFJD#@5nT|;1 zaHCXn;Q0*dTr$@97<$GT7vwtQY_7J8#~DB5)#Hp&;&|hSoH^dyo|ncOKjiZ9#`iJ1 z*tj5fEH?VLi;WBN$Hm5jw8wpPKgL|olsLb007%g5(D~|ps^~>`ru*~z@DpRH7Vk!; zD}Q0HaP{Jg?uO1=r>ZOWqAr(uV*Jj)R8{q&JF%`09)@GDx)`RV*_;gD>6YYdo2OzM z_iXGO)U|xX8g~h zcR_ssy@31<2p;rr#6DS8rZXssFg+VWUHELKH(PI;zFkQ86mBACEkVO%jtK6@S$)vu zaVR+V0^xziI>K}~7>*L8Sr5XXBd?J@BFw(0!d#fk!2SZgvzO?Xg9i^6zK!_(ulLas zeOZV;Q-9u{H1Q*SWZ+M=PP>9egOFU zHa;9&A6fXzxreNTc7sVl1FiR2O;rDfTh|||Lc~!z-#Q-sC)(O<)8mKR>})9p3Lkj+kk(GdzCG`5d2k~XWHa-TXKjXL!bqGYS|1o=Xy;NZ4T2$gW3n1~eh(Y9r6!+PLqEhG z{ll|sXeT>DVyl`Qs?V9j`Td^ezLTTv(PSlE$(%dozLfLdTnPzYGBuRvOsf&yuuxty z%pR+=azx4`)%(1AeqcFD6>fcB=4oDf{+Uu^^nF zL-?qil4bKxl@*;0E3ivThFs}x(ME?1n`DKADZ$mSTUQMU7#;{lI>#RTreStAJA~~+ z$?Q?(JV0B!q-sj2#g-bp;V2q?>;m-YnBx z)~98jrkN+1kx$EVGQzl3HLhK~iV(?+qh*V_#2&HB3IgLw=d&ieL&VO?ds6<2B>YGM zuf>>!bF|FUBt<81v@AzIT1+5TClHhrgv1q;^1=ENaoJ<4TOCt#KBbJRR%ldXf?2Xh z^Oef^#m()GVDHxUr^<2~IPfs3vA?(n1yHi-pO!t`rT$S<#wdLy3dUeVAt|1bbk=p{ z(=x-HC3b5T{bWed8SBxqIbG`MSdW%P>Ebh1zvS6Sta{TwsJ@axGnW1fM5oTph^?!h zn&fb+Cx3Nk4a58)&ZaVd{5~39qM&)FQ^1F-q$uGe&749J(E~5Iu|dNJ1Ad zv8}kf<0FdSIrxsT>Jxj)^dRUn$)U&B4!*e1DasEZ&gp4JL~PB8_=;*t#OGNnVmI_N z6Oqad#O`KQOHM}WKz@tPs}>?}I(3vqf1UAzjPW4~R9PKVJ2Ldr6NA$Amh9R&9$l5X z1pSD};T^;b^9jjR29P8B_YgbksR()=(-86-jkB)RQN@P4#)a{-Q}u~)Vu#^#sZn+K zRoXdz<|AQ`y5>3`b2yjiU69{XU(urCP}}yx*(}@MHjMf8Cu?D^k^)8>`*;XZNbzHIRpUj5}@RH8HoF zhzqFsAR_eRgwGOuMsSF?V%yZv-6sw!V0qY zhKulWT$}Qlz(^p6v5Bh$w+QYLtPuP{@H;^cXEU4+tvnGkAgxF|RVi>&)q-Y%9Rzy` z4iqdFU=KkKTT>sHASX+Rc)p(j`r2bePvjc}4^ocW zSxJsdd4?QU?mKey^w3q2@=LFFpdbrDZ=Lpa-5q1 z*%{|V1H(=@C;qeZjT1H4>E=XF4m;a8_`*&$cJLen`Z}s1TfKE0VQOc5M85Jr(;`jH z7@J?v043LrByNFjBvJ4>xM=LMVy~0cLZvRw8s)4AQ=3k8@;np|fz+XG?lRM;o0{CFF5q?ttxI3nY0pJ&EcUcyQUToJaUT?@anJWqMOo=j(*d^P(aEC!gb7Vkw| zPXkM^4q#kcGd`0Jz0(nU6b}F_7*BTqHJ8rAB+Om_~tWx!sZJ zezgGg(y5A?Wu!Zwyh)Wtdosh<-GnNlwyw>HSG%J<@xc`#R!``b6xKF37i(K!K?vth zBh(LHx9+Nj#CT5IM-BoJRw=3hnh#wcoS0@f59i7F&&HB`ArNDUvZ_I(o)G#vcyH1F z1?WNq-G#3Na)RJM;cI{|**FG9Ef<=JUDOAV0J}`zh9DThR&Wn0_*oi2&(`-G_;ler zfMZed*@#llh~7ZO4Q6OBIDf!{890P<4<8^P?T-N80cU!coEE89GoZWY*An3gDD(mD zz{|)#g(6MxXfyE>=Y~gF;jrUjc#M@8!adcCBpSV&i#i7nAG*N3*3A^Cx9+H2ht0H^ zW+@gfXG@_0kR#H}lC0Jz>Gdsm*Ku%A zAkxf!)SO-Pb*&AEfOo+hSJ$N=cj5hKAN2g~Ge@NLVf8unsn$vG9@Vl)>mSwU)TdeJ z!PjXS?-??nClN|?9CqRKEIn^f%Ob6K@ZiB=mvr#m)v`#dY4tf1$h6vlyIpFNqghfQ zOHbyiLWMF%q;*e-brWkG_!!7iHu$g>&zWHaD;2K?PUWYb4h*A`yS-g+`!ujs1@@Bz2;hOjTHp%-gDfzhT# z2!_X}PcsDQXA96KB*7wGW9<5_&~J$eMi6P;8e-p9&*s}@(~qpyBYiG_Fa?7BHUpNx z&i@2`^&%OlBb)|!bq$P2>nZRGTX?=^9kcP(;3sUHuV37{TDL%~bgw~BX*0Mws>%%3 zs&R#CS%+aCJY1N~`c(*zwJj;3KMAcc{9*(TjtBaMt2VFaC8_V`ruqYU5PgKZ%+G;1 zWT_MQ9k>YtaV^MugMW|5E?4yZ!5iSY2=XDc2j^EK?Z<;ZZsQMt?*-?F8uhcl>!8|; zeZYDQf?FY2Dh5x1Z^boX&0~P)z~2IAQ$oH8oCk{@i{F)f;Qv7QzTnh<2;K(I#d6_% zb^I7Sm|?E@;6mhvH;uGTLvRBG!3_Lg#sg~&@oU6Vsqffo@On26D9H~lkR#v82l@=^qmIr_Fx`4mouyz-$ zDNFM`PKN|Yycqj}?_fm^-o(i9s*>hd z6;&-pWWh{4cOl6th0Fz+(|Ybg0T8d4XCJkS&K|J*Rh_`YtU4NXCQ6ZkMM!>CeeJ_v zH|=rNt=NNaI(;P))VyL(YBkwa?CIx9_%>3--{%=h>D2o?2O?{K8)-3g-EZCH-6nY2 zI|9`M8XTVpL%(FTFElh9nsEB@+GqwkX-HoMCdUtqI-lo5|O)`iTKXxPK5pzB6=@-5RvOX#8P~45uv|>h(zur z;%)d|BIJW~EUje}1|J5aL@}C(KF%>jyr17soU6SXb->Bw=;ED1tc7XuL_|1~*cNWB zM7TRVLWKNLBKoQk1z+Ti&o-{~llp6Efp#p_K9P%QfZ{G8;(9+zL(=xY;E!*pliJUj*DxDwY9aV64-xDpMB zsCntc`562o!mcqf7A0@S6Bsrp_D9z~5gBMhgke6>jrv2Jia{?TZkg_d9Dr&;J_BQu zMA++&I@sSzj(BzNBkcQ-4@H@XsIhkwyL-&%F#X|muN7+TFe*^_MiLY76cDG2llKUW zvXMUwCt>0!JRL-}cXPY(swzG;PQ7uVg)H#>@l;Qu`XHypWOaE^eYbjkV3R0y{A{#1 z$9_J|lc3(bw}}i5ZiqqHZ!7DGw&X!*YehA%(>DgEj8>I>d{OG(4|?jUe&3~vc0$*% z1U3C3_vob$d0MK%p+U2qTNC5eqOdrx`W0@!P)4bRe`qXMV-6Z~Ht)}+G54+r6!*$cI;zk z_*r7NP~=NQzFZFhBfuUC@YwDb!=qw&TntZ&{H(}-5c#hnXIHkb6ju<)4D=!*qj=5G z8R#c+J)#Tw7?Drs5HJJGp}}~#GzzXD!f=%sZV~wbBJ7We{)Fg16FG-`8Lmp?9QvjG z6X+`?E+<02638p_0*8R9;7~3V+eN{lT*^6g>zj)P4af}U2^JDz&mmn#G(hC@hzLi| zW9qfzG4v}%zDeX|K!yv9K=aH1YXtWQ9ws7!qd*!S7dd;sC_gLmiz3fL#r5I5A8{HM zH6SiPCTt-AjR#1VAtP=Sak#7?@ z*VxP}Mx_;`!!X0+)4=lKadsmUK3v|qMEqzqBSPLzboQPZE)lGel(Y5-`9V#^7>NkwSzbhX{Fh zA{wSUMP5S0ZI}s+90wO?BCgm1%5lXOihPC0SBiWmkXPt4a-?&Xh;;Ba1@BZu=*9hF zgb74Mmf@+KnB2QoqqAJ7Mr!v-AwKTkb=Z7&n?Ya4}n;lpi7C8B<003+{% zkEdYQ7~Fp!evXIH09Z`L1iXZjA!52inUXa5LEZBC@ zb9fWU8KP9MS5g z@9I6E>P++b)l2m=iX8pah58xwm4cwpP?^{@!Yod~SBmR#!TI)`NkpC+5s{ZHVzGQe z@Zyk9kmaFJ_GaWIW=_NwuZn&?Cf!Y+^{Q~Qt?nT_WWo6mJ=>W15JTF~O*PYL!-?w+ zKR3>m89t^B;?#R=DDJE49+QW+)flyUyEon0>t+)+6chD!x{&GZbc=2_?yNxV&RTS{ zWldI{W8)e+-zhYc2U>Kyx|6Q6Q#ZA03Fb{a)zi#02E*URYR zZZ#7l(r-006`sA-OpJK>R-;etZDvMf_m+tiy~Sfyc(dEg%!m%R8Sl=Wx0#s{2Z5X! z(YeUXjOYX8{+@rw1QYI{`>!HnKe~^Z88NMo(O>Cf{8ekIz42*{oOAn{i4jZt8Yj#; zx9i<=9gU0^Z_aXT1ADvKL3iWr+C&9L)sIqd!ll)DV?R^o?fs0$>H*=M?l2y!x80!@ zZ^0J4cNmA&6F^S>=yRuWSRHz&abW%8PUEop!<|My`Yz+JI_)l#rwex(hgENXWB+J> zZ=DZn`Iz9RmC&)Ujy~*5ogDHRn-bqj0wY) zzfsS`rO#pJ&0mJAg6BNO`*iw$_CD?WTvna%mU*pPW5X3rCE3=teA{!Lmc{`UZA$Ps zcZDx!JkaD>+)<=dqj6_*;&XEWIKE=FdmH&PI7btyU*5?7f^!~d#Sq@hMS%3d=950H zZwWWxCRblJiM=kc$EM&G81IGf81pq*EsL=Jj`Mal{#Erk#};GtN8*%fS%g{POE@QB zc?- z=O8+Vq^qaC_2@AxzG8C72;BmDGCW^dIlzIBY2AyD?_;gU=jqkS@_5_8XRGc^Pa`6H zLt+d0@WfZR{_wm(J}?{02PIxHV4}yTasUBN$!|$Pz8)pgpP@L_V^n-UrZrzf=yueJ zn4$-7v~gE*=(`aSNq1s>8N_SXKkm!OEefJ9TO>xSIyKrl*y~xQ84s zM}vvb44-(8)! z#(ZaWvdnl_pZDDCaMU$BRsMlair}~O%;vHl6n3m^fzO)fnyZPo6lOYCH&?6Q zX_x7Ixw-o2XMDOuwp8cHYqiw-QK}aE+xba4?{AkGUJI9FxbZ3|=-trooYYbcT^*C@ z{1#hC{@yfE{n(?>AO1Ux^3~^`wQlHa-P-6kVlzm39Ta@t+V9+jEh9G~P*?2mNMU85 zx!>6@S9N|drV%!WJV#khDP*7LD#uGO9E8vRVyyI8O5ubyTy7}Sc?KIlj)Y|eg%?CP z37bArm^K^2IeBX0Gz6<;P9ttmEk{99LQV1wHqELV)NE=7{+i);Zh_f$>@AsdTSI?% zIBJa7Y!vz71^5U=qf{4giLT36;lIHz;6~hR**J1wT04KsUf^TQoiMc&=X?r=4;ze? zhl)oAKmM*RJETASa@(|Nm1jQujz3p^@HbDMBT$TBSC4a7<_N*f#&=qr{?4O_4;8=L z7LwrLL*>9b`x4EJ#{s_+SAsu=|I=ApFz)#(&Ob>s4-fep;NkVm@F#e{dLM!-FlP4- z4UPkO6yQH6=>LlZ2g~QcV|_`pUYI*IVl;M`a7X9>U=<=lOV9bAmyICxv| zXM~>zk49q`w2wes;plf;Ci({8jnGVS?2h3%1^jh1L;IkI&xGHi-`0n*=s6Sv`fuF_ zjvh@NU@Z9O_#Dd;Jx2xJLWA*w=r@6{MS>g*WPI;|KZSeF_Ko}#@Ly1Yg16u-_~(WP zw1EScqc(ELPd*0lgNLJr;jz&Cdhic$i8&5SeM@j2PvE};Rr4lrs7%WReJ|0|hSLsi zvvK-pT-B>Jb$TSa4Of?5YM6vAD6eW6+GmXq2_0EOUz11G&_~zcF*SHC>j8WGtPq@! z9Xwp{@p{6>IhTO*v9F5!+U@PCeO>D%DD`iS7W%C%SB=pnl489LJ}Vdi@x5=;V_+v$ zSI@aNgG!qLrps7Af?wtZ*N5NYtfS!Jf{TX-4`c>vr8#gv`GCqn7mxbj9c=ontNH+P zm}%VrK@Mt(Is8_^RRid=tlPkkS10PXI9oe-aAmF0;Jf4}jaRHBMBmKf@WmiJ!{+c? z^Q!e|8o0@(f*=)*K+s@SwE^`x)@E?7Pa4!;bs?d?mGvI<9LEUiD?-BOT3>>{Z_}R% z>e)1Llg)oaa175#FalOeJ4aJ%ov`U6z&TD4w2!MUJ>$#Qb;z!70R7K4`zB(~^bw$) z)fR#%{R%~i-|7+)VF#-ZIUag*$TMf-1E3GH@!=uiJL(MC^^>5-aD+}DaheD@J`qgd zAsDQ(@khYd*!Ytn2^8oA?E28hI@VeN`xrE%!T8te@RGg@6JWMMkZ&_!lNUVbxx!rt z583p84bc}`r@*;WiaAVy?EHJ^FWL0JGJLT7+}e}Rz1<)jHFgZzWqX8n9s_-`O<$+F zhVz#8(DB*znb04!*|z`>rjG!<^s30m*eL76l)%orA;1Znz6ks?8^0Soc+i!G1+we8 z&21Rkd2{%!iJq(JBLhWNDGWN;4CaSK*w!tE97v&YtavW)TU1k(GRk+z%SeM zExGJ-@Nii}tOD>s`pbnca%^&j&^q?^Jo)T|AxVe zs|I?mTQE8oHX&f8vg`e5w!`o~XAZxWT-}WGDVSt627kh)XS;BfMi8+J{6i zMJH(2_k?~u-lu{IGD17=2mMBy{$B7cHctEMBY>BnQ83tMGq@i-c)0MM$r9W37&EY@ zUl+76kExw=N$;69{bKM^8($9oh;Y<@zx5&n^K1qi!Jn}4*TEOr_-^oLZ2Ud&Wj0;` z9y~ba5>jIDudnJ0agP$LU#<$kYg^IPKegs1G1bP|fVHr3wm%)!=pD7|2kxyQo?L@3 zsKHm%;BVI8-_+o7)xY2-TU?Pmcpw|;R`*bWHLwPsq^7-re6Fn_-cy5rRf9XKf4EJ$ z(KUFz8oWgf-Y%4@D_(DGpkJua8eW5s10Rf*W;se2he}ckek-2K9>Sjme;y4%mhesB z?}76tn)V04W6_kdwv&Gaek0oMA%+L6A0T)Rf+=Ef1^f!yMlrDB@HX;SM95D|MvxBv z8#2^i?Aw6%fxfr!p7Qp>pV(Nu$KMyiBlJ4(P$4Gj+eccjhZuORPr#o;3CF;I3Dy`E zsyQlD+231Bt@3%3YIW)~dE~_2lPq}7;eSh2?(-g1dm_CJ%ioUlRyfO-#dzOxsF{77 zk!t0(tO&JXcTBGOc66->^;sWhlnM;XiBNC)y%}oHkFCR1eqU_K@rU1As5aNhid0{& zij7cB7c_}h6`DpM+wXvrE&9Nr_IR3Y#IH61W55r6h z;;J5G3jVr=m49)!_ijg{xT9Rev0yA0<_ot9=B+7Ph1CV^GA>|vMvb_~n^gyT>?b=B zi~Z?EI!!1n=l9Y*-qgTWy&UA#n2cpX)r%o=IB(3h$KJK3R&PQZj0Kkd59ZAd34s`f z+GDU9?41N2s4j$~!E6euISd{N<+JC6^1U^<YZy2}GN5Ab z^~N`bA4})Z!d6{rxmPc|87w|8{Vm_9wwkrCZ71^V(Pho$(v#h&8fkx(f&P?m&@&<#v8^Rn%)uCbD>*E)c#%DPz60+{C zc%yO$ToYd{dsJ17@HUFL3AC=J`NO@l;|B({T^dvb6&1t1H^%2yE3&H!=)DWqDhxWuv?e9QoxtM|q!il=m6q z&0xPd2KHj7coWMXAM2grbXpsfr`S76O)T~nYi0T8#on(SkeBbB;BDooVuJlZr?W)9Tl=Ib<2fV3G^`69CqK;lE%h!7>qn9e%Rq=h< zw%>oL%9$NV`Qe-DO^H>}RBz+tZ@xMAR{rZq{ra@&@mcMUZ2Qe?t)4%xOP*RX)!VR9 z#>r=Xb6Zz#+4`H;Z($+JluwPpBE7XVbyit(Y%l%ARBuy!4K)8(Rp&?0gB{I1CmKC@ z!CO>bf0{SWnG@m!>h$V;b3T(vXdUYizOWQH$!-svR9n(sH;QURBXOl4*DuWfG%YJ;R&R#WtE9 z>ZYlOwSyzxb|=xWH1xA;w^aOPo)NLmbIXUk>3JAIx4W}eXY>EavM#y)6WkOTj;Yn< zz=hG*$G#D;+gvpJUzg+myD;1yP)F`GlIpuKd-n}VDZ=a}uC`NK&p6|84Sl@6^;E@e zIfKm_l8qN6M4Ilo4raKAE8ppU^G-qFLZPX=r88ZX55mK0dzkrk{ANtuC!$j?l?Zu#VmAwe9yomHp3LA0zG)i~|0&bZZ;@F7NToUDJ@rHb zy{&00a%8j(5#jQQP0i$4x=iYUn!jP4P0CN0K{I+lB268CcjB!wDWEROk8>Si5fKsI zPDF%v5|7Jd07Nj592p!;JYznit=lZR{psS4BqC${x@A1$iHK(c@gv!d_^3FxeqzQq ztw00qZ>XI+XVMS}B2Vbng|h+iOYv|;2Ii3?1M`V}v>&6MRI!*G2|h!_6;s4!relG_ zz|WB*Bddt$2zrr-_|^dejPNB2Q0(zrySj|Q^|*;wiB~36^1wxgLp(d3QdWKKRdt^B+!!R z!K4!+BDjHAAEWR@+`}7*NT?%mteK5VeIYr*-$KN*+KY%QdK=M;F*D*u@a3YBIg`~W`y?=5hZ%s7+B8`ACO&$(FeMM92tFH z>|P)u!)u8s8AtuO1@244I&j-2B0f$tpnfy)A@mp%lLF}ZQf>r`4>dgrLTwqMDR6F=Ao7o zGvF3QL)FCxOn z5D|YYP(S~16g-KxocM$69vq9>OnwAz*TjFI;u4=iy(IpKi$Xkx>O=e#^_KWK3QI&~ z<912hL_C}LJ*I3CpT^WHBCf;@m@lGth|Z@V4YitxoOL0hLaQ%ud5% z;$KkviB)LBiOAp-BJ8ITJ@5}B;wkzQ5hX7rBA(eqw7+wR|H3RCBErunBK#8po}ffe z5x+8P3o`=FSz!cAiO-{u#Pi4t5fQ8;B7)UKRIW8dT!EK}2)}`d@UIY8W4wg;6KXvX z;a?*nd|*3I5bzBm0&3R)1bmD9MOiuWTTE_|0Phl^KR{fI9%l& z%_r`HQzEeeo(du^Wf~DBZAippnn^^<*_epOtr-y+XhHlEPXQ4Hz%Bk98DtBgkx$x6)XZn!_jf=G#d-;Kr<Z`q@+C6Vxw_;gPR>*L{n<4b=I6_(!WM6_c(;Jqf3FE_1FLE%BzP(=L}Njx

    1. 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%0Ad)gypcQJ^v2*;q^MH++MrUG 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 Date: Mon, 7 Nov 2016 21:59:27 +0100 Subject: [PATCH 106/107] Tab -> spaces --- .../TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp index d1148ade4e8..67eb1bb24b4 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/wifi_emac/wifi_emac_api.cpp @@ -265,7 +265,7 @@ static void send_packet(emac_interface_t *emac, void *buf) static bool wifi_link_out(emac_interface_t *emac, emac_stack_mem_t *buf) { (void)emac; - // Break call chain to avoid the driver affecting stack usage for the IP stack thread too much + // Break call chain to avoid the driver affecting stack usage for the IP stack thread too much emac_stack_mem_t *new_buf = emac_stack_mem_alloc(emac, emac_stack_mem_chain_len(emac,buf),0); if (new_buf != NULL) { emac_stack_mem_copy(emac, new_buf, buf); From 639bd4fa28528fd3ad70979b7e52c957e5916ba5 Mon Sep 17 00:00:00 2001 From: Anna Bridge Date: Tue, 8 Nov 2016 10:54:52 +0000 Subject: [PATCH 107/107] Update MBED_LIBRARY_VERSION to 129 --- mbed.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mbed.h b/mbed.h index baabacb2584..b32106ca19f 100644 --- a/mbed.h +++ b/mbed.h @@ -16,7 +16,7 @@ #ifndef MBED_H #define MBED_H -#define MBED_LIBRARY_VERSION 128 +#define MBED_LIBRARY_VERSION 129 #if MBED_CONF_RTOS_PRESENT #include "rtos/rtos.h"

    Q3y@ zf1hj{v7W(#4f}2!R+0_L@5Dy?XV!3C`RRyH%UO^=hJEYFkx09-DWfX`c`o72hQo+8 zidmb^Ueq$MOOp2IuhTj326<3+)!1T7ni@V$H(bzcPsSs+a@2ESvgY z@TE&TLRLa`h*hSR^eUp?lA-D`PD75 z!M`2-b)x!X^iq+Wt;CPB8s@qZT|Vwol!I?B(U`{}v&BKRsC9nYDu2DToXgA6T@eG3$_0FgaNJ3 zqxEfi>zhFXf7&%WL%`g0Nd4-gi1J6isRp#WDBm%!mQ9g?-GW%_R7-1v<#oj2QGIx~ z^|0kNp*{`oSer2QS>oyY`TDd2#s+b%VGnCBlIN7zWtYQH-{QHg!UK?wpbP0?V`1IYQHs?mkrMw8%{e6d+I&upJv7k zFDx5ZTH@EeV{aKmzoNC9F^-H)62=S7Hu8?Ud4Sg3kPkS0&SK?+Qmb&QYAcH?J!?-? za#bVRYgd5}Sw(v#L;X=6!s?s>1XNQN%}efc@@%61c%j!)F9C_+mO(po?9mWKY;J&O z5J?svg(Qrc`Jn4`{Bpn|pVQng?I^>jf~T@HjHEauVB0YV6=t%>f%pH2tnY<_V@3lQ&O|_*O{%i0c>S{ph;$W)W@1k4-X2ng~ zx)N)jxy#U0sR-y9n&GLQ;Tuf)yPP$tTK;wr5goZxU;X<#zHX7@*WPh#=p7S=-eDN3 zJJsAMRw`6`R&X%#BUt(Az1Cz?KTHU;Zooz%G)T5?$#RNJHgP^y;GrHc%Re1MYwdpz zdS#{-CcHrAXxCny$DHml@}tGeytsD>HnBo(NdB*|+ut1S9M8E-pNTbvSf?jdWy)DG z;HK2&GFiE;yS;XIJV&%39c5#P^5J`^B}EhJ*f{nm1%_V89PC^|3B9O1dej ztOb(ROGej>2rx|`0dTKFI_u|tY;H-v?P}&;qxc~DG+iId?;z%0E_Y`PcjBY#O{q6v+`Z7xHQgeo zyGPZJ+D|n(4QjNs1L@cJKa4tHKFm#~cfF>+>y}R^|19-3e&}s~9c*5k*2m&=O0t?B zR9ucM&};s*9Tdb~pShRDX=$^wCRKygsDTI$gKWT_8_150*57w*@Pn`5%@0l~3gp+p zo_&1=v^t%CILJ++eyG!~!wi8Q1YW$?>0>bt1nrMc(aQ5pYDhg?qdEO%`FebpXMiZ% z6uhevF_CHQUIq&dqGd#&lqg| zMcIM%EVY_dV%CzqaTeZEK;P3xv(^fHaiaBA)rDSuud!a$)=Q38H1 zQ37X}i_x5-G4eGvd#B&hWL4kCj!B9x*wJGB>gnFJT&KK^@t2B6?DlPSeB|HY_(-u; zA8^tddi7%+7J`1FiDm@arjQu z0a=1LM7D3RCj*hv(mQ77y7IYww6@Fy>c3T8nRLy*{f1h(MDOb&_}d#qexEVlP|v+( zY(!j-dPKMyFUhI-G^x)XUN-J35cRl8!_@LNA2&lNH7UTnTDxH_&G#4ky=ag5L)aS| zDT4FJS-_Sciq}AA}xT-NSE6_lpevlv^K*E=R^$w(B zqKkh4ihvdJM2cIT2Ad$dJ6h+Epdr>;6d`xN&#yE?8Y#6~9d&+Jlf9VJw4Ghl6!|_@^Kj3B$M~6BYVFo zlS4;4L?bugzC|RBjTN348!>Bi3CiuNyr8rwo4n>p46-WZ)N&TfuUYyt(N9!)y+%?- z#hk03yZqN9nhMuKe)2($YpDn2F3@@H75bT(86aVp8HcEaAtmO^ ztF!S!CU8MA*^}cwj?xHh95m^(JA`>a7#-=TQA+9;D`N_*Akk`T1}n-AV-C*AUbq-Y2xizNr!-IwaO;+6wrmBm zOty^ZfbbTpgO3&YIuX}W3;twcVuRj8rDzi`EcS7s^@rizz z^uG)%wKTb4PY)UoUiehvI&dVZ^alwO#`BZ} zS_C~g3p^^?gfpSuFCy|aLv$HBr|)2T8}5b=60YjGs2#=*q+=~wi@rF8z6e6^PPWOz zvT+~KDvpIYcoAY;7f>|rPL7)hr1s0aCoQsttcg8{zfoX{###~otWOA^SdM7dnElq( zOe_Pk_*S4yxpH-k_L5%MT(ik$`R4E+wa$g-v`-r##|YzNx69gBz}wV)`Q8kZ-W+dp z*`vsnO+Ih}WFkToCO?1D+q8lQ5jy6=qL=P&F3AY9nSY6-5CS&=2ROuRe#vhy*;ehV zt}jtwQ5l#^`bPoJ{ww*Z#31>Q)ssFmYt;aF?CJjjp~`f`0?6Z&hCE1*Yjl8ZVAjC3A_>s817N6 zsCd-(?;Xb>qPlSef2njtb}85O9&h~&PH54vc0sK7Kx!2a!luA}yng3}@JRn+A?M89 zYfwAJoMH)w`mxjd!}a>R>#G)4*6UslWF1pqRlk!*EvC&v)Dzf*F|i&kISpfIUE9gl zC%qZ6eVX}f6QUIu&HJ?Vc0++R(&V&HqjSO;+NXt}E1Dc7oI87O=W@Fqvt^&Q(LSdA zcA#mE5Hn+A+l%XxVqFOzlj>+sr`V%=^LLFBPatlYJ&)}HJ=$~lE`HB8prsgLr$%wk z*CDd_I>@cUZb@{ZKGXj`2z;YHwXeSx9#Sle#SeslJ;->M6yFD5(9Ucc*%pj8lJH&w z_9vybh7h?I*m_+2MB-P=_iNWN%d7#=;&s){UP{Q}XEAUN% zguK^sZs}V-?jO5~bQDDV6kuZ^1X8!A!FkNWfaNyN6oqPmsGr zf1=eTiAr-d*Wi+xD~(ro1z;I85SG98;kCk>ev)jQJbcBfzJn*x&RMX-SB9_BH=gcY z4?S3gYeZ zi9^w(sMMbT;f#kqfmYU$QFs)!y?6q(c8hh0uSk>bhPH{=4rE#PzvG{Yrgdp7)7%cf%)IMXg1)&$OJrW4ITZ z4KbPr(C*lhGg*9ktx^rz3*0UXVsEhc#99q;*SUDPc49gFC*xylsr7S67D0b`>=PZr zYBuS;n>@mIPYdyM;aHau^T%9!|HUOEI^%q82$2JlApzsv%7hg~m}TBRwm|_H@)&$jMlMZU5B!OsE3zgrf`@RtBZV$!xpw=uth+2E~qjyE!8al6ADXhLv&KpbiTEYsd-QyQoy3sk( zkNw1p1_PpSep`z=5ko{i;*0@=D^iHGI5}-?q{Q z91hzPxv=BS0!=bT^B_MRgC(%2+y_lY+3M4R{dC=$4}gs(UKA>NF!+J~vpec|y?g zR5!?y{|9BItGNbRBPpuZ4KzO*>h9Zwy)sHozO_I;aByduGd5&lwnEol9m4rv@> zpToPK(8tJ1q7=VXff3=BAai{Sh%^VVQ|gRA!PON2pJqGRZx(JOU&s-9uVp#O+u$i* zp=P%m8VZ70E<#Qy2w-O7dq+i1!Qb-J6E{ze+c4(ef~3r*p`B{An$Gl2(BNQ@#kasxn#HfL zeGL4_JBXqI{de46OI*i0puuzG5fOddgBB-%O=XOHt9pcgFXqKy2xrk-tFeO&dai~h z1c&j9RtFJ-wUW!*Ce1=iKDpp#|14m(r0z=bzlQYtXz6WeX%;^ldh9N0YZm`Qi1-~A z`{i;P!Re9b(0Z^WWU2P6)n}Y=i5ZuTZCY?ns|!=Tz7y4g2GsxOp(c&1*rxMc@Ek-W z!z@umgoo7XCSZ>+)v`_CSbV~bXU+$o(|lrsXGYYAeVbaYxb(x-$$}j0z)AI$Ck)xelCyiwO!6B zu_=Y*13+o0D^D#rS{WLe%1UYAe#QV2l zW~OpW@Ei<)Z;S7yaY=mm@HoqqHv&a+Ewlpn_ihK3TmnrN!}`a-59|(|Ts~#KxSCmA zXO2D1;&*{ZCJYqxxBgYo)Whe{*v!RM4r70aLJI1)2Zarf*nwFW+H-E$r(9)LzTR zrt1F70Vh!EeUL>fgYegwJUk!27?>Hx7rTt8lemIK*ko$Ey#tfmX&u`Il>GSa#kx(z zfdr-PZ6}xS@^)$!*`38*g4|KdyjhGBIU^9s0T-!bXJnu7V++ka$7hl4=FA z@#+iUX+K_t1D4(Hz<*e=vXFbb!bH(k9kq40vc9*i2yCq z5yVhRl>tj+_1goIoa*a0U`3IH_8Kj<5mc?Xlpb851zAgnXWy654WmAMaoo%~m685RJ%-g3Kk)+DB?bC? zrnv_vhoRcM)ZbhKk6yBn4m3knR)9~Q&L|!l>R0+ptj9r=WNN4kz@hjbmMT3P(PUPridIfowQPLsBtPzJKNEZ`AfWysa(m17(9 zAADGpeXCDgkvJf|9;bO|a=F{6Pu9(AybV2lt$hwT-kaUfo{}swz%lmrBnH?-#8aDy zFOL%s;iic5*)Ca#q1UWMSjCKINYZe|MYIXoI1q1`k^>0sD^te=A|&3u+S7I`WFo6N zDQUgLM&-^HS9c1Joer#}C{#&NLfl;7AcWZj(#Dv9dp}7(E8*!LlBs3nEm>6S6#qkpg)8uLPiUQtu2ojkxljVT zhap=0MIWw<3*`nW&z}uWnrJxn{#ClpIOy$Zwtn;L#K1ouq-&(j&zqkK?P@&`*i4vH zR`rEJj-tBQr#XOV6#sqVz1h&ZA?m9w{Ajv5u46!Jzi#bRW7+u(9Cp|l9 z+wf&`ADve#D~KUh1V4A`Nuk%&W5&q!L!ZByS;mmeE!Y-9+bgK+`dsbJxvXw^u5J3o zGuOwIx+5h@NDOWRXDouVHAae|-41bz!?b2%KwER`Q)`|wo>LI1MF9$+ROfE5^gDs( zJfNP2?o3heUC-FtR+n+B7cNc7GmUpO<-uciHt(-`(1Umai^UNBmoQ~{$Z9#QzuMtU^%)xpFxd=Q+bU+!s7&xO0lXIL&Yd{ttSt+BD-C#gEy{=$R8kXG}li()D}s zP=M|g51ldntakVwZsED%d-@s0a73B$5Z+Hms)w??(`umF>1TsI*J-4!-gZ}xUu-9o zrabWL6i2!aa+X7ZO&)m42Fx$)I(N7!;;@eAdjVfs%Uaep;?5@IXv7cJMM+>YcRk4o z>Ti2#zLsKbp4TafarC)Sm4Vk!Yu9{uhyabvl@=9)z*7aSn4sgR0x<`1HPF_9MxYTS z3#?JQ%XoT6S(CH4WZ_a4OTw42*nTt45f^k~3-AkCuw#?#IWk}mU%=S~g=St7HqeAQ zn^1fDxgdRqWHp>Q><5B${2cZ*1$8vAFt+%(D(DX<82VUto|j!Z!HTP^uJBxO!D5LpyvzB zU5geJ*Cf?Aur$Oqy{Zknq-G#X5GtB~EoqYtkaYAumZ-0d>fZ)2Jivc-UhyvUAr=CI zmYU1E;ICeLaTV|-fv0a|3jVQ1`&$v5`ke6Z0dh%p;qH`_;`PxkK{XI!BDpQIO#=5_wA7LfIpcD+{x@nW{g(vFOzp` z#$4sfa|=sxgwJe+{Wx7od__2tcJu)g7cin-w8C3JMPU;?^ZOC|%zMwy1bt$CmeG54 zWUB8#idzWzYb{HtC;E<2^uNf8;D^?^K-r?GH>PMIR!>)lscVOkJ8kOPWON3fz~0zx zu+GlF??&{NVJ(pD^&OCwWTk(hhOKF=-J}ah=>YhM9U1^bbjMAv=*aVmf5VyzEwAFI z;gF*sXjqeac3X0p|KOS`#|U6o6Y_OVq$+2To<4M`7E!SnAy3wlE;Ci~j+;ooV9?8E zu-r%4QSN=kujgtblpM~#p)Pcn1Z~lH=2)6^WksGrWCkOmEJU;?-H0z0J)*5~AApXc zUfX~f*QM`_rsg}fJK=H}VL?u|w%&GeY_EC;_6g8OqJSr!X2ux(rw~sO(f&Buln{<0 z?dK-coIcD9&WO~*gP#CF8$O;mH=O(aybGZ7bL>C|d2#@8Et?gxa-hftg?;+^Pz-wn z`BZB{P4t@Nh4T)tIi*{j<~g!=EUNi7+Svr8a{&=;){g@+&rJTaBs_kuiw)Y=aT$Eb?#L?z$CjZ{P$LSff4v+-jZ!( zZG~1K6z^e_WXPo1y51DHu(iO;h!xm9LNu!Vd5nM^rh{vMWrTHBt`h<{l;5 zeTe3Q1|5f8kIrrMVx9{^pUKz=zf!FI=eQV+Eu1lvs}ywiTZnSJ$qXI?a&cDlhv8wo zRcrK5*IK|3S*!0pOu=5=Cg?0oK;1!%;k>D!j&A|Ah%kIJaSysvNFIg)A!_W}0dGIb z;YOYpktel>mIh4^kGKhh!D=0 zcT)N0Ueje0yphgB51;6PwNTKn+hxB6d_h!Ky;;5OrgMnk!T6YhvGsj$W&=GHeZ=i{%EW)r z`eTwG3mVne5+Pb^DYCscS2n0N=r#R!W@Mbf6^?URqZEmU zRixT~llCvCK^1zPux;j?wbJw8kpzk2hVP$O3faUOpV>=X_e98N!fYwm<}zyLv|gaS zZ`SU(M!OL0+99miUMBp2c*F`IW_HR%uk3Bxbb6Vhmf68%!D!%YP!B#k#IrYIZYK*s zAq!O4NMSVs7mF*1Y_!3ypEG*^`U;F!if?I_w|Hki{j;^qzXw?Fd6*Pw;aXH!#N1*E+b3~S}$&MPOGejTHn zR-!FfKLc|&>;5fdX)Q^X$k0=`yUtgCE8#W&dpWCpAzVdC;Fp)-J)I@PIad0b@}yh& zK6L6_+MgjFmgEwmNwmhL^img?Yj%pisH~xN&4pI}1lF%1PE+qriaT6k?wq)ThnG6> z0W?o(e2^b5=x5M0jsF}mgwIU}pQ)+Gbn3|i$DN*6p=$(W)K6fZ%;tZP}#gQKyihx#n? zeZH2}_sz2|O%~h;iugEoB2xVMh1EjXrsL4Mp4MQgRR~PogxZZ*ij;z99^%=-E2`%% z%r~50TTfaglh~`ilcc*$Exjr?^%d8J z=us9`0X@^uPDJ;q&EsviU{6@7YY9{20HqFV7O3>F{O)uVArg^A1?~lCzdP3uCE5Mb z83ubi_`#zbk|$5%_wlh5e{X_KRW4Rn2eXLS+kKXahCPNn9&(JS!3iI^=3dJYJDxiQ znh-#26^Cz38RRCJO%TVDwcv$d!RngT#&cwY6ow5F2flA~Y+^7ueZ-JX!RfHBaR!_Y zp^#>5RbORYYUf)CK~s>c1mLxX@`+y4SfDYL21G&epar8j-c~;^Q+94Ofh&b>7>L2Q zM=tnTX3|v{NvH+=&aKQfEi%QwD81m!(Spg*8X$Vwe#TS83B-UmOc@t_sO(1n2>+S( z2k#24SzR~IPg>&5?DZuj-Jz1#7moDPainrT;z~)3+jt+wyw$OAAqVN*tvI)aV6$`& zVrF}*MOc}6E91u@i8@a_0P0lCEh}C|HT=#{ELe;Ba__?V3-2lj?qc83oPh&NMgZIX zz>+%)^5V>MVBsk2OE4#}(_+|Pza@q6W>J6ITO`Mi&+#SU`&Np#+uKViI+B8@N3i0| zcVn)%9|X#n5av|Y*NhzQ@Q?p3qV$VCjPrn?u;b4o&Nr(|x<*9~AYWbk{<0Z9dvGKB zcyT^-$db+qRy?21-1xc z<^;BTx9hQ$QR`X83El82s-qSO0)5%eseAj0&an9X$>vAu;kkZ1xrV+aL`c#hFZNuN zCr}qLywdx4cZg?WdF9{(G@go1NaCljL7u{oV$ah4$0taWj%x|-DF-C+6=1qG;dczb zb6V#IWY7Ob*C<2N<7xALT2{-dylj#)z7~i&=ndtJc9OAu4EjT*>WuatR6-8_!OBB< zTx`{QlGu7Fl$DMd(c~8^7uUpaFT^&tp3ypEXS4`ou)t|v#&wNihWb}g-*Z}ixIR(n zoLHL~pPZRBcH7GO#EsnRSbN_`TrEDnp7&hr9IOZIhwfjOYA_*@S2qw=%XnMG~jRk-aX9+pVXkHh_H6zN)k$e?~mG} zCTsARqCqzWRFR7&MN=xTjFhTnjr2U~e+;ty^z1ITrlb#zsy`%b_+m%+Iv;w72@3i6 zBt?8HWY3=s(mZH>AhlaN2L5ovF|5hpYYQZmrA7Ol7@YaSF zuLy-S(D)yLe!YmF8~qL5tek=Nh#9p$zW!EkX#S|8h!znIKpsz~u}Rx>bg<{y3$109 zQ-e+O(`%DcZIQBYfq!do1ZL$Y(}YOlG;`$SG$XVK0&K0Z3ktbEVkZq@{eq7)uf6v1 ztw&6v z(q6Z6g4g&Q!~D4?oSbTn7_kR@8&kwww2>ee_!H`T1N*T9>fdvq+>O>xeuWrv!C?4S zzsp}4=CC8{gI!yHPiEpdFL-gqfagzsBq5^l&E9u3!Onu8K(qS^=6WNJjV^oSWPuca zGj!4=#a|C0-mL0Q+QSUo*d6v}JWCjfF8?gQp?cGT@B2R~Fm)MCH%CSw^0yU{j&Ak) z!Ue%ikOb(RpJ;0kyXxB*6$P-s;Err67|~I$l~(xInz9$`E7be_N5VG+C=G9W=+VYc zH$)19uDotFtG6(?SndYGgJHkvdE)^W(l7Uw#`s1LG!`CvVSq|RX|QGR=x;A>AB+0Y z9Hsfbwv2p!Z}soj+n~1HuzxXD#4Y`Z>kys{J<{lMQxrQ(sAa8Ifm#;%L%|VMI)0G`^?!&HHn4sX2+1eSz-}`m8(!%R9=Knwe<|<)XRCAEp#!4YjVHRseUn(XZ_RkYoa{t3q>?^BIaE)jz(bRO($CtsPKu` zufR9ngkQXEEaH!4VP)@Dj}O{sOglRfvdfAR?$WQhg^PiQ=j03WqQ!phT`l}izuX;q z=${H#2mG9s%W_U$N#nM8Mt$e<9lOqXk4gIy1;V&$09cZ*sCJo-}9awk;dtcj+4__)DEd_X8nKs^~mEt@wLngq5aoNBpV3W6Kbyfo+eBam91=q zZENe)JzRW;VP2WDwr*-RNg%w?G4sImJW|ucVvaHkREnh^n((tr z8?qc7Uuf@jQXDAIjl5QWUggS~zbbzOEh8ktmzMoevpYYyk~U)69#|@icuwHslX(L$ z9`Rgg6D(b)!xs{^wN6)q5Gj0w_HFpsAGLqjKWt@ru05}pWd|6%b7nLg0PgIbL}7OA z$~}o2orqtM#>LlT$L|ANY4mc3&A?lH*6Z5;M@>1%1yE|<8!@+M|B+2R)4lzOsP zIQ1|e5vyMXE^;HZ$)8~6p2T`Jvx$%KK;1No3D|cw<1V8p37}|Pi_m4{%+OeTGCeJ_ zA2Hld;yEwk^H2=TshBG?Ps%TrRT`RhYW8|(JWwpg6@@D?HW?bgH&qzx4K4O~RGYcK zRyuKIOg6k2VYRJfXU8qTdnZn{#>q!N0>(zZa{~|yBu5BeTCp)(=24r$!5K|9_aGw3 zB4Ua6oEAUG1!)y!@!y1=^zMhm$oz8yw7Tt2tU?^1>F@yn0>{=(uG^zaz0-cg1?k@Q z#CYJWym8kFNDET-z3`@WF&JFchdrNm1ab^txMkR&T@6)iXf<@Xncc7va{-u17RQL_{~06ofbs7OQtr1m^G>MRq`z+0~L3^<$ zBd+t=lug<^rl~%SbbB{Kw>J-(^O4#o(>H1JnWLi-zM{A$&e;Ep*2Qvq{QCoqxZc^? z)8iQowZpase9pfZ#S5n=HPxcAt2+YN;ekCF7nl&E9AxL^KwW69q4kQ^jg*$q92LCI zty2#ef?mi4+mlJ4(9MTE@zzk1vi~y-pnct@h~)&e~8$9p1SLzoR$U*=&?YazR7c2wh`q zinB`}utl=nAypG16z`fHg+(CRD%DQzT>EtLu7{;6vFd ztI2YBr#2o|p$vAV4=2`urrM|X>Q9Ws&KS=GM6KWJs{q$85&j!6*;BN(0X_V=PPc#W z-tC(KTK^lIrD*;2UZm~Y5Ton@c(C7q+EdOHwYMmgFU5&bYB9!31H9H#W$kj)wWK<} z_mI~d0!l<;N>lR#Zr#7=LIB^7HlTJSJ<1CUjy!&F{wDUk?*%VWrTqBX($Y99H7cM_ z%un=*!I#el38LnW%Jc~rVDU3e$sZeHwXHk61+{o4z=aH#t{-`S@5X-6J4^yoGzyK$ zkIG)J$qtST(_V+R`^HCZD);3Y;ugb)tsBW+!V11j_%^6Y#NAw;9pEMz;=JJwr5Sox^f~Vzv}qyEf2=E+bz`LFk;7Zrp3C9Ck<|6T z3-aHTk+gyYKFm3BCC$*}$^Ps+bx3jBJ?UQvv(i6u%XQL;>&HlTi4|b=aLof+=6U7s ze%92jKHcYkkHKj~|POhP;q zjnA+=9{m{8dFZjwkHnNz51z-@JZfrI9`>GxCe496Rz$&(E((ftaVr3KsQ+RL*(we5 z#}g87KH%21GWP*dC^bglzm6RnAPx14_}|_u;J-ORPcf2vVEX>e^$ly;T;}|)_q+4U z%g@0od&)cx``lzbQy%95K259DhZ+mfilr=z_dGs`_02ZVSGqu+FDRB+<)g|nk{+DP z91+Ur*0t;+S%sy?9=Hv3oaFK%zw^-lR`c~o3>3uYs@MC|Ak^xmYW4My_HKm?7LhH^9F4<-6~`UV`}>BgWYi@^~C z9ULWEI#50vtxG4P@jdqANkGRDpFlK%=j5(V=BNNB;vlnVQt>!bMW*8%5XArJ}MaTe>gITb}F4WMjJHypuG9oz0q&F}M z=`%*-xshl0YIB&-K6-}fEC&t$=ou{?hCCL#RUS2CRL9sE@59bbW)%x=UMleB_?_nR zi@Tf*S^^GeTJ93Aq~6H7!B3U!H*nn&P(KfKH8D=9FO$m+SjmO&m3Qx3F>e0;Ark2(i+hc^Ds3&r*2j z9erYga!|>B>SO`p@M2wWK-`55Tpl8?I2E#aBTB(VZo&7-ao#e?_lXPE>Up++8T%GO zAVVDNnFQ|-2BS(A?`OA`JbvXmXYs{Q_Bf1=%o63wvp1J&&5z!#HK$AQ&H&Qs^TTv@ zy^k#a={z+r={>oS(oX`P*$|^=ur5KzPotcNCm5T+F^3#-6kjqR{%t<^QsSFC!E=fW zYD2`E63_Y%xT?I0^eT)qoe%ZC==02Dn00AD`!ohl0J~YNmasoll%c7g0tNDb9$gZ# zCB^1S=E|$0xT%In1H860bwR)LDe;G27Vy#iWu%i4S2r!d{D#K`yG*g~CPzv*b62kE z%1irObuW2|Cy(b^sP z5VA(K3sEYXt1i@hCX2WZ+}QdHIFoF}r`ZfQyxw^Ae7{1wm)IGf9C0ERAjxiGb_e{pDV7BkcJ%oy4lVmfvplNoBj_0x81FdUEpYti$l#0`06RVB* zaril(dfCq=`L|Emjl4>$Ji-AleTC#q7y8w?^B&mOjzleP?Dub+Sj{FJko~)zPr06% zvfIBMPq1H*6<|sA~&1H=i-R^# zSYpAiq~Cz^?$@Eop8bJ%;2Y(dNXhc0+)JJ7h0IPtclD|#QJy^;|4kWhTe{Lx|D;li ztq>g&mM%^6jqpN?XlwN};6K`)t*&mJ)PU`nl|^+g0|)Hf%!jH1&dnXBm7_XLBkJ$* zj4CMf&5=7sO+p;(lBl4o!5b=B$Zcl2tVQ)r6-A3*T*iCcf)_TJG;x2PnD6fDd_Y~!iu-{NC z6YF<-_;&uOduLWDzKKT{)TZX0GWZfj>wr+^>eK355Z}jJ+2VfL_4An@0Na!&9Z}}& z;p#tH!s@yDDtc}@jKnqMqiqh0_0)EhczRzfHdFB-UruO5eqc`T z?)oq^S0cv3Bc#DXA9xORPS;7+cY4K@>)<*3ipR4`hxgkNHxSHt{d_i2itSCM++*Y=CcD>16eTt>6qlwqTC9{cHT&xgK;OgXN7 z3M3j2-{|xRjmcD!7Da)khzC!J&{!_pf3vWP z-g&FB$&U7HSq?^4Lhiy^z(f`2%~i%NV%;tNHe1FuktB|hE4jfkw{I|AH1CP+G7m}^vxZ=#QdC(q>pD2J# zLeB>*@X&76a!@|3n`iOkim?SFY`m#otWQV1dw;<(?hrkpi+F#=F^Y{sN0#M$eXS>_ zV1#dvn=c)+^t$j_rTU1p89Y+Pjic^3ys?d0{v^$ow@=vQ`gy?M`Is;O(0^ov^V;3O zoYXXEBKm;7oN+Y`!pYpp&h@!|GDy9`3%oJ=9~i3 zCw_>d5x#X3G>2!eGGyBk4Jt928`BLB?vi@TawpdczmQGNO4G(w8BLijT#;XyE$)N{ z5|REIyB0J^&eZZ#MJro9>&COLY&IekfLE&)Z6JGSAMCFQak)#9^j-!mOj+cZ82|1w z@#1$h$1R<~eA_LO1l>$Fv-qWQuPH)$EZ`tmBl_1R{Wr-FG{*i4D-e1UKZc1e$p+nN zH+=7RQ-s;ZR{FoM#N$oVetKFtXUq=5<`;jn&!!%KJbe6eUo@4j?;AdTu5X`uynXn1 zd*4}QOG8OL`ByM#fgOIY&j3GT2TN@PLL_eOO#>s|kxhnd)luPJ3Vzb@*w5feJQ%A-6xuoX zN|8b-{6hH(K5i$LB)_$#w<5@z?S&mZX*_+aCvH*1l}RnHA(Xsl1yD0|jqU0N)-e+j zA!O7r4G8GfR!*B7J`Li;uN+FcUKETsD-`Hti|nj1OGMin7dGuR4G z4%WCGV+@B9ZIPeHx{)gd-MmaA*)*fRRPGMQc3&cPap-whM_V?=$%OUpu)djjn019} zhns3$_EmD+>yEz%yX?au0ksSHr;Z1oio2d6+UiqIt}9cgFV`Ycwxxa^WU(4=YrQjA zv?l3ipb4`A#B+^*FrbOhd{+)jYVDxAUIYEU)o7`w_~kNw6cJU%5BFeODgHvKo_Msb zp-5JsK|y+P&A80PLAw4N-0d`$U6WlDA$twkZ3bey6Mmn&E)8BP7_&U5+Fc$)L8_0B zrt_NdBSHqCF^#7h@kL$q{)D~-k=25*9AfNwZ@^ujffbTILKY98PU^J7^9=H5Ed?Jg zAyl%XrmWPk@dYqm&Se%Q4mk&VU=Qv!;5j8eh_PRZpTmDTG7V-nXS8%I=;)D)h`p$~ z7jfx)>^%Y2`cr-8h`xm@$#iG7oLq1OcVx66_Hb`qy)0#j0WT0)@xKh%!1|@&UdsY- zJk2e~{yzscDP^)cXL7{vO!z267^RfH&gHAoM5rVySz5HJmr~3@3f~54bj^%fMHG!d zmLrCayQqGZbDL6W6TD-VSGqM5s=O(o+rg9bg8ebb<%K{@VLWiNNKt)OGe#Wu8s`$& zPxam<&e=ZBYgxGtXuNG0xp<(6To|(|QPa%o3QoaJwX^hn%E*z6*t0Pmz!s|U#E&KYrqISf#w;rzW z2&XC*CXXxJVto$kJiBG;4CsKDk_^Q7M6uHWkdUdpDT^bj#k*nj1l-UtNUA6D)s~FegHVv&w;n0d)6`32~cU^@YeIEz#JUQ zSAK|nHz>M{LGaHP@!rhl4#?pAr+P^?YrLb-S_l=H@A^Wi)}?yne7)P`(m=1V_hI1P ze+BJ=#~HlBc_nIxS#^hb(J-3$2=(q9RoVbf8ys@JKSJ*TU(9z-$7mLptWQ59OX+Z7A<3AfDU9@a$1Om$) z2mlQcSWJEdkQ~fM<~1r)Xk1_DGIRGgDizqT#D3-dgzwS<-)90(m{p3!#|~N~iskOl zSq&zuCui^%&p$E-v*Q@pHccF@rSxFh)Ys`@;m-=CTCe)jUx>RkK$ex;u_yB{U6jl3 z@5$nh0VfR1Q#N-|wwWSMJmsu&4nLLqrA+tIQ(RRc?q;}~!#(O7@Dx{RuEW`**s~q{ zpQ~v|YhcPH=F7LbiZkM1_u7Cq#>TGp9$`1ln^isNrIIMdDvgcSfIV>mese;PMRq#t zr32tH?T_EupR%_eNWERy3MW$3^%F7Ko=nK#9;+yj&oQA7ai}-mqCYI(l6I;uexZ-z zv9U2ZrWDBjRh^t5!zQ&IdJ|@~Ku->d)>;r^%^FCfTId`Odg~S%!rWMO8|1OAP*=4T z^CAm$R{m4I=w0s>QqiJqidCEd{2B*)$pP=nfvI)f@&8g-9z{8Aa2}{*B?l2Tz=*n3 zyp%3CtLzTI-maH2A}fcl|9H(FJAi8u57sVqQ|b)V^41#RBN9g(R<(U(>z&1;_0tTY z`G`SAbMknSkJj zqm#-59;|-8?|sElAw$z5+GGO|oFun^`=m<7m(Ta_s!p~|s*zZ{r(Y*U!CR1W*fK7A zY|*%!u_+=X_Fi}rp@)?MHw;aBb_}>BC+4V>UabYZ%lP*G1U)uG=<=Kik|4>)$K9W zZ%2#w&$eWt_4{RWu@ZS(48VIt%mptOax`lsPF#WtR zMtim=9)@Rl=3x!6<Frs9XVmx6IE+8B0HZ=K79Vk6ZwQ`<>Hnl%cim_Q>e3sgT(x?+sI^brnrqdaDa6{gn5{$ZfdI$dJ+bpcms;h2^o#1Z zzP)_rbM#TV=S%ermDtDq`y5z%Mnm8cq!zqdp*CPyi1?>pCCjOPNWgok#G3o;mf{G- zvl>^EOvT@O>21Nw?|%hfq_^C2`7K(!C0Xvb3~BJ5lFPmEfM;J<;$}_Ar*2J$TivgCdSgHDpI_ps+Seb8K2*5Zq5HBo zc56TMC+Zn4LRj&Rwsk1m$2|`fa+8{o)1LSh7~g*EcY7WBFMHx?|8h~a2GLKVeYsPpNAQOd<|PS7P;;e)uZ!m*VqE zim^0!5QwXQMC31^+>tje}i`bC0cipsrLJ`$QqJBQp3oCF_6aE=eo0=$=Fqq|??qO3Ss#X)&wt zbo4mtC{E;+^aOa%pxA`W%1#L)<^InD+ZBnKkovnYf0HD%<{rKkvwbO7y-X@Pnmt)=JI5DeI;F z*dXMreL%e;*1DY)6r1>nt$v!PxBy&z(5l4HFStn~LYheh;bh8IxNK7lrY7{t*5Hfn zC!g9Fhuj^2c(X~r_x-J{M^txmB_m@9;Utge`_J5;Zqx|J0^Ox;$+A8cO@;`cf zkZjFgV%!_X)~ntnF~qmf(l}iXZv?xDG5T-tDNs|8J;rG_C08EFH3#AFF|xSH+ls|M zSIEnRu$v^uXr({3jf93I7XN(c3K|WrqB7G=<3o|B_JWPYhO+$%W7KwxH5%)vGsN79 zaR=?93#>jgURB_ZYIWWwx$)${-#5@qaK4{V^$QPi;@U>We{s zRdUXJXNk=ZFPh}JRMoe}jq&NH*XBSQle|VFyzJEYUJgEf8#m7F5bgW= zxT};qwo>PL8H_RKl#mhe=xk4Ts*x z!WbvOw5vtF2e59WzC980f;e3F_oME?PEk5CEMr6mmQtO|FT_8GXP+GsRv257v_63^ z0z4|Cw-1t}%c8ReZK$=Zey_@jiP3#<_T@6AZ}fpj-Tjm)h`Z1xw-2NoOYi0HMn$8ZUi9duH!s`C}JnzA+POA+%(D?abo&k!w9&lNU zh*9f~L8~ab$@_(HL}!(nVTLm>^~a??a70!&-lpk_a{rE)kOoL?Mk~0{MJ`@3xY=3h z**xP&Po{zM9O+3A45yBSt%&neR%l;#qz z+r3&`=3Y_m2EqZeytqtU4YUXl1L!|k1-qBbxy+HNi5svgAlwp6PXV$l=wI6k{_&i}lztD@aOnw($*fZ{P>5Ed`PP7mDrg6U(y&)fIrf3g`67;_=k%<2e~n}mFH6MFV&zS~8#Ld1487NL78yQWPgGl0Yo)D@f)HT?t9R1a$A8s< z7;7mJfqVz!*CoJw6n{3MLs@7dkag!p>JnJf(X75&8jX1VRm8=XbVKTSO z)SBl#Xjc8XN?fF|r**<2q>Z@0u%@p11=uY7%)cPp?w`jk%C>X!{SRUP0q)^cJO3+; z?f(NUaz(N{zR3l?Wdx*pueptKt=^&JwF+g%5EHHQ&Y@)8~)^TNXrggPY=2-?L60mslP{%3=2AVPtk=z` z99?-~a3b#EDle=kKdzkl({bffSU*3&@4K>D7kHfODLi7XypS{bxboMsO7%=<;bX9s zp2a<16y`~;g5$~$g;}=a%AapS8fPC@{#eK?qmf=6&h=#e+UdugX9^eMnJ=(M&;2#C z-ifC&k1L({eVQo-C_=L+M>cU5+KV(8#k*%5g@HOnJg%(G!n;RPsaS*WC_bYlYUf_Y zRwzq_9mn4N^=u9tY1E4a(X)i^yTygtaT`3#@*S`e&p}x_gM55quRJOd?;RRu75*Fy zu}-I}M&Z&sde%edEC$=*Srj<@dKYInt|VT>JB*H*;N}$_&U`nHM9$sh(0)bdIUH-4 z3ICgQ9|Bu*y^8WXH^7=ZXv8_gTg_qC+^9@o9ql%FJ8c?Kit*>RJ~~5~ z9Xd1XLIZMoCX=pI_I;tO0SBf4+w7Vwp2mN0IW0^Ke3y)u>fJ9^Kj=w;l$4gpid^e? zz-{rAyGz_b&y=7LHza}{uO|SWbO8~*$|P3y4@9OP0=K;z^`1zK26P}9Q~dfdtun3Q}R?8bYYJWH?OS*BITvP?YlK;~o}+vK12|MX|5Pb6m1S56?3AQ!*4 zpKo02^h=G3De{$afqkN+M+nz=68l?KI{=F!r1TgAa7?-qLRb|@X6a2S``5u>MKurd71B08RaK0W=JdfL0OYUIKxcD-FwwXBfu((r!?V+4epz=tz} z6ROx)Ho*>_Xz~HDN4Lvtk{!sZEw`=*mW%0WmG}o}yL&OpQ51so&>YF;#_SKSvEKM( zg|--x2YJ{xZ5|nZes?B3?NLZZvAC-*VO<(3^$4&TX-a<$uT*{if`|=1A~sKAoQO3O zM=^DS(-DCvch70GKH>rtfJNsTKSRsYf|F|nqz5|~Xfwh->`iH}^pv)TlxC(6PP-sa zONmUo0Q4~Z*MPP20=vfR^xmrTTp7*CN(oy%*7o%G5?5iC#CZJP;KCVRAcc)ma%F~K zu-In>$s-%s5{;66cztWd>c@ykEy-&iNHywQO^ne({OTb?WR9eR{#+BeB1k39VVn{g zh2}*3?*lFHMHSVwQ~coLL+hREfvO5c@CP7a~gGCY9WgwR^ool zO~(CcSgmHO9IerWW&)xuhemif@bPK7@*JAOd0=>CC_m#t5w@y3Fo#S7K86ARYK2ap z=44{5-+^+-Ksh+na+ow6HQ*4m;-y&0!835UJZOLMfNeORnurlTy5NlhHqj=@!JRJB zSn*$_S7e8BAm@m-8pQcdvShpmX+a+uhuX9uxSYKF9y5^H(;#? z4|T}Oi!g@3Ob1;)o?!?ug~x8NRaRIX-?%4GJOD;4t^R;*Pt%IoFy=!t%PbZY-D7ZCSG@)qupjIe7O z5%m=2dN-9u(ZGF(IQqSDxBIB_y`7GY2UD%wH_3KNI>etJ`q$%Ahp3-KQT7y_ML;R8 zoprruo!YaO1A(cRY{AW*=U@}(N`L@D)S0sO?e06>*&d^Ng?ozIjZ*#rJ)%Rp1N}7t zPe!c;+^zAVLqG1f9@+%y$~!&zf1`8Og_Dcz;G2Sd-i^^EW8f5kX-;DW2e}nmytzZB=@;oP`>4&0Kq zgNujdJ!UDA(y;ET9U#e%i?8mzB<*pCFDjPq#hQkl=0##!Fk#i^olaxc618Om5xSou zOOpQpC#CujfiQ^CN+f+2G1gp+XD5=}Pl%#Cgn6J4-ov5^*O7a)v}pX*zKe*M%`EAJ z+78_dzjy(Rm74K1G&(LRXJidsmtZwgRyTO668)FLjDC)E}f1@qK4 zqJ#~&r!u(5vkBg=qi5{)pcNXKWw%?v$`W?H8Ek(g`koNd#tZwX_hC#dr^q-DN8OG} zMMTa!BoE4vWcg!QgBbT0JBwXoF?$$1a+^c1JtgZiKQ*GaZy!pH03YBvf}SZ_z_kSQ zJDqPF(qoNGWkPj9afOBWGho6(1cKh&YH_sy#yvNpRKnRBYg2KxEy{71)}u6HY*cN3 zQ<3Ki{PbvtG^W#dPwTAD@XiNWt2_-lDKExp`i6}D_k^-G`DZN z@?K79@H6H89K_tivGE|7B>NcJ?z=gpM?J!CSAL(fPI-@CryR}6fgN#rFM0DLhU3}o z%DX&i&fdj6@A9IlQTaXHg`=bVYD6hvc}G^VmHH}pqKn`;^#QefI+qKHS@>}|?B zwQu08Hm4TnwgDZ&MF+VCY*V4jxWEa_2_F@iPHE%X+FwZOea^e(y9<=of>|1 z6)T&9Z_A@T#J49${A_}W>txwmq!xTZ$gVSS7jIvjqJQXTc zw~t2}dEtlHwS$NWrs6QtrTrJ>(Zt-73A@FK9JddeRU`49)I+N^6q_uP#ez`?#WwNrVoz`DW>*_zg$GU?!K^o$d6$w)UW`Yr%P z=k{S$gVep3V=w4vyAZEYh;it>9E|eNDZG8yI~}7qM)F*Yv3iWK8vHt>;5B52$GSm! z2Cd{o-i`2Xf2WA8OzAS~xl-e_V{Lr+z^dZ>zqO@Ytn>n>V4jx)^bU z1|icMZj*3k#c!nziuU$rlpQ?Q8;#mY8ojQ$@9w`84Jjo|x*_liWfPX0o#zbX zhcX+y=tqkVm^xOHt^bcQ`4#%WkR^s&A@ymD_GxREw>YMRHz+f&b_A$SXH*?m>|^-A z>?-0ZII?_$GGhe4=^16_h}RV7m=D1BeO#G#wf1a5gx+wBCEsBBzrLY^-XM_X3C|0# z@?pI^O`uefk204gG&V$%X>3%oI*@`Dzm&q#(#T3M#OuPZvsSg2Q(Co=`&8E7^(jALe7H0Z@=qs+1(|&s*Qv{1Ve&6;K*}ovsr_6RQ12tSfI;1x zI-+BFU0wrHmVBbZoi~iX65fx5Pqdi6q~81iqS#--q|>j8jaF%l*ns zp$2bb(Ibjo7!jzE=71%5su04JWPW!K=l95Pe$%=*MyS*S7$vhhmYHL151Ieb_U0`c zzor$(%uvOO4T^1yoo!Gw!U623pp2V;$(YHw&vmiYO!d! zRY*$?wOOA@?E?nN5505$z?%_POm!}74@sX&b0X9>OT&BEK8&WC94c$0$vMrx{1obH z<_Q1gdh`eM!}Z9m;4n8fDAgmlP5i~#k5VmC9d>xA2CeQ1V3XCJ9TVBDwv8ifH*=zG zXtEzi+jv5KC%x%Iv<-hCP2HP1f~{atjy<7NtL^rc;d<2K?N+zY>{&wjp}fpD|E;an z@$%QGBSEdb5q3rz;D4>bOSN}?@KWtfbtdcXQq4{IUu!2>bN2uB+W%g2-}On z_#rk9n)ZX|65xp^p0^{sFBp%%m^g;m}ZBSwafq>tGNA?&~C<1O4=$u|6YfE}<*A z_*DuAzVP>XV$FM>H-c#_6RS5W$D=66cX^tRXfDS0@H@$KW09NMW6H5wtr(AY4gFXL z?iI!$%`;D`n6k+Oz$!>dc2saBO1Xzex=gMNAM4`vY+SYZ(O}WkqHDaqdAnvC#E{yZ?XWif`+pau<7V#)%+U=NWxA*dFd#?bA!wt!2M~(ni;@vB7 zwBlR*k1V$=-ve&0$V$tqd8@!!ys~cP9x!ybZu)i;?p$5BTEP2u^7Pi^{7vt{>I71u zdl^If;zX?Ylk({mPoNEd4mn{5YF1x`d(LuXbAO8Pbx7Y5O?-@k`m~zD^(*(T!Ym0F zYR^*Z%KuvVgz`><-PF-m3I@OZyxmm4(qKB-_Jr~~ylX$|D~ z|2ux~DtZIPA)I@+L3?rBW6+i9j=^>_IrTrJuQ1~=d9}D+`3-NEu7_;OmtKkZEqjYd zCgrn9CS{O5UpJ+0nc_+7=STeaYga@row+2zUb;K;CwKpN?FRSjka~+nl3)4gAn(V1 zxzF!7@^ys=Ga0LZH|b4kI!xhmME=`5*`dnEeD*G+MNrf7(dH?hpT7N4I!8u+`ovL= zp7?;L^w1NA|L^p4Aw36&(=%Psq&eXu|1K&;R(^k!_UvYqC7<5Kr7ttT4~=soHuvq) zRaDZ}M?65mjSfFny#sAad$C|~#4Hd}p#;Y{4|>ln-|ZF7o?Gt08@KZ{K~2|Kpf$xJ zAwDhvgo+G2j?9;o06&?CU#rFz;Uy;421od++5>nqbO7*sb@^yjd)Fb7$EdA)RkS86 zVUcC#9gvat!S{bL7z|RGu88Yg&()i_?o$>`d^)gG{|G1V7#U8z#^Ui}&R-7$H-mi2 zxpxQrGF{a}J9rLQ)v?gh(J|#W#M2ow{IW?7HGRE93G=XTz@`Ven&(t*QXu6JjhE!& zyJ3;#&Jt%}h~#eG5Ix)LrAU=U93tlsQy5nT3t&V>v_r1QC=mx7qVoXX@k4AGbaJ`6 z;sW0443%8&IT6ne^v#YQ!O`TH9Ny6@uy29+4N; z1h=}b$NE{6_H^ob4YXcrulMt~e*#uF7yjWp3*4?!LQfV}ALgn4KS=bv~`g0nVO0 z_!DTn^c3Gx8eF{40LvNB-YtvohZoEJ&pLUx1`+?B?t`}rEM7{8j<&%5oQUlijK>f3 z>vlCcG>5et`yhU&9?O{a?3(sLif?=OZ6z;idc7xW_YqZEzXVb zL?2yiKhNv1ovp9h=a?80;=dZmwOYTq#`lUdcjA>_a~@%0?wODBmYLh&6`qMm_lRJS z1`hB6SeMuoQxIo$X2ixR><*_yI1hK|1n%9Z-fQ*P7yY4U1P7ng*_Cdp{SJwA8yz3P zev1A+4mvzAI!-4YOcZ*K=>9#3PM8+Gc90dfI$yfAb%w^*wcylD?@tqoaHCyp2a!nWMMPc?{9K7zz=e_qKNzoztSi2 zEB#8p$glD%17c%uE+mvekzegshHzxYQ9^8le#);fOC#nCzrtZ_#g@l*BDR8sEd>8S z(Gdll-Rd_f74z^#&5>=g3AzE}a7xA?>H*N~u)~|w6z2aVg)`JtFL1Ht(6!=ieq|z; zyiRYsK}~**6#o>ZZsEqH^Mn^;9T3aPlF)_`Z(hhr*MQG2K0$_l@if}O#2&rW>voU@k zaH$5_(|Ty~jty!h7GYz7V~ZbBz(b4gIK%LF#kWYmnO@SWwpsoD!kOIie0ZSWWppgh zL;mko^KqZpu{@dHc`V~{dRx@=l0C9@JrE`Pvu5(@Gjl`-a(%a$=byQ4-YM(uWemBmvCMt<}I^c78bGIX0Aq8)RqeHZKv2^=)=-a=NNh zJmShn?sl=t0TxAWfup|J;E7;5L^H$n1Fo58ld( zC)P>gBBbnfq;Miq`U-IVYk@NSU3A(gn70Qa;^(`8@`{QtybH3T1=RNU)Ve26$gev8Dk zI~WfPvLZp;X<^$&V0@b~U^>V;qz)R3_4{vf){`cF7!CD+(*PR-M?SG)N{Ed~Ra--H zv@1j2s4Y^hlcnuatrrbYt(*4GsTN`7WMc|{@=Pu`^etX|Pc)%iNW*?aIR;RQcRKxU zb;81Rc#BJqmP~EWxp>Uw))()mu~ooa!J2r9${4mfoa>NizM!$G=qKNa;7W45S^kr8 zt(Y5q`F(#@pEcTKnfQICd1aX}NPk0qNPo}8e-F&-BuE0BwIpnHTG0Y$fs;<}MzA;4 zVMC=cPBK)ljs@)5XK^eJp z-%oK58sTw3b`Kg;{O$Ha!D{%5jTWqW^}m4sWG@wfZ1PU0d6Dcr7jQ3)!(+9wUju857+mdK zgWB*rxNwPd;oHYum9bpp)g(zzyV#eZ9VLWJC(`Cor=xY0{`coy;tLoYjCcdY0s|1x405-utg~YuYCn<`{2iA z&UVD#MLS%X&`KMXt7=xw61L|>#v*RJ@T}%1bs7W8^1)z*XTEu|^fJZbKASpGi&icG zBS!5|crG)TI`MC3c*MEk;(s6H&l+Hd`EuYnXNu?fYQC9=&UA|Zl{I67ku^M|EEfH( zOqhQwG|d*sY;@)g*}aNcXF``@1$2i+@AkjbJ08B-EPAJZJ5tTJ_#O7>EdK_jU*?)O zCDhcUW_9M?3K@WrKUyFA zao%2!{OKSwdhsTFRmAsfO}&6=^eVuCT5GgtbH25#c0+q!RHL_Rt5`JcU(#`dnvOc> zH%dCV(@5XJxapLF#Yh2u!eV|G(y-W%a|!XPh!u7=@;^1*>6hO+^Dg_Ss8ybg(Zb`f z{scn|WC6<90H5X^Rg_*0d_SM|@r@_uVKFA0pv+$PP?>fcl;l8Xpd|nh+z8iPCG2H4fKGI%-2? z{4VekbDy*!P7&@PPn30v=pE|>&+fj>YHe&*YvVxgX4J-L^i23FH_6DojNHq}{Q;>% z(fIimSxFdYfpKeLh~M?oy#Ar>n%)vy60@OEBP^wWgG+=(p!%7;wO~v-h%X&k5|7W;I2L+je42tyyAs7H?@@!PP7!f32jB(*Q=mR ztTmdm8LmtxW)Kfoni=LG72gIt-ipdrrP?SobLeUJ4C*Alxg7JhO-kw&>yge+&=x4& zGjSCMyV|y#% ziIdV*#Q6BYkaq8}o+jYqb_ihpX8GQmT6%erayKTfc}ryZS>*2v>_0!s20kEq(Prz;VGW zc4#twrxf|b@vk1Xn8l(xvr`)HdMK=iB4^E1raIv`eFjQC!otfh;r>)U9`arW##sO9pp#orT{kM6Ux* zPR0)fl!}>on(jWVS`sP0aPbsIv1I4}G z^%k`(Q6YUok9^C zqxHVzL=2{;Rxk(WmT&QK6Zvqu?-l3~YSp-#7r^wL5=rVMWmC%x&cX_e?i45I-l{Np ztHQa-^N0G%K1r{A8oDoJmjU=Bm(IsdPQHV zweXC%D%F~D8hzfDIzhnJhV6(mpL$ZQr`ta0>9|_GX0Pz2PJI9HZp?#NX^JQ}c{sWGWcpURo^8vWaAoMq;EQ>=S7n5LCEe^}S6vl4lb1VTV%U|} zq?U{y|Md}9UK+|J?GYdx^U{3S^Je*SuhN}PTa}BFpgVIXx5 z18YqD6$N7rS(c#pgxv+6mRPH5)&<|`Tc>(t9cdfq%BKRo2$98 zm^BeQjgS6%5Um=$fREOzdzdSt^VK~Y_U=>n?AW_o-K)Xgo$8(&do_q5#>M9-zo=Hn zoNO9%?owuBeCbGoh6~#ewm{zlt7tn&{c#I^PvUn1ZH(Hq4LTL8hd;}T@6R(Wziauf z_&lVT_t<5;`;u+{(i;|{BSs4GHXOfmR0b?`lb3q!FJ0uztX!a8@#$io@$W%`%_ue`e5f6pA_e(;TQDgf! z!>+Nb9F`Mr3=6__qcHCbMU-v5_>7Bf$c=hgE4A7hFHQUe0oc?O-d5#;0sB*dpeRKOcH#1&s zttzit3*05{hdg3xq_J!r(i@<%LLa@lZHgaWi%M3Q4z&C#_R{m-Mmr`~97v*&Yd;^qFjvCz#u6Ry?bUAJSD*9%%Z6{daQO6_OyPZbfSV*Xn&D|7k56) zqW>XJolI9w%e*xCdfNMkysdz?VXW#_aPMKw2A?9Np$IFtH5{TOT4qJ(B7P#fcz@n+ z6}PRevnq>4&&l@g*<3nyZ*Php< zV64?00($XvTzgx#`?i^@?0AOXh1KM1Nbf4H!%SQet2l5FMH2Awp?$*QtwPFIaI_XZ zg!_{DKpraH<$v_;a_GMK2qOlf)pE&mki5oE3T^ZWrQ?BuZyOpHF_$hoGqv=Quj$#j zW3~Ov?zT1f%u_bD3FEImEd*K|qru8+8JjtoH1&qfeD>3L;LOe7emt-YD?H433aUSqg z;jT&=w+jTIJ|`Ydy~YTep$+Hh&AgNe9%~J}Xh|QI8yfLA5BVg!U<_n1{RGqDzyvS> zP1HgX(S{8H;`S#$solUE5H>V9)(s%0o!2)~+AML6-SNMoELkJ9*;dG)FThtz-UimM zDtq*p3@Z`o@uCN@C$H#^&s3USTvs-q<74A7>lZaDU9bc6a2rh27$d6j|Rxo)CnHfluN35ck|prHairPdm?m{byjso8!_- z>29Z|A$8!>%2dOr46%*;;1=y*w}bfy5yYaezz3JbKSONLfu|}RoITj*?>d6DCEv&O zG*_i`RtmRID+sVjCqr8t$3uAmS7Dy~!FNJ2q?2N<*(IglK~F~af1~7fun8%LGsdx! zE5~J)Oucn#_0e`mAvfk!8=+ozI!eEOd#=!z5+8X!9lG+@)P3{$6htX@6&j_JZMB7` z+WzZ1hnb!*M*a=gb+IeedtX)e&F6JL-fKS9W(Ypx=sX>z^#FY6bHU0$dH&VFXsksK zEaCe#IU})7*IKSDX5(Ci*$Q{_4Bs4OjC&6BME~Xx&g@6;c-q0APW8_8a^vO~{v*t; z+TC>p_n%=FuSR*0EspdsUC_gjzT!ltk=^|V$m{>Ou$6eqi z%02uC4`LHa^bWgE0Unr(P^?1Td6r7N_T+Ohs`;#9YFIyOzIi#%f$^P5K^Zaixm z^@91?SAlM-WL%&!_VOb=rkPcm{wuFGy>NBq$^4CNTO6Ex;IKx{Z)TP%N!!_>U4AE? z+tzZ&Lo+;fXZT@9uneoi4T^ZU;v25H(_yp#+JXDwhyc*YO=NOQM^J+WV zx{=|CY3GUI*F|sTaPz+itD}?+tRweOr4mTzfeMugiNP z-zc7rks>QW>Gh{awVfYp4S4Paq`(Cnww;yK<~6UrvkbFX`bBN0E3Kk^D?RT$A!(sc zw4;sAlCqT)IaxB`l(LZYKXxe7l7;IJ;`$ue@+#1Fx1<``K$?+J3AxO#)}Cw|c@-B5 zIAUKXpS2G^n}Vo~2f9Y0KSK8CDfRzY=JaM|@R=E31V+r5tfblCfr-+8(UE-`Wxwjm z(u~sqN7~o){#Q+t1KV$*8kj7*z^Hz*?T0fzzK81Wv%yPscjXyvWK{}yhtLO~(-_(R zt0oawL9Ic^vJpMQL(beWat27p(z30n$yV!W$;n7Vl=yF#zA`+czW1!5G*L1JzmrlbfZKo!4RMR~! zd*I~CM{hMZ&2a(kdA>C*qf3*%am87s!(Z6MWt*CI-!d{Zx_Kn{@nmzWWAEY2iTcy; zq72hRsn8v^I`n5UC+beST(*E~mA#Mavgh06>lA*1sb$uMNKI?!9@gZL+YDdpp+|_! zHs+k)q;0+z-})X81H=fHc&I znZo76tg&Tat<>VowK0#zo_1ct4A2n?&5cSoM{;i?<|w_xeE2D+#!hpJE=2F|M*Pr$ zSl6J&{?GVLLybY9Sq_H4U&%7{r|<$OI`q$g zi&xuBOrA&DP*Ul~da@CC3J9SnmyYAiNkJ9!gs5palSyTn8_gmF5z-?&Yryd$0I8{R z*cP#{rbvrf@1d5`ku2&ph;+fT*vZ$3)$BXy_8X3l^;f_uIK^>FYHm!%tG3Qq}!E!7h+5IaJ8l; z$h%HSm3R#sVLN0#17v0{!oa|63NrDL$lJiRQ%ypa9G?=da_Q{Cg694TQ+A=1Y| zepMxH;9Xj_D!knz8G__Nr&C7`T8n2nNh0E*UG`4D3v%5ZNCU-sn2RmNF(x^V=0K9= zXx{kmG9di!JEj699WcFY8ta+w(Ygg`ntS8jb}*5F+r9BEMPoFy!_OBwdkr&rpI5YO z4*oM{TKv4iu{rq9vu6Ak*q4i^9(=1ylVLZpZS@lP?%muz@ASm}ENPGH}td_qpbaVWE&9#XiwC3z){e zKs?@KW@B@}Q~t6tw+4t-_R<3}c)+D}J;HFrmrE1STdo?6qK356UQfEz0o@@N{W?K; zvex~Vr_x>eB<6L;=YUIX(ti!iN|$8# zZOmt%DY^STQ}nH$L7(`Y=YWDJx$TifT=Y?3AGFBN3B_1LaXUTkZ|lWHu~BlKJ>Tm8 z_SdZRp3pBNbf^0#ciQ1E$h|?a>A7a{0oF{hLL>Fp<-gjQs_Po{;6oFDmbn3uidieo zI_B_a%A$y&ljEOhD-7;=s1`U*V37~8T{Lcw_E${1+g%jWmx`y}SM;L(`Zw`Ef1`eK zzJDa1O5?Y+u^03GM$?{$c0&TY&pj{5A^z0=VeH-GqpGew@O{oa^PW7wAxy%VB)|lN zOaN_Es*@Q!%mk2tw)KJaB%+>x=pa-_pw|h{2?$JhXaH-2+BUv=nbfqT775j>(Aste zv=!9r*xue^f-vDRb23S0e&2Nl)c$_=j~{#{=e^H9d#}Cr+UxOMx5~d6^e-U3#(sLM z{6zVpa`xPX$n)YIBD?lzOyChk=|YdZ~RAK6j>8yf^Y67>}xJR|2S~eEhgzl4Zrc3eEMmYNX?_Sy?;R{*j{fYw=g^yG);u~_X1n1DwTqtr z2)yGX#dPpB_!1lYjMKEca*@LYm>+G^meN!7e7pFx`IQ#UE^5VJ3~&Y`^s*0{T0&ng z%L4wH`3R33Rb0ol%cjWMy{xQb4$WsAbWCHcElbTYO#y>f`785ZY2a*zaMxY_9K%Ui zsI{~Ex6aOs(y{TxE$&-92NkE*VL5=mOqdkacHC-a9sIt&i|xn^yv|{hY9ydweCznw z#XY#v+GvvqC;d)EyEi*lko{XNBs^sIEUK;V&t6#H&m^0~2|9IFAPqtuum)L`Up%*b zmejROZti+Smb5_o*#qi47V1!2-X0Dpk2vgdU9Y@!j{4tCRztwO(L~bmi||NThsX~u z2mUPw)A4~}l5yUJ_0jg|rUhK^rq%MYFJ-w|e&i#JGg-1d`dDydf189pDXi=TrSAnlH`cv@k?1Jx9LQ!=b|35vwnz2Bp}%d_lO%~nObjE>aJe;<|l_IcxH>a@N8T?3^_KjDyffdR@c?N%NXCOt5{ z_n%D@mrNx7YLc33DAKPYk*G+LJUi(Do24pT>4`p&T~_SleT&NVupZxvp9Q~~@C{L; z)w)D$wKgw6X2zywuB=JA8319 ze$m9r1WA(U-H7IHu5}9!aFcM4)DZn=Qw8o~WfM{II+Wb$k)%)mb)9(rU&L=FHs{)< zCAk$9OSnlte?W`*rE>{i(fok)h$J;HYi{0ylIUIR+W&pX8mZe3iwDrSZroG^pQtl_ zqn)*Dtt9ibc2nzpkW^#_pRpV@QWsz*k19ZK>U{{=d>(C8QQ)pyp@&Y|%P=|*TY$;s zb^_lFbIgoK3fZUdcS@(y?0d@!*}I7MzaHnvPfsuIcNf4fZl8w>X8a7H8B=+pRyYVr z<7D(8aXV<$5YwJrCw5s`><8&a^l>>>U=Pjfl;|qo{<&h``Gxe1d!K@itT+ygozV8j zF6MK{GgJZ0rH9zW&FDu?-mLt*aXaJ+y`)>Ad)$sJT{nRSwP}%z%V}2@xKlE5$nOlz5q?G zaOXu%DYGyqAID#8$D$QP_S!j9=J$KOiobq$b zL|A`xAcw}IV3D}~Maw40M)-!(FMxL#ZKit!NJBTGo>?Odn61i#R11pNyommN7(bFN zXdT}Q{xg;$PmGWwp5%moE+>qq@sMVhm=1)j%fFDS+dSo=;lu^&a>Fo>tO}b}RJ2$h ztOhrI5!}?;bO7A+z(cj*rnS;k_|rTXvdQLN33>x+88>)w1?sU7>*fz5|9r4sG=?Bo zSdA*KuBm6*yiAsdbm9;qG5f^b(1$rdA}g-&VHzi1)u(=vd(u2k?(+4OmxTT0H$fVj zj_q}@3jG2elO*%KgSgBMbacha9v<-?KC>OGppR|9vdtZh$2&)?u*s9AtUVPAb@}wj zvUBxr<0#>E{=(!veD%y@u+qa%=j-DH%DZ~)MO<5gy3IyiKgC=@?dk3D0eM)ESr&H! z{@+7CYItI9q3;gGD*ZZ(^0nO-6Lhy$yA*3<=@IlivQZ(^h@7R~orl;gd(X1DEe+#* z&oI;78{y3>!~}M0wP|4q?nVY6$n+H74#~cUsVKa{f0ToF5^^+2uu9GGQWb;T@4cjBe3x8WQ`oqG>|dmm5O-$YhndaAOQo&yRf?)heq zC+xOZ;t{k;X6!>X>=Kn2YaM$D~m}+qV#5^6;_|wCNFTx^G2f~(w{p` zOU1K^Yg2B}_&rMI%uP6RepL142HqiG!-Zj2s}g#Vo=0X?G}qGIF6Gdm1bu<7YNF~} zVT{C(fl+r-TLY~@4KhE}=&F!08X3U#;Wwvhkp&!CMv*^-ozP=WSEGy8+k1xMfu!kM zy;G|+!FFZTl*-UUOAYcC^O%(l@~u-!k2K&6t7wqgWJfjm+h6UWSqjPIghO?(7xss} z$iIs%VNwxh&>Mrcyj1+3$Wl?QA_}*Uuqx!AQu9@uO+1P*KO1PT)uQIrvxzR`4@kxT z1{5e{qD=h9uy*eT(P;e6$-_#OfV{yj$|bzF6j4950Vj8ApL0q?5|1Jl)M2_Fs5&LK zv7gR#v)#y@RKW$O&*k@w5t8vYhdY5oTMf%pN#)tZheNb~Ht|G~t1?EXpgnaJ)Sj8M zCy`$u6@Ly$6xqm_@hrR=9l&X#KIUu_zz?Wrrvd>z75{PC4|Lsld zrc&UezWbA#hdlV=M51(f0_IwSaK>xIS9?V2?-`?qf%L&RX`Qt8;foVY(kchud`~*l zD-Ot6T3}!4R=^Kybs@VKzY?4yx$BL=nmkSWSdkB|@afyVk7|(tY_`eXQXt+Y8`_`s zP(HA!Wx62ZHx825jfVN5Pm9OjNv?x6a}e1evV&)~92(qEumGM_SwRc3)RzQ}&uJs_ zTAUe&d~rd(gZhZY-uL^<9}RbU{E!PA$VTzqR{A@m^}Amfzea@{T>6~5EqnSAlak|Q zWdgu}-)0kIr^zFq z>p85)r$sJ#`R57M3~Ei3V#S@;rMW6Iw1UV$>pwK;C@B5p&|qi5HQ_^peFY`>d$6Do zf5W(b*iYPmdsp}}_xiqI>Lf`YKu7fbNqK|cU5IG?x)m|HQ@ z-*x|24a-^Qa=FDDem+hT9h62@l-d}ry66_ui9ul9MZ z&<+?cxIei&4*c=>S%v)I(#SrxN2xd2v0`9}-;dB4T7jppGl#Xv zWT{1F;4V;mVMK!*)K!>0X2-Nzdj8&_y50lbG<*MPWU!mo8w_X;rXGD%faZwuA{pSZ z@E)-2yd&iKtV9;i6V$90=OQF8&{_@rq8_n5GFbs=?oGv=ql-KTZ-iD4I_3=jPQ@3G z5?z&y&Y!zW`M}DmHi#9!dd%aNxk=l_h0emS?eE9CkxTRPt1jHNa9ijFg?aDlXF4w2 z3k@ip!_~xL*Lv*Tw|JIoK4x<^<-ft9!4F103>hYI6R%>PZ&OO7J{9*|2i)^*%2-y0 zxPfiTHI2`>wkczn4lAycBdq3sBdU(H)%LC2>;Hi--UY8`mgpO1hbJ_cdK}Y>s%Hv7t$bN^&MFY5+tm`48D;KzE$g?$2YN^8un_Ye~rbZdM;c;;L3 z$k!-+E%I1bYP{MhK&r!bKhV7Gupw|pW0F_y@Bf$;oX|G}vFhJ|H3zfJ2=9X)<6THR zOlXv9qLj-_iJuyQy`bGH_u^V3yszCpldb%8Eb$+scZ*rR+K@-g3cLyW^RGUicx>2; ztfD4cKCVwl6RI_QdN5|jr3sCb_Ae(+3|Zx4OIa0VV7psvv*daoc55Y@Y`WBU|4m`4 z)l6x|i8^S1>ZAwUdiepglG1BOexXk=@+7y;$4xby%1AiGrE@9=61l1Gh3bH?b1rFb zd4Dys2E-eYSz&qkCFFZyiNC-D`;ffCS07J5?yww^$cu;v#~(u8BIH)F_@sI2nri~` zJEX0##FJ@WbR#CmjW@%SU+Z1~2lAj~Z zv>}=$SBH>aj;ojGT)m{uTrxX3Po&oogT}*>MYcA?@kScWyOc^~s;n~M4$MF6@R#-qASFR#q#jjLCMMW$)*%Os z{qSx-MS@l^I>NKqR^cphHv{Umd-QWy>T3^a}}jyk+=~Vh(KzEH^*sPsNW6#W3HIuSjOTGl)S}hFEhp@cS!o_&GET2V_Y$ zpe!Keh%k6IyZTeYf?(?>Dwjxka?g+(bHS4C`^G9jMLAEpK$wnRujAHb_$7 z=h9TOL!`I+hloxnbHirzY#wxQuwyy8)Ed$^H1}Q)A8oFRo`zo#_Lo>*R?AYHQu3vf zO3lsn{@%e`3T~OLX&(34ud?3A${)^;zdrEn*q=BT^glaxQ`5{N_m0o89FU$%9%IZE?w<4?1W7rPfij;c=k=1D-@ogNm@g45Jq*rVJljzi=RD;$URepZoW zBWzbtaUkOa(db6RBG>|Kyv^U$CYZZgS;ybIIqMxLZBObUk8KU|X_OxY=C&Qu&XdS$ zsO(_YMm0wwa?;_bPYhxl1kr!7o_psNAW!BYpxeBEg+9NpT(8=cnp7#|MdY97-Y%5k zdH*)_LDA*14tpL;nb_7{R83asYk`VzG4h=lZ^(`8Q7LV#G)3ld*UzLEXyJ;B+0@Hems6C+&!N$Y z_3W6}EHmp^afbXW&{A1=VqhEmdA@^KCl8QAj>89TBTz~hywy|j0%bk4#2Bd-U!fEBAx%7Jka(3&^)Gba~U$ykz*K zNIn4FT3a_S(V4{QtTHYNPugzOf6h)1zdGCNT;1SZw|a|r%Zk3$$6%4A{~Pd)vk_CB z`)5@qLvBXkOsE=((fA8ky;H{Oms9H+OrU{9;q|HtDQee}cXjdj;)&fG5O?w(Xr-`N9VnZ=WlNj-JWkPcoqi z8Nut_?LHU0RQEcypGAD@+M3MmPX6SVIsA#SQT#p0Dw@P>Z);oD_|{e~0Mt|eRu2P3 zRftzI&9@RzRwFk`Mn{jl{r~}!xooXf}Xj%|Gb`A6sS{t=w-{ruHZQcHHufxCa zMzU1I=Ok~CmyAC@?&WUiGJo_YT2Vi!g+sn2bR+2?a>*dVwyn+S>^%2C~arpu;6C)M)(W)B~PBwCx;U zH2x2*C84Rnz8Q%CXQpYI1bRrt4%685ZzyMeY-x-TebP9g`3ofpReWR(W!axiq-Cy!>+HX1P=>6L2P=mTPhiO%gk*FuXI z09T=Tl`Pcs)zztHm76qSv=)8b6!4&~O@4j&fZVRuv7-uIHz3FPXOVo1l zl;a&_vqK+K$yKBAGe8=l^(oOqMuMA(!JqnV0Cel+ z2Mf5+aBR?H`Jh{J`Abc8exvpXVL^U({-f~xmnA0HVTBxx{}K}68GlQ_ILPy!@)my~ zYFg;WOk^63ca45mTvGl&-B)SACLe>94ebfLt?g@B;7Mo%X=SSn4Mkhnc-4H@N zzpxcj|BK*k|B#r~y5T^RE^6^0hdT7Ki!9mFXxyiM-&l{CXhdx>V}P*Hfbbngo}zN2 zzgWfrnbTD4pBT+5}`AQ$j_Rj79nPYMT~3@ zov=%(yfiUCeZ5HEv+BzCELXpW!B^!>JT%OJ0?B&JOAB#y3?7&4Ff^$>g<^mFLNar$ zW9zu3{qb??HK1h1KlLW!&!{+Azhgo@jTMLpJ72C6K;H18ZK&L1sZ3+hR^mI zBiTOaBs3M!OPHpYy0X1Aj;npO-qAP@{FoTDg_FltH)FrhEpzg&C+TXz!X^N!;Nbd!FbH4%MiR*F4 zXgo4p1C8BK;)g?al=w2VFC^<9yqDI`Sy$e=2T{i42c!>^M;litK=QqAgyG%h9^;jJ z)?c~Dpx%Rb;;w}1p+I*TuH5BC{jZiWn79T#Vm|x<<^ihz7<>V8w*=W_<#p> zHGtNEl?%j;m1y~-_QJzh$4&6vgnDhH$B3_{S*%>X2mI~5i+$X}e%^q#u7XFXiQBVZe(z#E_f_Hmc-{!!VifOQ z`c>j)l?r`5u)(2Sbt+}Nld|r51y-*vVuj@`!CAfVfKX?d zo}>kqPrdc4_!^8P@8MKW8N6u-O@U@cLK~;7Jn%~NYL3BIQCealYlKaPzanC-I9$nw z=f&mtA5u(6ss3#E5@t)U{}LgJn@69kEDo~+^m^iB*CH%T0nca*ev)M{HHOKx=^ zJk!^>1l;z)iv`x^i`UdI6<@@eqsP{rIm$|AaP7PBUX7aV{z78waIU8lJavO93skeQ zP!^4~=|mse(*S!EbPDsXbNW6Z*v49&o_s`iprR z`K{c~2K-}|j4K;Aew=BB1)5+X@8|gwPRx$6RTk-aCa$+~r1laheK!kn6gTNT-a@czX{Y1KpZ>=v%kVy+aWk^Fr(40qZZ` z;?@kb7QbUQ0tcaUPNq&y)QNPXWoVzeJcF3KGq0UmbVo06--53M&IHa`0VT9GIs-=z@g@AFJ=(UP;Ts?8=Z)*J?GHS5$+e=s z-^dj@zVwgAcMk3H9D+pkF3Y`ZW+<;CcW(ozxpNM)RjL%Zdg#l55tR6)pX!63X^Ew| z+hZ|J@pRXEL!V3tRbw7rTVLHY8h>PHK`5uA4y9zi4`>b0>&+O+SN*;E#K3s??&C*o zR5!l|GcV1>0q2r1zB7A4jOEam*AHn#Tr)yTXnVIiLo3tFhJnB}Bt4~v&EP8E8S){Q za35&XDQ51t)_j+!83+_3M{1f~SB>n~xSl1c?OYKd+{)~*aX^QdWB)ag5dF;tFKc%h zqF2v8)k|jzUF&c6Nx`vPH`?AU;B{M(K~Ms(}Nejm0Z2V%wrHP{hrrm^v-SNIC5IY=8TeEa7)%HQt} zh=(vPHeZo7-d27T&<+GjHmGA#XfegsE-*yAav!{Bh_C({EAUvWf;dLs%#39$4#e#Qc)bM73C{jDhB0xw=Nxd@<{g{SQT_Y3 zKIto%M&J4*)Y%S5R?z$Xn`AXd{o2j=T9PnGVj4euwe~cZbZ$Pd!@kAnIAJXF5!o! z0~%d;5v6NcO#7Az>vtAoZ>4*-%K0rPO1p>Smw)8?!T9+y_Ab5LP1(h8?<`mmaz9fr zlTEoj#^?VDdo>@Xr*h$+IfawQFG(w8Q%8Tg`~S#hI7ItSBt+U~P)+xZHd!7P<4{NFVNKbg~VJF5za$Zvjm`;){$Y37?K zinC#RBwQDwDrY$$CJzj3;C$xwvQs=hP8M@(JLddkh+|XX(Yw6cZ_GQ%?>ksZxJnL4 zh9ogqn6_gqXqIQ%;1Y|b=HpMcDTR&NE}}~Pvz8+T$J)*mFe7pG&BWITZL8n~L;^#W zDipoX==Mw(Hy{GSY)5Y2Dq5{{rSpJ2>>j_tIrbFy>drH{CT*7=e`VDlYi}C$5hy~( zeS}Tv|B&|X!rnhWLgt9}Or1<<3xR37CWrEm<-e~vwwXLDs0OX50gz~dLo7H)?p#fE z8B9EqHUzUQ#`YUa4P7H~_ekez)P@;4G(lsB_VV^8t{3TBFkX$?V9|$#@Q;JMymJlm z%xEwFLCrIBA+d2Z+H04!m-|+cpI;#|u4V4}CGOGxM7?kojv{5eOMS_do=rgqL}PDAXe3+KT>>6KN%_sZUmmvv!SsR*Oq-ZcAJ|HdR{tT9P_MJEZIGncm>`Y0r&>hihbi( z0JE9_(}1jY`cu@RZ1SI!JN@Pz3_ zX4e3xvHJ4VFQV3K91*;NtrVr0qjnjz20c(Q+AnRVQhPds`0^a}?r)yC;pyK@ITA7$rUd3*(1;lr#?< zYf;a?kus=n{^rbLtieX&kBpGlcAxkue29@RSo|tcmwuDJ9kj0xhk>tay~I}ZVXKK2 z5~|UPLdl4Xd_8H?;i?8s6a zt5>)FMm}>a36dbU=IT%2nq81MP)j;dk33;m;i&EZ=V7uyS_NLi;+M!X*@YSat<2^gLAm;CisDbLz7JUDo~+k zb9HYF=Hw!7O#_qxJ!XY`onm>-qU230l|ID`xDS7I!fE`?67G>i#j<}gbY1yC)YJ@G zG!*Ucgl?k3`;SPgNO5!a*wgHWuv@IhEaKX6IV zTxe@)f+S{ZI;2#vP5dvLI7Jv1_5te^0A&n4jW>Xk)p6!RQoQ=el zWUKgBw7nkmcr@2=Qo!hY564+nJIelk%0_FAnSB@ilNW%db1N*B!X+(qtw0roRKa&~ zK?l~^(WLn;;0RKtQTb@jbyN!Op%N~`|BW(J)}|_fr6d7uFbl{c+Q=;AXt2qST=NOS zAEeUAdl@tvr4sVKRl)JQvRz?i%DE*iVJcn@yVn^s93~`_6d3U5wv{*lDsPNLT#f z4*2q`={tABmleKmBjZ4^=Mx{N?LZtp7k?{xE`D@`o1}|U7M$6p(Zowb+~nouCnDT+ znutJNpz)1Qpj5xd;UDPZW%$+ebhVl#8XH7gfd^tAWEcrgM(0I>1Viqj0Ll;ZH zw8VV*<3m^n!AJ4nI1^jk*y``V_85L7tGqEdGf%%$*RBm-jQP+(NBc>6 zHGlfd(senLPn=oG<7*7isvo^Lt}u%$j~q3QKe?YYbcm@pR*#A7hy0zvS1LJ@GpOZq zfc%vO+1q%cKhc^#CbG~W@yt?cJr-Ud{#K-Q(R4)4*#ugz7&Yw<(msxJjf>q{e)ttcHu|C$p$w@*d?j zL~x9$>B2gR%hH{u7{oC(FCWnexxtc}BDxdWq-T{2h2$$nSfiXXFIO*(`VQnWg$@ebxd|b5a}P@ILM2|MckgwJm1Z0WtTaP2^tT z5yN>RbyzXl5lJl|+RJ(#e$6zlRw;(yEum+Xvz!n@+at)$5xd~eL#!=lbzn3;jWJXW zpPF;naC|whJEVG4b@p;l9fo) zt%JSo1Nd+q>vae)P>9+NL{x(_=9(V9s4t|o8?E9l#*Ys(+YjB49wtME4n{0HgcmMTLOM@we+udAZ7v-`8Eye(R(UiGu&PmIL1hGoboy^bp zcy$=W^t9se#dvqJ)t3XT(LCfaBAYDnC1|W#$eIA(ChJmg^fl{sHvDJ=*+d?tvLMmh&ij20ZSG$uHz~&kCm4%-Cd|(q&=`z^+g*juufpdO z#!+VbGU7lTrYUKgF8B}B!J9N7KJt8`aAeiIRr9C3NEnGfL0@P3b{V3_fV+$6E-ll+ z>swR~ZST9dj?=a;Rq-QMMEY_XPWXKG(51wdq!v+ow?urt&farCU!U7(3zF@&uB8`L&4;s93BlKdHi)hhPb=ESnzE^7@ZnP9 zOwhASS#B=MBHWb<@m{poKT^>xZr+J|L3y>k zndk1oQ*R>&?a)&Ag4GW-BZi9$R2Se*ilhO5x#VveYOV+iK(v`~LRm_BAf>r9sx0k8 zRQ^MSK}&?a|7`sb)pjgJ$(Fp>pA!=J%?3zuC4Tw za+~?I*2tYfqApTP?=diA?-n!5ZP3d~nfmLrcy0li?dfi|t8%<;*{}zwT zT!#jA1w@Y*5)((Mhw|YgM_=x+Wr4dI;G=Oiv44mYIiS7_Brc4wj<4d~=^QuJ@0)ps zX!h)g7U-#Gfe%5{_7&{0geZWq0@_&uzDT@~d>Ow74CA}njq(rXV+1)I7FrV|w1| zLJSW1$Z(R>0&IT2fR*CWQHHV8H3C~@{ElII8@=m9#B@D;*h3s>{kh>>%;fLGqf^567=KhDe(+KdA$YmO9IO;{<}~1G4a$*X4Xxnth?K$Q<@#{A6CfrcV^QTgufzne|d zUvxFhpXy^(mB@f$0ZJ5CnG@PsZmObam70k=yX#BahcCk~Ak8`ZIp8%@Zdvk)Rw-B+u><6qQS4ye)u^Ly!@~p&*%I(bOlyqgCE{vJKeXG>DATtGsvYA zbn7G=;jgSvaaAsCLu|?-OW3>-vD^odVRjDNgS`+eEbKGx?f;Z0LsuO#GQIwgRXiir zVFl=f=f}l(S(1DYW~nyuQtJp-bD$B-*pinCl0UlcdaQ4WM+x2^!RJd@f1p7q14=8G zBew-KQvUQ-e<5sGkYH5whUM^*LQFq%BMw4FBp5P8s@M;+po{t?=Asn%$uXZGT@e28Bx_(A_Zap-sjCEvwr^-fwRX$ADe487<%CPBn8rWDb`+y|Y5~;+Ans z%Ci+-(hqWaC8F~#fV3_^8_9ymeG$tZJ#fXBPTK*^2IOEv3j9634F05di8^T?dK-C$ zB^`KUX;QDs1Pa=ac*Y(#Rz{H5Z-QiC4($Nl!L$0*b{yGybMY6R{?I|Vk&V4itP1-5 zm++hx&l&L>!Tt!gvyroACNLEq0{`j5Ino<^t}Nb(m<|74aBR{uG24$IMIws~))wB# zZ1LIKJKG#F=6FxJ)6glur`%-_w!WvB^-{}wilF~1&b|RY^jDm3K^!dKH5@NYZkdm9 zh#c11E;DHD#T5Tawyf>qr8XdcaFY>Z2Dy!8!%oskSXW&rHpPVqYO&DkXmHLoNvQXvQYoD{n0j#jL-VSA*0h}xhPj%d8Gx1djJ2GW%*WFW6WT{NnGCU;zZ3>cyEY6U(NoWdivQRK!;Dfhn~9 z_Nz1h=Ze(6(7kX0s8~R5qrRKv2~(DxzP%w6?>8S?qBz1rvisi0T9SjO&_n6^1)Nyt zv#GK>A3hlHTMqh3&-tAZ+nVYCkOd~zfsQSZ#8|;?G5>8wWaX-06xr!ta8tzFGFz&W zs8?nw8-S-rPyYAF49}#wMqjDSBjeK^sdoMZd5Uk1e5a){meyEY)8?*~EI6*b^t8*> zudQ4op~m(JHq9WX0cx|IB&fdbMsbnF=nZ${JC`!PuXENo3HSfJh%4i7SB>!oZ5T#yJ%D7)NI7~C*Dkaf%psY>r0J( zKheS&?B`s4YgEpztMOmh z;g2Q0RJ1|(k|n}Pw0_p>4P3C`!oeDTU;~6{6VJEfZ2kixhD9L_xaoaP3~os+})KGXEvKj?t@`*(34@)o=W?L@Z|d9h#Mf4X!0TlIgIe+~Ij z8)lP#ZJslrG4RpMeJ|W*JkoyK^G9AlhM>cE=1phSk?&e&TG)QP+j-g%biEV#CGI(J zTiyx6^D-VGTVh^>G$7lY{E-b#MBh(@u2Xy-wG5tN`oD@7!~nL&K_m0yTrBZ~@`~rJ zL2W@^_$}3YXYQjUfsc)7_xVeW4|Tx%-u+NPl#c$eJn&!;$HyKtM47;>0b2168hNs& z=~Qk{ln(5`j6N1zo!Ok>SmHKXYvO&uGZMS^7dMHtj^B>2+32)|)ocz^t8mwJ1^4i| zf4EI#lct)*0Z#t{?%CtaK9zZ51HEk~{e2GQK;I@VPGw-9LUmafOa63 z$Ws=Ij?z`0hUG@JzU~J(c%rjOl;w-4EZC#@&sn|)ICy?&md*QnBQMXDOC_hg6@S;s zf5hKDIjhAe1<6VT&8sC(7c>C>p({n}bylUFbW*%;zCJkn`Z0>7fV0ht#JayqY***z z8^Tznnsn9EPwVy}j=*88=aE$x>qvnYxYyE&qbc9k8-WnO!PY3J%`fqw9}VMP+jWL% z+R&5!+j60$p!>7oo0tu4drp$S@KxexquO!CXpOZMk_M9qk(o-^mwv*Mb=_N^=sS|} zrqmj&y_c8`2ep)I7waQoJ>gJh{?V5hRBC6_w81-|V?WkPde7e^H^(rSuQJvBS2x8} zf7!iEyo!SP9~@&L%DdLmUoGg@*EBj!UuTYcr~59; zJm6>^!)*L9B&^o#VIZ^Te1pu+eGkvJi13t~=f^KAsfn#~eHO_|>SG&RFL$$=-$kg^ zZ1tO6N4nXx|Abx+=)36*b&=lSUFg3^Kd=t@BXZXz<4CNQ``E>7wy}Gb+i1^tx1Ues zra868{xbTZQZ*g^1lP_E+xm6c6Z?(%D1RR4X6~<&>tlW0f{JB(E$ninsh*JB5-SP+ z&4m^iG~I|Obu~r`vTfEW#ne0xdhvkE-+haN*^c9QK*c_tklY?CrqTcJPZ<98ttZC1 znC*S_iCwPWNA~m^*~?1qq8H|G>ehu(!=l2FA3jA>(+vIiF z!!WnkQTpX0T}uKOeP@=at6%5>&1et8^ekasVMCDGCAEOChKL8KcJTS+rbx z5k^une%mM)+)G|G=p(xG0HV|HPvRWKZ$U)CT1<#|lmRGP0`|8QK39OkRUx1k9*bVRSV zG`J_%F*l;viZt-iI9~efTupyF*0nQg?==@9yU;ABW}vtjKI1b$owawn-W(`=%=p;k7e9(yiq3T_I4!oQ>T*$&Hsy-$gb*6`hqI*l7G1JvJw)yWHif z@7L>r(uf`p!YeK)neo>wHDZ?Bt}(hA5sPT!IoCV*s#9oHe*XvfiauwowMU`2;$wKVpSIwDU*gJthpk z)D9X;B$w%G#+}{{z7YyB^o$>}nW@N#{2W9ncK9yP8-;qJ&i@{@!K!@S2$gOdCfVp4 z-ZE1E;{|o#_Vv)@-acx$T=@7-%q=-0FBXk|t)6uA-OvS2KZPq#>O}G>%7r|bjHie9 z+|Et*Lu0NLzOU3wE0WpH#}Tu~?Ib;KMyIb2Kd;UM8;-#C2)|K>CChf^6Y^0Y>*`kt zGi;L%)a;Al5_QC!hHY`A^?Tp@-bXWL%(y7nVm-vU);911Yz#b)wYk@~z!Lvw!cne2 z>S&ZXHG1ifE)y&p;~bpCBljcdlQ%n#;;-NX?cms?9-DBiv#E4b6qL=5p!5n+58+x| zGR^v*ZhZ~C3pB2den(P!>42-PyWGL5Go#-ony{jHN{Oj6OTI`MEUu2v?h(JJS2IxF zv0x!EzVkx*sk%>$Q;DKm| zyEA8CQ_d%-v(90H&o7$`+K#=~EvTi((3h*y6zg;?xb8+*3|_myaSmHT6OwH)_z#UV zqBUUPA)%|cFRj~K;FRQ% zT#6NNIcSQb_5)k*bQ-zPQ}n;7wh8qoPwS{Hl+iI+y1 zY6+hP-R;@L)=}$I+vabZyS?E+h^yw%(v{IAzVY{Qz?ydy+C+!B@V=l@-N;oSW5{5& zYoDXgWx^dr_kH^wvSjd=v$5)|Htlmvakabr*rW9WjWBwveC4f0>RTI;Z=Al^pR5+M zIYj*zJ>qFIHwPM8UkvP7TKF8mBh{$cQvgkK*#^Cq_OJ9jrMx9E1h+Wk?E?FjG% z`S#l@TA@?gISU>;-@%V^p4h?@;eS~X+69ebQCXXrkB)2cAQwosuLAk0UdGzzzO9<@ zJzG79C*Ibbj3*Jf-z-1S)>ev`%g66=wL51WSyVb^wq{QQ~{5NRpy^y@GH%UE`Ibyc*B0WG<)s47yFjH2p*)VU|}BF z09L|(DEw>ap0VCrj2~%pTVN}?TC&^qI55P{CKitbGd%%cbIL93@9kW(<#qu+5gE+X zU!|$NZ6V5inmO|-;-iUX*hH)Rvz6mQ*9hkm4XKHe(8h=lx7rWa;az7F(?*{9R>@P@ z!BFR#PIzEc05=AfC=yZsW#J4%49aNYcC5-bC{tOT>VApJ=bVf6 zu{KaMHO#{vW3*ipE&^UwQKYrOC}t@8Uh~uLB1H5-n~rfAbQpmogc0YohAXf#F&%!& zof%jA%}+LPKHT~Lx-T!BA7xuJ_mD<_v+g&yI#34VoLt0=s8S8S(}a4x4t-z@Bdgta z!ly&rH`ebW*WX-xuTgh$##8qK|MLF+g@t2JzTR8w%Xl|cM2b8%!6mbnSC?>S1 z4qj7aIk|4wx)xsJXp>Bf>?~inxZzs}OMmG$PRmG2Z1VEnv+;AIjfA8Xe9_GXJLmGd zrM16BezVK*hLMyS->60D+2Zr_BXUP&R=%lPGtAvF^T;k`t)HxIo%1tqS#BoZ5w7~C zFhxm`M~F7kg=wZ`r;X`YJy*DDtiKzHru-eo~${HK+?P^SQ z@ZKftB?taKn<|Xftp!Rlcw+|VkdFvk9YAxuu9qSqG3qMeX$ss)WhHn!@)kXeF?au! zu}5Pt)-zUo-}mJFb-rA9yunX)px!ioZoJ zAbLKQV!z_oKJRJnWfkjI8WGF5>1&$agVE#-#ST|&U4%%p|L^s#H6|bu^(Rbe^rxzs z9spi%hTg&F(MOAuNp-rEKS!PZdIl@I3NblXzmk-K_}!x*|j6;AhK*^t=XiP6Vot!wbQ;1@SRR?gM``PqqRqr7o(63b zeUt5%^_)$-H z5eRAEPyOjCpgybiM(*WmSRPeW%RItQgT=vVLJm7*D%8Q}iwpD7e6({0h17(RHjro^ zVxUAVgC!3!I;O+amrq=I>pgfYtTkcED&l~5-U9qgh*wM}o=1tf(CG10XME9pSDv_C zeS&m-8uck$#~s8cAve{}nePXV3*kusWd^uvL-A)*wQW0``fxQ+OQ++w8}THuR%Y#9 zQ!7pBrL$Ey`-_w{8d`Z1dMogCZ&}e#vkPa=qj~>YW)6agfH zYY@#c7=M1KJ~R7O(Y)$*jq&6z)?POzlCCL6#=x_QkCjZ{=Am!fF)AIsU2E*2Y3Sn` zlMVB78oHC%;nwZeOR=WO;OR)c4e0#EYHA$Dvo!EGtHA+4We! z!Y{|wJviHa8TXn1Zzk{;flCAvNpp_dL0^7!?fb14QF+5@~-KehWNYMQ&}q zB4B^#T(kFX?>&-tP6Iq6*aX5*3MwAq4o2hMDHkm}VJ`Ohk^O*<*PrQCY^>oUCl5h=)-p7vCk?Xa2fpLeQge5Oce8}cV0{w*h>B)&Il z>y?)ie(lBh-qGTyf{fFqsJxu4{1@ZF(ayH_l*M|oc`VV>zNGHU`rYI&I0=Zbk?0!8 zg%vrlte+c615rzFiLR;kO&9sfMEoH|kh?-Z_2>lSlRKIWf?Hxjr5uo&e4w|=}37%Jc#JxuihNhcmm7eeD~ z9HBA23jO-#5t0|~nfHLaOSyruiZ=$`dE7*jHow3sFw+hP&}-I4;)_{9%u+#S&e)BH0$?LE!Y*5>#7>E>mKuymQy;of; zPKxfr(GP*+KxfutpN<1g%cr~0>JH0#{JjgU={EKGaMclT>OX~lS(SOoWavt~X!CE% zTdy?W`uNWp7_CBTm$jLV@FmR_35Br%TJ7TzPOyr&i@~P`p1li!3ANK=2EA@hr4yAv zwo2g!pS{!lXM>WFOXc`EJ714kHHtu64?EP0dF)*4BoIm=yyVb8lK87W^Q5~X{(}~YU z@x9BNQ6bYi*cS>Gq-eOSom;%Dl)d0x{ar+|G^5pk5~pe4#9QM6%HlH@Pc zHY~<_^ie=Jq_*Hoqo%`pcnoubgb^E+p1?c$aL&^6L_>+J5oOU(t(A5M zc0RQM(jU{VTcL}L0}}FZeBUrQE)btBhqHk2^ebJ9KQZUKUTXEaQ-n8y^_o=3s^kF@6v(WrRBmUza$}ti5*!kyb|AWPy$}8r0uXb z={mek`i_H5hK?PcSQ8f|x@CgB`LD|CJfpPL^H;@zt*y-X%22#+7^u$hl_D!I&UU%@9#$l7Inm4X(QA;%@M=y8+$132W{WC6c(vMOXJG;8j$18C_oj>N*KwrY3Lm z`_xQ_<#+Gi^ZVm>&i9<}IX&mpJk`}z)zzP_dg`gCs-9|Zdgy9k(hvvUsHbMMtjD9A zNYK!G16CoH6dF~T5C>&1O6{VO2^3gWO4#^ zoAJK2F21c~;aPVrS|CYjaC%ujTCpp19o8kg1+3-MUBVoY z-4TgFte1m-`6n@|AM`9?vI=dlc9Uum^VuvnXmhMa;c}204CDNbya!3EXG!#a%sHJv z*BOE7mm@44hpQM|9f(Lgux*L?Q@-t5aKb3x4$D5(nESP*Mt0xcI&5iWyKtWibGC|f zQ|`bgWQHHMYDpW1^fwQ)FZ%&yeM~jpeJ9*xXV-(3t@${m)Mbi0|EAmH#_8pev&*@i zajl#+f2*?OBG=fd8m4E&R1mpW6V4HzE#iz$B={Wd)&nRHrl}Rud{O2 zo|ueP7AyG4SOLMTD0A(qp9c;l^j*KKfP{YS-fqQJgCt8c7qWA|TJ>cyTs4zoFDExUJc)Be-K zMz%57nLnYx&~2Xlg5}%}T_KM>&idS|pX61IX)HNOL2IwZF22D)KE`x7|EmlZl3JgH zWX;b?fc$rlER z-B_{wHnZZPEU0=IE5CG}J#@b3Nt&y0%}>J8;MKsaaIMs`w`}o=Q?*hDoliL13TeFL zsO6fk1=bDwz4KdzhO)&MPhsaCb{~AM>+JSRKsXmwf#; zF|CFsfx~-Rbvc;3AZb01m+V>g9JLB{OIOhxaqf=X`*dFy8Pf5euX|z5GX>_0p5hLA znC@sWv;{&iB^(#D#n zso%@ESEuen%g?Bx6DMzDMO;kx$sMm0o~(M`V)D_aMIjpFeamll%qjd$)uw_uB4!?g z=cfGJQU}Y7SW`UOw8PX+tkx>sEYqp`s|>T^d#pS5FE(`xt)lc<;6S)(2al1$Jib3YpT%|zO`pt5T#$3)y+RD-_z&L5k(po~=&RQ8h&#%;D^$O14_#@UKzy>hqWVzyLYW)2Tm0tEqimTW6ce50CW8S;> zCnsRFHa4BJ*`cu+553Z%L3bTAFdk(GXJa9(w049y4k~r&&E7Wbg7h(Ma!wMLcMlr%T9xJ{qi8yt%G0kZ>5P!}PIaM^fc-5LP&SO7} zx_p{jV&QyYoRRI3n%zwIq@JP^ulL!pt~av(>0n>*UkAw?ePba;t5S^XlH4|jR(Z9BLbSPwcQt{XdW zS6p6Ov*Wf_c31CXV^^#LN7!rN;i*VtLK+j&L^Vc6?5rY@(eP-nH0*|ckl1LjU{6q3PJub&sTj{<~ttz5WDtdF4pGd${JS0i3Ub{qVheV6z4*Ca(sT zV9xGppdK?zy+0AbH9hQ9b*%MaU+7OEcipe4scAuLUV{jp8U5C}zp!u3zB&6^o{;@< zMwf)#k28H*Q^CY;R+?CR&qa;w&Zdy!Vf5AzXKV4WoY~cjA-@Ol6r<1nl;Uwe)#Aao z^%!s}!f$9>H9#YA;A`kv|Pmye08EGekwXIRg% zQ)8dTsj=alDc$?PbGmd-x%RGM{q#Mpv6vr?!7AJ?d@T{HaAETrGzOG?JzeCQ=enR* zcymLY>zv7s6JI<(@$h6|STU`^xs=$yOax?)WF6_qn74(*!e$_2OHUzQ%3vj9;{K0XukIs+Ogt8I8ZCG zH6CN@JKj2O9yDUz1)J}gL_N~Nod+q8Q4`^ma84E|lj(ZRl4O61FBM!sBv`sK1* zdw-~_Oxb&&;Ls`dtqh#*BlfKfk#E!p%hUS`&N6-4MZL94!Qf#@?N25xb!C)Zc}b`5 zE7I!*hBuEdO6=a7VZmOq??Kb=r=7;5TD= zvA&G8Nyc}@pJFcO4Xh=DpYdQ1^j}Ri-v&oUVkF-aBs&Q^?CNzktdI)?S_iYzp3FZo zdGXh=##!lX<(TDE1LnFJf6_q`$8HK@kvtZ**GyT0ULx5U*&hcR=N9KPqyDb2S%I<>L%&URIQF))CFGW`g{_t1W;9})xGQ+dfpATycnDe_5oF1{C&>XSpk%YMe zL0VmsAK9N?VZo}}^d|4&y`JM-V@`V$<`vm>1Fp!lJx<+oIg+taj}=Nkz>JXznzVV? z8y6Q6TA#tZ{^WG5u6%>ty+6#>b3Fq$1NG}MoLQqpX2!8o3g`bVT28W`qj_T6IvVI7 zBDo8?t4fb!%@-GUV=X>&Ji2mT_c-%1^`Yoqf zu!Ac2_u*rY{(kR5$W}Nx05+cg7I*-%IB6`#3`@&i*HT^M(MMx#)9}p>hC7dY+FSNI zYT0}39y(T&H=nZ}5N$a3&MMPD{m^*K20u193fUkXvH@xW)-_kWbbBeu_QI0lZ~N*K zo28FvXR-n9)l^{X#{MJT1e-Ix$Nj-ygkq#WxB4F%Uv(Zlh2946^!Mw?_xdu>O{z{=OB3 zVj7<&W-tqWFT%mbA5L*b?pFV{x!a@mauOSLHiY>{ahKUdfnE?J7&ChE?_g(u?W2{i z5{~VmWfp$3Tpz+RK%(0yW_Opcnj8-cbADrirTazaK`WmNt44&KV%A8#O;*hFeTP*y zNk`4qWYFx_!CvNz;Bfg@cxax!$Fr2X3t@Z6aIxn_n#jM%c6;N@6SjNzd!(t|0S=Rm zJBtYaIQiH+-x!1C<-&@-C+Rry z9wm*?mNx=RMu#tN(cdTA zntl=;aTf4R*a^`D^-GiBTgz(oe~dD%O$<^Nj3h3La5<7|k@sBqO5D z>ZRT%5~R+ncjNegeBC>f-nJBcZGe5DzXyFGHo`EXC6;2(8|#;chNETiqW{nf4cnkc z-^R-Or$}3zh7k#y`%1-GLBGOTL05u*8?MLz+84G(IW^3VzU5`*E)KmEDR*+=VU&Am zh;f|7ROyJ$zkLz>1w~&Y6L8tls}#)@@YTfPn!jraps zDB`y_*FZB6X{Bv>Ib$ z6VAel{M$_*bC>MWH0xJ^9hk?=M=k0fYOeV-a40;NX;WGkM7Zx6daQ==-j^PXB5{U} z#|&*J#+0M5a7FVCnB$*_8uVRY?l8`=F0>a`!9niRC_(;Z_?h06JtH{Xe#?C%( z^xI6qw=q4o8hyL#QP>mt*v?kX;eGVOjGBEngh$>hIKKJpsbUCprlOxVLQ-c8OASTZt7kmgYdEx~t zeIX$Z|N9fH^dQ_GxO%uIxaZ*RPdETw78`?bawGQp*#ke%{l&Lqr{5o^BusB0&z zCO_(8KCiqiV4T|}mk#XWIM|Zr+kV@(Dv|iV7$W}5u&WvjgxHStz~e((Tx@NhN#0!S zlsRi}VCHaAb0y|mzQI@=d)EZW6+KDKM$FQjN7@gEXyECge{s&w;~;(E1YTZ$lxyUg zX(YbXNpX~Muze^HI2U4;dfy9w6Q~%O(88mx50{1ly&?AW*I-?c2Ao6wVAe=) zaNqFVPMnM`4+QTX3PERk6;ky|Cw6AEU}c`$)Xx4_EUPWaaliaEA$Z>Ov*lR%Mo6`n z3d+@>IPz`qwy?`3I?dJdU>nJ-uv2Bx_pUU{i?J^cIwJo~Iv%T_7N$4#WtsAwWZF^5 z+RniOAlBAmMPCedK{882XE6@Y30JYob0Nk<9A=&8Wu47hu*@ONmW@6!-7cGP#?Q_{ zyBjM{`F$JB?ezs$FC59h%75(Jo9&EI?s3Mh6>EM{F&918Lg{X2S9wk(Cu7f*VC^6$ zG2QIW!GS>Q$YhsZ=%S5KQ3eCIg}FmHuz^J6GUCZwEuuoL^cz|WzZWqWT;wkA)@ zr%j$}?8#EFR}Q;nf8fM&y%no# zebYXmj;ZW=;;6&NR+e20TmZ*m;kk(+SgMbP{W6nH@myANS4DBFn%A

xhh=dkM} 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 z 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ℜiq1Wb~=W7w@*Fa9+ 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