@@ -54,13 +54,13 @@ namespace klib::core::atsam4s::io {
5454 * @brief Internal write implementation
5555 *
5656 * @note software doesnt check if stop is correctly send
57- *
58- * @tparam SendStop
59- * @param address
60- * @param data
61- * @param size
62- * @return true
63- * @return false
57+ *
58+ * @tparam SendStop
59+ * @tparam std::span<const uint8_t>
60+ * @param address
61+ * @param data
62+ * @return true
63+ * @return false
6464 */
6565 template <bool SendStop = true , typename T = std::span<const uint8_t >>
6666 constexpr static bool write_impl (const uint8_t address, const T& data) {
@@ -116,22 +116,36 @@ namespace klib::core::atsam4s::io {
116116 * @note software doesnt check if stop is correctly send
117117 *
118118 * @tparam SendStop
119+ * @tparam RepeatedStart
119120 * @tparam std::span<const uint8_t>
120121 * @param address
121122 * @param data
122123 * @return true
123124 * @return false
124125 */
125- template <bool SendStop = true , typename T = std::span<const uint8_t >>
126- constexpr static bool read_impl (const uint8_t address, const T& data) {
126+ template <bool SendStop = true , bool RepeatedStart = false , typename T = std::span<uint8_t >>
127+ constexpr static bool read_impl (const uint8_t address, const T& data, const uint32_t device_address = 0 , const uint8_t device_address_size = 0 ) {
127128 // hardware does not writes with less than 1 byte
128129 if (!data.size ()) {
129130 // return we could not transmit the data
130131 return false ;
131132 }
132133
133- // set the address we want to read from
134- read_write_set_address<true >(address);
134+ // check if we have a repeated start condition
135+ if constexpr (RepeatedStart) {
136+ // make sure the SendStop flag is true
137+ static_assert (SendStop, " Repeated starts require the SendStop flag to be enabled" );
138+
139+ // set the address we want to read from
140+ read_write_set_address<true >(address, device_address_size);
141+
142+ // set the data to transmit
143+ I2c::port->IADR = device_address;
144+ }
145+ else {
146+ // set the address we want to read from
147+ read_write_set_address<true >(address);
148+ }
135149
136150 // start the transaction
137151 I2c::port->CR = 0x1 ;
@@ -164,6 +178,23 @@ namespace klib::core::atsam4s::io {
164178 return (wait_for_status (mask) & mask) == 0x1 ;
165179 }
166180
181+ template <typename T = std::span<uint8_t >, typename G = std::span<uint8_t >>
182+ constexpr static bool write_read_impl (const uint8_t address, const T& tx, const G& rx) {
183+ // check if data is out of range
184+ if (tx.size () > 3 ) {
185+ return false ;
186+ }
187+
188+ // get the device address
189+ uint32_t addr = 0 ;
190+ for (uint8_t i = 0 ; i < tx.size (); i++) {
191+ addr = (addr << 8 ) | tx[i];
192+ }
193+
194+ // read the data
195+ return read_impl<true , true >(address, rx, addr, tx.size ());
196+ }
197+
167198 public:
168199 /* *
169200 * @brief Init the i2c bus
@@ -244,6 +275,38 @@ namespace klib::core::atsam4s::io {
244275 constexpr static bool write (const uint8_t address, const multispan<const uint8_t >& data) {
245276 return write_impl<SendStop>(address, data);
246277 }
278+
279+ /* *
280+ * @brief Write up to 3 bytes and read data. This
281+ * uses the repeated start in the i2c protocol. If
282+ * you do not want to use repeated start use
283+ * write/read instead
284+ *
285+ * @param address
286+ * @param tx
287+ * @param rx
288+ * @return true
289+ * @return false
290+ */
291+ constexpr static bool write_read (const uint8_t address, const std::span<const uint8_t >& tx, const std::span<uint8_t >& rx) {
292+ return write_read_impl (address, tx, rx);
293+ }
294+
295+ /* *
296+ * @brief Write up to 3 bytes and read data. This
297+ * uses the repeated start in the i2c protocol. If
298+ * you do not want to use repeated start use
299+ * write/read instead
300+ *
301+ * @param address
302+ * @param tx
303+ * @param rx
304+ * @return true
305+ * @return false
306+ */
307+ constexpr static bool write_read (const uint8_t address, const std::span<const uint8_t >& tx, const klib::multispan<uint8_t >& rx) {
308+ return write_read_impl (address, tx, rx);
309+ }
247310 };
248311}
249312
0 commit comments