11use crate :: common:: { DmaBuffer , DummyDelay } ;
22use crate :: i2c:: common:: { I2cConfig , I2cSEvent , I2cXferMode } ;
3+ use crate :: i2c:: i2c:: HardwareInterface ;
34use crate :: uart:: UartController ;
45use ast1060_pac:: { I2cbuff , I2cglobal , Scu } ;
56use core:: cmp:: min;
@@ -298,10 +299,12 @@ impl<I2C: Instance, I2CT: I2CTarget> Drop for I2cController<'_, I2C, I2CT> {
298299 // Disable i2c controller
299300 self . i2c . i2cc00 ( ) . write ( |w| unsafe { w. bits ( 0 ) } ) ;
300301 // Disable interrupt and clear interrupt status
301- self . i2c . i2cm10 ( ) . write ( |w| unsafe { w. bits ( 0 ) } ) ;
302- self . i2c . i2cm14 ( ) . write ( |w| unsafe { w. bits ( 0xffff_ffff ) } ) ;
303- self . i2c . i2cs20 ( ) . write ( |w| unsafe { w. bits ( 0 ) } ) ;
304- self . i2c . i2cs24 ( ) . write ( |w| unsafe { w. bits ( 0xffff_ffff ) } ) ;
302+ self . enable_interrupts ( 0 ) ;
303+ self . clear_interrupts ( 0xffff_ffff ) ;
304+ #[ cfg( feature = "i2c_target" ) ]
305+ self . enable_slave_interrupts ( 0 ) ;
306+ #[ cfg( feature = "i2c_target" ) ]
307+ self . clear_slave_interrupts ( 0xffff_ffff ) ;
305308 }
306309}
307310macro_rules! dbg {
@@ -312,6 +315,154 @@ macro_rules! dbg {
312315 }
313316 } ;
314317}
318+
319+ impl < ' a , I2C : Instance , I2CT : I2CTarget > HardwareInterface for I2cController < ' a , I2C , I2CT > {
320+ type Error = Error ;
321+
322+ fn init ( & mut self ) {
323+ self . init ( ) ;
324+ }
325+ fn configure_timing ( & mut self , config : & mut I2cConfig ) -> Result < ( ) , Self :: Error > {
326+ let scu = unsafe { & * Scu :: ptr ( ) } ;
327+ config. timing_config . clk_src =
328+ HPLL_FREQ / ( ( scu. scu310 ( ) . read ( ) . apbbus_pclkdivider_sel ( ) . bits ( ) as u32 + 1 ) * 2 ) ;
329+
330+ let p = unsafe { & * I2cglobal :: ptr ( ) } ;
331+ let mut div: u32 ;
332+ let mut divider_ratio: u32 ;
333+
334+ if p. i2cg0c ( ) . read ( ) . clk_divider_mode_sel ( ) . bit_is_set ( ) {
335+ let base_clk = config. timing_config . clk_src ;
336+ let base_clk1 = ( config. timing_config . clk_src * 10 )
337+ / ( ( p. i2cg10 ( ) . read ( ) . base_clk1divisor_basedivider1 ( ) . bits ( ) as u32 + 2 ) * 10 / 2 ) ;
338+ let base_clk2 = ( config. timing_config . clk_src * 10 )
339+ / ( ( p. i2cg10 ( ) . read ( ) . base_clk2divisor_basedivider2 ( ) . bits ( ) as u32 + 2 ) * 10 / 2 ) ;
340+ let base_clk3 = ( config. timing_config . clk_src * 10 )
341+ / ( ( p. i2cg10 ( ) . read ( ) . base_clk3divisor_basedivider3 ( ) . bits ( ) as u32 + 2 ) * 10 / 2 ) ;
342+ let base_clk4 = ( config. timing_config . clk_src * 10 )
343+ / ( ( p. i2cg10 ( ) . read ( ) . base_clk4divisor_basedivider4 ( ) . bits ( ) as u32 + 2 ) * 10 / 2 ) ;
344+
345+ // rounding
346+ if config. timing_config . clk_src / ( config. speed as u32 ) <= 32 {
347+ div = 0 ;
348+ divider_ratio = base_clk / config. speed as u32 ;
349+ if base_clk / divider_ratio > config. speed as u32 {
350+ divider_ratio += 1 ;
351+ }
352+ } else if base_clk1 / ( config. speed as u32 ) <= 32 {
353+ div = 1 ;
354+ divider_ratio = base_clk1 / config. speed as u32 ;
355+ if base_clk1 / divider_ratio > config. speed as u32 {
356+ divider_ratio += 1 ;
357+ }
358+ } else if base_clk2 / ( config. speed as u32 ) <= 32 {
359+ div = 2 ;
360+ divider_ratio = base_clk2 / config. speed as u32 ;
361+ if base_clk2 / divider_ratio > config. speed as u32 {
362+ divider_ratio += 1 ;
363+ }
364+ } else if base_clk3 / ( config. speed as u32 ) <= 32 {
365+ div = 3 ;
366+ divider_ratio = base_clk3 / config. speed as u32 ;
367+ if base_clk3 / divider_ratio > config. speed as u32 {
368+ divider_ratio += 1 ;
369+ }
370+ } else {
371+ div = 4 ;
372+ divider_ratio = base_clk4 / config. speed as u32 ;
373+ let mut inc = 0 ;
374+ while divider_ratio + inc > 32 {
375+ inc |= divider_ratio & 1u32 ;
376+ divider_ratio >>= 1 ;
377+ div += 1 ;
378+ }
379+ divider_ratio += inc;
380+ if base_clk4 / divider_ratio > config. speed as u32 {
381+ divider_ratio += 1 ;
382+ }
383+ divider_ratio = min ( divider_ratio, 32 ) ;
384+ div &= 0xf ;
385+ }
386+
387+ let mut scl_low: u8 ;
388+ let mut scl_high: u8 ;
389+ if ( config. timing_config . manual_scl_low & config. timing_config . manual_scl_high ) != 0 {
390+ scl_low = config. timing_config . manual_scl_low ;
391+ scl_high = config. timing_config . manual_scl_high ;
392+ } else if ( config. timing_config . manual_scl_low | config. timing_config . manual_scl_high ) != 0 {
393+ if config. timing_config . manual_scl_low != 0 {
394+ scl_low = config. timing_config . manual_scl_low ;
395+ scl_high = divider_ratio as u8 - scl_low - 2 ;
396+ } else {
397+ scl_high = config. timing_config . manual_scl_high ;
398+ scl_low = divider_ratio as u8 - scl_high - 2 ;
399+ }
400+ } else {
401+ scl_low = ( divider_ratio * 9 / 16 - 1 ) as u8 ;
402+ scl_high = divider_ratio as u8 - scl_low - 2 ;
403+ }
404+ scl_low = min ( scl_low, 0xf ) ;
405+ scl_high = min ( scl_high, 0xf ) ;
406+
407+ /*Divisor : Base Clock : tCKHighMin : tCK High : tCK Low*/
408+ self . i2c
409+ . i2cc04 ( )
410+ . write ( |w| unsafe { w. base_clk_divisor_tbase_clk ( ) . bits ( div as u8 ) } ) ;
411+ self . i2c . i2cc04 ( ) . write ( |w| unsafe {
412+ w. cycles_of_master_sclclklow_pulse_width_tcklow ( )
413+ . bits ( scl_low)
414+ } ) ;
415+ self . i2c . i2cc04 ( ) . write ( |w| unsafe {
416+ w. cycles_of_master_sclclkhigh_pulse_width_tckhigh ( )
417+ . bits ( scl_high)
418+ } ) ;
419+ self . i2c . i2cc04 ( ) . write ( |w| unsafe {
420+ w. cycles_of_master_sclclkhigh_minimum_pulse_width_tckhigh_min ( )
421+ . bits ( scl_high - 1 )
422+ } ) ;
423+
424+ if config. smbus_timeout {
425+ self . i2c . i2cc04 ( ) . write ( |w| unsafe {
426+ w. timeout_base_clk_divisor_tout_base_clk ( )
427+ . bits ( 2 )
428+ . timeout_timer ( )
429+ . bits ( 8 )
430+ } ) ;
431+ }
432+ if config. timing_config . manual_sda_hold < 4 {
433+ self . i2c . i2cc04 ( ) . write ( |w| unsafe {
434+ w. hold_time_of_masterslave_data_thddat ( )
435+ . bits ( config. timing_config . manual_sda_hold )
436+ } ) ;
437+ }
438+ }
439+ Ok ( ( ) )
440+ }
441+ fn enable_interrupts ( & mut self , mask : u32 ) {
442+ self . i2c . i2cm10 ( ) . write ( |w| unsafe { w. bits ( mask) } ) ;
443+ }
444+ fn clear_interrupts ( & mut self , mask : u32 ) {
445+ self . i2c . i2cm14 ( ) . write ( |w| unsafe { w. bits ( mask) } ) ;
446+ }
447+ #[ cfg( feature = "i2c_target" ) ]
448+ fn enable_slave_interrupts ( & mut self , mask : u32 ) {
449+ self . i2c . i2cs20 ( ) . write ( |w| unsafe { w. bits ( mask) } ) ;
450+ }
451+ #[ cfg( feature = "i2c_target" ) ]
452+ fn clear_slave_interrupts ( & mut self , mask : u32 ) {
453+ self . i2c . i2cs24 ( ) . write ( |w| unsafe { w. bits ( mask) } ) ;
454+ }
455+ fn handle_interrupt ( & mut self ) {
456+ //check slave mode first
457+ if self . i2c . i2cc00 ( ) . read ( ) . enbl_slave_fn ( ) . bit ( ) {
458+ if self . aspeed_i2c_slave_irq ( ) != 0 {
459+ return ;
460+ }
461+ }
462+ self . aspeed_i2c_master_irq ( ) ;
463+ }
464+ }
465+
315466impl < ' a , I2C : Instance , I2CT : I2CTarget > I2cController < ' a , I2C , I2CT > {
316467 pub fn new ( i2c : I2C , config : I2cConfig , uart : Option < & ' a mut UartController < ' a > > ) -> Self {
317468 let i2c = unsafe { & * I2C :: ptr ( ) } ;
0 commit comments