Jump to content

Search the Community

Showing results for tags 'MSP432'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • News
    • Announcements
    • Suggestions
    • New users say Hi!
  • Spotlight!
    • Sponsor Spotlight
    • Sponsor Giveaways
  • Energia
    • Energia - MSP
    • Energia - TivaC/CC3XXX
    • Energia - C2000
    • Energia Libraries
  • MSP Technical Forums
    • General
    • Compilers and IDEs
    • Development Kits
    • Programmers and Debuggers
    • Code vault
    • Projects
    • Booster Packs
    • Energia
  • Tiva-C, Hercules, CCXXXX ARM Technical Forums
    • General
    • SensorTag
    • Tiva-C, Hercules, CC3XXX Launchpad Booster Packs
    • Code Vault
    • Projects
    • Compilers and IDEs
    • Development Kits and Custom Boards
  • Beagle ARM Cortex A8 Technical Forums
    • General
    • Code Snippets and Scripts
    • Cases, Capes and Plugin Boards
    • Projects
  • General Electronics Forum
    • General Electronics
    • Other Microcontrollers
  • Connect
    • Embedded Systems/Test Equipment Deals
    • Buy, Trade and Sell
    • The 43oh Store
    • Community Projects
    • Fireside Chat
  • C2000 Technical Forums
    • General
    • Development Kits
    • Code Vault
    • Projects
    • BoosterPacks

Calendars

There are no results to display.


