@@ -148,11 +148,21 @@ impl<P: PIOExt> PIO<P> {
148148 . write ( |w| unsafe { w. irq_force ( ) . bits ( flags) } ) ;
149149 }
150150
151+ /// Calculates a mask with the `len` right-most bits set.
152+ fn instruction_mask ( len : usize ) -> u32 {
153+ if len < 32 {
154+ ( 1 << len) - 1
155+ } else {
156+ 0xffffffff
157+ }
158+ }
159+
160+ /// Tries to find an appropriate offset for the instructions, in range 0..=31.
151161 fn find_offset_for_instructions ( & self , i : & [ u16 ] , origin : Option < u8 > ) -> Option < usize > {
152- if i. len ( ) > PIO_INSTRUCTION_COUNT {
162+ if i. len ( ) > PIO_INSTRUCTION_COUNT || i . is_empty ( ) {
153163 None
154164 } else {
155- let mask = ( 1 << i. len ( ) ) - 1 ;
165+ let mask = Self :: instruction_mask ( i. len ( ) ) ;
156166 if let Some ( origin) = origin {
157167 if origin as usize > PIO_INSTRUCTION_COUNT - i. len ( )
158168 || self . used_instruction_space & ( mask << origin) != 0
@@ -208,7 +218,7 @@ impl<P: PIOExt> PIO<P> {
208218 {
209219 self . pio . instr_mem [ i + offset] . write ( |w| unsafe { w. bits ( instr as u32 ) } )
210220 }
211- self . used_instruction_space |= ( ( 1 << p. code . len ( ) ) - 1 ) << offset;
221+ self . used_instruction_space |= Self :: instruction_mask ( p. code . len ( ) ) << offset;
212222 Ok ( InstalledProgram {
213223 offset : offset as u8 ,
214224 length : p. code . len ( ) as u8 ,
@@ -223,7 +233,7 @@ impl<P: PIOExt> PIO<P> {
223233
224234 /// Removes the specified program from instruction memory, freeing the allocated space.
225235 pub fn uninstall ( & mut self , p : InstalledProgram < P > ) {
226- let instr_mask = ( ( 1 << p. length as u32 ) - 1 ) << p. offset as u32 ;
236+ let instr_mask = Self :: instruction_mask ( p. length as usize ) << p. offset as u32 ;
227237 self . used_instruction_space &= !instr_mask;
228238 }
229239}
0 commit comments