madias 0 Posted May 20, 2014 Share Posted May 20, 2014 Hello, I'm trying to collect some standard procedures porting arduino(mostly avr, sam is easier) libraries to energia/lm4f. Maybe all forum members could help together, creating a little howto: Porting libraries to Energia/Stellaris LM4F Version 2014-05-20 1. First, it is necessary to examine the files to the following: 1.1 #if ARDUINO >= 100 #include <Arduino.h> #else #include <WProgram.h> #endif and change it to: #include <Energia.h> (or let #include <Arduino.h> as only line) 1.2 change #include <pins_arduino.h> to #include <pins_energia.h> 2. If PROGMEM was used: remove all PROGMEM and replace pgm_read_byte with * and better add a static const or insert this line on top: (Untested) #define PROGMEM #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) or insert:(Untested) #define pgm_read_word(data) *(data) #define pgm_read_byte(data) *(data) #define PROGMEM 3. __delay_cycles macro 3.1 easy way: use delayMicroseconds(xxx) where xxx is to try&error 3.2 use SysCtlDelay(xxx); -> Thread: http://forum.stellarisiti.com/topic/1980-delay-cycles/ 4. Pin related macros/stuff 4.1 insert:(Untested) #define cbi(reg, mask) GPIOPinWrite(reg, mask, 0) #define sbi(reg, mask) GPIOPinWrite(reg, mask, mask) #define pulse_high(reg, bitmask) { sbi(reg, bitmask); cbi(reg, bitmask); } #define pulse_low(reg, bitmask) { cbi(reg, bitmask); sbi(reg, bitmask); } 4.2 Conversation: (now I need your help for converting!) Arduino / AVR: #define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )#define analogInPinToBit(P) (P)#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) ) So your help is desired, I'll update this thread as soon as I get new information. Maybe we can build together a conversation.h file, so we can include it to every library (for testing) Regards Matthias igor 1 Quote Link to post Share on other sites
igor 163 Posted May 21, 2014 Share Posted May 21, 2014 0. If want to maintain backwards compatibility (one library to run on both Arduino and LM4F) #if defined(__AVR__) //Leave the AVR arduino code as is #else //alternative code for LM4F #endif 1.1 Can just leave those include statements as is, Arduino.h includes Energia.h 2. #if !defined(__AVR__) #if !defined(PROGMEM) #define PROGMEM #define memcpy_P(dest, src, len) memcpy((dest), (src), (len)) #endif #if (13 == ENERGIA) // Energia version 13 pgm_read_byte and pgm_read_dword do not work under some circumstances. #undef pgm_read_byte #undef pgm_read_dword #endif #ifndef pgm_read_byte #define pgm_read_byte(x) (*(const unsigned char *)(x)) #endif #ifndef pgm_read_dword #define pgm_read_dword(x) (*(const unsigned long *)(x)) #endif #endif 4.2 digitalPinToPort, digitalPinToBitMask, digitalPinToTimer - these all exist in Energia.h (Not sure if need any conversion, depends how the result is used) portOutputRegister - consider/compare to Energia portDATARegister But, if you want to take better advantage of the capabilities of the Stellaris/Tiva processors you could do something like this. #define portMaskedOutputRegister(port, mask) \ ((volatile uint8_t *) (((uint32_t)portBASERegister(port)) + (GPIO_O_DATA + (((uint32_t)mask) << 2)))) The mask you supply will be applied before writing to the port in question, so one does not have to do read the port, twiddle the bit(s) of interest, write it back. Can just write it, and only the bits indicated by the mask will be changed. So oepin = digitalPinToBitMask(oe); oeport = portOutputRegister(digitalPinToPort(oe)); *oeport |= oepin; *oeport &= ~oepin; // can become oepin = digitalPinToBitMask(oe); oeport = portMaskedOutputRegister(digitalPinToPort(oe), oepin); *oeport = 0xFF; *oeport = 0; Note that in the bit set example, you could use oepin in place of 0xFF, however if you are writing 1's to several ports in nearby code, the compiler may be able to keep the one value in a register, rather than having to load a bunch of different port masks. (Also, the original AVR code will still work, it just takes more instructions.) If you define a mask which selects several pins, you can output to them all together with a single write, e.g. *rowport = row; // Add bit shifts as needed if the pins for row do not start at pin 0 Rather than having to split row up one bit at a time. Edited August 2014 - add parenthesis around parameters in PROGMEM, add test to be sure PROGMEM not already defined. [Edited November 2014 - updated definitions of pgm_read_byte. Replace versions from Energia 13 which don't work right.] madias 1 Quote Link to post Share on other sites
igor 163 Posted May 21, 2014 Share Posted May 21, 2014 Addition/caveat to my above post The #defines for memcpy_P, etc. need extensive testing, and/or review by somebody who really knows all the ins/outs/and gotchas of macros. (i.e., it should work in a simple case, but I am not sure that it will always work right, e.g. if the call to memcpy_P is generated by a macro and has fancy macro arguments.) Other options might be to create an inline function called memcpy_P that calls memcpy, or to make memcpy_P an alias for memcpy. Additional - for the #define PROGMEM may be well to protect them inside #ifndef, i.e. #if !defined(PROGMEM) #define PROGMEM #endif etc. So that if something else provides the fix (e.g. if Energia incorporated similar fixes) we wouldn't wind up with multiple define errors. Quote Link to post Share on other sites
madias 0 Posted May 23, 2014 Author Share Posted May 23, 2014 Thank you for your postings, igor! I'll change my first posting as soon, as I have a little time left! Maybe it´s a good idea to implement the fastdigital-library for the portOutputRegister stuff: http://forum.stellarisiti.com/topic/442-energia-library-stellaris-launchpad-fatfs-energia-library/?p=3420 Quote Link to post Share on other sites
igor 163 Posted May 23, 2014 Share Posted May 23, 2014 3.3 For very short delays (e.g. one cycle) use __NOP() Don’t muck about trying to be clever: for a one-cycle delay just use __NOP(), the ARM CMSIS standard spelling for an inline function that emits the NOP instruction. Where it has an effect, it’s a one-cycle effect. Where it doesn’t, other instructions don’t behave any better. This item may need some refinement (e.g. add the code for the NOP function, if it is not part of Energia.) Quote Link to post Share on other sites
igor 163 Posted August 19, 2014 Share Posted August 19, 2014 2.1 If avr/pgmspace.h is included (e.g., uses more than just PROGMEM) #include "avr/pgmspace.h" AVR chips have separate address spaces for program memory and data memory, while ARM chips do not separate them. pgmspace.h defines various access structures and libraries. There are a few pgmspace.h replacement files for machines like the ARM. For example, the one from Teensy 3 https://github.com/PaulStoffregen/cores/blob/master/teensy3/avr/pgmspace.h There are various places you can put the file. I do not know where the "best" place to put pgmspace.h would be. The following directories work (if you want to make it generally available, without having to specially include it in a particular project). (Would be nice if it was included as part of Energia.) For Tiva/Stellaris [Energia Dir]/hardware/lm4f/cores/lm4f/avror[Energia Dir]/hardware/lm4f/tools/lm4f/arm-none-eabi/include/avr For MSP430[Energia Dir]/hardware/msp430/core/msp430/avror[Energia Dir]/hardware/tools/msp430/msp430/include/avr Quote Link to post Share on other sites
igor 163 Posted August 19, 2014 Share Posted August 19, 2014 5. Working on multiple platforms. There are various macros to help select appropriate code for the current platform. Environment/libraryENERGIA - Energia environment (Tiva/CC3200/MSP430/C2000 )CORE_TEENSY - TeensyDuino (AVR/ ) MAPLE_IDE - libmaple (STM32) MPIDE - chipKIT ARDUINO - (AVR/SAM/x86/...) - also defined by other environments, like ENERGIA. Processor family:__MSP430_CPU__ or __MSP430_HEADER_VERSION__ - MSP430 [???] - MSP432__arm__ - Should be true for any ARM processor (e.g. Tiva, Stellaris, CC3200, SAM/Arduino Due, STM32, Freescale, ... )__AVR__ - Atmel AVR processors (original Arduino, Teensy before version 3, etc.) __ARDUINO_X86__ - Intel x86/Galileo Board: (Arduino 1.5.7 BETA) ARDUINO_SAM_DUE - Arduino Due ARDUINO_AVR_xxx (YUN, LEONARDO, MEGA, ....) - Various AVR Arduinos see for example Embededxcode: Manage code for multiple platforms Additional examples and information: http://forum.stellarisiti.com/topic/1965-architecture-for-conditional-compilation-in-energia/ http://forum.43oh.com/topic/5670-one-sketch-multiple-architectures/ [Edit: Oct 1 2014: Added Board, added x86 processor] [Edit: Need to add MSP432] madias 1 Quote Link to post Share on other sites
igor 163 Posted October 22, 2014 Share Posted October 22, 2014 6. Analog pins 6.1 Analog pin names on CC3200 Arduino standard analog pin names (A0, A1, etc.) are not defined in Energia. The following code can be included as a workaround. // Check to be sure CC3200 CPU #if defined(__CC3200R1M1RGC__)// Do not conflict in case A0 does get fixed #if !defined(A0) static const uint8_t A0 = 23; static const uint8_t A1 = 2; static const uint8_t A2 = 6; static const uint8_t A3 = 24; #endif#endif For further information, see https://github.com/energia/Energia/issues/483 Caution: Note that analog input pins on the CC3200 can not handle as much voltage as Digital pins. Be careful to keep the input in range when a pin is set to Analog input. [Edit: 1 Nov 2014 - changed to Energia pin numbers, rather than PIN_ macros ] 6.2 Analog read range On arduino, analogRead returns a 10 bit unsigned value (0 - 1023). Some Arduinos can read more bits in an analog to digital conversion. For instance the Arduino Due has 12 bit ADCs, so it can read values (0-4095). Although the Due normally returns 10 bits, analogReadResolution(number of bits) lets code select how many bits to read. Unfortunately the API does not appear to provide an official indicator of how many bits can be read. However it happens that Arduino Due does define #define ADC_RESOLUTION 12 Other platforms vary in how many bits ADCs output. Unlike the Arduino, many other wiring platforms return the full ADC range from analogRead, and there is little standardization in indicating how many bits to expect. (On Energia, some devices return 10 bits, while others return 12 bits.) On the MSP430 Energia uses various symbols to indicate ADC resolution. It could be convenient to extend ADC_RESOLUTION by defining it on other platforms. #if defined(__MSP430_HAS_ADC10__) || defined(__MSP430_HAS_ADC10_B__) //#define ADC_RESOLUTION 10 #elif defined(__MSP430_HAS_ADC12_PLUS__) || defined(__MSP430_HAS_ADC12_B__) #define ADC_RESOLUTION 12 #endif On Tiva/Stellaris and Maple, ADC has 12 bits. [This is a work in progress - more later] Quote Link to post Share on other sites
igor 163 Posted November 1, 2014 Share Posted November 1, 2014 Use caution with calls inside class constructors. Although some arduino libraries call pinMode, or other library functions inside class constructors, this may not be prudent portable programming practice, and may lead to unpredictable results. If a global object of the class is created, it can not rely on the order in which other objects are initialized, so it can not rely on them being in working state. Likewise hardware may not have been initialized. One workaround is to place pinMode, etc. in a "begin()" method, and require that it be called before the class is used. http://forum.43oh.com/topic/6011-tiva-delaymicroseconds-unreliable/?p=52601 http://forum.stellarisiti.com/topic/2165-strange-behavior-pinmodedigitalwrite-within-library/ spirilis 1 Quote Link to post Share on other sites
johnrdorazio 0 Posted April 3, 2015 Share Posted April 3, 2015 Following up on this, I need some help with the definitions needed to port the OneWire library for Arduino to Energia for the MSP430. The hardware abstraction layer in the library has this: // Platform specific I/O definitions #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 IO_REG_ASM asm("r30") #define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) #define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(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__) #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__) // Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due. // http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268 // If you have trouble with OneWire on Arduino Due, please check the // status of delayMicroseconds() before reporting a bug in OneWire! #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)) #ifndef PROGMEM #define PROGMEM #endif #ifndef pgm_read_byte #define pgm_read_byte(addr) (*(const uint8_t *)(addr)) #endif #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 #else #error "Please define I/O register types here" #endif Looking around some forums I found that these definitions might work for the Tiva / Stellaris boards, though i haven't had a chance to test yet: #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) I would like to know what definitions are needed for the MSP430: #elif defined(__MSP430__) I can't use GPIO_O_DATA in defining "portMaskedOutputRegister", it's not defined for the MSP430... Quote Link to post Share on other sites
igor 163 Posted April 4, 2015 Share Posted April 4, 2015 Look in the energia header files (Energia.h) for the MSP430, should find definitions of many of the macros. Probably don't want to try to replicate portMaskedOutputRegister - it uses special features of the LM4F output ports (not present on many other ARMs, not sure if present on MSP430). Quote Link to post Share on other sites
igor 163 Posted August 17, 2015 Share Posted August 17, 2015 Sharing and using libraries: Some Misconceptions about Libraries Posting a Library for Energia bluehash 1 Quote Link to post Share on other sites
Rei Vilo 695 Posted October 3, 2015 Share Posted October 3, 2015 About Pin Naming User igor 1 Quote Link to post Share on other sites
Mariana 0 Posted September 24, 2018 Share Posted September 24, 2018 Hola, estoy intentando usar una librería de arduino para energía específicamente la librería del PID pero cuando la agrego y la compilo me da el siguiente error (imagen): no se si alguien pueda ayudarme a solucionar este error por favor y gracias. Quote Link to post Share on other sites
venkatesh223 0 Posted November 14, 2018 Share Posted November 14, 2018 hello there I am planning to start a project using msp432p401r launchpad with a 3.5 inch TFT touch screen. This is my first time doing such a project. I hope that I can get some advice I have searched for 3.5" TFT touch screen with resolution of 480x320. Most of them are compatible with Arduino and Raspberry PI. Here is the link ('https://www.waveshare.com/wiki/3.5inch_TFT_Touch_Shield" Can anyone please help me porting the below project of arduino, Lcd touch to energia so that i can interface the LCD with MSP432P401R. 3.5inch_TFT_Touch_Shield_Code.7z 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.