Master-only TwoWire class for LPC1768
This commit is contained in:
		
				
					committed by
					
						 Scott Lahteine
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							d5bf9e74c4
						
					
				
				
					commit
					6856eccc77
				
			
							
								
								
									
										238
									
								
								Marlin/src/HAL/HAL_LPC1768/Wire.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								Marlin/src/HAL/HAL_LPC1768/Wire.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,238 @@ | ||||
| /* | ||||
|   TwoWire.cpp - TWI/I2C library for Wiring & Arduino | ||||
|   Copyright (c) 2006 Nicholas Zambetti.  All right reserved. | ||||
|  | ||||
|   This library is free software; you can redistribute it and/or | ||||
|   modify it under the terms of the GNU Lesser General Public | ||||
|   License as published by the Free Software Foundation; either | ||||
|   version 2.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|   This library is distributed in the hope that it will be useful, | ||||
|   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|   Lesser General Public License for more details. | ||||
|  | ||||
|   You should have received a copy of the GNU Lesser General Public | ||||
|   License along with this library; if not, write to the Free Software | ||||
|   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | ||||
| */ | ||||
|  | ||||
| #ifdef TARGET_LPC1768 | ||||
|  | ||||
| extern "C" { | ||||
|   #include <stdlib.h> | ||||
|   #include <string.h> | ||||
|   #include <inttypes.h> | ||||
|   #include <lpc17xx_i2c.h> | ||||
|   #include <lpc17xx_pinsel.h> | ||||
|   #include <lpc17xx_libcfg_default.h> | ||||
| } | ||||
|  | ||||
| #include "Wire.h" | ||||
|  | ||||
| #define USEDI2CDEV_M 1 | ||||
|  | ||||
| #if (USEDI2CDEV_M == 0) | ||||
|   #define I2CDEV_M LPC_I2C0 | ||||
| #elif (USEDI2CDEV_M == 1) | ||||
|   #define I2CDEV_M LPC_I2C1 | ||||
| #elif (USEDI2CDEV_M == 2) | ||||
|   #define I2CDEV_M LPC_I2C2 | ||||
| #else | ||||
|   #error "Master I2C device not defined!" | ||||
| #endif | ||||
|  | ||||
| // Initialize Class Variables ////////////////////////////////////////////////// | ||||
|  | ||||
| uint8_t TwoWire::rxBuffer[BUFFER_LENGTH]; | ||||
| uint8_t TwoWire::rxBufferIndex = 0; | ||||
| uint8_t TwoWire::rxBufferLength = 0; | ||||
|  | ||||
| uint8_t TwoWire::txAddress = 0; | ||||
| uint8_t TwoWire::txBuffer[BUFFER_LENGTH]; | ||||
| uint8_t TwoWire::txBufferIndex = 0; | ||||
| uint8_t TwoWire::txBufferLength = 0; | ||||
|  | ||||
| uint8_t TwoWire::transmitting = 0; | ||||
|  | ||||
| // Constructors //////////////////////////////////////////////////////////////// | ||||
|  | ||||
| TwoWire::TwoWire() { | ||||
| } | ||||
|  | ||||
| // Public Methods ////////////////////////////////////////////////////////////// | ||||
|  | ||||
| void TwoWire::begin(void) { | ||||
|   rxBufferIndex = 0; | ||||
|   rxBufferLength = 0; | ||||
|  | ||||
|   txBufferIndex = 0; | ||||
|   txBufferLength = 0; | ||||
|  | ||||
|   /* | ||||
|    * Init I2C pin connect | ||||
|    */ | ||||
|   PINSEL_CFG_Type PinCfg; | ||||
|   PinCfg.OpenDrain = 0; | ||||
|   PinCfg.Pinmode = 0; | ||||
|   #if ((USEDI2CDEV_M == 0)) | ||||
|     PinCfg.Funcnum = 1; | ||||
|     PinCfg.Pinnum = 27; | ||||
|     PinCfg.Portnum = 0; | ||||
|     PINSEL_ConfigPin(&PinCfg); // SDA0 / D57  AUX-1 | ||||
|     PinCfg.Pinnum = 28; | ||||
|     PINSEL_ConfigPin(&PinCfg); // SCL0 / D58  AUX-1 | ||||
|   #endif | ||||
|   #if ((USEDI2CDEV_M == 1)) | ||||
|     PinCfg.Funcnum = 3; | ||||
|     PinCfg.Pinnum = 0; | ||||
|     PinCfg.Portnum = 0; | ||||
|     PINSEL_ConfigPin(&PinCfg);  // SDA1 / D20 SCA | ||||
|     PinCfg.Pinnum = 1; | ||||
|     PINSEL_ConfigPin(&PinCfg);  // SCL1 / D21 SCL | ||||
|   #endif | ||||
|   #if ((USEDI2CDEV_M == 2)) | ||||
|     PinCfg.Funcnum = 2; | ||||
|     PinCfg.Pinnum = 10; | ||||
|     PinCfg.Portnum = 0; | ||||
|     PINSEL_ConfigPin(&PinCfg); // SDA2 / D38  X_ENABLE_PIN | ||||
|     PinCfg.Pinnum = 11; | ||||
|     PINSEL_ConfigPin(&PinCfg); // SCL2 / D55  X_DIR_PIN | ||||
|   #endif | ||||
|  | ||||
|   // Initialize I2C peripheral | ||||
|   I2C_Init(I2CDEV_M, 100000); | ||||
|    | ||||
|   // Enable Master I2C operation | ||||
|   I2C_Cmd(I2CDEV_M, I2C_MASTER_MODE, ENABLE); | ||||
| } | ||||
|  | ||||
| uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) { | ||||
|   // clamp to buffer length | ||||
|   if(quantity > BUFFER_LENGTH){ | ||||
|     quantity = BUFFER_LENGTH; | ||||
|   } | ||||
|    | ||||
|   // perform blocking read into buffer | ||||
|   I2C_M_SETUP_Type transferMCfg; | ||||
|   transferMCfg.sl_addr7bit = address >> 1; // not sure about the right shift | ||||
| 	transferMCfg.tx_data = NULL; | ||||
| 	transferMCfg.tx_length = 0; | ||||
| 	transferMCfg.rx_data = rxBuffer; | ||||
| 	transferMCfg.rx_length = quantity; | ||||
| 	transferMCfg.retransmissions_max = 3; | ||||
| 	I2C_MasterTransferData(I2CDEV_M, &transferMCfg, I2C_TRANSFER_POLLING); | ||||
|  | ||||
|   // set rx buffer iterator vars | ||||
|   rxBufferIndex = 0; | ||||
|   rxBufferLength = transferMCfg.rx_count; | ||||
|  | ||||
|   return transferMCfg.rx_count; | ||||
| } | ||||
|  | ||||
| uint8_t TwoWire::requestFrom(int address, int quantity) { | ||||
|   return requestFrom((uint8_t)address, (uint8_t)quantity); | ||||
| } | ||||
|  | ||||
| void TwoWire::beginTransmission(uint8_t address) { | ||||
|   // indicate that we are transmitting | ||||
|   transmitting = 1; | ||||
|   // set address of targeted slave | ||||
|   txAddress = address; | ||||
|   // reset tx buffer iterator vars | ||||
|   txBufferIndex = 0; | ||||
|   txBufferLength = 0; | ||||
| } | ||||
|  | ||||
| void TwoWire::beginTransmission(int address) { | ||||
|   beginTransmission((uint8_t)address); | ||||
| } | ||||
|  | ||||
| uint8_t TwoWire::endTransmission(void) { | ||||
|   // transmit buffer (blocking) | ||||
|   I2C_M_SETUP_Type transferMCfg; | ||||
|   transferMCfg.sl_addr7bit = txAddress >> 1; // not sure about the right shift | ||||
| 	transferMCfg.tx_data = txBuffer; | ||||
| 	transferMCfg.tx_length = txBufferLength; | ||||
| 	transferMCfg.rx_data = NULL; | ||||
| 	transferMCfg.rx_length = 0; | ||||
| 	transferMCfg.retransmissions_max = 3; | ||||
|   Status status = I2C_MasterTransferData(I2CDEV_M, &transferMCfg, I2C_TRANSFER_POLLING); | ||||
|    | ||||
|   // reset tx buffer iterator vars | ||||
|   txBufferIndex = 0; | ||||
|   txBufferLength = 0; | ||||
|  | ||||
|   // indicate that we are done transmitting | ||||
|   transmitting = 0; | ||||
|  | ||||
|   if (status == SUCCESS) | ||||
|     return 0; // success | ||||
|   else | ||||
|     return 4; // other error | ||||
| } | ||||
|  | ||||
| // must be called after beginTransmission(address) | ||||
| size_t TwoWire::write(uint8_t data) { | ||||
|   if (transmitting) { | ||||
|     // don't bother if buffer is full | ||||
|     if (txBufferLength >= BUFFER_LENGTH) { | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|     // put byte in tx buffer | ||||
|     txBuffer[txBufferIndex] = data; | ||||
|     ++txBufferIndex; | ||||
|  | ||||
|     // update amount in buffer    | ||||
|     txBufferLength = txBufferIndex; | ||||
|   } | ||||
|  | ||||
|   return 1; | ||||
| } | ||||
|  | ||||
| // must be called after beginTransmission(address) | ||||
| size_t TwoWire::write(const uint8_t *data, size_t quantity) { | ||||
|   size_t sent = 0; | ||||
|   if (transmitting) | ||||
|     for(sent = 0; sent < quantity; ++sent) | ||||
|       if (!write(data[sent])) | ||||
|         break; | ||||
|  | ||||
|   return sent; | ||||
| } | ||||
|  | ||||
| // must be called after requestFrom(address, numBytes) | ||||
| int TwoWire::available(void) { | ||||
|   return rxBufferLength - rxBufferIndex; | ||||
| } | ||||
|  | ||||
| // must be called after requestFrom(address, numBytes) | ||||
| int TwoWire::read(void) { | ||||
|   int value = -1; | ||||
|    | ||||
|   // get each successive byte on each call | ||||
|   if(rxBufferIndex < rxBufferLength) { | ||||
|     value = rxBuffer[rxBufferIndex]; | ||||
|     ++rxBufferIndex; | ||||
|   } | ||||
|  | ||||
|   return value; | ||||
| } | ||||
|  | ||||
| // must be called after requestFrom(address, numBytes) | ||||
| int TwoWire::peek(void) { | ||||
|   int value = -1; | ||||
|    | ||||
|   if(rxBufferIndex < rxBufferLength){ | ||||
|     value = rxBuffer[rxBufferIndex]; | ||||
|   } | ||||
|  | ||||
|   return value; | ||||
| } | ||||
|  | ||||
| // Preinstantiate Objects ////////////////////////////////////////////////////// | ||||
|  | ||||
| TwoWire Wire = TwoWire(); | ||||
|  | ||||
| #endif // TARGET_LPC1768 | ||||
| @@ -1,4 +1,4 @@ | ||||
| /* | ||||
| /** | ||||
|  * TwoWire.h - TWI/I2C library for Arduino & Wiring | ||||
|  * Copyright (c) 2006 Nicholas Zambetti.  All right reserved. | ||||
|  * | ||||
| @@ -19,39 +19,49 @@ | ||||
|  * Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts | ||||
|  */ | ||||
|  | ||||
| // Modified for use with the mcp4451 digipot routine | ||||
|  | ||||
| #ifdef TARGET_LPC1768 | ||||
|  | ||||
| #ifndef TwoWire_h | ||||
| #define TwoWire_h | ||||
| #ifndef _TWOWIRE_H_ | ||||
| #define _TWOWIRE_H_ | ||||
|  | ||||
| #include <inttypes.h> | ||||
|  | ||||
| #define BUFFER_LENGTH 32 | ||||
|  | ||||
| class TwoWire { | ||||
|   private: | ||||
|     static uint8_t rxBuffer[]; | ||||
|     static uint8_t rxBufferIndex; | ||||
|     static uint8_t rxBufferLength; | ||||
|  | ||||
|     static uint8_t txAddress; | ||||
|     static uint8_t txBuffer[]; | ||||
|     static uint8_t txBufferIndex; | ||||
|     static uint8_t txBufferLength; | ||||
|  | ||||
|     static uint8_t transmitting; | ||||
|  | ||||
|   public: | ||||
|     //TwoWire(); | ||||
|     TwoWire(); | ||||
|     void begin(); | ||||
|     void beginTransmission(uint8_t); | ||||
|     void beginTransmission(int); | ||||
|     uint8_t endTransmission(void); | ||||
|     size_t write(uint8_t); | ||||
|     uint8_t endTransmission(uint8_t); | ||||
|  | ||||
|     uint8_t requestFrom(uint8_t, uint8_t); | ||||
|     uint8_t requestFrom(int, int); | ||||
|      | ||||
|     virtual size_t write(uint8_t); | ||||
|     virtual size_t write(const uint8_t *, size_t); | ||||
|     virtual int available(void); | ||||
|     virtual int read(void); | ||||
|     virtual int peek(void); | ||||
|  | ||||
|     inline size_t write(unsigned long n) { return write((uint8_t)n); } | ||||
|     inline size_t write(long n) { return write((uint8_t)n); } | ||||
|     inline size_t write(unsigned int n) { return write((uint8_t)n); } | ||||
|     inline size_t write(int n) { return write((uint8_t)n); } | ||||
| }; | ||||
|  | ||||
| //extern TwoWire Wire; | ||||
| extern TwoWire Wire; | ||||
|  | ||||
| TwoWire Wire; | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| extern "C" uint8_t digipot_mcp4451_start(uint8_t sla); | ||||
| extern "C" void digipot_mcp4451_init(void); | ||||
| extern "C" uint8_t digipot_mcp4451_send_byte(uint8_t data); | ||||
|  | ||||
|  | ||||
| void TwoWire::beginTransmission(uint8_t sla) { digipot_mcp4451_start(sla);} | ||||
| void TwoWire::begin(void) {digipot_mcp4451_init();} | ||||
| size_t TwoWire::write(uint8_t data) {return digipot_mcp4451_send_byte(data);} | ||||
| uint8_t TwoWire::endTransmission(void) {return 1;} | ||||
|  | ||||
| #endif | ||||
| #endif  // TARGET_LPC1768 | ||||
| #endif // _TWOWIRE_H_ | ||||
|   | ||||
| @@ -37,6 +37,7 @@ | ||||
| #include "../module/temperature.h" | ||||
| #include "../module/stepper.h" | ||||
| #include "../gcode/parser.h" | ||||
| #include "binary.h" | ||||
|  | ||||
| #include <Wire.h> | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user