diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..a5a9d5f
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,213 @@
+# EditorConfig for Visual Studio 2022: https://learn.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options?view=vs-2022
+
+# This is a top-most .editorconfig file
+root = true
+
+#=====================================================
+#
+# nanoFramework specific settings
+#
+#
+#=====================================================
+[*]
+# Generic EditorConfig settings
+end_of_line = crlf
+charset = utf-8-bom
+
+# Visual Studio spell checker
+spelling_languages = en-us
+spelling_checkable_types = strings,identifiers,comments
+spelling_error_severity = information
+spelling_exclusion_path = spelling_exclusion.dic
+
+#=====================================================
+#
+# Settings copied from the .NET runtime
+#
+# https://github.com/dotnet/runtime
+#
+#=====================================================
+# Default settings:
+# A newline ending every file
+# Use 4 spaces as indentation
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
+
+# Generated code
+[*{_AssemblyInfo.cs,.notsupported.cs,AsmOffsets.cs}]
+generated_code = true
+
+# C# files
+[*.cs]
+# New line preferences
+csharp_new_line_before_open_brace = all
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_case_contents_when_block = false
+csharp_indent_switch_labels = true
+csharp_indent_labels = one_less_than_current
+
+# Modifier preferences
+csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:suggestion
+
+# avoid this. unless absolutely necessary
+dotnet_style_qualification_for_field = false:suggestion
+dotnet_style_qualification_for_property = false:suggestion
+dotnet_style_qualification_for_method = false:suggestion
+dotnet_style_qualification_for_event = false:suggestion
+
+# Types: use keywords instead of BCL types, and permit var only when the type is clear
+csharp_style_var_for_built_in_types = false:suggestion
+csharp_style_var_when_type_is_apparent = false:none
+csharp_style_var_elsewhere = false:suggestion
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
+
+# name all constant fields using PascalCase
+dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
+dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
+dotnet_naming_symbols.constant_fields.applicable_kinds = field
+dotnet_naming_symbols.constant_fields.required_modifiers = const
+dotnet_naming_style.pascal_case_style.capitalization = pascal_case
+
+# static fields should have s_ prefix
+dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
+dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
+dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
+dotnet_naming_symbols.static_fields.applicable_kinds = field
+dotnet_naming_symbols.static_fields.required_modifiers = static
+dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
+dotnet_naming_style.static_prefix_style.required_prefix = s_
+dotnet_naming_style.static_prefix_style.capitalization = camel_case
+
+# internal and private fields should be _camelCase
+dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
+dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
+dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
+dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
+dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
+dotnet_naming_style.camel_case_underscore_style.required_prefix = _
+dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
+
+# Code style defaults
+csharp_using_directive_placement = outside_namespace:suggestion
+dotnet_sort_system_directives_first = true
+csharp_prefer_braces = true:silent
+csharp_preserve_single_line_blocks = true:none
+csharp_preserve_single_line_statements = false:none
+csharp_prefer_static_local_function = true:suggestion
+csharp_prefer_simple_using_statement = false:none
+csharp_style_prefer_switch_expression = true:suggestion
+dotnet_style_readonly_field = true:suggestion
+
+# Expression-level preferences
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_prefer_collection_expression = when_types_exactly_match
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
+dotnet_style_prefer_auto_properties = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:silent
+dotnet_style_prefer_conditional_expression_over_return = true:silent
+csharp_prefer_simple_default_expression = true:suggestion
+
+# Expression-bodied members
+csharp_style_expression_bodied_methods = true:silent
+csharp_style_expression_bodied_constructors = true:silent
+csharp_style_expression_bodied_operators = true:silent
+csharp_style_expression_bodied_properties = true:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_accessors = true:silent
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = true:silent
+
+# Pattern matching
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+
+# Null checking preferences
+csharp_style_throw_expression = true:suggestion
+csharp_style_conditional_delegate_call = true:suggestion
+
+# Other features
+csharp_style_prefer_index_operator = false:none
+csharp_style_prefer_range_operator = false:none
+csharp_style_pattern_local_over_anonymous_function = false:none
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = do_not_ignore
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# License header
+file_header_template = Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.
+
+# C++ Files
+[*.{cpp,h,in}]
+curly_bracket_next_line = true
+indent_brace_style = Allman
+
+# Xml project files
+[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
+indent_size = 2
+
+[*.{csproj,vbproj,proj,nativeproj,locproj}]
+charset = utf-8
+
+# Xml build files
+[*.builds]
+indent_size = 2
+
+# Xml files
+[*.{xml,stylecop,resx,ruleset}]
+indent_size = 2
+
+# Xml config files
+[*.{props,targets,config,nuspec}]
+indent_size = 2
+
+# YAML config files
+[*.{yml,yaml}]
+indent_size = 2
+
+# Shell scripts
+[*.sh]
+end_of_line = lf
+[*.{cmd,bat}]
+end_of_line = crlf
\ No newline at end of file
diff --git a/.github/.changelog-config.json b/.github/.changelog-config.json
index 60c9504..d969d52 100644
--- a/.github/.changelog-config.json
+++ b/.github/.changelog-config.json
@@ -37,7 +37,7 @@
}
],
"sort": "ASC",
- "template": "${{CHANGELOG}}\n\n**Full Changelog:** ${{RELEASE_DIFF}}\n\nThe following NuGet package is available from this release:\n\n:package: [nanoFramework.Devices.Can](https://www.nuget.org/packages/nanoFramework.Devices.Can/)",
+ "template": "${{CHANGELOG}}\n\n**Full Changelog:** ${{RELEASE_DIFF}}\n\nThe following NuGet packages are available from this release:\n\n:package: [nanoFramework.Devices.Can.Core](https://www.nuget.org/packages/nanoFramework.Devices.Can.Core/)\n:package: [nanoFramework.Device.Can.Stm32](https://www.nuget.org/packages/nanoFramework.Devices.Can.Stm32/)",
"pr_template": "* ${{TITLE}} by @${{AUTHOR}} in #${{NUMBER}}",
"empty_template": "- no changes",
"max_tags_to_fetch": 200,
diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml
index 04974da..644b2ae 100644
--- a/.github/workflows/pr-checks.yml
+++ b/.github/workflows/pr-checks.yml
@@ -10,6 +10,8 @@ jobs:
check_package_lock:
name: nanoFramework
uses: nanoframework/nf-tools/.github/workflows/check-package-lock.yml@main
+ with:
+ solution: 'nanoFramework.Device.Can.sln'
check_nuget_latest:
name: nanoFramework
uses: nanoframework/nf-tools/.github/workflows/check-packages-updated.yml@main
diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml
index 572a883..654dc41 100644
--- a/.github/workflows/update-dependencies.yml
+++ b/.github/workflows/update-dependencies.yml
@@ -7,7 +7,7 @@ name: Daily update dependencies
on:
schedule:
- # At 00:10 UTC.
+ # At 00:10 UTC.
- cron: '10 00 * * Wed,Fri'
repository_dispatch:
types: update-dependencies
@@ -18,4 +18,5 @@ jobs:
uses: nanoframework/nf-tools/.github/workflows/update-dependencies.yml@main
secrets: inherit
with:
- solutionsToCheck: 'nanoFramework.Device.Can.sln'
+ solutionsToCheck: |
+ nanoFramework.Device.Can.sln
diff --git a/README.md b/README.md
index f177bdb..ae706a6 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[](https://sonarcloud.io/dashboard?id=nanoframework_lib-nanoFramework.Devices.Can) [](https://sonarcloud.io/dashboard?id=nanoframework_lib-nanoFramework.Devices.Can) [](LICENSE) [](https://www.nuget.org/packages/nanoFramework.Device.Can/) [](https://github.com/nanoframework/Home/blob/main/CONTRIBUTING.md) [](https://discord.gg/gCyBu8T)
+[](https://sonarcloud.io/dashboard?id=nanoframework_lib-nanoFramework.Devices.Can) [](https://sonarcloud.io/dashboard?id=nanoframework_lib-nanoFramework.Devices.Can) [](LICENSE) [](https://www.nuget.org/packages/nanoFramework.Device.Can/) [](https://github.com/nanoframework/Home/blob/main/CONTRIBUTING.md) [](https://discord.gg/gCyBu8T)

@@ -6,11 +6,28 @@
### Welcome to the .NET **nanoFramework** CAN Class Library repository
+These libraries are the successor of the `nanoFramework.Device.Can` class library that required a native component and was available for two STM32-based boards. The direct replacement of that library is `nanoFramework.Device.Can.Stm32`.
+
## Build status
| Component | Build Status | NuGet Package |
|:-|---|---|
-| nanoFramework.Device.Can | [](https://dev.azure.com/nanoframework/nanoFramework.Device.Can/_build/latest?definitionId=25&repoName=nanoframework%2FnanoFramework.Device.Can&branchName=main) | [](https://www.nuget.org/packages/nanoFramework.Device.Can/) |
+| nanoFramework.Device.Can.Core | [](https://dev.azure.com/nanoframework/nanoFramework.Device.Can/_build/latest?definitionId=25&repoName=nanoframework%2FnanoFramework.Device.Can&branchName=main) | [](https://www.nuget.org/packages/nanoFramework.Device.Can.Core/) |
+| nanoFramework.Device.Can.Esp32 | [](https://dev.azure.com/nanoframework/nanoFramework.Device.Can/_build/latest?definitionId=25&repoName=nanoframework%2FnanoFramework.Device.Can&branchName=main) | [](https://www.nuget.org/packages/nanoFramework.Device.Can.Esp32/) |
+| nanoFramework.Device.Can.Mcp2515 | [](https://dev.azure.com/nanoframework/nanoFramework.Device.Can/_build/latest?definitionId=25&repoName=nanoframework%2FnanoFramework.Device.Can&branchName=main) | [](https://www.nuget.org/packages/nanoFramework.Device.Can.Mcp2515/) |
+| nanoFramework.Device.Can.Stm32 | [](https://dev.azure.com/nanoframework/nanoFramework.Device.Can/_build/latest?definitionId=25&repoName=nanoframework%2FnanoFramework.Device.Can&branchName=main) | [](https://www.nuget.org/packages/nanoFramework.Device.Can.Stm32/) |
+
+## The .NET **nanoFramework** CAN Class Libraries
+
+To exchange CAN messages by a .NET **nanoFramework** application, at least one device dependent class library is required:
+
+- `nanoFramework.Device.Can.Esp32` uses the CAN/TWAI implementation of an ESP32 microcontroller. This requires a matching firmware/target version for the microcontroller that provides the native part of the implementation. In general an external CAN transceiver is also required.
+- `nanoFramework.Device.Can.Stm` uses the CAN implementation of a STM32 microcontroller. This requires a matching firmware/target version for the microcontroller that provides the native part of the implementation. In general an external CAN transceiver is also required.
+- `nanoFramework.Device.Can.Mcp2515` uses an external CAN device based on the MCP2515 chip. It is a 100% .NET implementation that works with every microcontroller, and can be used in combination with the ESP32 or STM32 library. MCP2515 boards typically include a CAN transceiver.
+
+All device dependent libraries are based on:
+
+- `nanoFramework.Device.Can.Core` contains the common classes and interfaces. As the `nanoFramework.Device.Can` namespace implements the basic ISO 11898 CAN message transfer, this library can be used to implement higher-level protocols (e.g., CAN-TP or ISO-TP as used in ODB II) in device independent libraries.
## Feedback and documentation
diff --git a/Stub-generation.md b/Stub-generation.md
new file mode 100644
index 0000000..9ff5d27
--- /dev/null
+++ b/Stub-generation.md
@@ -0,0 +1,5 @@
+# Stub generation
+
+The libraries that require a native components generate a stub for the native part on each build. The stub is placed in, e.g., the `nanoFramework.Device.Can.Stm32\bin\Release\Stubs` directory.
+
+The native component will probably require access to the common classes in `nanoFramework.Device.Can.Core`. As that library is pure .NET, no stub is required. To generate the stub, select the **GenerateStub** configuration (instead of *Debug* or *Release*) in the *nanoFramework.Device.Can.sln* solution and build the solution. The stub will be placed in the `nanoFramework.Device.Can.Core\bin'\GenerateStubs\Stubs` directory.
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 1acb88a..89d195f 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -17,6 +17,10 @@ trigger:
- assets/*
- .github/*
+ tags:
+ include:
+ - v*
+
# PR always trigger build
pr:
autoCancel: true
@@ -29,34 +33,137 @@ resources:
name: nanoframework/nf-tools
endpoint: nanoframework
-pool:
- vmImage: 'windows-latest'
-
variables:
- - group: sign-client-credentials
- name: DOTNET_NOLOGO
- value: true
- - name: buildPlatform
- value: 'Any CPU'
- - name: buildConfiguration
- value: 'Release'
- - name: solution
- value: 'nanoFramework.Device.Can.sln'
- - name: nugetPackageName
- value: 'nanoFramework.Device.Can'
-
-steps:
-
-# step from template @ nf-tools repo
-# all build, update and publish steps
-- template: azure-pipelines-templates/class-lib-build.yml@templates
- parameters:
- sonarCloudProject: 'nanoframework_lib-nanoFramework.Devices.Can'
-
-# step from template @ nf-tools repo
-# report error
-- template: azure-pipelines-templates/discord-webhook-task.yml@templates
- parameters:
- status: 'failure'
- webhookUrl: '$(DiscordWebhook)'
- message: ''
+ value: true
+
+jobs:
+
+##############################
+- job: Build_Library
+ condition: >-
+ and(
+ not(startsWith(variables['Build.SourceBranch'], 'refs/tags/v')),
+ or(
+ eq(variables['UPDATE_DEPENDENTS'], 'false'),
+ eq(variables['StartReleaseCandidate'], 'true')
+ )
+ )
+ pool:
+ vmImage: 'windows-latest'
+
+ variables:
+ - group: sign-client-credentials
+ - name: buildPlatform
+ value: 'Any CPU'
+ - name: buildConfiguration
+ value: 'Release'
+ - name: solution
+ value: 'nanoFramework.Device.Can.sln'
+
+ steps:
+
+ # build step only
+ - template: azure-pipelines-templates/class-lib-build-only.yml@templates
+ parameters:
+ sonarCloudProject: 'nanoframework_lib-nanoFramework.Devices.Can'
+ runUnitTests: false
+ unitTestRunsettings: '$(System.DefaultWorkingDirectory)\.runsettings'
+
+ # build the 4 libs step
+ - template: azure-pipelines-templates/class-lib-package.yml@templates
+ parameters:
+ nugetPackageName: 'nanoFramework.Device.Can.Core'
+
+ #- template: azure-pipelines-templates/class-lib-package.yml@templates
+ # parameters:
+ # nugetPackageName: 'nanoFramework.Device.Can.Esp32'
+
+ #- template: azure-pipelines-templates/class-lib-package.yml@templates
+ # parameters:
+ # nugetPackageName: 'nanoFramework.Device.Can.Mcp2515'
+
+ - template: azure-pipelines-templates/class-lib-package.yml@templates
+ parameters:
+ nugetPackageName: 'nanoFramework.Device.Can.Stm32'
+
+ # publish the libs
+ - template: azure-pipelines-templates/class-lib-publish.yml@templates
+
+ # create GitHub release build from main branch
+ - task: GithubRelease@1
+ condition: >-
+ and(
+ succeeded(),
+ eq(variables['System.PullRequest.PullRequestId'], ''),
+ startsWith(variables['Build.SourceBranch'], 'refs/heads/main'),
+ not(contains(variables['Build.SourceBranch'], 'preview')),
+ eq(variables['StartReleaseCandidate'], false)
+ )
+ displayName: Create/Update GitHub release
+ inputs:
+ action: edit
+ gitHubConnection: 'github.com_nano-$(System.TeamProject)'
+ tagSource: userSpecifiedTag
+ tag: v$(MY_NUGET_VERSION)
+ title: 'nanoFramework.Device.Can Library v$(MY_NUGET_VERSION)'
+ releaseNotesSource: inline
+ releaseNotesInline: 'Check the [changelog]($(Build.Repository.Uri)/blob/$(Build.SourceBranchName)/CHANGELOG.md).
Install from NuGet
The following NuGet packages are available for download from this release:
:package: [nanoFramework.Device.Can.Core](https://www.nuget.org/packages/nanoFramework.Device.Can.Core/$(MY_NUGET_VERSION)) v$(MY_NUGET_VERSION).
:package: [nanoFramework.Device.Can.Esp32](https://www.nuget.org/packages/nanoFramework.Device.Can.Esp32/$(MY_NUGET_VERSION)) v$(MY_NUGET_VERSION).
:package: [nanoFramework.Device.Can.Mcp2515](https://www.nuget.org/packages/nanoFramework.Device.Can.Mcp2515/$(MY_NUGET_VERSION)) v$(MY_NUGET_VERSION).
:package: [nanoFramework.Device.Can.Stm32](https://www.nuget.org/packages/nanoFramework.Device.Can.Stm32/$(MY_NUGET_VERSION)) v$(MY_NUGET_VERSION).'
+ assets: '$(Build.ArtifactStagingDirectory)/*.nupkg'
+ assetUploadMode: replace
+ isPreRelease: false
+ addChangeLog: false
+
+##############################
+- job: Update_Dependents
+ condition: >-
+ or(
+ and(
+ startsWith(variables['Build.SourceBranch'], 'refs/tags/v'),
+ eq(variables['StartReleaseCandidate'], 'false')
+ ),
+ and(
+ contains(variables['getCommitMessage.COMMIT_MESSAGE'], '***UPDATE_DEPENDENTS***'),
+ eq(variables['StartReleaseCandidate'], 'false')
+ ),
+ eq(variables['UPDATE_DEPENDENTS'], 'true')
+ )
+
+ pool:
+ vmImage: 'windows-latest'
+
+ variables:
+ DOTNET_NOLOGO: true
+
+ steps:
+ # need this here in order to persist GitHub credentials
+ - checkout: self
+ fetchDepth: 1
+
+##################################
+# report build failure to Discord
+- job: Report_Build_Failure
+
+ dependsOn:
+ - Build_Library
+ - Update_Dependents
+ condition: >-
+ or(
+ failed('Build_Library'),
+ failed('Update_Dependents')
+ )
+
+ pool:
+ vmImage: 'windows-latest'
+
+ steps:
+
+ - checkout: self
+
+ # step from template @ nf-tools repo
+ # report error
+ - template: azure-pipelines-templates/discord-webhook-task.yml@templates
+ parameters:
+ status: 'failure'
+ webhookUrl: '$(DiscordWebhook)'
+ message: ''
diff --git a/nanoFramework.Device.Can.nuspec b/nanoFramework.Device.Can.Core.nuspec
similarity index 55%
rename from nanoFramework.Device.Can.nuspec
rename to nanoFramework.Device.Can.Core.nuspec
index 1c078c4..ba6a94e 100644
--- a/nanoFramework.Device.Can.nuspec
+++ b/nanoFramework.Device.Can.Core.nuspec
@@ -1,9 +1,9 @@
- nanoFramework.Device.Can
+ nanoFramework.Device.Can.Core
$version$
- nanoFramework.Device.Can
+ nanoFramework.Device.Can.Core
nanoframework
false
LICENSE.md
@@ -15,20 +15,19 @@
images\nf-logo.png
Copyright (c) .NET Foundation and Contributors
- This package includes the nanoFramework.Device.Can assembly for .NET nanoFramework C# projects.
-This package requires a target with nanoFramework.Device.Can v$nativeVersion$ (checksum $checksum$).
+ This package includes the nanoFramework.Device.Can.Core assembly for .NET nanoFramework C# projects.
+It contains the device-independent part of the implementation of the nanoFramework.Device.Can namespace.
nanoFramework C# csharp netmf netnf canbus can
-
-
-
-
-
-
+
+
+
+
+
diff --git a/nanoFramework.Device.Can/CanController.cs b/nanoFramework.Device.Can.Core/CanController.cs
similarity index 100%
rename from nanoFramework.Device.Can/CanController.cs
rename to nanoFramework.Device.Can.Core/CanController.cs
diff --git a/nanoFramework.Device.Can/CanControllerEventListener.cs b/nanoFramework.Device.Can.Core/CanControllerEventListener.cs
similarity index 100%
rename from nanoFramework.Device.Can/CanControllerEventListener.cs
rename to nanoFramework.Device.Can.Core/CanControllerEventListener.cs
diff --git a/nanoFramework.Device.Can/CanControllerManager.cs b/nanoFramework.Device.Can.Core/CanControllerManager.cs
similarity index 100%
rename from nanoFramework.Device.Can/CanControllerManager.cs
rename to nanoFramework.Device.Can.Core/CanControllerManager.cs
diff --git a/nanoFramework.Device.Can/CanEvent.cs b/nanoFramework.Device.Can.Core/CanEvent.cs
similarity index 100%
rename from nanoFramework.Device.Can/CanEvent.cs
rename to nanoFramework.Device.Can.Core/CanEvent.cs
diff --git a/nanoFramework.Device.Can/CanMessage.cs b/nanoFramework.Device.Can.Core/CanMessage.cs
similarity index 100%
rename from nanoFramework.Device.Can/CanMessage.cs
rename to nanoFramework.Device.Can.Core/CanMessage.cs
diff --git a/nanoFramework.Device.Can/CanMessageEvent.cs b/nanoFramework.Device.Can.Core/CanMessageEvent.cs
similarity index 100%
rename from nanoFramework.Device.Can/CanMessageEvent.cs
rename to nanoFramework.Device.Can.Core/CanMessageEvent.cs
diff --git a/nanoFramework.Device.Can/CanMessageFrameType.cs b/nanoFramework.Device.Can.Core/CanMessageFrameType.cs
similarity index 100%
rename from nanoFramework.Device.Can/CanMessageFrameType.cs
rename to nanoFramework.Device.Can.Core/CanMessageFrameType.cs
diff --git a/nanoFramework.Device.Can/CanMessageIdType.cs b/nanoFramework.Device.Can.Core/CanMessageIdType.cs
similarity index 100%
rename from nanoFramework.Device.Can/CanMessageIdType.cs
rename to nanoFramework.Device.Can.Core/CanMessageIdType.cs
diff --git a/nanoFramework.Device.Can/CanMessageReceivedEventArgs.cs b/nanoFramework.Device.Can.Core/CanMessageReceivedEventArgs.cs
similarity index 100%
rename from nanoFramework.Device.Can/CanMessageReceivedEventArgs.cs
rename to nanoFramework.Device.Can.Core/CanMessageReceivedEventArgs.cs
diff --git a/nanoFramework.Device.Can/CanSettings.cs b/nanoFramework.Device.Can.Core/CanSettings.cs
similarity index 100%
rename from nanoFramework.Device.Can/CanSettings.cs
rename to nanoFramework.Device.Can.Core/CanSettings.cs
diff --git a/nanoFramework.Device.Can.Core/Properties/AssemblyInfo.cs b/nanoFramework.Device.Can.Core/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..b4e7a5c
--- /dev/null
+++ b/nanoFramework.Device.Can.Core/Properties/AssemblyInfo.cs
@@ -0,0 +1,22 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("nanoFramework.Device.Can.Core")]
+[assembly: AssemblyCompany("nanoFramework Contributors")]
+[assembly: AssemblyProduct("nanoFramework.Device.Can.Core")]
+[assembly: AssemblyCopyright("Copyright (c) .NET Foundation and Contributors")]
+
+#if STUBGENERATION
+////////////////////////////////////////////////////////////////
+// update this whenever the native assembly signature changes //
+[assembly: AssemblyNativeVersion("100.1.0.0")]
+////////////////////////////////////////////////////////////////
+#endif
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
diff --git a/nanoFramework.Device.Can/key.snk b/nanoFramework.Device.Can.Core/key.snk
similarity index 100%
rename from nanoFramework.Device.Can/key.snk
rename to nanoFramework.Device.Can.Core/key.snk
diff --git a/nanoFramework.Device.Can.Core/nanoFramework.Device.Can.Core.nfproj b/nanoFramework.Device.Can.Core/nanoFramework.Device.Can.Core.nfproj
new file mode 100644
index 0000000..0595177
--- /dev/null
+++ b/nanoFramework.Device.Can.Core/nanoFramework.Device.Can.Core.nfproj
@@ -0,0 +1,102 @@
+
+
+
+
+
+ Debug
+ AnyCPU
+
+
+ GenerateStubs
+ AnyCPU
+
+
+ Release
+ AnyCPU
+
+
+ StubGeneration
+ AnyCPU
+
+
+
+ $(MSBuildExtensionsPath)\nanoFramework\v1.0\
+
+
+
+ Debug
+ AnyCPU
+ {11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 99ca76e4-d76f-42c9-9e62-49c2f499aa02
+ Library
+ Properties
+ 512
+ nanoFramework.Device.Can
+ nanoFramework.Device.Can.Core
+ v1.0
+ bin\$(Configuration)\nanoFramework.Device.Can.Core.xml
+ true
+ true
+
+
+ true
+
+
+ key.snk
+
+
+ false
+
+
+ True
+ $(DefineConstants);STUBGENERATION
+
+
+ bin\$(Configuration)\Stubs
+ nf_device_can_core_native
+ nanoFramework.Device.Can.Core
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\packages\nanoFramework.CoreLibrary.1.16.11\lib\mscorlib.dll
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoFramework.Device.Can/packages.config b/nanoFramework.Device.Can.Core/packages.config
similarity index 100%
rename from nanoFramework.Device.Can/packages.config
rename to nanoFramework.Device.Can.Core/packages.config
diff --git a/nanoFramework.Device.Can/packages.lock.json b/nanoFramework.Device.Can.Core/packages.lock.json
similarity index 100%
rename from nanoFramework.Device.Can/packages.lock.json
rename to nanoFramework.Device.Can.Core/packages.lock.json
diff --git a/nanoFramework.Device.Can.Esp32.nuspec b/nanoFramework.Device.Can.Esp32.nuspec
new file mode 100644
index 0000000..b384dbf
--- /dev/null
+++ b/nanoFramework.Device.Can.Esp32.nuspec
@@ -0,0 +1,39 @@
+
+
+
+ nanoFramework.Device.Can.Esp32
+ $version$
+ nanoFramework.Device.Can.Esp32
+ nanoframework
+ false
+ LICENSE.md
+
+
+ docs\README.md
+ false
+ https://github.com/nanoframework/nanoFramework.Device.Can
+ images\nf-logo.png
+
+ Copyright (c) .NET Foundation and Contributors
+ This package includes the nanoFramework.Device.Can.Esp32 assembly for .NET nanoFramework C# projects.
+It contains the device-dependent part of the implementation of the nanoFramework.Device.Can namespace for ESP32-based devices.
+This package requires a target with nanoFramework.Device.Can.Esp32 v$nativeVersion$ (checksum $checksum$).
+ nanoFramework C# csharp netmf netnf canbus can
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoFramework.Device.Can/Properties/AssemblyInfo.cs b/nanoFramework.Device.Can.Esp32/Properties/AssemblyInfo.cs
similarity index 83%
rename from nanoFramework.Device.Can/Properties/AssemblyInfo.cs
rename to nanoFramework.Device.Can.Esp32/Properties/AssemblyInfo.cs
index 0a2eb3f..c85aca7 100644
--- a/nanoFramework.Device.Can/Properties/AssemblyInfo.cs
+++ b/nanoFramework.Device.Can.Esp32/Properties/AssemblyInfo.cs
@@ -4,14 +4,14 @@
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("nanoFramework.Device.Can")]
+[assembly: AssemblyTitle("nanoFramework.Device.Can.Esp32")]
[assembly: AssemblyCompany("nanoFramework Contributors")]
-[assembly: AssemblyProduct("nanoFramework.Device.Can")]
+[assembly: AssemblyProduct("nanoFramework.Device.Can.Esp32")]
[assembly: AssemblyCopyright("Copyright (c) .NET Foundation and Contributors")]
////////////////////////////////////////////////////////////////
// update this whenever the native assembly signature changes //
-[assembly: AssemblyNativeVersion("100.0.5.1")]
+[assembly: AssemblyNativeVersion("100.1.0.0")]
////////////////////////////////////////////////////////////////
// Setting ComVisible to false makes the types in this assembly not visible
diff --git a/nanoFramework.Device.Can.Esp32/key.snk b/nanoFramework.Device.Can.Esp32/key.snk
new file mode 100644
index 0000000..67c9bb0
Binary files /dev/null and b/nanoFramework.Device.Can.Esp32/key.snk differ
diff --git a/nanoFramework.Device.Can.Esp32/nanoFramework.Device.Can.Esp32.nfproj b/nanoFramework.Device.Can.Esp32/nanoFramework.Device.Can.Esp32.nfproj
new file mode 100644
index 0000000..e106016
--- /dev/null
+++ b/nanoFramework.Device.Can.Esp32/nanoFramework.Device.Can.Esp32.nfproj
@@ -0,0 +1,73 @@
+
+
+
+
+ $(MSBuildExtensionsPath)\nanoFramework\v1.0\
+
+
+
+ Debug
+ AnyCPU
+ {11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {7CE9A616-F4A4-43EA-B067-526155C823AC}
+ Library
+ Properties
+ 512
+ nanoFramework.Device.Can
+ nanoFramework.Device.Can.Esp32
+ v1.0
+ True
+ bin\$(Configuration)\nanoFramework.Device.Can.Esp32.xml
+ true
+ true
+
+
+ true
+
+
+ key.snk
+
+
+ false
+
+
+ bin\$(Configuration)\Stubs
+ nf_device_can_esp32_native
+ nanoFramework.Device.Can.Esp32
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\packages\nanoFramework.CoreLibrary.1.16.11\lib\mscorlib.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoFramework.Device.Can.Esp32/packages.config b/nanoFramework.Device.Can.Esp32/packages.config
new file mode 100644
index 0000000..2db295a
--- /dev/null
+++ b/nanoFramework.Device.Can.Esp32/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoFramework.Device.Can.Esp32/packages.lock.json b/nanoFramework.Device.Can.Esp32/packages.lock.json
new file mode 100644
index 0000000..0ab0f5c
--- /dev/null
+++ b/nanoFramework.Device.Can.Esp32/packages.lock.json
@@ -0,0 +1,25 @@
+{
+ "version": 1,
+ "dependencies": {
+ ".NETnanoFramework,Version=v1.0": {
+ "nanoFramework.CoreLibrary": {
+ "type": "Direct",
+ "requested": "[1.16.11, 1.16.11]",
+ "resolved": "1.16.11",
+ "contentHash": "2XW+Zn0lQ+lOcxDbB1l2ga2rNoj9Jv2IeJwXE4ka1r+swmxn5N/otlMJVEXJgK8trUeD/E8T7+J7dXjU8UReHw=="
+ },
+ "nanoFramework.Runtime.Events": {
+ "type": "Direct",
+ "requested": "[1.11.29, 1.11.29]",
+ "resolved": "1.11.29",
+ "contentHash": "y3Y0SNfr1afMor4xrsiB1ETldjKvmnzBTcEH5gizFFXw3RNBB/N8npWqkCJn4HZS0TEENlH2vVrib3bWYMx5+Q=="
+ },
+ "Nerdbank.GitVersioning": {
+ "type": "Direct",
+ "requested": "[3.7.115, 3.7.115]",
+ "resolved": "3.7.115",
+ "contentHash": "EpXamaAdRfG/BMxGgvZlTM0npRnkmXUjAj8OdNKd17t4oN+2nvjdv/KnFmzOOMDqvlwB49UCwtOHJrAQTfUBtQ=="
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/nanoFramework.Device.Can.Mcp2515.nuspec b/nanoFramework.Device.Can.Mcp2515.nuspec
new file mode 100644
index 0000000..0bde20b
--- /dev/null
+++ b/nanoFramework.Device.Can.Mcp2515.nuspec
@@ -0,0 +1,38 @@
+
+
+
+ nanoFramework.Device.Can.Mcp2515
+ $version$
+ nanoFramework.Device.Can.Mcp2515
+ nanoframework
+ false
+ LICENSE.md
+
+
+ docs\README.md
+ false
+ https://github.com/nanoframework/nanoFramework.Device.Can
+ images\nf-logo.png
+
+ Copyright (c) .NET Foundation and Contributors
+ This package includes the nanoFramework.Device.Can.Mcp2515 assembly for .NET nanoFramework C# projects.
+It contains the device-dependent part of the implementation of the nanoFramework.Device.Can namespace for a CAN-bus that is accessed using a MCP2515.
+ nanoFramework C# csharp netmf netnf canbus can
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoFramework.Device.Can.Mcp2515/Properties/AssemblyInfo.cs b/nanoFramework.Device.Can.Mcp2515/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..82075e5
--- /dev/null
+++ b/nanoFramework.Device.Can.Mcp2515/Properties/AssemblyInfo.cs
@@ -0,0 +1,15 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("nanoFramework.Device.Can.Mcp2515")]
+[assembly: AssemblyCompany("nanoFramework Contributors")]
+[assembly: AssemblyProduct("nanoFramework.Device.Can.Mcp2515")]
+[assembly: AssemblyCopyright("Copyright (c) .NET Foundation and Contributors")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
diff --git a/nanoFramework.Device.Can.Mcp2515/key.snk b/nanoFramework.Device.Can.Mcp2515/key.snk
new file mode 100644
index 0000000..67c9bb0
Binary files /dev/null and b/nanoFramework.Device.Can.Mcp2515/key.snk differ
diff --git a/nanoFramework.Device.Can.Mcp2515/nanoFramework.Device.Can.Mcp2515.nfproj b/nanoFramework.Device.Can.Mcp2515/nanoFramework.Device.Can.Mcp2515.nfproj
new file mode 100644
index 0000000..c7fd1f9
--- /dev/null
+++ b/nanoFramework.Device.Can.Mcp2515/nanoFramework.Device.Can.Mcp2515.nfproj
@@ -0,0 +1,67 @@
+
+
+
+
+ $(MSBuildExtensionsPath)\nanoFramework\v1.0\
+
+
+
+ Debug
+ AnyCPU
+ {11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {9263BAA1-79C2-4A5F-9B36-EF2B24D6DF26}
+ Library
+ Properties
+ 512
+ nanoFramework.Device.Can
+ nanoFramework.Device.Can.Mcp2515
+ v1.0
+ bin\$(Configuration)\nanoFramework.Device.Can.Mcp2515.xml
+ true
+ true
+
+
+ true
+
+
+ key.snk
+
+
+ false
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\packages\nanoFramework.CoreLibrary.1.16.11\lib\mscorlib.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoFramework.Device.Can.Mcp2515/packages.config b/nanoFramework.Device.Can.Mcp2515/packages.config
new file mode 100644
index 0000000..2db295a
--- /dev/null
+++ b/nanoFramework.Device.Can.Mcp2515/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoFramework.Device.Can.Mcp2515/packages.lock.json b/nanoFramework.Device.Can.Mcp2515/packages.lock.json
new file mode 100644
index 0000000..0ab0f5c
--- /dev/null
+++ b/nanoFramework.Device.Can.Mcp2515/packages.lock.json
@@ -0,0 +1,25 @@
+{
+ "version": 1,
+ "dependencies": {
+ ".NETnanoFramework,Version=v1.0": {
+ "nanoFramework.CoreLibrary": {
+ "type": "Direct",
+ "requested": "[1.16.11, 1.16.11]",
+ "resolved": "1.16.11",
+ "contentHash": "2XW+Zn0lQ+lOcxDbB1l2ga2rNoj9Jv2IeJwXE4ka1r+swmxn5N/otlMJVEXJgK8trUeD/E8T7+J7dXjU8UReHw=="
+ },
+ "nanoFramework.Runtime.Events": {
+ "type": "Direct",
+ "requested": "[1.11.29, 1.11.29]",
+ "resolved": "1.11.29",
+ "contentHash": "y3Y0SNfr1afMor4xrsiB1ETldjKvmnzBTcEH5gizFFXw3RNBB/N8npWqkCJn4HZS0TEENlH2vVrib3bWYMx5+Q=="
+ },
+ "Nerdbank.GitVersioning": {
+ "type": "Direct",
+ "requested": "[3.7.115, 3.7.115]",
+ "resolved": "3.7.115",
+ "contentHash": "EpXamaAdRfG/BMxGgvZlTM0npRnkmXUjAj8OdNKd17t4oN+2nvjdv/KnFmzOOMDqvlwB49UCwtOHJrAQTfUBtQ=="
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/nanoFramework.Device.Can.Stm32.nuspec b/nanoFramework.Device.Can.Stm32.nuspec
new file mode 100644
index 0000000..d81b17e
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32.nuspec
@@ -0,0 +1,40 @@
+
+
+
+ nanoFramework.Device.Can.Stm32
+ $version$
+ nanoFramework.Device.Can.Stm32
+ nanoframework
+ false
+ LICENSE.md
+
+
+ docs\README.md
+ false
+ https://github.com/nanoframework/nanoFramework.Device.Can
+ images\nf-logo.png
+
+ Copyright (c) .NET Foundation and Contributors
+ This package includes the nanoFramework.Device.Can.Stm32 assembly for .NET nanoFramework C# projects.
+It contains the device-dependent part of the implementation of the nanoFramework.Device.Can namespace for STM32-based devices.
+This package requires a target with nanoFramework.Device.Can.Stm32 v$nativeVersion$ (checksum $checksum$).
+ nanoFramework C# csharp netmf netnf canbus can
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoFramework.Device.Can.Stm32/CanController.cs b/nanoFramework.Device.Can.Stm32/CanController.cs
new file mode 100644
index 0000000..9706f93
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/CanController.cs
@@ -0,0 +1,271 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// See LICENSE file in the project root for full license information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+
+namespace nanoFramework.Device.Can
+{
+ // This should be a TypedEventHandler "EventHandler"
+#pragma warning disable 1591
+ public delegate void CanMessageReceivedEventHandler(
+ Object sender,
+ CanMessageReceivedEventArgs e);
+
+#pragma warning restore 1591
+
+ ///
+ /// Represents a CAN controller on the system.
+ ///
+ public sealed class CanController : IDisposable
+ {
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private static CanControllerEventListener s_eventListener = new CanControllerEventListener();
+
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private bool _disposed;
+
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private CanMessageReceivedEventHandler _callbacks = null;
+
+ // this is used as the lock object
+ // a lock is required because multiple threads can access the CanController
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private readonly object _syncLock = new object();
+
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ internal readonly int _controllerId;
+
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private readonly CanSettings _settings;
+
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private readonly CanMessage _message;
+
+ ///
+ /// Controller ID for this .
+ ///
+ public readonly string ControllerId;
+
+ internal CanController(string controller, CanSettings settings)
+ {
+ // the CAN id is an ASCII string with the format 'CANn'
+ // need to grab 'n' from the string and convert that to the integer value from the ASCII code (do this by subtracting 48 from the char value)
+ _controllerId = controller[3] - '0';
+
+ ControllerId = controller;
+
+ // check if this controller is already opened
+ var myController = FindController(_controllerId);
+
+ if (myController == null)
+ {
+ _settings = new CanSettings(settings);
+
+ // call native init to allow HAL/PAL inits related with Can hardware
+ NativeInit();
+
+ // add controller to collection, with the ID as key
+ // ** just the index number ***
+ CanControllerManager.ControllersCollection.Add(this);
+
+ // add the controller to the event listener in order to receive the callbacks from the native interrupts
+ s_eventListener.AddCanController(this);
+ }
+ else
+ {
+ // this controller already exists: throw an exception
+ throw new ArgumentException();
+ }
+ }
+
+ ///
+ /// Opens a CAN bus with the settings provided.
+ ///
+ /// The id of the bus.
+ /// The bus settings.
+ /// The CAN controller requested.
+ public static CanController FromId(string controllerId, CanSettings settings)
+ {
+ //TODO: some sanity checks on controllerId
+ return new CanController(controllerId, settings);
+ }
+
+ ///
+ /// Write message to CAN Bus.
+ ///
+ /// CAN mesage to write in CAN Bus.
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ public extern void WriteMessage(CanMessage message);
+
+ internal static CanController FindController(int index)
+ {
+ for (int i = 0; i < CanControllerManager.ControllersCollection.Count; i++)
+ {
+ if (((CanController)CanControllerManager.ControllersCollection[i])._controllerId == index)
+ {
+ return (CanController)CanControllerManager.ControllersCollection[i];
+ }
+ }
+
+ return null;
+ }
+
+ #region IDisposable Support
+
+ private void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // remove controller from controller collection
+ CanControllerManager.ControllersCollection.Remove(this);
+
+ // remove the controller from the event listener
+ s_eventListener.RemoveCanController(_controllerId);
+ }
+
+ DisposeNative();
+
+ _disposed = true;
+ }
+ }
+
+#pragma warning disable 1591
+ ~CanController()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ lock (_syncLock)
+ {
+ if (!_disposed)
+ {
+ Dispose(true);
+
+ GC.SuppressFinalize(this);
+ }
+ }
+ }
+
+#pragma warning restore 1591
+
+ #endregion
+
+ #region Events
+
+ ///
+ /// Indicates that a message has been received through a object.
+ ///
+ public event CanMessageReceivedEventHandler MessageReceived
+ {
+ add
+ {
+ lock (_syncLock)
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException();
+ }
+
+ CanMessageReceivedEventHandler callbacksOld = _callbacks;
+ CanMessageReceivedEventHandler callbacksNew = (CanMessageReceivedEventHandler)Delegate.Combine(callbacksOld, value);
+
+ try
+ {
+ _callbacks = callbacksNew;
+ }
+ catch
+ {
+ _callbacks = callbacksOld;
+
+ throw;
+ }
+
+ NativeUpdateCallbacks();
+ }
+ }
+
+ remove
+ {
+ lock (_syncLock)
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException();
+ }
+
+ CanMessageReceivedEventHandler callbacksOld = _callbacks;
+ CanMessageReceivedEventHandler callbacksNew = (CanMessageReceivedEventHandler)Delegate.Remove(callbacksOld, value);
+
+ try
+ {
+ _callbacks = callbacksNew;
+ }
+ catch
+ {
+ _callbacks = callbacksOld;
+
+ throw;
+ }
+
+ NativeUpdateCallbacks();
+ }
+ }
+ }
+
+
+ ///
+ /// Handles internal events and re-dispatches them to the publicly subscribed delegates.
+ ///
+ /// The Event type.
+
+ internal void OnCanMessageReceivedInternal(CanEvent eventType)
+ {
+ CanMessageReceivedEventHandler callbacks = null;
+
+ lock (_syncLock)
+ {
+ if (!_disposed)
+ {
+ callbacks = _callbacks;
+ }
+ }
+
+ callbacks?.Invoke(this, new CanMessageReceivedEventArgs(eventType));
+ }
+
+ #endregion
+
+ #region Native Calls
+
+ ///
+ /// Get next available in the _ internal buffer.
+ /// If there are no more messages available null will be returned.
+ ///
+ ///
+ /// A or null if there are no more messages available.
+ ///
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ public extern CanMessage GetMessage();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern void DisposeNative();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal static extern string GetDeviceSelector();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern void NativeInit();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern void NativeUpdateCallbacks();
+
+ #endregion
+ }
+}
diff --git a/nanoFramework.Device.Can.Stm32/CanControllerEventListener.cs b/nanoFramework.Device.Can.Stm32/CanControllerEventListener.cs
new file mode 100644
index 0000000..f0278d2
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/CanControllerEventListener.cs
@@ -0,0 +1,93 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// See LICENSE file in the project root for full license information.
+//
+
+using nanoFramework.Runtime.Events;
+using System;
+using System.Collections;
+
+namespace nanoFramework.Device.Can
+{
+ internal class CanControllerEventListener : IEventProcessor, IEventListener
+ {
+ // Map of serial device numbers to CanController objects.
+ private ArrayList _canControllersMap = new ArrayList();
+
+ public CanControllerEventListener()
+ {
+ EventSink.AddEventProcessor(EventCategory.Can, this);
+ EventSink.AddEventListener(EventCategory.Can, this);
+ }
+
+ public BaseEvent ProcessEvent(uint data1, uint data2, DateTime time)
+ {
+ return new CanMessageEvent
+ {
+ // Data1 is packed by PostManagedEvent, so we need to unpack the high word.
+ ControllerIndex = (int)(data1 >> 16),
+ Event = (CanEvent)data2
+ };
+ }
+
+ public void InitializeForEventSource()
+ {
+ }
+
+ public bool OnEvent(BaseEvent ev)
+ {
+ var canMessageEvent = (CanMessageEvent)ev;
+ CanController device = null;
+
+ lock (_canControllersMap)
+ {
+ device = FindCanController(canMessageEvent.ControllerIndex);
+ }
+
+ // Avoid calling this under a lock to prevent a potential lock inversion.
+ if (device != null)
+ {
+ device.OnCanMessageReceivedInternal(canMessageEvent.Event);
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public void AddCanController(CanController controller)
+ {
+ lock (_canControllersMap)
+ {
+ _canControllersMap.Add(controller);
+ }
+ }
+
+ public void RemoveCanController(int index)
+ {
+ lock (_canControllersMap)
+ {
+ var controller = FindCanController(index);
+
+ if (controller != null)
+ {
+ _canControllersMap.Remove(controller);
+ }
+ }
+ }
+ private CanController FindCanController(int controllerId)
+ {
+ for (int i = 0; i < _canControllersMap.Count; i++)
+ {
+ if (((CanController)_canControllersMap[i])._controllerId == controllerId)
+ {
+ return (CanController)_canControllersMap[i];
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/nanoFramework.Device.Can.Stm32/CanControllerManager.cs b/nanoFramework.Device.Can.Stm32/CanControllerManager.cs
new file mode 100644
index 0000000..6c0ee2d
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/CanControllerManager.cs
@@ -0,0 +1,48 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// See LICENSE file in the project root for full license information.
+//
+
+using System.Collections;
+
+namespace nanoFramework.Device.Can
+{
+ internal sealed class CanControllerManager
+ {
+ private static readonly object _syncLock = new object();
+
+ // backing field for ControllersCollection
+ // to store the controllers that are open
+ private static ArrayList s_controllersCollection;
+
+ ///
+ /// collection.
+ ///
+ ///
+ /// This collection is for internal use only.
+ ///
+ internal static ArrayList ControllersCollection
+ {
+ get
+ {
+ if (s_controllersCollection == null)
+ {
+ lock (_syncLock)
+ {
+ if (s_controllersCollection == null)
+ {
+ s_controllersCollection = new ArrayList();
+ }
+ }
+ }
+
+ return s_controllersCollection;
+ }
+
+ set
+ {
+ s_controllersCollection = value;
+ }
+ }
+ }
+}
diff --git a/nanoFramework.Device.Can.Stm32/CanEvent.cs b/nanoFramework.Device.Can.Stm32/CanEvent.cs
new file mode 100644
index 0000000..cca6405
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/CanEvent.cs
@@ -0,0 +1,23 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// See LICENSE file in the project root for full license information.
+//
+
+namespace nanoFramework.Device.Can
+{
+ ///
+ /// Describes the possible types of events for the CAN controller.
+ ///
+ public enum CanEvent
+ {
+ ///
+ /// A CAN message was received.
+ ///
+ MessageReceived = 0,
+
+ ///
+ /// An error has occurred.
+ ///
+ ErrorOccurred
+ }
+}
diff --git a/nanoFramework.Device.Can.Stm32/CanMessage.cs b/nanoFramework.Device.Can.Stm32/CanMessage.cs
new file mode 100644
index 0000000..e7b5291
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/CanMessage.cs
@@ -0,0 +1,79 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// See LICENSE file in the project root for full license information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+
+namespace nanoFramework.Device.Can
+{
+ ///
+ /// CAN message.
+ ///
+ public class CanMessage
+ {
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private uint _id;
+
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private CanMessageIdType _identifierType;
+
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private CanMessageFrameType _frameType;
+
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private byte[] _message;
+
+ ///
+ /// Message ID (SID or EID format, depending on ).
+ ///
+ public uint Id
+ {
+ get { return _id; }
+ set { _id = value; }
+ }
+
+ ///
+ /// Message identifier type.
+ ///
+ public CanMessageIdType IdentifierType
+ {
+ get { return _identifierType; }
+ set { _identifierType = value; }
+ }
+
+ ///
+ /// Message frame type.
+ ///
+ public CanMessageFrameType FrameType
+ {
+ get { return _frameType; }
+ set { _frameType = value; }
+ }
+
+ ///
+ /// Message data.
+ ///
+ ///
+ /// Maximum lenght of data buffer is 8.
+ ///
+ /// If the message buffer exceeds the maximum allowed lenght.
+ public byte[] Message
+ {
+ get { return _message; }
+ set { _message = value; }
+ }
+
+ ///
+ /// Creates a CAN message.
+ ///
+ public CanMessage(uint id, CanMessageIdType identifierType, CanMessageFrameType frameType, byte[] message)
+ {
+ _id = id;
+ _identifierType = identifierType;
+ _frameType = frameType;
+ _message = message;
+ }
+ }
+}
diff --git a/nanoFramework.Device.Can.Stm32/CanMessageEvent.cs b/nanoFramework.Device.Can.Stm32/CanMessageEvent.cs
new file mode 100644
index 0000000..c511e6a
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/CanMessageEvent.cs
@@ -0,0 +1,15 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// See LICENSE file in the project root for full license information.
+//
+
+using nanoFramework.Runtime.Events;
+
+namespace nanoFramework.Device.Can
+{
+ internal class CanMessageEvent : BaseEvent
+ {
+ public int ControllerIndex;
+ public CanEvent Event;
+ }
+}
diff --git a/nanoFramework.Device.Can.Stm32/CanMessageFrameType.cs b/nanoFramework.Device.Can.Stm32/CanMessageFrameType.cs
new file mode 100644
index 0000000..a00690b
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/CanMessageFrameType.cs
@@ -0,0 +1,23 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// See LICENSE file in the project root for full license information.
+//
+
+namespace nanoFramework.Device.Can
+{
+ ///
+ /// CAN message frame type.
+ ///
+ public enum CanMessageFrameType
+ {
+ ///
+ /// Data frame.
+ ///
+ Data = 0,
+
+ ///
+ /// Remote request frame.
+ ///
+ RemoteRequest
+ }
+}
diff --git a/nanoFramework.Device.Can.Stm32/CanMessageIdType.cs b/nanoFramework.Device.Can.Stm32/CanMessageIdType.cs
new file mode 100644
index 0000000..283b05c
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/CanMessageIdType.cs
@@ -0,0 +1,23 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// See LICENSE file in the project root for full license information.
+//
+
+namespace nanoFramework.Device.Can
+{
+ ///
+ /// CAN message identifier type.
+ ///
+ public enum CanMessageIdType
+ {
+ ///
+ /// Standard Identifier.
+ ///
+ SID,
+
+ ///
+ /// Extended Identifier.
+ ///
+ EID
+ }
+}
diff --git a/nanoFramework.Device.Can.Stm32/CanMessageReceivedEventArgs.cs b/nanoFramework.Device.Can.Stm32/CanMessageReceivedEventArgs.cs
new file mode 100644
index 0000000..fa6ee7a
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/CanMessageReceivedEventArgs.cs
@@ -0,0 +1,18 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// See LICENSE file in the project root for full license information.
+//
+
+namespace nanoFramework.Device.Can
+{
+ ///
+ /// Provides data for the event.
+ ///
+ public class CanMessageReceivedEventArgs
+ {
+ internal CanMessageReceivedEventArgs(CanEvent msgValue)
+ {
+
+ }
+ }
+}
diff --git a/nanoFramework.Device.Can.Stm32/CanSettings.cs b/nanoFramework.Device.Can.Stm32/CanSettings.cs
new file mode 100644
index 0000000..a7ac738
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/CanSettings.cs
@@ -0,0 +1,88 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// See LICENSE file in the project root for full license information.
+//
+
+namespace nanoFramework.Device.Can
+{
+ ///
+ /// Represents the settings for CAN bus.
+ ///
+ public sealed class CanSettings
+ {
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private byte _baudRatePrescaler;
+
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private byte _phaseSegment1;
+
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private byte _phaseSegment2;
+
+ [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
+ private byte _syncJumpWidth;
+
+ ///
+ /// Initializes a new instance of .
+ ///
+ /// Bus baud rate prescaler.
+ /// Phase segment 1.
+ /// Phase segment 2.
+ /// Synchronization jump width.
+ public CanSettings(byte baudRatePrescaler, byte phaseSegment1, byte phaseSegment2, byte syncJumpWidth)
+ {
+ _baudRatePrescaler = baudRatePrescaler;
+ _phaseSegment1 = phaseSegment1;
+ _phaseSegment2 = phaseSegment2;
+ _syncJumpWidth = syncJumpWidth;
+ }
+
+ ///
+ /// Initializes a copy of a object.
+ ///
+ /// Object to copy from.
+ internal CanSettings(CanSettings value)
+ {
+ _baudRatePrescaler = value._baudRatePrescaler;
+ _phaseSegment1 = value._phaseSegment1;
+ _phaseSegment2 = value._phaseSegment2;
+ _syncJumpWidth = value._syncJumpWidth;
+ }
+
+ ///
+ /// Gets or sets the baud rate prescaler.
+ ///
+ public byte BaudRatePrescaler
+ {
+ get { return _baudRatePrescaler; }
+ set { _baudRatePrescaler = value; }
+ }
+
+ ///
+ /// Gets or sets the value for phase segment 1.
+ ///
+ public byte PhaseSegment1
+ {
+ get { return _phaseSegment1; }
+ set { _phaseSegment1 = value; }
+ }
+
+ ///
+ /// Gets or sets the value for phase segment 2.
+ ///
+ public byte PhaseSegment2
+ {
+ get { return _phaseSegment2; }
+ set { _phaseSegment2 = value; }
+ }
+
+ ///
+ /// Gets or sets the value for the synchronization jump width.
+ ///
+ public byte SyncJumpWidth
+ {
+ get { return _syncJumpWidth; }
+ set { _syncJumpWidth = value; }
+ }
+ }
+}
diff --git a/nanoFramework.Device.Can.Stm32/Properties/AssemblyInfo.cs b/nanoFramework.Device.Can.Stm32/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d2dc91f
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/Properties/AssemblyInfo.cs
@@ -0,0 +1,20 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("nanoFramework.Device.Can.Stm32")]
+[assembly: AssemblyCompany("nanoFramework Contributors")]
+[assembly: AssemblyProduct("nanoFramework.Device.Can.Stm32")]
+[assembly: AssemblyCopyright("Copyright (c) .NET Foundation and Contributors")]
+
+////////////////////////////////////////////////////////////////
+// update this whenever the native assembly signature changes //
+[assembly: AssemblyNativeVersion("100.1.0.0")]
+////////////////////////////////////////////////////////////////
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
diff --git a/nanoFramework.Device.Can.Stm32/key.snk b/nanoFramework.Device.Can.Stm32/key.snk
new file mode 100644
index 0000000..67c9bb0
Binary files /dev/null and b/nanoFramework.Device.Can.Stm32/key.snk differ
diff --git a/nanoFramework.Device.Can/nanoFramework.Device.Can.nfproj b/nanoFramework.Device.Can.Stm32/nanoFramework.Device.Can.Stm32.nfproj
similarity index 91%
rename from nanoFramework.Device.Can/nanoFramework.Device.Can.nfproj
rename to nanoFramework.Device.Can.Stm32/nanoFramework.Device.Can.Stm32.nfproj
index 6342a57..75cd363 100644
--- a/nanoFramework.Device.Can/nanoFramework.Device.Can.nfproj
+++ b/nanoFramework.Device.Can.Stm32/nanoFramework.Device.Can.Stm32.nfproj
@@ -9,15 +9,15 @@
Debug
AnyCPU
{11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- 99ca76e4-d76f-42c9-9e62-49c2f499aa02
+ {695177A1-93CE-4AC4-88A2-EEFDDF327D0F}
Library
Properties
512
nanoFramework.Device.Can
- nanoFramework.Device.Can
+ nanoFramework.Device.Can.Stm32
v1.0
True
- bin\$(Configuration)\nanoFramework.Device.Can.xml
+ bin\$(Configuration)\nanoFramework.Device.Can.Stm32.xml
true
true
@@ -32,8 +32,8 @@
bin\$(Configuration)\Stubs
- nf_device_can_native
- nanoFramework.Device.Can
+ nf_device_can_stm32_native
+ nanoFramework.Device.Can.Stm32
@@ -67,6 +67,9 @@
..\packages\nanoFramework.Runtime.Events.1.11.29\lib\nanoFramework.Runtime.Events.dll
+
+
+
diff --git a/nanoFramework.Device.Can.Stm32/packages.config b/nanoFramework.Device.Can.Stm32/packages.config
new file mode 100644
index 0000000..2db295a
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoFramework.Device.Can.Stm32/packages.lock.json b/nanoFramework.Device.Can.Stm32/packages.lock.json
new file mode 100644
index 0000000..0ab0f5c
--- /dev/null
+++ b/nanoFramework.Device.Can.Stm32/packages.lock.json
@@ -0,0 +1,25 @@
+{
+ "version": 1,
+ "dependencies": {
+ ".NETnanoFramework,Version=v1.0": {
+ "nanoFramework.CoreLibrary": {
+ "type": "Direct",
+ "requested": "[1.16.11, 1.16.11]",
+ "resolved": "1.16.11",
+ "contentHash": "2XW+Zn0lQ+lOcxDbB1l2ga2rNoj9Jv2IeJwXE4ka1r+swmxn5N/otlMJVEXJgK8trUeD/E8T7+J7dXjU8UReHw=="
+ },
+ "nanoFramework.Runtime.Events": {
+ "type": "Direct",
+ "requested": "[1.11.29, 1.11.29]",
+ "resolved": "1.11.29",
+ "contentHash": "y3Y0SNfr1afMor4xrsiB1ETldjKvmnzBTcEH5gizFFXw3RNBB/N8npWqkCJn4HZS0TEENlH2vVrib3bWYMx5+Q=="
+ },
+ "Nerdbank.GitVersioning": {
+ "type": "Direct",
+ "requested": "[3.7.115, 3.7.115]",
+ "resolved": "3.7.115",
+ "contentHash": "EpXamaAdRfG/BMxGgvZlTM0npRnkmXUjAj8OdNKd17t4oN+2nvjdv/KnFmzOOMDqvlwB49UCwtOHJrAQTfUBtQ=="
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/nanoFramework.Device.Can.sln b/nanoFramework.Device.Can.sln
index 5124105..902148c 100644
--- a/nanoFramework.Device.Can.sln
+++ b/nanoFramework.Device.Can.sln
@@ -2,28 +2,64 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32505.173
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "nanoFramework.Device.Can", "nanoFramework.Device.Can\nanoFramework.Device.Can.nfproj", "{99CA76E4-D76F-42C9-9E62-49C2F499AA02}"
+Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "nanoFramework.Device.Can.Core", "nanoFramework.Device.Can.Core\nanoFramework.Device.Can.Core.nfproj", "{99CA76E4-D76F-42C9-9E62-49C2F499AA02}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B46D657A-F9AC-427C-A131-5323F92F211C}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Packages and stubs", "Packages and stubs", "{B46D657A-F9AC-427C-A131-5323F92F211C}"
ProjectSection(SolutionItems) = preProject
- nanoFramework.Device.Can.DELIVERABLES.nuspec = nanoFramework.Device.Can.DELIVERABLES.nuspec
- nanoFramework.Device.Can.nuspec = nanoFramework.Device.Can.nuspec
+ nanoFramework.Device.Can.Core.nuspec = nanoFramework.Device.Can.Core.nuspec
+ nanoFramework.Device.Can.Esp32.nuspec = nanoFramework.Device.Can.Esp32.nuspec
+ nanoFramework.Device.Can.Mcp2515.nuspec = nanoFramework.Device.Can.Mcp2515.nuspec
+ nanoFramework.Device.Can.Stm32.nuspec = nanoFramework.Device.Can.Stm32.nuspec
NuGet.Config = NuGet.Config
+ README.md = README.md
+ Stub-generation.md = Stub-generation.md
version.json = version.json
EndProjectSection
EndProject
+Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "nanoFramework.Device.Can.Esp32", "nanoFramework.Device.Can.Esp32\nanoFramework.Device.Can.Esp32.nfproj", "{7CE9A616-F4A4-43EA-B067-526155C823AC}"
+EndProject
+Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "nanoFramework.Device.Can.Stm32", "nanoFramework.Device.Can.Stm32\nanoFramework.Device.Can.Stm32.nfproj", "{695177A1-93CE-4AC4-88A2-EEFDDF327D0F}"
+EndProject
+Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "nanoFramework.Device.Can.Mcp2515", "nanoFramework.Device.Can.Mcp2515\nanoFramework.Device.Can.Mcp2515.nfproj", "{9263BAA1-79C2-4A5F-9B36-EF2B24D6DF26}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ GenerateStubs|Any CPU = GenerateStubs|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{99CA76E4-D76F-42C9-9E62-49C2F499AA02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{99CA76E4-D76F-42C9-9E62-49C2F499AA02}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99CA76E4-D76F-42C9-9E62-49C2F499AA02}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {99CA76E4-D76F-42C9-9E62-49C2F499AA02}.GenerateStubs|Any CPU.ActiveCfg = GenerateStubs|Any CPU
+ {99CA76E4-D76F-42C9-9E62-49C2F499AA02}.GenerateStubs|Any CPU.Build.0 = GenerateStubs|Any CPU
{99CA76E4-D76F-42C9-9E62-49C2F499AA02}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99CA76E4-D76F-42C9-9E62-49C2F499AA02}.Release|Any CPU.Build.0 = Release|Any CPU
{99CA76E4-D76F-42C9-9E62-49C2F499AA02}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {7CE9A616-F4A4-43EA-B067-526155C823AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7CE9A616-F4A4-43EA-B067-526155C823AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7CE9A616-F4A4-43EA-B067-526155C823AC}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {7CE9A616-F4A4-43EA-B067-526155C823AC}.GenerateStubs|Any CPU.ActiveCfg = Debug|Any CPU
+ {7CE9A616-F4A4-43EA-B067-526155C823AC}.GenerateStubs|Any CPU.Build.0 = Debug|Any CPU
+ {7CE9A616-F4A4-43EA-B067-526155C823AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7CE9A616-F4A4-43EA-B067-526155C823AC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7CE9A616-F4A4-43EA-B067-526155C823AC}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {695177A1-93CE-4AC4-88A2-EEFDDF327D0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {695177A1-93CE-4AC4-88A2-EEFDDF327D0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {695177A1-93CE-4AC4-88A2-EEFDDF327D0F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {695177A1-93CE-4AC4-88A2-EEFDDF327D0F}.GenerateStubs|Any CPU.ActiveCfg = Debug|Any CPU
+ {695177A1-93CE-4AC4-88A2-EEFDDF327D0F}.GenerateStubs|Any CPU.Build.0 = Debug|Any CPU
+ {695177A1-93CE-4AC4-88A2-EEFDDF327D0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {695177A1-93CE-4AC4-88A2-EEFDDF327D0F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {695177A1-93CE-4AC4-88A2-EEFDDF327D0F}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {9263BAA1-79C2-4A5F-9B36-EF2B24D6DF26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9263BAA1-79C2-4A5F-9B36-EF2B24D6DF26}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9263BAA1-79C2-4A5F-9B36-EF2B24D6DF26}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {9263BAA1-79C2-4A5F-9B36-EF2B24D6DF26}.GenerateStubs|Any CPU.ActiveCfg = Debug|Any CPU
+ {9263BAA1-79C2-4A5F-9B36-EF2B24D6DF26}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9263BAA1-79C2-4A5F-9B36-EF2B24D6DF26}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9263BAA1-79C2-4A5F-9B36-EF2B24D6DF26}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/spelling_exclusion.dic b/spelling_exclusion.dic
new file mode 100644
index 0000000..8c0e1f8
--- /dev/null
+++ b/spelling_exclusion.dic
@@ -0,0 +1 @@
+nano