Recent

Author Topic: Is it possible to write bytes to the Master from this procedure ?  (Read 345 times)

pascalbythree

  • Sr. Member
  • ****
  • Posts: 277
https://github.com/ccrause/fpc-avr/blob/master/src/library/i2cslave_unit.pas

https://github.com/ccrause/fpc-avr/blob/master/src/examples/i2cslave/i2cslavedemo.pp


Code: Pascal  [Select][+][-]
  1. // Reply with current counter value, then increment counter
  2. procedure DataRequestHandler(out data: byte; out ACK: boolean);
  3. begin
  4.   data := counter;
  5.   inc(counter);
  6.   // Can supply more data
  7.   ACK := true;
  8.  
  9.   {$ifdef DEBUGPRINT}
  10.   uart_transmit(ord('T'));
  11.   uart_transmit_hex(data);
  12.   uart_transmit(10);
  13.   {$endif DEBUGPRINT}
  14. end;

Code: Pascal  [Select][+][-]
  1. // Reply with current counter value, then increment counter
  2. procedure DataRequestHandler(out data: byte; out ACK: boolean);
  3. begin
  4.   //what to add here?
  5. end;
  6.  

Hello to all freepascal.org members, can somebody answer weither it is possible to send strings/bytes from this AVR slave to a master in freepascal? Must i code something in this unit? or am i looking in the wrong direction? Greets, Wouter van Wegen
« Last Edit: March 08, 2025, 02:27:33 pm by pascalbythree »

ccrause

  • Hero Member
  • *****
  • Posts: 1026
Re: Is it possible to write bytes to the Master from this procedure ?
« Reply #1 on: March 13, 2025, 07:30:37 am »
Short answer,yes. The demo is a trivial counter example and the slave always returns the value of the counter, then increments the local value.

To send more complex data (multi-byte length) the master requesting the data must know how to request and interpret the data. For example to receive text, is the text encoded or plain ASCII, is it fixed or variable length?

A simple implementation for handling a variable length string could be as follows on the slave side:
- Master initiates I2C transaction by writing a byte value to slave that should be interpreted as selecting a status string.
- The slave receives this byte and stores it to know what should be returned when the master issues a read request.
- The master initiates a read request.
- The slave returns the first byte of the string and increments an internal index to the string. End return value with ACK.
- The master receives the byte. If the slave ended with ACK, read another byte.If the slave ended with NACK, end transaction.
- When the slave sends the last byte of the string, end the transaction by sending a NACK.

Untested code for illustration of the slave side implementation:
Code: Pascal  [Select][+][-]
  1. const
  2.   SLAVE_STATUS_STRING = 1;
  3.  
  4. var
  5.   state: byte; // what to return when returning data
  6.   status: shortstring;
  7.   index: byte;
  8.  
  9. procedure DataReceivedHandler(data: byte; ACK: boolean);
  10. begin
  11.   state := data;
  12.   // If addressing status, reset index to start of string
  13.   if state = SLAVE_STATUS_STRING then
  14.     index := 1;
  15. end;
  16.  
  17. procedure DataRequestHandler(out data: byte; out ACK: boolean);
  18. begin
  19.   case status of
  20.     SLAVE_STATUS_STRING:
  21.     begin
  22.       data := status[index];
  23.       inc(index);
  24.       ACK := index < length(status);
  25.     end;
  26.   end;
  27. end;

 

TinyPortal © 2005-2018