-
Notifications
You must be signed in to change notification settings - Fork 214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding support for the ESP32C3 #733
Merged
+524
−59
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
#[cfg(feature = "riscv-esp32c3")] | ||
pub use esp32c3::*; | ||
|
||
#[cfg(feature = "riscv-esp32c3")] | ||
mod esp32c3 { | ||
use crate::{ | ||
analyze::Analysis as CodegenAnalysis, | ||
codegen::util, | ||
syntax::{analyze::Analysis as SyntaxAnalysis, ast::App}, | ||
}; | ||
use proc_macro2::{Span, TokenStream as TokenStream2}; | ||
use quote::quote; | ||
use std::collections::HashSet; | ||
use syn::{parse, Attribute, Ident}; | ||
|
||
#[allow(clippy::too_many_arguments)] | ||
pub fn impl_mutex( | ||
_app: &App, | ||
_analysis: &CodegenAnalysis, | ||
cfgs: &[Attribute], | ||
resources_prefix: bool, | ||
name: &Ident, | ||
ty: &TokenStream2, | ||
ceiling: u8, | ||
ptr: &TokenStream2, | ||
) -> TokenStream2 { | ||
let path = if resources_prefix { | ||
quote!(shared_resources::#name) | ||
} else { | ||
quote!(#name) | ||
}; | ||
quote!( | ||
#(#cfgs)* | ||
impl<'a> rtic::Mutex for #path<'a> { | ||
type T = #ty; | ||
|
||
#[inline(always)] | ||
fn lock<RTIC_INTERNAL_R>(&mut self, f: impl FnOnce(&mut #ty) -> RTIC_INTERNAL_R) -> RTIC_INTERNAL_R { | ||
/// Priority ceiling | ||
const CEILING: u8 = #ceiling; | ||
unsafe { | ||
rtic::export::lock( | ||
#ptr, | ||
CEILING, | ||
f, | ||
) | ||
} | ||
} | ||
} | ||
) | ||
} | ||
|
||
pub fn interrupt_ident() -> Ident { | ||
let span = Span::call_site(); | ||
Ident::new("Interrupt", span) | ||
} | ||
|
||
pub fn extra_assertions(_: &App, _: &SyntaxAnalysis) -> Vec<TokenStream2> { | ||
vec![] | ||
} | ||
|
||
pub fn pre_init_checks(app: &App, _: &SyntaxAnalysis) -> Vec<TokenStream2> { | ||
let mut stmts = vec![]; | ||
// check that all dispatchers exists in the `Interrupt` enumeration regardless of whether | ||
// they are used or not | ||
let rt_err = util::rt_err_ident(); | ||
|
||
for name in app.args.dispatchers.keys() { | ||
stmts.push(quote!(let _ = #rt_err::Interrupt::#name;)); | ||
} | ||
stmts | ||
} | ||
pub fn pre_init_enable_interrupts(app: &App, analysis: &CodegenAnalysis) -> Vec<TokenStream2> { | ||
let mut stmts = vec![]; | ||
let mut curr_cpu_id:u8 = 1; //cpu interrupt id 0 is reserved | ||
let rt_err = util::rt_err_ident(); | ||
let max_prio: usize = 15; //unfortunately this is not part of pac, but we know that max prio is 15. | ||
let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id)); | ||
// Unmask interrupts and set their priorities | ||
for (&priority, name) in interrupt_ids.chain( | ||
app.hardware_tasks | ||
.values() | ||
.filter_map(|task| Some((&task.args.priority, &task.args.binds))), | ||
) { | ||
let es = format!( | ||
"Maximum priority used by interrupt vector '{name}' is more than supported by hardware" | ||
); | ||
// Compile time assert that this priority is supported by the device | ||
stmts.push(quote!( | ||
const _: () = if (#max_prio) <= #priority as usize { ::core::panic!(#es); }; | ||
)); | ||
stmts.push(quote!( | ||
rtic::export::enable( | ||
#rt_err::Interrupt::#name, | ||
#priority, | ||
#curr_cpu_id, | ||
); | ||
)); | ||
curr_cpu_id += 1; | ||
} | ||
stmts | ||
} | ||
|
||
pub fn architecture_specific_analysis( | ||
app: &App, | ||
_analysis: &SyntaxAnalysis, | ||
) -> parse::Result<()> { | ||
//check if the dispatchers are supported | ||
for name in app.args.dispatchers.keys() { | ||
let name_s = name.to_string(); | ||
match &*name_s { | ||
"FROM_CPU_INTR0" | "FROM_CPU_INTR1" | "FROM_CPU_INTR2" | "FROM_CPU_INTR3" => {} | ||
|
||
_ => { | ||
return Err(parse::Error::new( | ||
name.span(), | ||
"Only FROM_CPU_INTRX are supported as dispatchers", | ||
)); | ||
} | ||
} | ||
} | ||
|
||
// Check that there are enough external interrupts to dispatch the software tasks and the timer | ||
// queue handler | ||
let mut first = None; | ||
let priorities = app | ||
.software_tasks | ||
.iter() | ||
.map(|(name, task)| { | ||
first = Some(name); | ||
task.args.priority | ||
}) | ||
.filter(|prio| *prio > 0) | ||
.collect::<HashSet<_>>(); | ||
|
||
let need = priorities.len(); | ||
let given = app.args.dispatchers.len(); | ||
if need > given { | ||
let s = { | ||
format!( | ||
"not enough interrupts to dispatch \ | ||
all software tasks (need: {need}; given: {given})" | ||
) | ||
}; | ||
|
||
// If not enough tasks and first still is None, may cause | ||
// "custom attribute panicked" due to unwrap on None | ||
return Err(parse::Error::new(first.unwrap().span(), s)); | ||
} | ||
Ok(()) | ||
} | ||
|
||
pub fn interrupt_entry(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> { | ||
vec![] | ||
} | ||
|
||
pub fn interrupt_exit(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> { | ||
vec![] | ||
} | ||
|
||
pub fn async_entry( | ||
_app: &App, | ||
_analysis: &CodegenAnalysis, | ||
dispatcher_name: Ident, | ||
) -> Vec<TokenStream2> { | ||
let mut stmts = vec![]; | ||
stmts.push(quote!( | ||
rtic::export::unpend(rtic::export::Interrupt::#dispatcher_name); //simulate cortex-m behavior by unpending the interrupt on entry. | ||
)); | ||
stmts | ||
} | ||
|
||
pub fn async_prio_limit(app: &App, analysis: &CodegenAnalysis) -> Vec<TokenStream2> { | ||
let max = if let Some(max) = analysis.max_async_prio { | ||
quote!(#max) | ||
} else { | ||
// No limit | ||
let device = &app.args.device; | ||
quote!(1 << #device::NVIC_PRIO_BITS) | ||
}; | ||
|
||
vec![quote!( | ||
/// Holds the maximum priority level for use by async HAL drivers. | ||
#[no_mangle] | ||
static RTIC_ASYNC_MAX_LOGICAL_PRIO: u8 = #max; | ||
)] | ||
} | ||
pub fn handler_config( | ||
app: &App, | ||
analysis: &CodegenAnalysis, | ||
dispatcher_name: Ident, | ||
) -> Vec<TokenStream2> { | ||
let mut stmts = vec![]; | ||
let mut curr_cpu_id = 1; | ||
//let mut ret = ""; | ||
let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id)); | ||
for (_, name) in interrupt_ids.chain( | ||
app.hardware_tasks | ||
.values() | ||
.filter_map(|task| Some((&task.args.priority, &task.args.binds))), | ||
) { | ||
if *name == dispatcher_name{ | ||
let ret = &("cpu_int_".to_owned()+&curr_cpu_id.to_string()+"_handler"); | ||
stmts.push( | ||
quote!(#[export_name = #ret]) | ||
); | ||
} | ||
curr_cpu_id += 1; | ||
} | ||
|
||
stmts | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this new hook is required by ESP32C3 for un-pending the dispatchers' interrupt, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep