Add request, capture, flush to TWIBus
This commit is contained in:
		
							parent
							
								
									132322e4d9
								
							
						
					
					
						commit
						bd928a69ec
					
				| @ -5285,8 +5285,8 @@ inline void gcode_M121() { endstops.enable_globally(false); } | ||||
| 
 | ||||
|     uint8_t bytes = code_seen('B') ? code_value_byte() : 1; | ||||
| 
 | ||||
|     if (i2c.addr > 0 && bytes > 0 && bytes <= 32) { | ||||
|       i2c.reqbytes(bytes); | ||||
|     if (i2c.addr && bytes && bytes <= TWIBUS_BUFFER_SIZE) { | ||||
|       i2c.relay(bytes); | ||||
|     } | ||||
|     else { | ||||
|       SERIAL_ERROR_START; | ||||
|  | ||||
| @ -86,32 +86,72 @@ void TWIBus::send() { | ||||
|   this->reset(); | ||||
| } | ||||
| 
 | ||||
| void TWIBus::echodata(uint8_t bytes, const char prefix[], uint8_t adr) { | ||||
| // static
 | ||||
| void TWIBus::echoprefix(uint8_t bytes, const char prefix[], uint8_t adr) { | ||||
|   SERIAL_ECHO_START; | ||||
|   serialprintPGM(prefix); | ||||
|   SERIAL_ECHOPAIR(": from:", adr); | ||||
|   SERIAL_ECHOPAIR(" bytes:", bytes); | ||||
|   SERIAL_ECHOPGM (" data:"); | ||||
| } | ||||
| 
 | ||||
| // static
 | ||||
| void TWIBus::echodata(uint8_t bytes, const char prefix[], uint8_t adr) { | ||||
|   echoprefix(bytes, prefix, adr); | ||||
|   while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read()); | ||||
|   SERIAL_EOL; | ||||
| } | ||||
| 
 | ||||
| void TWIBus::reqbytes(const uint8_t bytes) { | ||||
|   if (!this->addr) return; | ||||
| void TWIBus::echobuffer(const char prefix[], uint8_t adr) { | ||||
|   echoprefix(this->buffer_s, prefix, adr); | ||||
|   for (uint8_t i = 0; i < this->buffer_s; i++) SERIAL_CHAR(this->buffer[i]); | ||||
|   SERIAL_EOL; | ||||
| } | ||||
| 
 | ||||
| bool TWIBus::request(const uint8_t bytes) { | ||||
|   if (!this->addr) return false; | ||||
| 
 | ||||
|   #if ENABLED(DEBUG_TWIBUS) | ||||
|     debug(PSTR("reqbytes"), bytes); | ||||
|     debug(PSTR("request"), bytes); | ||||
|   #endif | ||||
| 
 | ||||
|   // requestFrom() is a blocking function
 | ||||
|   Wire.requestFrom(this->addr, bytes); | ||||
| 
 | ||||
|   // Wait until all bytes arrive, or timeout
 | ||||
|   // Wait for all bytes to arrive
 | ||||
|   millis_t t = millis() + this->timeout; | ||||
|   while (Wire.available() < bytes && PENDING(millis(), t)) { /*nada*/ } | ||||
|   while (Wire.available() < bytes) | ||||
|     if (ELAPSED(millis(), t)) { | ||||
|       #if ENABLED(DEBUG_TWIBUS) | ||||
|         SERIAL_ECHO_START; | ||||
|         SERIAL_ECHOLNPGM("i2c timeout"); | ||||
|       #endif | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|   // Simply echo the data to the bus
 | ||||
|   this->echodata(bytes, PSTR("i2c-reply"), this->addr); | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void TWIBus::relay(const uint8_t bytes) { | ||||
|   #if ENABLED(DEBUG_TWIBUS) | ||||
|     debug(PSTR("relay"), bytes); | ||||
|   #endif | ||||
| 
 | ||||
|   if (this->request(bytes)) | ||||
|     echodata(bytes, PSTR("i2c-reply"), this->addr); | ||||
| } | ||||
| 
 | ||||
| uint8_t TWIBus::capture(char *dst, const uint8_t bytes) { | ||||
|   this->reset(); | ||||
|   uint8_t count = 0; | ||||
|   while (count < bytes && Wire.available()) | ||||
|     dst[count++] = Wire.read(); | ||||
|   return count; | ||||
| } | ||||
| 
 | ||||
| // static
 | ||||
| void TWIBus::flush() { | ||||
|   while (Wire.available()) Wire.read(); | ||||
| } | ||||
| 
 | ||||
| #if I2C_SLAVE_ADDRESS > 0 | ||||
| @ -120,7 +160,7 @@ void TWIBus::reqbytes(const uint8_t bytes) { | ||||
|     #if ENABLED(DEBUG_TWIBUS) | ||||
|       debug(PSTR("receive"), bytes); | ||||
|     #endif | ||||
|     this->echodata(bytes, PSTR("i2c-receive"), 0); | ||||
|     echodata(bytes, PSTR("i2c-receive"), 0); | ||||
|   } | ||||
| 
 | ||||
|   void TWIBus::reply(char str[]/*=NULL*/) { | ||||
| @ -142,6 +182,7 @@ void TWIBus::reqbytes(const uint8_t bytes) { | ||||
| 
 | ||||
| #if ENABLED(DEBUG_TWIBUS) | ||||
| 
 | ||||
|   // static
 | ||||
|   void TWIBus::prefix(const char func[]) { | ||||
|     SERIAL_ECHOPGM("TWIBus::"); | ||||
|     serialprintPGM(func); | ||||
|  | ||||
| @ -33,6 +33,8 @@ | ||||
| typedef void (*twiReceiveFunc_t)(int bytes); | ||||
| typedef void (*twiRequestFunc_t)(); | ||||
| 
 | ||||
| #define TWIBUS_BUFFER_SIZE 32 | ||||
| 
 | ||||
| /**
 | ||||
|  * TWIBUS class | ||||
|  * | ||||
| @ -70,7 +72,7 @@ class TWIBus { | ||||
|      * @brief Internal buffer | ||||
|      * @details A fixed buffer. TWI commands can be no longer than this. | ||||
|      */ | ||||
|     char buffer[32]; | ||||
|     char buffer[TWIBUS_BUFFER_SIZE]; | ||||
| 
 | ||||
| 
 | ||||
|   public: | ||||
| @ -134,6 +136,14 @@ class TWIBus { | ||||
|      */ | ||||
|     void address(const uint8_t adr); | ||||
| 
 | ||||
|     /**
 | ||||
|      * @brief Prefix for echo to serial | ||||
|      * @details Echo a label, length, address, and "data:" | ||||
|      * | ||||
|      * @param bytes the number of bytes to request | ||||
|      */ | ||||
|     static void echoprefix(uint8_t bytes, const char prefix[], uint8_t adr); | ||||
| 
 | ||||
|     /**
 | ||||
|      * @brief Echo data on the bus to serial | ||||
|      * @details Echo some number of bytes from the bus | ||||
| @ -144,14 +154,48 @@ class TWIBus { | ||||
|     static void echodata(uint8_t bytes, const char prefix[], uint8_t adr); | ||||
| 
 | ||||
|     /**
 | ||||
|      * @brief Request data from the slave device | ||||
|      * @details Request a number of bytes from a slave device. | ||||
|      *          This implementation simply sends the data to serial | ||||
|      *          in a parser-friendly format. | ||||
|      * @brief Echo data in the buffer to serial | ||||
|      * @details Echo the entire buffer to serial | ||||
|      *          to serial in a parser-friendly format. | ||||
|      * | ||||
|      * @param bytes the number of bytes to request | ||||
|      */ | ||||
|     void reqbytes(const uint8_t bytes); | ||||
|     void echobuffer(const char prefix[], uint8_t adr); | ||||
| 
 | ||||
|     /**
 | ||||
|      * @brief Request data from the slave device and wait. | ||||
|      * @details Request a number of bytes from a slave device. | ||||
|      *          Wait for the data to arrive until the timeout | ||||
|      *          interval expires. Return true on success. | ||||
|      * | ||||
|      * @param bytes the number of bytes to request | ||||
|      * @return status of the request: true=success, false=timeout | ||||
|      */ | ||||
|     bool request(const uint8_t bytes); | ||||
| 
 | ||||
|     /**
 | ||||
|      * @brief Capture data from the bus into the buffer. | ||||
|      * @details Capture data after a request has succeeded. | ||||
|      * | ||||
|      * @param bytes the number of bytes to request | ||||
|      * @return the number of bytes captured to the buffer | ||||
|      */ | ||||
|     uint8_t capture(char *dst, const uint8_t bytes); | ||||
| 
 | ||||
|     /**
 | ||||
|      * @brief Flush the i2c bus. | ||||
|      * @details Get all bytes on the bus and throw them away. | ||||
|      */ | ||||
|     static void flush(); | ||||
| 
 | ||||
|     /**
 | ||||
|      * @brief Request data from the slave device, echo to serial. | ||||
|      * @details Request a number of bytes from a slave device and output | ||||
|      *          the returned data to serial in a parser-friendly format. | ||||
|      * | ||||
|      * @param bytes the number of bytes to request | ||||
|      */ | ||||
|     void relay(const uint8_t bytes); | ||||
| 
 | ||||
|     #if I2C_SLAVE_ADDRESS > 0 | ||||
| 
 | ||||
| @ -181,6 +225,7 @@ class TWIBus { | ||||
|       /**
 | ||||
|        * @brief Send a reply to the bus | ||||
|        * @details Send the buffer and clear it. | ||||
|        *          If a string is passed, write it into the buffer first. | ||||
|        */ | ||||
|       void reply(char str[]=NULL); | ||||
|       inline void reply(const char str[]) { this->reply((char*)str); } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user