!Qwert 0 Posted October 7, 2014 Share Posted October 7, 2014 I have an issue when using the Capacitive Sensing Library from Arduino. I used the ver. 5 that allows non-AVR boards to use the library. My problem is when I complied it in Energia, I get these errors: /Users/apple/Documents/Energia/libraries/CapacitiveSensor/CapacitiveSensor.h:94:2: error: 'IO_REG_TYPE' does not name a type /Users/apple/Documents/Energia/libraries/CapacitiveSensor/CapacitiveSensor.h:95:11: error: 'IO_REG_TYPE' does not name a type /Users/apple/Documents/Energia/libraries/CapacitiveSensor/CapacitiveSensor.h:96:2: error: 'IO_REG_TYPE' does not name a type /Users/apple/Documents/Energia/libraries/CapacitiveSensor/CapacitiveSensor.h:97:11: error: 'IO_REG_TYPE' does not name a type I am not that strong in coding and I would like some assistance into how to solve this problem. Thanks. here is the h file where the error is coming from: #ifndef CapacitiveSensor_h #define CapacitiveSensor_h #if ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif // Direct I/O through registers and bitmask (from OneWire library) #if defined(__AVR__) #define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) #define IO_REG_TYPE uint8_t #define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) #define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask), (*((base)+2)) &= ~(mask)) #define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) #define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) #define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) #elif defined(__MK20DX128__) || defined(__MK20DX256__) #define PIN_TO_BASEREG(pin) (portOutputRegister(pin)) #define PIN_TO_BITMASK(pin) (1) #define IO_REG_TYPE uint8_t #define IO_REG_ASM #define DIRECT_READ(base, mask) (*((base)+512)) #define DIRECT_MODE_INPUT(base, mask) (*((base)+640) = 0) #define DIRECT_MODE_OUTPUT(base, mask) (*((base)+640) = 1) #define DIRECT_WRITE_LOW(base, mask) (*((base)+256) = 1) #define DIRECT_WRITE_HIGH(base, mask) (*((base)+128) = 1) #elif defined(__SAM3X8E__) #define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER)) #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) #define IO_REG_TYPE uint32_t #define IO_REG_ASM #define DIRECT_READ(base, mask) (((*((base)+15)) & (mask)) ? 1 : 0) #define DIRECT_MODE_INPUT(base, mask) ((*((base)+5)) = (mask)) #define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+4)) = (mask)) #define DIRECT_WRITE_LOW(base, mask) ((*((base)+13)) = (mask)) #define DIRECT_WRITE_HIGH(base, mask) ((*((base)+12)) = (mask)) #elif defined(__PIC32MX__) #define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin))) #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) #define IO_REG_TYPE uint32_t #define IO_REG_ASM #define DIRECT_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0) //PORTX + 0x10 #define DIRECT_MODE_INPUT(base, mask) ((*(base+2)) = (mask)) //TRISXSET + 0x08 #define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) = (mask)) //TRISXCLR + 0x04 #define DIRECT_WRITE_LOW(base, mask) ((*(base+8+1)) = (mask)) //LATXCLR + 0x24 #define DIRECT_WRITE_HIGH(base, mask) ((*(base+8+2)) = (mask)) //LATXSET + 0x28 #endif // some 3.3V chips with 5V tolerant pins need this workaround // #if defined(__MK20DX256__) #define FIVE_VOLT_TOLERANCE_WORKAROUND #endif // library interface description class CapacitiveSensor { // user-accessible "public" interface public: // methods CapacitiveSensor(uint8_t sendPin, uint8_t receivePin); long capacitiveSensorRaw(uint8_t samples); long capacitiveSensor(uint8_t samples); void set_CS_Timeout_Millis(unsigned long timeout_millis); void reset_CS_AutoCal(); void set_CS_AutocaL_Millis(unsigned long autoCal_millis); // library-accessible "private" interface private: // variables int error; unsigned long leastTotal; unsigned int loopTimingFactor; unsigned long CS_Timeout_Millis; unsigned long CS_AutocaL_Millis; unsigned long lastCal; unsigned long total; IO_REG_TYPE sBit; // send pin's ports and bitmask volatile IO_REG_TYPE *sReg; IO_REG_TYPE rBit; // receive pin's ports and bitmask volatile IO_REG_TYPE *rReg; // methods int SenseOneCycle(void); }; #endif Quote Link to post Share on other sites
igor 163 Posted October 7, 2014 Share Posted October 7, 2014 This thread gives some suggestions/help on porting libraries http://forum.stellarisiti.com/topic/1983-howto-porting-libraries-some-help-needed/ The immediate cause of the error messages is that you need to have a segment which will provide definitions relevant to the Tiva launchpads. (up in the list of macros based on cpu types). #define IO_REG_TYPE uint8_t (Which says that ports are 8 bits wide). Of course you will need to figure out what the appropriate values are for all the other macros in that section. Here is a start on it, (this is just from examples/memory, I haven't tested this - so may be syntax errors, and may have too many & on the BASEREG item.) Direct read and mode input/output still need to be filled in. (Looking at the code for driverlib should give you the HWREG versions for those functions). Energia.h is another good source. #elif defined(__TM4C129XNCZAD__) || defined(__TM4C1294NCPDT__) || defined(__LM4F120H5QR__) || defined(__TM4C123GH6PM__) #define portMaskedOutputRegister(base, mask) \ ((volatile uint8_t *) (base + (GPIO_O_DATA + (((uint32_t)mask) << 2)))) #define PIN_TO_BASEREG(pin) (&((uint32_t)portBASERegister(digitalPinToPort(pin)))) #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) #define IO_REG_TYPE uint8_t #define IO_REG_ASM #define DIRECT_READ(base, mask) #define DIRECT_MODE_INPUT(base, mask) #define DIRECT_MODE_OUTPUT(base, mask) #define DIRECT_WRITE_LOW(base, mask) (portMaskedOutputRegister(base, mask) = 0) #define DIRECT_WRITE_HIGH(base, mask) (portMaskedOutputRegister(base, mask) = 0xFF) Might be helpful if you posted a link to the library in question (so those offering assistance could see what the library code looks like). One can infer what several of these macros are supposed to do from the name, but some are a bit obscure. energia 1 Quote Link to post Share on other sites
!Qwert 0 Posted October 8, 2014 Author Share Posted October 8, 2014 Okay, I will try out the link you posted and the example code once I get the chance. Here is the cpp file along with the header file: /* CapacitiveSense.h v.04 - Capacitive Sensing Library for 'duino / Wiring https://github.com/PaulStoffregen/CapacitiveSensor http://www.pjrc.com/teensy/td_libs_CapacitiveSensor.html http://playground.arduino.cc/Main/CapacitiveSensor Copyright (c) 2009 Paul Bagder All right reserved. Version 05 by Paul Stoffregen - Support non-AVR board: Teensy 3.x, Arduino Due Version 04 by Paul Stoffregen - Arduino 1.0 compatibility, issue 146 fix vim: set ts=4: */ #if ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #include "pins_arduino.h" #include "WConstants.h" #endif #include "CapacitiveSensor.h" // Constructor ///////////////////////////////////////////////////////////////// // Function that handles the creation and setup of instances CapacitiveSensor::CapacitiveSensor(uint8_t sendPin, uint8_t receivePin) { // initialize this instance's variables // Serial.begin(9600); // for debugging error = 1; loopTimingFactor = 310; // determined empirically - a hack CS_Timeout_Millis = (2000 * (float)loopTimingFactor * (float)F_CPU) / 16000000; CS_AutocaL_Millis = 20000; // Serial.print("timwOut = "); // Serial.println(CS_Timeout_Millis); // get pin mapping and port for send Pin - from PinMode function in core #ifdef NUM_DIGITAL_PINS if (sendPin >= NUM_DIGITAL_PINS) error = -1; if (receivePin >= NUM_DIGITAL_PINS) error = -1; #endif pinMode(sendPin, OUTPUT); // sendpin to OUTPUT pinMode(receivePin, INPUT); // receivePin to INPUT digitalWrite(sendPin, LOW); sBit = digitalPinToBitMask(sendPin); // get send pin's ports and bitmask sReg = PIN_TO_BASEREG(sendPin); // get pointer to output register rBit = digitalPinToBitMask(receivePin); // get receive pin's ports and bitmask rReg = PIN_TO_BASEREG(receivePin); // get pin mapping and port for receive Pin - from digital pin functions in Wiring.c leastTotal = 0x0FFFFFFFL; // input large value for autocalibrate begin lastCal = millis(); // set millis for start } // Public Methods ////////////////////////////////////////////////////////////// // Functions available in Wiring sketches, this library, and other libraries long CapacitiveSensor::capacitiveSensor(uint8_t samples) { total = 0; if (samples == 0) return 0; if (error < 0) return -1; // bad pin for (uint8_t i = 0; i < samples; i++) { // loop for samples parameter - simple lowpass filter if (SenseOneCycle() < 0) return -2; // variable over timeout } // only calibrate if time is greater than CS_AutocaL_Millis and total is less than 10% of baseline // this is an attempt to keep from calibrating when the sensor is seeing a "touched" signal if ( (millis() - lastCal > CS_AutocaL_Millis) && abs(total - leastTotal) < (int)(.10 * (float)leastTotal) ) { // Serial.println(); // debugging // Serial.println("auto-calibrate"); // Serial.println(); // delay(2000); */ leastTotal = 0x0FFFFFFFL; // reset for "autocalibrate" lastCal = millis(); } /*else{ // debugging Serial.print(" total = "); Serial.print(total); Serial.print(" leastTotal = "); Serial.println(leastTotal); Serial.print("total - leastTotal = "); x = total - leastTotal ; Serial.print(x); Serial.print(" .1 * leastTotal = "); x = (int)(.1 * (float)leastTotal); Serial.println(x); } */ // routine to subtract baseline (non-sensed capacitance) from sensor return if (total < leastTotal) leastTotal = total; // set floor value to subtract from sensed value return(total - leastTotal); } long CapacitiveSensor::capacitiveSensorRaw(uint8_t samples) { total = 0; if (samples == 0) return 0; if (error < 0) return -1; // bad pin - this appears not to work for (uint8_t i = 0; i < samples; i++) { // loop for samples parameter - simple lowpass filter if (SenseOneCycle() < 0) return -2; // variable over timeout } return total; } void CapacitiveSensor::reset_CS_AutoCal(void){ leastTotal = 0x0FFFFFFFL; } void CapacitiveSensor::set_CS_AutocaL_Millis(unsigned long autoCal_millis){ CS_AutocaL_Millis = autoCal_millis; } void CapacitiveSensor::set_CS_Timeout_Millis(unsigned long timeout_millis){ CS_Timeout_Millis = (timeout_millis * (float)loopTimingFactor * (float)F_CPU) / 16000000; // floats to deal with large numbers } // Private Methods ///////////////////////////////////////////////////////////// // Functions only available to other functions in this library int CapacitiveSensor::SenseOneCycle(void) { noInterrupts(); DIRECT_WRITE_LOW(sReg, sBit); // sendPin Register low DIRECT_MODE_INPUT(rReg, rBit); // receivePin to input (pullups are off) DIRECT_MODE_OUTPUT(rReg, rBit); // receivePin to OUTPUT DIRECT_WRITE_LOW(rReg, rBit); // pin is now LOW AND OUTPUT delayMicroseconds(10); DIRECT_MODE_INPUT(rReg, rBit); // receivePin to input (pullups are off) DIRECT_WRITE_HIGH(sReg, sBit); // sendPin High interrupts(); while ( !DIRECT_READ(rReg, rBit) && (total < CS_Timeout_Millis) ) { // while receive pin is LOW AND total is positive value total++; } //Serial.print("SenseOneCycle(1): "); //Serial.println(total); if (total > CS_Timeout_Millis) { return -2; // total variable over timeout } // set receive pin HIGH briefly to charge up fully - because the while loop above will exit when pin is ~ 2.5V noInterrupts(); DIRECT_WRITE_HIGH(rReg, rBit); DIRECT_MODE_OUTPUT(rReg, rBit); // receivePin to OUTPUT - pin is now HIGH AND OUTPUT DIRECT_WRITE_HIGH(rReg, rBit); DIRECT_MODE_INPUT(rReg, rBit); // receivePin to INPUT (pullup is off) DIRECT_WRITE_LOW(sReg, sBit); // sendPin LOW interrupts(); #ifdef FIVE_VOLT_TOLERANCE_WORKAROUND DIRECT_MODE_OUTPUT(rReg, rBit); DIRECT_WRITE_LOW(rReg, rBit); delayMicroseconds(10); DIRECT_MODE_INPUT(rReg, rBit); // receivePin to INPUT (pullup is off) #else while ( DIRECT_READ(rReg, rBit) && (total < CS_Timeout_Millis) ) { // while receive pin is HIGH AND total is less than timeout total++; } #endif //Serial.print("SenseOneCycle(2): "); //Serial.println(total); if (total >= CS_Timeout_Millis) { return -2; // total variable over timeout } else { return 1; } } Thanks for your reply. I appreciate it. Quote Link to post Share on other sites
!Qwert 0 Posted October 10, 2014 Author Share Posted October 10, 2014 Okay, I took the example and insert it to the header file. Of course, I saw the errors when I compiled it to see what would happen. Now I do have a new issue, you mentioned that I had to fill the Direct read and mode input/output with certain mask and base values. You also mentioned that the driverlib should give me the HWREG versions for those functions or looking at the Eneriga.h is another source to look at. Sorry that I am asking much but I am a beginner in learning how to properly port libraries. Why I need to insert something to the Direct read and mode input/output (is it the pin mapping?) and what should I look at the HWREG to type it up? Here is the link where I found the HWREG reference: https://github.com/energia/Energia/blob/master/hardware/lm4f/cores/lm4f/main.cpp Quote Link to post Share on other sites
igor 163 Posted October 10, 2014 Share Posted October 10, 2014 The macros in question are doing what pinMode( ) and digitalRead( ) do. The library is using lower level calls probably either to increase speed, or to do things which the regular Wiring calls do not do. So the file to look at is where those functions are defined. https://github.com/energia/Energia/blob/master/hardware/lm4f/cores/lm4f/wiring_digital.c int digitalRead(uint8_t pin) { uint8_t bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); uint32_t portBase = (uint32_t) portBASERegister(port); if (port == NOT_A_PORT) return LOW; if(ROM_GPIOPinRead(portBase, bit)){ return HIGH; } return LOW; } This tells us how to get the base and the mask from a pin (first 3 lines). Then we skip the error checking (we are after performance, not safety, good coding or defensive programming). So to read a pin given the base and mask #define DIRECT_READ(base, mask) ((ROM_GPIOPinRead(base, mask)) ? 1 : 0) Which should work, but we can go even deeper to make it even faster (avoiding the procedure call). To translate that into even lower level we search the source for GPIOPinRead( https://github.com/energia/Energia/blob/master/hardware/lm4f/cores/lm4f/driverlib/gpio.c (Technically I skipped a step there - if one didn't know that we can just drop the ROM_ part of the name (it is part of a mapping scheme to allow use of ROM or user compiled versions of the library), one could search for ROM_GPIOPinRead and find the header file where it gets translated/etc. and find that it is associated with GPIOPinRead.) Again taking off the error checking we wind up with: #define DIRECT_READ(base, mask) (HWREG(base+ (GPIO_O_DATA + (mask<< 2)))) Since HWREG is just a macro which expands to reading a particular memory address we can't get much lower. Following similar steps should handle pinMode. Of course normally a library should use the regular digitalRead/Write/etc. calls if it can. Hopefully the designers of this library had good reason for going to lower levels. (i.e. When writing a library only use this approach if benchmarking has shown that the regular calls are a bottleneck in your library.) Quote Link to post Share on other sites
!Qwert 0 Posted October 10, 2014 Author Share Posted October 10, 2014 Ok, correct me if I get something wrong. So the HWREG is just allowing an extension reading of the total pins available according to the memory address. For adding the rest on #define DIRECT_MODE_INPUT(base, mask) #define DIRECT_MODE_OUTPUT(base, mask) I should look further on the GPIO.c at: for DIRECT_MODE_INPUT: //***************************************************************************** void GPIOPinTypeGPIOInput(uint32_t ui32Port, uint8_t ui8Pins) { // // Check the arguments. // ASSERT(_GPIOBaseValid(ui32Port)); // // Make the pin(s) be inputs. // GPIODirModeSet(ui32Port, ui8Pins, GPIO_DIR_MODE_IN); // // Set the pad(s) for standard push-pull operation. // GPIOPadConfigSet(ui32Port, ui8Pins, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); } //***************************************************************************** and for DIRECT_MODE_OUTPUT: //***************************************************************************** // //! Configures pin(s) for use as GPIO outputs. //! //! \param ui32Port is the base address of the GPIO port. //! \param ui8Pins is the bit-packed representation of the pin(s). //! //! The GPIO pins must be properly configured in order to function correctly as //! GPIO outputs. This function provides the proper configuration for those //! pin(s). //! //! The pin(s) are specified using a bit-packed byte, where each bit that is //! set identifies the pin to be accessed, and where bit 0 of the byte //! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. //! //! \return None. // //***************************************************************************** void GPIOPinTypeGPIOOutput(uint32_t ui32Port, uint8_t ui8Pins) { // // Check the arguments. // ASSERT(_GPIOBaseValid(ui32Port)); // // Set the pad(s) for standard push-pull operation. // GPIOPadConfigSet(ui32Port, ui8Pins, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); // // Make the pin(s) be outputs. // GPIODirModeSet(ui32Port, ui8Pins, GPIO_DIR_MODE_OUT); } I have to figure out what to write up the required base and mask values from the memory address for each one? Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.