55 */  
66
77#include  < Wire.h> 
8+ #include  < stddef.h> 
89#include  < zephyr/sys/util_macro.h> 
910
10- arduino::ZephyrI2C::ZephyrI2C (const  struct  device  *i2c) : i2c_dev(i2c)
11- {
11+ //  Helper function to get ZephyrI2C instance from config pointer.
12+ static  arduino::ZephyrI2C* getInstance (struct  i2c_target_config  *config) {
13+     return  reinterpret_cast <arduino::ZephyrI2C*>(
14+         reinterpret_cast <char *>(config) - offsetof (arduino::ZephyrI2C, i2c_cfg)
15+     );
16+ }
17+ 
18+ static  int  i2c_target_stop_cb (struct  i2c_target_config  *config) {
19+     arduino::ZephyrI2C *instance = getInstance (config);
20+     return  instance->stopCallback (config);
21+ }
22+ 
23+ static  int  i2c_target_write_requested_cb (struct  i2c_target_config  *config) {
24+     arduino::ZephyrI2C *instance = getInstance (config);
25+     return  instance->writeRequestedCallback (config);
26+ }
27+ 
28+ static  int  i2c_target_write_received_cb (struct  i2c_target_config  *config, uint8_t  val) {
29+     arduino::ZephyrI2C *instance = getInstance (config);
30+     return  instance->writeReceivedCallback (config, val);
31+ }
32+ 
33+ static  int  i2c_target_read_requested_cb (struct  i2c_target_config  *config, uint8_t  *val) {
34+     arduino::ZephyrI2C *instance = getInstance (config);
35+     return  instance->readRequestedCallback (config, val);
36+ }
37+ 
38+ static  int  i2c_target_read_processed_cb (struct  i2c_target_config  *config, uint8_t  *val) {
39+     arduino::ZephyrI2C *instance = getInstance (config);
40+     return  instance->readProcessedCallback (config, val);
41+ }
42+ 
43+ //  I2C target callback structure.
44+ static  struct  i2c_target_callbacks  target_callbacks = {
45+     .write_requested  = i2c_target_write_requested_cb,
46+     .read_requested  = i2c_target_read_requested_cb,
47+     .write_received  = i2c_target_write_received_cb,
48+     .read_processed  = i2c_target_read_processed_cb,
49+     .stop  = i2c_target_stop_cb,
50+ };
51+ 
52+ arduino::ZephyrI2C::ZephyrI2C (const  struct  device  *i2c) : i2c_dev(i2c), i2c_cfg({0 }) {
53+     ring_buf_init (&txRingBuffer.rb , sizeof (txRingBuffer.buffer ), txRingBuffer.buffer );
54+     ring_buf_init (&rxRingBuffer.rb , sizeof (rxRingBuffer.buffer ), rxRingBuffer.buffer );
55+ 
1256}
1357
1458void  arduino::ZephyrI2C::begin () {
15-    ring_buf_init (&rxRingBuffer. rb ,  sizeof (rxRingBuffer. buffer ), rxRingBuffer. buffer ); 
59+ 
1660}
1761
1862void  arduino::ZephyrI2C::begin (uint8_t  slaveAddr) {
19- 
63+     i2c_cfg.address  = slaveAddr;
64+     i2c_cfg.callbacks  = &target_callbacks;
65+     
66+     //  Register I2C target
67+     i2c_target_register (i2c_dev, &i2c_cfg);
2068}
2169
22- void  arduino::ZephyrI2C::end () {}
70+ void  arduino::ZephyrI2C::end () {
71+     //  Unregister I2C target
72+     //  TODO
73+     // i2c_target_unregister(i2c_dev, &i2c_cfg);
74+ }
2375
2476void  arduino::ZephyrI2C::setClock (uint32_t  freq) {
25-     uint8_t  speed = 	I2C_SPEED_STANDARD;
26- 	if (freq >  0x06u  ) {
27- 		if (freq == 100000 ) {
28- 		  speed = I2C_SPEED_STANDARD;
29- 		} else  if (freq == 400000 ) {
30- 		  speed = I2C_SPEED_FAST;
31- 		} else  if (freq == 1000000 ) {
32- 		  speed = I2C_SPEED_FAST_PLUS;
33- 		} else  {
34- 		  speed = I2C_SPEED_STANDARD;
35- 		}
36- 	} else  {
37- 		speed = (uint8_t ) freq;
38- 	}
39- 	uint32_t  i2c_cfg = I2C_MODE_CONTROLLER |
40- 					I2C_SPEED_SET (speed);
41- 
42- 	if  (i2c_configure (i2c_dev, i2c_cfg)) {
43- 		// Serial.println("Failed to configure i2c interface.");
44- 	}
45- }
46- 
47- void  arduino::ZephyrI2C::beginTransmission (uint8_t  address) { //  TODO for ADS1115
77+     uint8_t  speed;
78+ 
79+     if  (freq == 100000 ) {
80+       speed = I2C_SPEED_STANDARD;
81+     } else  if  (freq == 400000 ) {
82+       speed = I2C_SPEED_FAST;
83+     } else  if  (freq == 1000000 ) {
84+       speed = I2C_SPEED_FAST_PLUS;
85+     } else  {
86+       speed = I2C_SPEED_STANDARD;
87+     }
88+ 
89+     i2c_configure (i2c_dev, I2C_SPEED_SET (speed) | I2C_MODE_CONTROLLER);
90+ }
91+ 
92+ void  arduino::ZephyrI2C::beginTransmission (uint8_t  address) {
4893  _address = address;
49-   usedTxBuffer = 0 ;
5094}
5195
5296uint8_t  arduino::ZephyrI2C::endTransmission (bool  stopBit) {
53-   int  ret = i2c_write (i2c_dev, txBuffer, usedTxBuffer, _address);
54-   if  (ret) {
55-     return  1 ; //  fail
97+   uint8_t  *data = NULL ;
98+   size_t  max = ring_buf_capacity_get (&txRingBuffer.rb );
99+   size_t  len = ring_buf_get_claim (&txRingBuffer.rb , &data, max);
100+ 
101+   if  (data) {
102+     if  (i2c_write (i2c_dev, data, len, _address)) {
103+       return  1 ; //  fail
104+     } else  {
105+       ring_buf_get_finish (&txRingBuffer.rb , len);
106+     }
56107  }
108+ 
57109  return  0 ;
58110}
59111
60- uint8_t  arduino::ZephyrI2C::endTransmission (void ) {  //  TODO for ADS1115 
112+ uint8_t  arduino::ZephyrI2C::endTransmission (void ) {
61113  return  endTransmission (true );
62114}
63115
64- size_t  arduino::ZephyrI2C::requestFrom (uint8_t  address, size_t  len,
65-                                        bool  stopBit) {
116+ size_t  arduino::ZephyrI2C::requestFrom (uint8_t  address, size_t  len, bool  stopBit) {
66117  uint8_t  buf[len];
67118  int  ret = i2c_read (i2c_dev, buf, len, address);
68119  if  (ret != 0 )
@@ -77,22 +128,16 @@ size_t arduino::ZephyrI2C::requestFrom(uint8_t address, size_t len,
77128  return  len;
78129}
79130
80- size_t  arduino::ZephyrI2C::requestFrom (uint8_t  address, size_t  len) {  //  TODO for ADS1115 
131+ size_t  arduino::ZephyrI2C::requestFrom (uint8_t  address, size_t  len) {
81132  return  requestFrom (address, len, true );
82133}
83134
84- size_t  arduino::ZephyrI2C::write (uint8_t  data) {  //  TODO for ADS1115
85-   txBuffer[usedTxBuffer++] = data;
86-   return  1 ;
135+ size_t  arduino::ZephyrI2C::write (uint8_t  data) {
136+   return  ring_buf_put (&txRingBuffer.rb , &data, 1 ) > 0 ;
87137}
88138
89139size_t  arduino::ZephyrI2C::write (const  uint8_t  *buffer, size_t  size) {
90-     if  (usedTxBuffer + size > 256 ) {
91-     size = 256  - usedTxBuffer;
92-   }
93- 	memcpy (txBuffer + usedTxBuffer, buffer, size);
94- 	usedTxBuffer += size;	
95-   return  size;
140+   return  ring_buf_put (&txRingBuffer.rb , buffer, size);
96141}
97142
98143int  arduino::ZephyrI2C::read () {
@@ -115,15 +160,58 @@ int arduino::ZephyrI2C::peek() {
115160  uint8_t  buf[1 ];
116161  int  bytes_read = ring_buf_peek (&rxRingBuffer.rb , buf, 1 );
117162  if  (bytes_read == 0 ){
118-     return  0 ;
163+     return  - 1 ;
119164  } 
120165  return  (int )buf[0 ];
121166}
122167
123- void  arduino::ZephyrI2C::flush () {}
168+ void  arduino::ZephyrI2C::flush () {
169+ 
170+ }
171+ 
172+ void  arduino::ZephyrI2C::onReceive (voidFuncPtrParamInt cb) {
173+   onReceiveCb = cb;
174+ }
175+ 
176+ void  arduino::ZephyrI2C::onRequest (voidFuncPtr cb) {
177+   onRequestCb = cb;
178+ }
179+ 
180+ int  arduino::ZephyrI2C::writeRequestedCallback (struct  i2c_target_config  *config) {
181+   return  0 ;
182+ }
183+ 
184+ int  arduino::ZephyrI2C::writeReceivedCallback (struct  i2c_target_config  *config, uint8_t  val) {
185+   return  0 ;
186+ }
187+ 
188+ int  arduino::ZephyrI2C::readRequestedCallback (struct  i2c_target_config  *config, uint8_t  *val) {
189+   //  Reset the buffer on new read requests. 
190+   ring_buf_reset (&txRingBuffer.rb );
124191
125- void  arduino::ZephyrI2C::onReceive (voidFuncPtrParamInt cb) {}
126- void  arduino::ZephyrI2C::onRequest (voidFuncPtr cb) {}
192+   if  (onRequestCb) {
193+     onRequestCb ();
194+   }
195+ 
196+   return  readProcessedCallback (config, val);
197+ }
198+ 
199+ int  arduino::ZephyrI2C::readProcessedCallback (struct  i2c_target_config  *config, uint8_t  *val) {
200+   if  (!ring_buf_peek (&txRingBuffer.rb , val, 1 )) {
201+       *val = 0xFF ;
202+   } else  {
203+     ring_buf_get (&txRingBuffer.rb , val, 1 );
204+   }
205+ 
206+   //  Contrary to what's documented, returning a negative value to
207+   //  indicate that there's no more data is not handled gracefully,
208+   //  and will halt the target, at least with ST drivers.
209+   return  0 ;
210+ }
211+ 
212+ int  arduino::ZephyrI2C::stopCallback (struct  i2c_target_config  *config) {
213+   return  0 ;
214+ }
127215
128216#if  DT_NODE_HAS_PROP(DT_PATH(zephyr_user), i2cs)
129217#if  (DT_PROP_LEN(DT_PATH(zephyr_user), i2cs) > 1)
0 commit comments