11// Licensed under the Apache-2.0 license
2-
32use crate :: common:: { DmaBuffer , DummyDelay , Logger } ;
43#[ cfg( feature = "i2c_target" ) ]
54use crate :: i2c:: common:: I2cSEvent ;
@@ -10,6 +9,7 @@ use core::cmp::min;
109use core:: fmt:: Write ;
1110use core:: marker:: PhantomData ;
1211use core:: ops:: Drop ;
12+ use core:: result:: Result ;
1313use core:: sync:: atomic:: { AtomicBool , Ordering } ;
1414
1515use embedded_hal:: delay:: DelayNs ;
@@ -314,16 +314,11 @@ impl<I2C: Instance, I2CT: I2CTarget, L: Logger> HardwareInterface for Ast1060I2c
314314 system_control : & mut S ,
315315 config : & mut I2cConfig ,
316316 ) -> Result < ( ) , Self :: Error > {
317- use crate :: syscon:: ResetId ;
317+ // Handle system-level initialization
318+ Self :: init_i2c_global_system ( system_control) ?;
318319
319- // Enable I2C clock and deassert reset
320- let reset_id = ResetId :: RstI2C ;
321- system_control
322- . reset_deassert ( & reset_id)
323- . map_err ( |_| Error :: Bus ) ?;
324-
325- // Initialize the I2C controller
326- self . init ( config)
320+ // Handle peripheral-level initialization (without SCU coupling)
321+ self . init_peripheral_only ( config)
327322 }
328323
329324 fn init ( & mut self , config : & mut I2cConfig ) -> Result < ( ) , Self :: Error > {
@@ -1820,6 +1815,134 @@ impl<'a, I2C: Instance, I2CT: I2CTarget, L: Logger> Ast1060I2c<'a, I2C, I2CT, L>
18201815 // Fallthrough is success
18211816 Ok ( ( ) )
18221817 }
1818+
1819+ /// Initialize the global I2C system using system control interface
1820+ fn init_i2c_global_system <
1821+ S : proposed_traits:: system_control:: ResetControl < ResetId = crate :: syscon:: ResetId > ,
1822+ > (
1823+ system_control : & mut S ,
1824+ ) -> Result < ( ) , Error > {
1825+ use crate :: syscon:: ResetId ;
1826+
1827+ if I2CGLOBAL_INIT
1828+ . compare_exchange ( false , true , Ordering :: SeqCst , Ordering :: SeqCst )
1829+ . is_ok ( )
1830+ {
1831+ // Use system_control for reset operations instead of direct SCU access
1832+ let reset_id = ResetId :: RstI2C ;
1833+ system_control
1834+ . reset_assert ( & reset_id)
1835+ . map_err ( |_| Error :: Bus ) ?;
1836+
1837+ let mut delay = DummyDelay { } ;
1838+ delay. delay_ns ( 1_000_000 ) ; // 1ms delay
1839+
1840+ system_control
1841+ . reset_deassert ( & reset_id)
1842+ . map_err ( |_| Error :: Bus ) ?;
1843+ delay. delay_ns ( 1_000_000 ) ; // 1ms delay
1844+
1845+ // I2C global configuration (still needs I2cglobal access)
1846+ let i2cg = unsafe { & * I2cglobal :: ptr ( ) } ;
1847+ i2cg. i2cg0c ( ) . write ( |w| {
1848+ w. clk_divider_mode_sel ( )
1849+ . set_bit ( )
1850+ . reg_definition_sel ( )
1851+ . set_bit ( )
1852+ . select_the_action_when_slave_pkt_mode_rxbuf_empty ( )
1853+ . set_bit ( )
1854+ } ) ;
1855+ /*
1856+ * APB clk : 50Mhz
1857+ * div : scl : baseclk [APB/((div/2) + 1)] : tBuf [1/bclk * 16]
1858+ * I2CG10[31:24] base clk4 for i2c auto recovery timeout counter (0x62)
1859+ * I2CG10[23:16] base clk3 for Standard-mode (100Khz) min tBuf 4.7us
1860+ * 0x1d : 100.8Khz : 3.225Mhz : 4.96us
1861+ * 0x1e : 97.66Khz : 3.125Mhz : 5.12us
1862+ * 0x1f : 97.85Khz : 3.03Mhz : 5.28us
1863+ * 0x20 : 98.04Khz : 2.94Mhz : 5.44us
1864+ * 0x21 : 98.61Khz : 2.857Mhz : 5.6us
1865+ * 0x22 : 99.21Khz : 2.77Mhz : 5.76us (default)
1866+ * I2CG10[15:8] base clk2 for Fast-mode (400Khz) min tBuf 1.3us
1867+ * 0x08 : 400Khz : 10Mhz : 1.6us
1868+ * I2CG10[7:0] base clk1 for Fast-mode Plus (1Mhz) min tBuf 0.5us
1869+ * 0x03 : 1Mhz : 20Mhz : 0.8us
1870+ */
1871+ i2cg. i2cg10 ( ) . write ( |w| unsafe { w. bits ( 0x6222_0803 ) } ) ;
1872+ }
1873+ Ok ( ( ) )
1874+ }
1875+
1876+ /// Initialize only the peripheral-level I2C controller (no SCU coupling)
1877+ #[ allow( clippy:: unnecessary_wraps) ]
1878+ fn init_peripheral_only ( & mut self , config : & mut I2cConfig ) -> Result < ( ) , Error > {
1879+ i2c_debug ! ( self . logger, "i2c peripheral init" ) ;
1880+ i2c_debug ! (
1881+ self . logger,
1882+ "mdma_buf {:p}, sdma_buf {:p}" ,
1883+ self . mdma_buf. as_ptr( ) ,
1884+ self . sdma_buf. as_ptr( )
1885+ ) ;
1886+
1887+ // Store configuration
1888+ self . xfer_mode = config. xfer_mode ;
1889+ self . multi_master = config. multi_master ;
1890+ self . smbus_alert = config. smbus_alert ;
1891+
1892+ // I2C peripheral reset and configuration (no SCU dependency)
1893+ self . i2c . i2cc00 ( ) . write ( |w| unsafe { w. bits ( 0 ) } ) ;
1894+ if !self . multi_master {
1895+ self . i2c
1896+ . i2cc00 ( )
1897+ . write ( |w| w. dis_multimaster_capability_for_master_fn_only ( ) . set_bit ( ) ) ;
1898+ }
1899+ self . i2c . i2cc00 ( ) . write ( |w| {
1900+ w. enbl_bus_autorelease_when_scllow_sdalow_or_slave_mode_inactive_timeout ( )
1901+ . set_bit ( )
1902+ . enbl_master_fn ( )
1903+ . set_bit ( )
1904+ } ) ;
1905+
1906+ // set AC timing
1907+ self . configure_timing ( config) ;
1908+ // clear interrupts
1909+ self . i2c . i2cm14 ( ) . write ( |w| unsafe { w. bits ( 0xffff_ffff ) } ) ;
1910+ // set interrupt
1911+ self . i2c . i2cm10 ( ) . write ( |w| {
1912+ w. enbl_pkt_cmd_done_int ( )
1913+ . set_bit ( )
1914+ . enbl_bus_recover_done_int ( )
1915+ . set_bit ( )
1916+ } ) ;
1917+ i2c_debug ! (
1918+ self . logger,
1919+ "i2c init after set interrupt: {:#x}" ,
1920+ self . i2c. i2cm14( ) . read( ) . bits( )
1921+ ) ;
1922+ if self . smbus_alert {
1923+ self . i2c
1924+ . i2cm10 ( )
1925+ . write ( |w| w. enbl_smbus_dev_alert_int ( ) . set_bit ( ) ) ;
1926+ }
1927+
1928+ if cfg ! ( feature = "i2c_target" ) {
1929+ i2c_debug ! ( self . logger, "i2c target enabled" ) ;
1930+ // clear slave interrupts
1931+ self . i2c . i2cs24 ( ) . write ( |w| unsafe { w. bits ( 0xffff_ffff ) } ) ;
1932+ if self . xfer_mode == I2cXferMode :: ByteMode {
1933+ self . i2c . i2cs20 ( ) . write ( |w| unsafe { w. bits ( 0xffff ) } ) ;
1934+ } else {
1935+ self . i2c . i2cs20 ( ) . write ( |w| {
1936+ w. enbl_slave_mode_inactive_timeout_int ( )
1937+ . set_bit ( )
1938+ . enbl_pkt_cmd_done_int ( )
1939+ . set_bit ( )
1940+ } ) ;
1941+ }
1942+ }
1943+
1944+ Ok ( ( ) )
1945+ }
18231946}
18241947
18251948macro_rules! transaction_impl {
0 commit comments