Found 91 results

  1. .sslConnect() not working

    I have a very basic requirement to send a HTTPS request to AWS. I am using the basic sample code from Energia for my MSP432. I have no issues establishing an unsecured HTTP request using .connect(), but AWS requires HTTPS. To that end, I am trying to use the .sslConnect() function provided in Energia to no avail - I am not able to establish a connect with the AWS server. Can anyone suggest what my issues are with the code below? Are there common issues I should look at to debug? Thank you! char server[] = "xxxxxxxx.execute-api.us-xxxx-2.amazonaws.com"; { Serial.println("\nStarting connection to server..."); // if you get a connection, report back via serial: if (client.sslConnect(server, 8443)) { Serial.println("connected to server"); // Make a HTTP request: client.println("GET /xxxx/myAWSfunction HTTP/1.1"); client.println("Host: xxxx.execute-api.us-xxxx-2.amazonaws.com"); client.println("Connection: close"); client.println(); } }
  2. Hi from dannyf

    Hi, new here. I worked professionally with lots of luminary and then ti chips. Still have trays of lm3s628, 801, and 811s. Got some of the earliest lm4f120 chips and launchpads. Loved their features. Not crazy about the adc however. My interests now are mainly in creating a generic framework for Arduino (the software). I had previously ported Arduino to a variety of chips, from stm8, pic24, and tm4c chips, including msp432. My recent work in progress is xduino, a generic framework for Arduino on a diverse group of chips. Nice to share my learning with you all. You can find me at dannyelectronics.wordpress.com
  3. Hello, I am trying to use my MSP432 to make a REST call to an endpoint I already have set up and configured. I know this endpoint works. However, when I try to use the the WiFiWebClient example in Energia, I receive an HTTP 301 redirect error. I suspect this could be due to the difference between HTTP/HTTPS. Is it possible to use make an HTTPS request using this Energia example? Thank you!
  4. Hi all, what are the best practices for conditioning signals coming onto (or leaving) an interface board? I'm interfacing an MSP432 LaunchPad to two sensor boards through two 2x6 pin-headers (two of the four I2C ports on each connector, and all four high-drive GPIO). An SPI port is available for a master/slave launchpad configuration (one master with up to three slaves), and two normal GPIO as well - just in case. A colleague recommended a "100 ohm" ferrite beads with a 100pF bypass cap and a 5V TVS to ground on each signal. I want the board to be solderable by hand, the ferrite beads are big enough being 1210s, and I picked 0805 bypass caps. However, the TVS recommended was a 1201 and the biggest chip TVS I could find was a 12V in an 0603 package. Does that seem right? Will as 12V part be a waste of time? What would you recommend? Also I'm curious about the orientation of the parts relative to each other for best routing. Can anyone share some insights? Many thanks, Dale booster-i2c-schematic-008-X04.pdf bom-pv-008-X04.pdf
  5. MSP-EXP432P401R Energia 1.6.10E18 Windows Education 10 x64 v1511 I am wondering if anyone has had experience or knows how I could make it so a board [RED LaunchPad /w msp432 EMT (48MHz)] will be available to all users in a domain environment. I originally tried using the CCS Cloud TI Agent but encountered some very odd registry issues with non admin users/domain users (Reference: https://e2e.ti.com/support/development_tools/code_composer_studio/f/81/t/650118#pi316318=2). We are able to install it fine for everyone with the local admin or administrative domain account, however when we goto Boards Manager and install that board it only applies to the current user. It looks like it may be specific to the user profile where it is installing this to as the only thing I could find related to the msp432 board was in this file location: C:\Users\domain_user\AppData\Local\Energia15\packages\energia\hardware\msp432r\5.6.1 Is there a registry or config file somewhere where I can change the location of where the boards get downloaded/installed to so it can be read from a location that all users have access to?
  6. MSP432 RTC User adjust

    can anyone some help me? I have some problems with user rtc configuration in msp432 I made a firmware where the user choose by hardware configuration adjust date and time (alarm clock). The problem is ... after the user adjust date and time I would like use the rtc to control the watch and show the current date and time in a lcd. The problem is ... after the user adjust date and time I would like use the rtc to control the watch and show the current date and time in a lcd. Soo i need some help in two things pass the user value (decimal) to hexadecimal or BCD and the inverse get the hexadecimal or BCD value to decimal to show in LCD . I'am using CCS, in CMSIS on attach i leave the code I have made to test it!
  7. MSP432 RTC User adjust

    can anyone some help me? I have some problems with user rtc configuration in msp432 I made a firmware where the user choose by hardware configuration adjust date and time (alarm clock). The problem is ... after the user adjust date and time I would like use the rtc to control the watch and show the current date and time in a lcd. The problem is ... after the user adjust date and time I would like use the rtc to control the watch and show the current date and time in a lcd. Soo i need some help in two things pass the user value (decimal) to hexadecimal or BCD and the inverse get the hexadecimal or BCD value to decimal to show in LCD . I'am using CCS, in CMSIS on attach i leave the code I have made to test it! test.zip
  8. MSP-EXP432P111

    Hi guys, The new Launchpad MSP-EXP432P111 was released some days ago. I bought one and it arrived today . The board use the XMS432P1111 (pre-production version of MSP432) microcontroller, a Cortex M4 with 48MHz, 2MB of flash, 256KB of SRAM (very impressive), 14bit ADC and many other peripherals, like the LCD driver. Apparently, the LCD is the same of other launchpads (eg.: EXP430FR6989), very interesting to understand how to use the LCD driver and develop some projects. The Out-of-Box demo has two modes: - Blink LED, where you can controll the frequency of blink pressing the button S1 and controll the color by pressing the button S2. - Temperature mode: Show the temperature based in the internal sensor (pressing S2), or based in an external temperature sensor (pressing S1), a LMT70, but it's necessary to put a jumper in R8, powering the sensor. There is a online GUI enabling to control other parameters like special characters in the LCD. The finishing of PCB's is impeccable, as always.
  9. RFC: CNC BoosterPack

    I have recently been working on a CNC BoosterPack that I will make available on Github when completed later in the spring. Current specifications: Support for my HALified version of GRBL (based on 1.1), currently drivers has been made for MSP432 (black version), Tiva C and MSP430F2955. NOTE: firmware is built with CCS 6.1, MSP432 driver is 100% CMSIS based. Opto-coupled inputs, NC switches recommended. Opto-coupled outputs with 200mA open drain drive for spindle on, spindle direction, flood and mist. Can drive most relays and solenoids directly. Output section can be powered from internal 3V3 or 5V source, or from external source. If powered from external source outputs can be made opto-isolated via jumper setting. PWM-output for spindle speed currently directly connected to MCU pin (could be changed to open drain). I2C (IIC) interface with selectable voltage level (3V3 or 5V) via level shifter, dedicated interrupt input. I2C pinout compatible with my 4x4 keyboard project, supports jogging etc. Optional EEPROM for configuration settings for MCUs with no internal EEPROM. Polulu 8825 motor driver breakout board compatible. Fault signal routed to GPIO input. Considered for later revision: Break out SPI interface and add full support for Trinamic motor drivers. Optional (SPI) DAC for motor speed (laser power) control. This might require a 4-layer PCB and also solving the pinout cabal... --- Anything you want changed? Terje
  10. MSP432E4

    I just spotted these and couldn't find any other thread about them. Headline is it an MSP432 with Ethernet, USB and CAN. http://www.ti.com/microcontrollers/simplelink-mcus/msp432/overview/msp432e4.html http://www.ti.com/product/msp432e401y http://www.ti.com/product/msp432e411y Launchpad: http://www.ti.com/tool/msp-exp432e401y
  11. Hi All First, I would like to thank @Rei Vilo for providing the Library for the Kentec (BOOSTXL-k350qvg) library with Energia. I copied the code out of https://www.youtube.com/watch?v=XyeUpk6P4kA (as I didn't find the powerpoint or pdf) and got it to work with an MSP430F5529 launchpad. (Energia 18, Windows as the Mac version doesn't work atm). Then I compiled the same code on a MSP432P401R launchpad and it runs a lot slower than on the F5529 (I assume this is a known issue, due to slow SPI speed ( https://github.com/energia/msp432-core/issues/27 ) but also doesn't look the same, the fonts are "skinnier on the MSP432. This discrepancy, I cannot explain. Another question: If I want to write a changing variable, in this case simply the x-coordinate of the touch to the screen, how do I locally clear the screen without redrawing everything (or if I want to make a bar graph that represents eg a changing value of a sensor? Do I always draw a black rectangle, then the bar/text etc? or is there a simpler way that is not immediately obvious to me now? Next step: I have to learn more about state machines to switch screens (settings), do stuff there, come back to main without the program getting into badly readable territory. Thank you very much for your help. //First steps with the Kentec Display #include "SPI.h" #include "Screen_K35_SPI.h" Screen_K35_SPI myScreen; uint16_t colours[6]; uint16_t x; uint16_t y; uint16_t z; uint8_t initFlag; void setup() { Serial.begin(9600); Serial.println(); Serial.println("hello"); Serial.println(); pinMode(RED_LED, OUTPUT); myScreen.begin(); myScreen.clear(); colours[0] = myScreen.calculateColour(255, 0, 0); colours[1] = myScreen.calculateColour(0, 255, 0); colours[2] = myScreen.calculateColour(0, 0, 255); colours[3] = myScreen.calculateColour(255, 255, 255); colours[4] = myScreen.calculateColour(255, 255, 0); colours[5] = myScreen.calculateColour(0, 0, 0); x = 0; y = 0; z = 0; myScreen.setPenSolid(true); myScreen.setFontSolid(false); myScreen.setFontSize(2); initFlag = 1; } void loop() { if (initFlag) { drawHomeScreen(); initFlag = 0; } if (myScreen.isTouch() > 0) { myScreen.getTouch(x, y, z); myScreen.gText(10, 10, btoa(x, 8), colours[3]); Serial.print(x); Serial.print(" "); Serial.print(y); Serial.print(" "); Serial.println(z); } if (z > 100) { if ((x < 160 && x > 0) && (y < 240 && y > 100)) { digitalWrite(RED_LED, HIGH); } else if ((x < 320 && x > 160) && (y > 100 && y < 240)) { digitalWrite(RED_LED, LOW); } else if ((x < 320 && x > 160) && (y > 0 && y < 100)) { drawSettingsScreen(); } } } void drawHomeScreen() { myScreen.clear(); myScreen.gText(30, 50, "TOUCH LCD DEMO", colours[4]); myScreen.rectangle(0, 100, 160, 239, colours[1]); myScreen.gText(50, 180, "ON", colours[0]); myScreen.rectangle(160, 100, 319, 239, colours[0]); myScreen.gText(235, 180, "OFF", colours[1]); myScreen.rectangle(160, 0, 319, 100, colours[2]); myScreen.gText(180, 50, "SETTINGS", colours[3]); } void drawSettingsScreen() { myScreen.clear(); myScreen.gText(10, 10, "TOUCH LCD DEMO", colours[0]); myScreen.gText(10, 30, "TOUCH LCD DEMO", colours[1]); myScreen.gText(10, 50, "TOUCH LCD DEMO", colours[2]); myScreen.gText(10, 70, "TOUCH LCD DEMO", colours[3]); myScreen.gText(10, 90, "TOUCH LCD DEMO", colours[4]); }
  12. I am hopeful there will be USB connectivity. This is all I have been able to uncover: Core ARM Cortex-M4, FPU MPU 48 MHz Processor:Cortex-M4, FPU MPU 48 MHz Cryptographic Engine:128.256 -bit HW accelerated AES Encryption Engine Memory 512 kB RAM, 2 MB ROM ROM:2 MB ROM:32 kB RAM:256 kB RAM:256 kB Clock & Power 1.62 V .. 3.7 V, 48 MHz Supply Voltage:1.62 V .. 3.7 V Operating Voltage Maximum Clock Frequency:48 MHz, Communication Other Other:4 x UART or SPI Other:4 x I2C or SPI Timer/Counter/PWM 4 x 16-bit Timer, 2 x 32-bit Timer Timer/Counter:4 x 16-bit Up to 4 timers/PWM/CCP Timer/Counter:2 x 32-bit GP Timers Analog 24-channel 14 bit ADC, 2 x Analog Comparator Temperature Sensor:1 x 2 x Analog Comparator
  13. Hello everyone, I have a project which requires GPS + Wi-fi capability and fastest clock speed mcu possible. For GPS capability I came across CC4000 which seems alright, but I'm confused on which launchpad board to select that has Wifi capability also. I have worked on Arduino but new to TI's Launchpad. Please suggest me for what should I buy. link for the CC4000 gps module kit : http://www.ti.com/tool/cc4000gpsem?keyMatch=gps&tisearch=Search-EN-Everything#descriptionArea
  14. Hi. In the beginning of this year I wrote two articles showing how to compile the CMSIS DSPLIB to use in MSP432 and one example of use. The sequence is very similar to used in Stellaris and Tiva line. The articles are in portuguese, but there is a embedded translator. Compiling the CMSIS DSPLIB to MSP432 Example of use - FIR filter I hope it's useful.
  15. Hi all, I need to import/upload data to my MSP432P401R to call upon in future programs. Since I want this data to exist and be saved when my MSP432 is offline/powered-off, I decided that saving it to flash is the way to go. However, I don't know how to do this. Can anyone offer guidance or suggestions? Or does anyone have a better way of doing this? I'm using Energia v18.
  16. Hello all, I am using MSP432 Launchpad and Energia latest V18. I am not able to download the MSP432 or any other board from board manager. I am getting an error attached in the file. Could anyone please help me with this? Thank you in advance.
  17. Hi all, When I try to connect my MSP432 launchpad to Energia v18, it connects to the right port, but it only gives me the option to list the board as a type of MSP430. When I go to Tools>Board>Board Manager, I get to the Boards Manager where I can download different types of board packages. When I try to install the Energia MSP432 Boards, I get a red error message at the bottom of the screen that says "Error downloading http://www.energia.nu/downloads/download_core.php?file=msp432-1.0.15.tar.bz2" I've tried connecting my board to Energia v17 and the board actually connected on that version. When I try to upload an example program like "Blink" on my board, I get an error that says "Upload Failed" with the following message below (see attached picture). I'm stuck and am unsure of what to do to get to be able to program my MSP432 through Energia regardless of the version. Any suggestions?
  18. Hi, I'm trying to do a timerA initiated multiple channel conversion with the ADC14 in an MSP432. It seems that TI-RTOS wants to use all the TimerA modules. I believe this because I see the TAxR value stop. I also made a simple timer routine to blink the LED in the TA0 ISR, and it works sometimes and not others. I notice that there doesn't seem to be any drivers for TI-RTOS for the timers, and no example code for doing a multichannel convert triggered by TimerAx. I have bare metal code for driverlib that works perfectly, but when I put it into Energia, I get no interrupts, as the timer is stopped. I can fight with TI-RTOS, and keep starting the timer in my loop(), but of course it isn't sampling at the rate I want then. I am wondering if perhaps I change the Times_NumberofTimerDevices to be one less, if I could use TimerA3. What do you all think? See for example Timer.c below: /* * Copyright (c) 2014-2016, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * ======== Timer.c ======== * */ #include <xdc/std.h> #include <xdc/runtime/Error.h> #include <xdc/runtime/Assert.h> #include <xdc/runtime/Startup.h> #include <xdc/runtime/Types.h> #include <ti/sysbios/BIOS.h> #include <ti/sysbios/family/arm/m3/Hwi.h> #include <ti/sysbios/family/arm/msp432/ClockFreqs.h> /* TODO: move this peripheral register definition to catalog? */ typedef volatile struct ti_catalog_msp432_peripherals_timers_TimerRegs { UInt16 control; UInt16 cctl_0; UInt16 cctl_1; UInt16 cctl_2; UInt16 cctl_3; UInt16 cctl_4; UInt16 cctl_5; UInt16 cctl_6; UInt16 count; UInt16 cc_compare_0; UInt16 cc_compare_1; UInt16 cc_compare_2; UInt16 cc_compare_3; UInt16 cc_compare_4; UInt16 cc_compare_5; UInt16 cc_compare_6; UInt16 expansion; UInt16 reserved[6]; UInt16 vector; } ti_catalog_msp432_peripherals_timers_TimerRegs; #include "package/internal/Timer.xdc.h" #define MC 0x0020 /* mode, control = continous up counting */ #define TxCLR 0x0004 /* clear timer counter */ #define CCIE 0x0010 /* compare interrupt enable */ #define CCIFG 0x0001 /* compare interrupt pending flag */ #define TSSEL 0x0100 /* source select = ACLK */ #define ID_MASK 0x00C0 /* input divider bit mask */ #define TIMER_CONTROL_START MC #define TIMER_CONTROL_CLEAR TxCLR #define TIMER_CONTROL_DEFAULT TSSEL #define TIMER_COMPARE_INTR_ENABLE CCIE #define TIMER_COMPARE_INTR_PENDING CCIFG #define TIMER_DELETED 0 #define BAD_TIMER_ID 1 #define NO_TIMER_AVAIL 2 #define NO_HWI_OBJ 3 #define BAD_PERIOD 4 #define READ_LATENCY 10 /* # MCLK cycles to allow for back-to-back read of count */ #define SYS_PERI_HALTCTL_REG 0xE004300C /* peripheral halt control reg */ #define REG(x) (*((volatile unsigned *)(x))) /* * ======== Timer_getAvailMask ======== */ UInt Timer_getAvailMask() { return (Timer_module->availMask); } /* * ======== Timer_getNumTimers ======== * Get number of timer peripherals available on the device. */ UInt Timer_getNumTimers() { return (Timer_numTimerDevices); } /* * ======== Timer_getStatus ======== * Get the FREE/INUSE status of the timer. */ Timer_Status Timer_getStatus(UInt timerId) { Assert_isTrue(timerId < Timer_numTimerDevices, NULL); if (Timer_module->availMask & (0x1 << timerId)) { return (Timer_Status_FREE); } else { return (Timer_Status_INUSE); } } /* * ======== Timer_getMaxTicks ======== */ UInt32 Timer_getMaxTicks(Timer_Object *obj) { return (0x0000FFFF / obj->period); } /* * ======== Timer_setAvailMask ======== */ Bool Timer_setAvailMask(UInt mask) { UInt i; UInt key; UInt tmpMask; key = Hwi_disable(); tmpMask = mask; for (i = 0; i < Timer_numTimerDevices; i++) { /* Check if mask is setting any currently used timer as available */ if ((tmpMask & 0x1) && (Timer_module->handles[i] != NULL)) { Hwi_restore(key); return (FALSE); } tmpMask = tmpMask >> 1; } Timer_module->availMask = mask; Hwi_restore(key); return (TRUE); } /* * ======== Timer_setNextTick ======== * Program the timer's interrupt threshold for the next tick. */ Void Timer_setNextTick(Timer_Object *obj, UInt32 ticks) { ti_catalog_msp432_peripherals_timers_TimerRegs *timer; UInt32 newPeriod = obj->period * ticks; UInt next; UInt previous; UInt now; /* get timer base address */ timer = (ti_catalog_msp432_peripherals_timers_TimerRegs *) Timer_module->device[obj->id].baseAddr; previous = obj->prevThreshold; /* next is relative to savedCurrCount */ next = obj->savedCurrCount + newPeriod; /* set the compare threshold for next interrupt */ timer->cc_compare_0 = next; /* * MSP432 timers will only interrupt if the timer counts *to* the threshold. * So we must check to make sure that the threshold wasn't set too late - * if it was set late, the timer count will need to wrap before the next * interrupt is triggered. To avoid this, after writing the next * interrupt threshold, we read the current count, and if the interrupt * threshold was set too late per the current count, we again write * to the timer to trigger an immediate interrupt. * * For the cases where the 'next' threshold is more than the 'previous', * the timer will not wrap before the next target tick interrupt. This * creates three regions shown below (A, B, C), where the current 'now' * count will reside: * * FFFF | - * | B * |<----- next - * | A * |<----- previous - * | C * 0 | - * * A - 'now' is greater than equal to 'previous', and less than 'next': * this is the 'normal' region, where the threshold has been set before the * next threshold, and no adjustment is needed. * * B - 'now' is greater than equal to 'next': the threshold was set * late, trigger an interrupt now. * * C - 'now' is less than 'previous': the threshold was set late, trigger * an interrupt now. * * For the cases where the 'next' threshold is less than the 'previous', * the timer count is expected to wrap before the next tick interrupt. * This creates the three regions shown below (D, E, F), where the current * 'now' count will reside: * * FFFF | - * | D * |<----- previous - * | F * |<----- next - * | E * 0 | - * * D - 'now' is greater than equal to 'previous': this is a 'normal' * region, where the threshold has been set before the next threshold, * and no adjustment is needed. * * E - 'now' is less than 'next': this is another 'normal' region, * where the threshold has been set early enough, and no adjustment is * needed. * * F - 'now' is greater than or equal to 'next' and less than * 'previous': the threshold was set too late, trigger an interrupt now. */ /* get current timer count */ now = Timer_getCount(obj); /* if not expecting wrap thru zero ... */ if (next > previous) { /* case "B": now is greater than or equal to next, interrupt now */ if (now >= next) { timer->cctl_0 |= CCIFG; } /* case "C": now < previous, count has wrapped, interrupt now */ else { if (now < previous) { timer->cctl_0 |= CCIFG; } } } /* else, expecting wrapping thru zero ... */ else { /* case F: now is between next and previous, interrupt now */ if ((now < previous) && (now >= next)) { timer->cctl_0 |= CCIFG; } } } /* * ======== Timer_Module_startup ======== * Calls postInit for all statically-created & constructed * timers to initialize them. */ Int Timer_Module_startup(Int status) { Int i; Timer_Object *obj; if (Timer_startupNeeded) { for (i = 0; i < Timer_numTimerDevices; i++) { obj = Timer_module->handles[i]; /* if timer was statically created/constructed */ if ((obj != NULL) && (obj->staticInst)) { Timer_postInit(obj, NULL); } } } return (Startup_DONE); } /* * ======== Timer_startup ======== * Here after call to main(). Called from BIOS_start(). */ Void Timer_startup() { Int i; Timer_Object *obj; if (Timer_startupNeeded) { for (i = 0; i < Timer_numTimerDevices; i++) { obj = Timer_module->handles[i]; /* if timer was statically created/constructed */ if ((obj != NULL) && (obj->staticInst)) { if (obj->startMode == Timer_StartMode_AUTO) { Timer_start(obj); } } } } } /* * ======== Timer_getHandle ======== */ Timer_Handle Timer_getHandle(UInt id) { Assert_isTrue((id < Timer_numTimerDevices), NULL); return (Timer_module->handles[id]); } /* * ======== Timer_Instance_init ======== * 1. Select timer based on id * 2. Mark timer as in use * 3. Init timer obj using params * 4. Create Hwi if tickFxn != NULL * 5. Initialize timer * 6. Configure timer (wrt emulation, frequency, etc.) * 7. Set period * 8. Timer_start() * */ Int Timer_Instance_init(Timer_Object *obj, Int id, Timer_FuncPtr tickFxn, const Timer_Params *params, Error_Block *eb) { Int status; UInt key; Int i; Hwi_Params hwiParams; UInt tempId = 0xffff; if (id >= Timer_numTimerDevices) { if (id != Timer_ANY) { Error_raise(eb, Timer_E_invalidTimer, id, 0); return (BAD_TIMER_ID); } } key = Hwi_disable(); if (id == Timer_ANY) { for (i = 0; i < Timer_numTimerDevices; i++) { if ((Timer_anyMask & (1 << i)) && (Timer_module->availMask & (1 << i))) { Timer_module->availMask &= ~(1 << i); tempId = i; break; } } } else if (Timer_module->availMask & (1 << id)) { Timer_module->availMask &= ~(1 << id); tempId = id; } Hwi_restore(key); obj->staticInst = FALSE; if (tempId == 0xffff) { Error_raise(eb, Timer_E_notAvailable, id, 0); return (NO_TIMER_AVAIL); } else { obj->id = tempId; } if (params->clockSource == Timer_Source_ACLK) { obj->controlRegInit = 0x0100 | params->inputDivider; } else if (params->clockSource == Timer_Source_SMCLK) { obj->controlRegInit = 0x0200 | params->inputDivider; } else if (params->clockSource == Timer_Source_EXTERNAL) { obj->controlRegInit = 0x0000 | params->inputDivider; } else if (params->clockSource == Timer_Source_EXTERNAL_INVERTED) { obj->controlRegInit = 0x0300 | params->inputDivider; } else { return (NO_HWI_OBJ); } obj->runMode = params->runMode; obj->startMode = params->startMode; obj->period = params->period; obj->periodType = params->periodType; obj->arg = params->arg; obj->intNum = Timer_module->device[obj->id].intNum; obj->tickFxn = tickFxn; obj->prevThreshold = 0; obj->savedCurrCount = 0; obj->rollovers = 0; obj->synchronous = params->synchronous; if (params->extFreq.lo == 0) { if (params->clockSource == Timer_Source_ACLK) { obj->frequency.lo = ClockFreqs_ACLK; } else if (params->clockSource == Timer_Source_SMCLK) { obj->frequency.lo = ClockFreqs_SMCLK; } } else { obj->frequency.lo = params->extFreq.lo; } obj->frequency.hi = params->extFreq.hi; obj->inputDivider = params->inputDivider; obj->inputDividerExp = params->inputDividerExp; if (obj->tickFxn) { if (params->hwiParams) { Hwi_Params_copy(&hwiParams, (params->hwiParams)); } else { Hwi_Params_init(&hwiParams); } hwiParams.arg = (UArg)obj->id; if (obj->runMode == Timer_RunMode_CONTINUOUS) { if (params->nesting == TRUE) { obj->hwi = Hwi_create(obj->intNum, Timer_periodicNestStub, &hwiParams, eb); } else { obj->hwi = Hwi_create(obj->intNum, Timer_periodicStub, &hwiParams, eb); } } else { if (params->nesting == TRUE) { obj->hwi = Hwi_create(obj->intNum, Timer_oneShotNestStub, &hwiParams, eb); } else { obj->hwi = Hwi_create(obj->intNum, Timer_oneShotStub, &hwiParams, eb); } } if (obj->hwi == NULL) { return (NO_HWI_OBJ); } } else { obj->hwi = NULL; } Timer_module->handles[obj->id] = obj; Timer_initDevice(obj); if (obj->periodType == Timer_PeriodType_MICROSECS) { if (!Timer_setPeriodMicroSecs(obj, obj->period)) { Error_raise(eb, Timer_E_cannotSupport, obj->period, 0); Hwi_restore(key); return (BAD_PERIOD); } } status = Timer_postInit(obj, eb); if (status) { return (status); } if (obj->startMode == Timer_StartMode_AUTO) { Timer_start(obj); } return (0); } /* * ======== Timer_reconfig ======== * * 1. Init obj using params * 2. Timer_init() * 3. Configure timer (wrt emulation, frequency, etc.) * 4. Set period * 5. Timer_start() * */ Void Timer_reconfig (Timer_Object *obj, Timer_FuncPtr tickFxn, const Timer_Params *params, Error_Block *eb) { obj->controlRegInit = params->controlRegInit | params->inputDivider; obj->runMode = params->runMode; obj->startMode = params->startMode; obj->periodType = params->periodType; obj->prevThreshold = params->prevThreshold; obj->rollovers = 0; obj->savedCurrCount = 0; obj->synchronous = params->synchronous; obj->inputDividerExp = params->inputDividerExp; if (obj->periodType == Timer_PeriodType_MICROSECS) { if (!Timer_setPeriodMicroSecs(obj, params->period)) { Error_raise(eb, Timer_E_cannotSupport, params->period, 0); } } else { obj->period = params->period; } obj->arg = params->arg; obj->tickFxn = tickFxn; if (params->extFreq.lo) { /* (extFreq.hi is ignored) */ obj->frequency.lo = params->extFreq.lo; } Timer_postInit(obj, eb); if (obj->startMode == Timer_StartMode_AUTO) { Timer_start(obj); } } /* * ======== Timer_Instance_finalize ======== */ Void Timer_Instance_finalize(Timer_Object *obj, Int status) { UInt key; /* note: fall through in switch below is intentional */ switch (status) { /* Timer_delete() */ case TIMER_DELETED: /* setPeriodMicroSecs failed */ case BAD_PERIOD: Timer_initDevice(obj); if (obj->hwi) { Hwi_delete(&obj->hwi); } /* Hwi create failed */ case NO_HWI_OBJ: /* timer not available */ case NO_TIMER_AVAIL: /* invalid timer id */ case BAD_TIMER_ID: default: break; } key = Hwi_disable(); Timer_module->availMask |= (0x1 << obj->id); Timer_module->handles[obj->id] = NULL; Hwi_restore(key); } /* * ======== Timer_start ======== * * 1. Hwi_disable() * 2. Clear the counter * 3. Clear timer interrupt flag * 4. Set next compare threshold (per configured period) * 5. Enable timer interrupt * 6. Start timer * 7. Hwi_restore() * */ Void Timer_start(Timer_Object *obj) { ti_catalog_msp432_peripherals_timers_TimerRegs *timer; UInt key; timer = (ti_catalog_msp432_peripherals_timers_TimerRegs *) Timer_module->device[obj->id].baseAddr; key = Hwi_disable(); /* reset timer counts */ timer->control |= TIMER_CONTROL_CLEAR; /* clear timer interrupt flag */ timer->cctl_0 &= ~TIMER_COMPARE_INTR_PENDING; /* zero previous threshold */ obj->prevThreshold = 0; /* set compare threshold for next interrupt */ timer->cc_compare_0 = obj->period; /* enable capture/compare 0 interrupts */ timer->cctl_0 |= TIMER_COMPARE_INTR_ENABLE; /* start timer */ timer->control |= TIMER_CONTROL_START; Hwi_restore(key); } /* * ======== Timer_stop ======== * * 1. Stop timer * 2. Disable timer interrupt * */ Void Timer_stop(Timer_Object *obj) { ti_catalog_msp432_peripherals_timers_TimerRegs *timer; timer = (ti_catalog_msp432_peripherals_timers_TimerRegs *) Timer_module->device[obj->id].baseAddr; /* stop timer */ timer->control = obj->controlRegInit | obj->inputDivider; /* disable capture/compare 0 interrupts */ timer->cctl_0 &= ~TIMER_COMPARE_INTR_ENABLE; /* clear timer interrupt flag */ timer->cctl_0 &= ~TIMER_COMPARE_INTR_PENDING; } /* * ======== Timer_setPeriod ======== * * 1. Stop timer * 2. Set period value in timer obj * */ Void Timer_setPeriod(Timer_Object *obj, UInt32 period) { Timer_stop(obj); obj->period = period; } /* * ======== Timer_setPeriodMicroSecs ======== * * 1. Stop timer * 2. Compute counts * 3. Set new period value in timer obj * */ Bool Timer_setPeriodMicroSecs(Timer_Object *obj, UInt32 period) { Types_FreqHz freqHz; UInt32 counts; UInt32 freqKHz; Timer_stop(obj); Timer_getFreq(obj, &freqHz); freqKHz = freqHz.lo / 1000; if (Timer_checkOverflow(freqKHz, period/1000)) { return (FALSE); } else { counts = (freqKHz * period) / 1000; obj->period = counts; obj->periodType = Timer_PeriodType_COUNTS; return(TRUE); } } /* * ======== Timer_trigger ======== * * 1. stop timer * 2. write the period with insts * 3. start the timer. * */ Void Timer_trigger(Timer_Object *obj, UInt32 insts) { UInt key; /* follow proper procedure for dynamic period change */ key = Hwi_disable(); /* Force SMCLK for sweep timer */ obj->controlRegInit &= ~0x0100; /* clear ACLK bit */ obj->controlRegInit |= 0x0200; /* enable SMCLK */ Timer_stop(obj); Timer_setPeriod(obj, insts); Timer_start(obj); Hwi_restore(key); } /* * ======== Timer_getPeriod ======== */ UInt32 Timer_getPeriod(Timer_Object *obj) { return(obj->period); } /* * ======== Timer_getCount ======== */ UInt32 Timer_getCount(Timer_Object *obj) { ti_catalog_msp432_peripherals_timers_TimerRegs *timer; UInt first; UInt second; timer = (ti_catalog_msp432_peripherals_timers_TimerRegs *) Timer_module->device[obj->id].baseAddr; /* if timer's source clock is synchronous to CPU: only read counts once */ if (obj->synchronous) { first = timer->count; } /* else, must do multiple reads to avoid possible spurious values */ else { /* read twice, expecting equal values, or within read latency */ do { first = timer->count; second = timer->count; } while ((first != second) && ((second - first) > READ_LATENCY)); } return (((UInt32) first) & 0xffff); } /* * ======== Timer_oneShotStub ======== */ Void Timer_oneShotStub(UArg arg) { Timer_Object *obj; obj = Timer_module->handles[(UInt)arg]; /* stop the timer (and disable this interrupt source) */ Timer_stop(obj); /* call the tick function */ obj->tickFxn(obj->arg); } /* * ======== Timer_oneShotNestStub ======== */ Void Timer_oneShotNestStub(UArg arg) { Timer_Object *obj; obj = Timer_module->handles[(UInt)arg]; /* stop the timer (and disable this interrupt source) */ Timer_stop(obj); /* enable interrupts to allow nesting */ Hwi_enable(); /* call the tick function */ obj->tickFxn(obj->arg); /* disable interrupts as unwind the ISR */ Hwi_disable(); } /* * ======== Timer_periodicStub ======== */ Void Timer_periodicStub(UArg arg) { Timer_Object *obj; ti_catalog_msp432_peripherals_timers_TimerRegs *timer; obj = Timer_module->handles[(UInt)arg]; timer = (ti_catalog_msp432_peripherals_timers_TimerRegs *) Timer_module->device[obj->id].baseAddr; /* clear timer interrupt flag */ timer->cctl_0 &= ~TIMER_COMPARE_INTR_PENDING; /* for DYNAMIC, mode latch prevThreshold and detect rollovers */ if (obj->runMode == Timer_RunMode_DYNAMIC) { /* * If the current threshold is less than the prevThreshold * then a rollover has occurred. * * If the current threshold is equal to prevThreshold then the timer * count wrapped around and generated a new interrupt; increment * the rollover count to resume ticking. */ if (obj->prevThreshold >= timer->cc_compare_0) { obj->rollovers += 1; } /* save previous threshold value */ obj->prevThreshold = timer->cc_compare_0; } else { /* save previous threshold value */ obj->prevThreshold = timer->cc_compare_0; obj->savedCurrCount = timer->cc_compare_0; /* set next interrupt threshold; interrupt now if set too late */ Timer_setNextTick(obj, 1); } /* call the tick function */ obj->tickFxn(obj->arg); } /* * ======== Timer_periodicNestStub ======== */ Void Timer_periodicNestStub(UArg arg) { Timer_Object *obj; ti_catalog_msp432_peripherals_timers_TimerRegs *timer; obj = Timer_module->handles[(UInt)arg]; timer = (ti_catalog_msp432_peripherals_timers_TimerRegs *) Timer_module->device[obj->id].baseAddr; /* clear timer interrupt flag */ timer->cctl_0 &= ~TIMER_COMPARE_INTR_PENDING; /* for DYNAMIC, mode latch prevThreshold and detect rollovers */ if (obj->runMode == Timer_RunMode_DYNAMIC) { /* * if the current threshold is less than the prevThreshold * then a rollover has occurred. */ if (obj->prevThreshold > timer->cc_compare_0) { obj->rollovers += 1; } /* save previous threshold value */ obj->prevThreshold = timer->cc_compare_0; } else { /* save previous threshold value */ obj->prevThreshold = timer->cc_compare_0; obj->savedCurrCount = timer->cc_compare_0; /* set next interrupt threshold; interrupt now if set too late */ Timer_setNextTick(obj, 1); } /* allow nesting of other interrupts ... */ timer->cctl_0 &= ~TIMER_COMPARE_INTR_ENABLE; Hwi_enable(); /* call the tick function */ obj->tickFxn(obj->arg); /* disable interrupts as unwind the ISR */ Hwi_disable(); timer->cctl_0 |= TIMER_COMPARE_INTR_ENABLE; } /* * ======== Timer_getExpiredCounts ======== * * This API is used by the TimestampProvider as part of retrieving a timestamp * using a timer and a tick counter. It returns the expired counts since the * last serviced timer interrupt. * * This API must be called with interrupts disabled; the TimestampProvider * must disable interrupts while retrieving the tick count and calling this * API. * * The TimestampProvider uses a 32-bit timer and 32-bit tick count to track * the timestamp. The tick count either comes from the Clock module or is * stored in the TimestampProvider's module state and incremented by an ISR * when the timer expires. * * For MSP432 we have 16-bit timers, and use a timer compare feature to * trigger an interrupt upon a specific threshold count being reached. The * timer counts can rollover (going thru zero), on the way to reaching the * next threshold. We need to accommodate this rollover as part of * determining expired counts. * * We also need to handle the case where there is a large period value used * for the timer, and the timer is ticking at a fast rate (e.g., the CPU * rate, via an SMCLK selection). For this case, it is possible that * interrupts are disabled before the timer reaches threshold, and then the * timer reaches the threshold count and asserts an interrupt, and then * continues to count upwards before it is read in this routine. If the * timer rolled past zero, then we need to know that there is an interrupt * pending, otherwise we'd report a low count, versus the period plus * that low count. * * To be sure to catch the interrupt, we sample the interrupt flag, read * the count, and then sample the interrupt flag again: * * intrFlag1 * count * intrFlag2 * * If intrFlag1 is set, then we know we've reached the period count, and * need to add it to the reported counts. If intrFlag2 is set, but * intrFlag1 wasn't, we know the timer just reached threshold, and simply * report the period count. * * If neither interrupt flag is set, we can then compute the expired counts by * comparing the count to the previous interrupt threshold (saved in the * timer object). If the current count is greater than or equal to the * previous threshold value, then we know there has been no counter rollover, * and the expired counts is simply: * * result = count - prevThresh * * If the current count is less than the previous threshold, then we know a * counter rollover has occurred since the last ISR. In this case, the * expired counts has to include those between the previous threshold and * zero, plus any counts after rolling past zero: * * result = (0 - prevTresh) + count * * Similar logic to compare the current count to previous threshold can * be used for the case where we know intrFlag1 has been set, and we * need to figure the counts to be added to the period counts. * */ UInt32 Timer_getExpiredCounts(Timer_Object *obj) { ti_catalog_msp432_peripherals_timers_TimerRegs *timer; UInt32 result32; UInt32 count32; UInt32 thresh32; UInt32 period32; UInt32 prev32; Bool intrFlag1; Bool intrFlag2; timer = (ti_catalog_msp432_peripherals_timers_TimerRegs *) Timer_module->device[obj->id].baseAddr; intrFlag1 = timer->cctl_0 & TIMER_COMPARE_INTR_PENDING; count32 = Timer_getCount(obj) & 0xffff; intrFlag2 = timer->cctl_0 & TIMER_COMPARE_INTR_PENDING; prev32 = obj->prevThreshold & 0xffff; /* interrupt pending before read count? */ if (intrFlag1) { thresh32 = timer->cc_compare_0 & 0xffff; /* threshold for interrupt */ period32 = Timer_getPeriod(obj) & 0xffff; /* period count */ /* threshold reached; no wrap thru zero yet */ if (count32 >= thresh32) { result32 = (count32 - thresh32) + period32; } /* threshold reached; count has wrapped thru zero */ else { result32 = (0x10000 - thresh32) + count32 + period32; } } /* new interrupt now pending, when wasn't before read the count */ else if (intrFlag2) { result32 = Timer_getPeriod(obj) & 0xffff; /* return period count */ } /* interrupt threshold not reached; check if wrapped thru zero */ else if (count32 >= prev32) { result32 = count32 - prev32; } /* interrupt threshold not reached; count has wrapped thru zero */ else { result32 = (0x10000 - prev32) + count32; } return (result32); } /* * ======== Timer_getExpiredTicks ======== */ UInt32 Timer_getExpiredTicks(Timer_Object *obj, UInt32 tickPeriod) { UInt32 ticks; ticks = Timer_getExpiredCounts(obj) / tickPeriod; return (ticks); } /* * ======== Timer_getCurrentTick ======== * Uses 48 bits of precision. * at 32.768 KHz, that's 8,589,934,592 seconds, * or 272 years before tick would be miscalculated */ UInt32 Timer_getCurrentTick(Timer_Object *obj, Bool saveFlag) { UInt32 rollovers; UInt currCount; UInt32 tick; UInt32 s1; UInt r; currCount = Timer_getCount(obj); rollovers = obj->rollovers; if (currCount < obj->prevThreshold) { rollovers += 1; } s1 = rollovers / obj->period; /* upper 32 of 48 bits */ r = rollovers - s1 * obj->period; /* remainder of upper division */ tick = (((UInt32)r << 16) + currCount) / obj->period; /* lower 16-bits */ tick = ((UInt32)(s1 & 0xFFFF) << 16) + (tick & 0xFFFF); /* save for later use by Timer_setNextTick() */ if (saveFlag != 0) { obj->savedCurrCount = tick * obj->period; } return (tick); } /* * ======== Timer_getFreq ======== */ Void Timer_getFreq(Timer_Object *obj, Types_FreqHz *freq) { UInt divider; switch(obj->controlRegInit & ID_MASK) { case Timer_ID_1: divider = 1; break; case Timer_ID_2: divider = 2; break; case Timer_ID_4: divider = 4; break; default: divider = 8; break; } divider *= (obj->inputDividerExp + 1); freq->lo = obj->frequency.lo / divider; freq->hi = 0; } /* * ======== Timer_getFunc ======== */ Timer_FuncPtr Timer_getFunc(Timer_Object *obj, UArg *arg) { *arg = obj->arg; return (obj->tickFxn); } /* * ======== Timer_setFunc ======== */ Void Timer_setFunc(Timer_Object *obj, Timer_FuncPtr fxn, UArg arg) { obj->tickFxn = fxn; obj->arg = arg; } /* * ======== Timer_checkOverflow ======== */ Bool Timer_checkOverflow(UInt32 a, UInt32 b) { return ((b > 0) && (a > Timer_MAX_PERIOD/b)); } /* ======== Timer_initDevice ======== * * 1. Stop timer (set control registers back to default value) * 2. Disable timer interrupt * 3. Clear any pending interrupt * 4. Clear counters * */ Void Timer_initDevice(Timer_Object *obj) { ti_catalog_msp432_peripherals_timers_TimerRegs *timer; UInt key; timer = (ti_catalog_msp432_peripherals_timers_TimerRegs *) Timer_module->device[obj->id].baseAddr; key = Hwi_disable(); /* stop timer; set default control register */ timer->control = MC | obj->controlRegInit; timer->expansion = obj->inputDividerExp; /* clear timer interrupt flag */ timer->cctl_0 &= ~TIMER_COMPARE_INTR_PENDING; /* reset timer counts */ timer->control |= TIMER_CONTROL_CLEAR; /* freeze the timer when the CPU is halted */ REG(SYS_PERI_HALTCTL_REG) |= 1 << obj->id; Hwi_restore(key); } /* * ======== Timer_postInit ======== */ Int Timer_postInit (Timer_Object *obj, Error_Block *eb) { UInt key; key = Hwi_disable(); Timer_initDevice(obj); Timer_setPeriod(obj, obj->period); Hwi_restore(key); return (0); } And if you think this might be worth pursuing, I'd really like a pointer on how to rebuild the stuff to make this work. Thanks, Rob
  19. Hi All, I need to make ADC14 measurements in the multi mode at a sample rate of 8 kHz, but would like to use Energia's Serial and I2C functions. I have a stand alone driverlib routine that works fine, and Energia code that works fine with the Serial, and I2C, however, I am having difficulty integrating them. I noticed that the ADC14CTL0 register is changed from what my routine called in setup() did. I started reading the code in Energia/emt/src/ti/runtime/wiring/msp432/, and it appears that I may need to modify it to make this work, but before I go hacking, I want advice. Is there a good way to get Energia to leave the ADC14 to me, or is there a way to use Energia's ADC14 routines to do multi conversions at 8 kHz? I'm enclosing my code in case it is of use: extern "C"{ #include <copy2_adc14.h> }; // most launchpads have a red LED #define LED RED_LED //see pins_energia.h for more LED definitions //#define LED GREEN_LED // the setup routine runs once when you press reset: void setup() { Serial.begin(115200); // initialize the digital pin as an output. //pinMode(LED, OUTPUT); adc14_(); //delay(500); //MAP_ADC14_enableConversion(); startSampling(); } // the loop routine runs over and over again forever: void loop() { static int i=0; Serial.print(i++); Serial.println("Hello!"); //digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second //digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW // delay(1000); // wait for a second } And the header file: /* * adc14_.h * * Created on: May 12, 2017 * Author: frohro */ #ifndef COPY2_ADC14_H_ #define COPY2_ADC14_H_ /* DriverLib Includes */ #include <ti/devices/msp432p4xx/driverlib/driverlib.h> #include <ti/sysbios/family/arm/m3/Hwi.h> /* Standard Includes */ #include <stdint.h> #include <stdbool.h> #define SMCLK_FREQ 24000000 #define SAMPLE_FREQ 8000 //Timer_A Continuous Mode Configuration Parameter const Timer_A_UpModeConfig upModeConfig = // This DOES work { TIMER_A_CLOCKSOURCE_SMCLK, // SM Clock Source TIMER_A_CLOCKSOURCE_DIVIDER_1, // SMCLK/1 = 24MHz (SMCLK_FREQ/SAMPLE_FREQ), TIMER_A_TAIE_INTERRUPT_DISABLE, // Disable Timer ISR TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE, // Disable CCR0 TIMER_A_DO_CLEAR // Clear Counter }; /* Timer_A Compare Configuration Parameter */ const Timer_A_CompareModeConfig compareConfig = { TIMER_A_CAPTURECOMPARE_REGISTER_1, // Use CCR1 TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE, // Disable CCR interrupt TIMER_A_OUTPUTMODE_SET_RESET, // Toggle output but (SMCLK_FREQ/SAMPLE_FREQ) // Should be 8 kHz sample rate }; /* Statics */ static volatile uint_fast16_t resultsBuffer[UINT8_MAX]; static volatile uint8_t resPos; int adc14_(void); void ADC14_IRQHandler(void); void startSampling(void); #endif /* COPY2_ADC14_H_ */ and the C file to run the ADC14: /* * ------------------------------------------- * MSP432 DriverLib - v4_00_00_11 * ------------------------------------------- * * --COPYRIGHT--,BSD,BSD * Copyright (c) 2017, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --/COPYRIGHT--*/ /* MSP432 ADC14 - Multiple Channel Sample without Repeat * * Description: In this code example, the feature of being able to scan multiple * ADC channels is demonstrated by the user a the DriverLib APIs. Conversion * memory registers ADC_MEM0 - ADC_MEM3 are configured to read conversion * results from A6, A12, A10, A8 respectively. Conversion is enabled and then sampling is * toggled using a software toggle. Repeat mode is not enabled and sampling only * occurs once (and it is expected that the user pauses the debugger to observe * the results). Once the final sample has been taken, the interrupt for * ADC_MEM3 is triggered and the result is stored in the resultsBuffer buffer. * * MSP432P401 * ------------------ * /|\| | * | | | * --|RST P4.7 |<--- A6 (Analog Input, Measured, Real) * | P4.1 |<--- A12 (Analog Input, Measured, Imaginary) * | P4.3 |<--- A10 (Analog Input, Reference Real) * | P4.5 |<--- A8 (Analog Input, Reference Imaginary) * | | * | | * * 4.1, 4.3, 4.5, 4.7 are the eventual pins needed. * * Author: Timothy Logan * This was modified by Rob Frohne to do multiple ADC at 8 kHz sample rate. ******************************************************************************/ #include <copy2_adc14.h> #define NUMBER_TIMER_CAPTURES 20 #define SAMPLE_LENGTH 128 /* static volatile uint_fast16_t timerAcaptureValues[NUMBER_TIMER_CAPTURES]; static volatile uint32_t timerAcapturePointer = 0; */ uint16_t refRe[SAMPLE_LENGTH]; uint16_t refIm[SAMPLE_LENGTH]; uint16_t measRe[SAMPLE_LENGTH]; uint16_t measIm[SAMPLE_LENGTH]; extern volatile bool doneADC; bool sendMeasurement = false; int numberFrequenciestoMeasure, frequencyIndex; float refSum, measSum; volatile bool doneADC = false; int adc14_(void) { /* Halting WDT */ WDT_A_holdTimer(); Hwi_Params params; // Register interrupt Hwi_Params_init(&params); Hwi_create(INT_ADC14, ADC14_IRQHandler, &params, 0); //Hwi_create(INT_TA0_N, TA0_N_IRQHandler, &params, 0); //Interrupt_enableSleepOnIsrExit(); resPos = 0; // Set to Vcore1 PCM_setCoreVoltageLevel(PCM_VCORE1); // Set to use DCDC //PCM_setPowerState(PCM_AM_DCDC_VCORE1); // Initializes Clock System /* These commented out because we need the Energia clock setup. The * data structures for the timer are adjusted accordingly. The time * between conversions may be four times as much as we had with these * parameters below, but this seems like the easiest way to make everything * play together for now. */ //FlashCtl_setWaitState( FLASH_BANK0, 2); //FlashCtl_setWaitState( FLASH_BANK1, 2); PCM_setPowerState( PCM_AM_DCDC_VCORE1 ); CS_setDCOCenteredFrequency( CS_DCO_FREQUENCY_24 ); //CS_setDCOFrequency(24000000); CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1 );; CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1 ); /* Initializing ADC (MCLK/1/1) */ ADC14_enableModule(); ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_1, 0); // Configuring debugging pins as output for debugging... GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN5); GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0); //Configuring GPIOs for Analog In GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN1 | GPIO_PIN3 | GPIO_PIN5 | GPIO_PIN7, GPIO_TERTIARY_MODULE_FUNCTION); // Configuring ADC Memory (ADC_MEM0 - ADC_MEM3 (A6, A12, A10, A8) with no repeat) // with internal 2.5v reference ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM3, true); // No repeat mode. ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A6, ADC_NONDIFFERENTIAL_INPUTS); ADC14_configureConversionMemory(ADC_MEM1, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A12, ADC_NONDIFFERENTIAL_INPUTS); ADC14_configureConversionMemory(ADC_MEM2, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A10, ADC_NONDIFFERENTIAL_INPUTS); ADC14_configureConversionMemory(ADC_MEM3, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A8, ADC_NONDIFFERENTIAL_INPUTS); /* Configuring Timer_A*/ Timer_A_configureUpMode(TIMER_A0_BASE, &upModeConfig); /* Configuring Timer_A0 in CCR1 */ Timer_A_initCompare(TIMER_A0_BASE, &compareConfig); /* Configuring the sample trigger to be sourced from Timer_A0 and setting it * to automatic iteration after it is triggered*/ ADC14_setSampleHoldTrigger(ADC_TRIGGER_SOURCE1, false); /* Enabling the interrupt when a conversion on channel 3 is complete*/ ADC14_enableInterrupt(ADC_INT3); //ADC14_enableConversion(); // Not needed because we enable it in .ino. /* Enabling Interrupts */ Interrupt_enableInterrupt(INT_ADC14); Interrupt_enableMaster(); /* Starting the Timer */ Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE); /* Going to sleep */ /* while (1) { PCM_gotoLPM0(); }*/ return 1; } void ADC14_IRQHandler(void) { uint64_t status; static int i = 0; //GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0); status = ADC14_getEnabledInterruptStatus(); ADC14_clearInterruptFlag(status); GPIO_toggleOutputOnPin(GPIO_PORT_P5, GPIO_PIN5); ADC14_disableConversion(); if(status & ADC_INT3) { //ADC14_disableConversion(); doneADC = false; ADC14_getMultiSequenceResult(resultsBuffer); measRe[i] = resultsBuffer[0]; measIm[i] = resultsBuffer[1]; refRe[i] = resultsBuffer[2]; refIm[i] = resultsBuffer[3]; //i=(i+1)%SAMPLE_LENGTH; if (i!=SAMPLE_LENGTH) { i++; //ADC14_enableConversion(); } else { i=0; doneADC = true; //ADC14_enableConversion(); } } ADC14_enableConversion(); } void startSampling(void) { ADC14_enableConversion(); // It is a mystery why I need to do this // instead of just calling ADC14_enableConversion() // from the .ino file! } Thanks, Rob
  20. Installing MSP432 broke MSP430

    I've been using Energia successfully (on Mac) with several programs and the MSP430FR5969 and MSP430F5529 LaunchPad boards for a couple of weeks now. Today I acquired an MSP432P401R LaunchPad and so installed the "Energia MSP432 boards by Energia" package from Boards Manager, version 3.8.0. After that all my MSP430 sources compile with large numbers of errors, and I can't get them to work. Is there some way I can undo the effect of installing the MSP432 update and get back to how things were before? I've tried downloading a fresh copy of the Energia application, and deleting the Energia15 folder in my Library folder, but I still get the errors and nothing works. Help!
  21. Hi, I'm trying send GPS (adafruit Ultimate GPS FeatherWing) coordinates to another location using XBees and then displaying GPS data on an LCD (Sharp 96 Booster Pack) using Energia. This involves 2 pairs of Xbees (4 total 2 different ranges), 3 MSP-EXP432P401R (Black Version), the GPS and the LCD. I wrote some code for the first MSP432 on getting GPS data and getting it to the XBee to transmit to another MSP432 (connected to 2 XBees). Although I haven't been able to test it (GPS and XBees aren't here yet) I feel like it will at least be close if not functional.GPStoXBEE.ino After writing the data to the XBee which should then transmit to it's paired XBee that the 2nd MSP432 is connected to. I then want to write the incoming data to the larger ranged XBee also connected to the 2nd MSP432 shown in the following code. XBEEtoXBEE.ino I think my method is kind of right but I won't get the correct output. I believe it will only be taking one char at a time every time the readXBee function is called. So how would I make it print the entirety of the GPS data if I don't know how long/what the data will be ahead of time? I just want to transmit exactly what I'm getting from the GPS itself. Lastly I have another longer ranged XBee connected to the 3rd MSP432 along with an LCD. I want to take the GPS data that is being received from the 2nd MSP432 and print it to the display. I edited the LCD example to get the following XBEEtoLCD.ino and it kind of works, I am able to print from the serial to the display but its only one character at a time every second and the char gets overwritten by the next char. How will can I change the code so that it will print what ever is in the serial in one go? Thanks in Advance
  22. Hi I'm new to using both the MSP-EXP432P401R (Black Version) and Energia. I want to attach a GPS (adafruit Ultimate GPS FeatherWing https://www.adafruit.com/product/3133) and an XBee to the micro-controller so I can send GPS data to another MSP432 micro-controller with an XBee. I see I can attach the GPS or XBee to the hardware uart pins 3.2(Rx) and 3.3(Tx) their listed as pins 3 and 4 respectively on the Energia Pin Map (https://cloud.githubusercontent.com/assets/951776/15053945/5f47bac6-1305-11e6-9ab5-c71d425194ce.jpeg) but where can I find two other hardware pins for attaching a second the second device? Or can I use some other pins (SPI or something) to have both items connected to the micro-controller?
  23. Hello people, I'am trying use a SDCARD only to regist data. All my project was made with "MSPClassic Registers", so I saw in the forum a Bluehash post, but was in CMSIS, in mode to satisfy my project I try to change some files. Now I have some problems to finish him there is someone who can help me?I need Something very simple, just confirm if the card is loaded or not and save data Conections: * P4.6 - CS (active low) * P1.6 - MOSI UCB0SIMO * P1.5 - CLK UCB0CLK * P1.7 - MISO UCB0SOMI FILES: spi.c lcd.c lcd.h main.c main.h pff.c pff.h config.h diskio.c diskio.h integer.h spi.h
  24. Hello! In my own automation system I have to encrypt data transferred between sensor and main controller (data transfers via twisted pair). For this reason, I need a special devices - encryption gateways (one gateaway installs on sensor-side, another on controller-side). These gateways realize following algorithm: Sensor-side: Receive some data from sensor (via discrete input); Encrypt data using AES; Transfer encrypted data to controller-side gateway. Controller-side: Receive encrypted data from sensor-side gateway; Decrypt data; Transfer data to controller (via discrete output). So, I need MCU with hardware accelerated AES, LaunchPad kit and Energia IDE support. From MSP portfolio I have chosen two models: MSP432P401R and MSP430FR5994 (MSP430FR5969 and MSP430FR6989 also meet my criteria). What is the best solution suitable for me and my goal? Thank you for your help!
  25. Hello fellows, I need some help, with a situation, I want convert some analog signals to digital and send him by the UART communication, but I dont get how to solve this problem. my digital values is represented by "tempADC" variable, soo how can I get a buffer with values to the pc with UART communication. I try many things, but i dont understand how to put my output signal in the terminal in this format. temperature: 40º temperature: 41º temperature: 42º temperature: 43º can anyone help me?! my code: #include "uart_Tx.h" #include "stdio.h" void UART_TxConfig(void){ /*CLOCK SYSTEM SUPORT (CS)*/ CS->KEY = 0x695A;/*UNLOCK ALL 16 LSB CS REGISTERS*/ CS->CTL0 = 0;/*RESET PARAMETERS*/ CS->CTL0 = CS_CTL0_DCORSEL_5;/**/ /*CLOCK SYSTEM*/ /*SELA_2 ACLK = REFOCLK*/ /*SELS_3 SMCLK = DCOCLK*/ /*SELM_3 MCLK = DCOCLK*/ CS->CTL1 = CS_CTL1_SELA_2 | CS_CTL1_SELS_3 | CS_CTL1_SELM_3; /*LOCK ACESSES TO REGISTERS*/ CS->KEY = 0;/*UNLOCK ALL 16 LSB CS REGISTERS*/ /*UART PIN CONFIGURATION*/ P1-> SEL0 |= BIT2 | BIT3; /*SET 2 UART PIN's*/ /*ACTIVE INTERRUPTION's*/ __enable_interrupt(); /*ACTIVE eUSCIA0 INTERRUPT IN NVIC MODULE*/ NVIC->ISER[0] = 1 << ((EUSCIA0_IRQn) & 31); /*CONFIGURE UART*/ UCA0CTLW0 |= UCSWRST; UCA0CTLW0 |= UCSSEL__SMCLK;/*SELECT SMCLK CLOCK SOURCE*/ /*BAUD RATE CALCULATION * BAUD RATE DIVISOR (TRANSMITIONS RATE) * 12MHz/(16*9600) = 78.125 VELOCITY *FRACTIONAL PORTION = 0.125 *FRACTIONAL */ UCA0BR0 = 26; /*48000000/16/115200*/ UCA0BR1 = 0x00; UCA0MCTLW = 0x1000 | UCOS16 | 0x0020; /*CONTROL WORD REGISTER*/ UCA0CTLW0 &= ~UCSWRST; /*SOFTWARE RESET DISABLE*/ UCA0IE |=UCRXIE; while(1){ } } /*UART INTERRUPT SERVICE ROUTINE*/ void EUSCIA0_IRQHandler (void){ if (UCA0IFG & UCRXIFG){ while(!(UCA0IFG & UCTXIFG)); UCA0TXBUF = UCA0RXBUF; //UCA0TXBUF = adcTemp; //P1->OUT ^= BIT0; } }
×