
PTB
-
Content Count
113 -
Joined
-
Last visited
-
Days Won
5
Reputation Activity
-
PTB reacted to energia in New Energia release 0101E0010 - 09/12/2013
I am happy to announce that release 0101E0010 just went up on energia.nu.
I want to thank everybody for their support and contributions. Energia would not have been possible without such an awesome community!
Here are the highlights:
Lots of bug fixes. We were not able to squash all of them but got most of the big ones. New MSP430F5529 USB LaunchPad support. This one has a lot of flash (128k) and a lot of ram (8k). Initial support for the CC3000 WiFi BoosterPack on the MSP430F5529 USB LaunchPad. Anaren AIR BoosterPack for RF connectivity on the MSP-EXP430G2 LaunchPad
Full release notes, F5529 LaunchPad pinmap and getting other details will go up over the weekend.
Happy making,
Robert
-
PTB reacted to RobG in (Universal) Color LCD graphics library (2)
This is my new universal graphics library (original one is here.)
Supported boards (this is out of the "box" support, but the library will work with any board after small changes.)
TI's MSP430FR5969 LaunchPad (ugl16msp only for now)
TI's MSP430F5529 LaunchPad
TI's MSP430G2 LaunchPad with G2553 chip
RobG's MSP430G2955 Dev Board
RobG's MSP430F5172 Dev Board
RobG's MSP430F5510 Dev Board
Supported displays
1.8" ST7735 based JD-T1800 - ugl8
2.2" HX8340 based displays - ugl8
2.2" ILI9225 based displays (touch panel) - ugl8
2.2" ILI9341 based displays 320x240 pixels - ugl16
Tiva versions are right here
ugl8msp.zip (name change 4/18/14)
ugl16msp.zip (updated 4/19/14)
-
PTB reacted to RobG in 10W & 20W RGB LED driver board
3 channel, high power LED driver, built to fit 10W RGB LEDs (those things are blindingly bright!)
Now on Tindie.
-
PTB reacted to abecedarian in Budget Workbench Necessites
I've nothing to add, but it looks like I need to drop another $1000 on my bench.
It's a cheap corner desk from WalMart with two monitors, center and left, and a laptop I rarely use in the cubby to the right.
Tower PC is under the left side and the right side has the subwoofer. The speakers are mounted left, behind a monitor, and right, behind the laptop.
Soldering iron is a 'cheap' Radio Shack unit and desoldering is a suction "bulb".
Breadboard jumpers are stuffed behind the monitor in the center, and behind a bag of tortilla chips.
Voltmeter is out in the truck, which needs a transmission rebuild.
What's a "reflow oven"? Does it work well with quesadillas?
;-)
-
PTB reacted to energia in Energia - "Maintenance Release"?
It has indeed been a long time since we have done a release. Although not officially announced yet (shhhhhh..), there is a release planned for Sep 12. So please hang in there for a couple more weeks.
-
PTB reacted to arre in Electric Scooter LCD on dashboard, powered by a TI Stellaris Launchpad
Hi all,
Another project to the list:
I fitted my electric scooter with an LCD on my dashboard, to display power consumption and the voltages of the batteries, using the stellaris launchpad.
The launchpad provided the digital out pins for the LCD (thanks to The_YonGrand for the lib), and the ADC measurements for the voltages & current of the battery.
You can it out in detail on my blog: http://arre234.blogspot.be/ , or directly take a peak in the code on https://github.com/arre525/escooterlcd
But here are already a few pictures to get you interested:)
Arnout
-
PTB reacted to calinp in [Energia Library] Petit FatFS SD Card Library
Hello,
This is a port of ChaN Petit FatFS SD library targeted to low RAM microcontrollers and offers a minimal FAT implementation, with limited write support. For more details see http://elm-chan.org/fsw/ff/00index_p.html
A lot of credits goes to the main contributors to this topic http://forum.43oh.com/topic/1427-petitefs-fatfs-sdcard-usci-code/
Because this library makes use of the SPI library included in Energia it works for both MSP430 and Stellaris launchpads.
With MSP430 I noticed some interference with Serial.print so before every call to the fat library I had to add a small delay. On Stellaris board these are not necessary.
Unzip and copy in Energia\hardware\msp430\libraries or Energia\hardware\lm4f\libraries .
[uPDATE] See post #15 http://forum.43oh.com/topic/3209-energia-library-petit-fatfs-sd-card-library/#entry30031
[DOWNLOAD LINK] http://forum.43oh.com/index.php?app=core&module=attach§ion=attach&attach_id=3019
-
PTB reacted to szymekrak1426459900 in The Stellaris-MP3-thing
Hi.
Finally I decided to say a word or two about a project I am currently working on. While this is nothing innovative or really impressive, this is my first invention that actually can be used for something.
This is a MP3 player, with colour LCD screen and touchpanel. I also hope to add some features that an iPod or something like don't have, for example serial console, or AVR programmer.
I have made something like a Booster Pack to connect elements together. While this is a perfboard with a lot of cables, and it looks ugly, it works and I can even say it is portable. I would like to make a real Booster Pack with everything needed, but I have no experience in etching PCBs yet.
My board connects the Launchpad with LCD screen and VS1003b board(which is responsible for sound and MP3/WMA decoding in my project). It also has SD card socket.
I dream of final device with rechargeable battery, VS1053/1063 for FLAC and OGG playback, and a RTC, all enclosed in a nice case.
Now, about the software. I am writing it in Energia IDE, but avoid using things like digitalWrite in parts of code where speed is important. For SD card, I use the FatFs library, the files that I posted before. The code may be a big mess, but it somehow works. Here is the list of what it currently has:
A simple menu to select "apps" Screen calibration. Data is stored in EEPROM so don't run my code without modifications if you own the revision of LM4F120 which stops working after EEPROM write attempt. The calibration algorithm is not very smart. The file selector used in below functions. This currently does not check extensions! Picture viewer. Currently it supports only RAW RGB565 bitmaps and it assumes they are 240x320. Support for BMP is coming, and maybe even some JPEG decoding if I finally understand how picoJPEG works. "Slide" is also RAW picture viewer, but it takes longer images(width 240, height longer than 320) and lets user scroll through the image with touch. It uses LCD's ability to do hardware scrolling and this feature looks nice. Code, however is not perfect and there is a bug which I am trying to fix. Minipaint lets user paint on the screen. This is meant for touch panel testing. But if I add saving feature, this may become more useful. Audio player. It plays MP3, WAV and WMA files. If VS1053 was used instead of VS1003b, also FLAC and OGG would be supported. It shows artist and title from ID3 tag, and also bitrate of MP3 and WMA files. Module player. This is ported from PIC32, the same code was used in Stellaris Mod Player presented there some time ago. But I am using the VS1003b for audio output and not PWM. The player needs optimization. It needs a lot of memory for buffers. With current settings I can play some of my mods, but 4 channel mods with large samples don't play properly. With larger buffer and maximum of 4 channels I can play all my 4 channel mods perfectly, but no mods with larger number of channels are supported. I am going to try putting also S3M playback. I think about making the buffers dynamically allocated, so they won't use RAM when MOD player is not in use. Plasma effect. It displays animated plasma, like in old classic intros. I attached some pictures of the thing. I put that piece of plastic on the Launchpad to diffuse LED lights. They are nasty, aren't they? Also, all my code is available if anybody wants to look at all the mess:
https://github.com/szymekrak/mp3thing
I look forward for any opinions and even criticism. I know everything is far from perfection. I would be pleased for any help and advice
I am also sorry if there were any mistakes in my English as this is not my native language.
-
PTB reacted to bluehash in Stellaris Launchpad Deal - $7.99
Buy Link.
Email:
Why pay full price when you can spend 39% less? Right now you can get the ARM-M4 LaunchPad Evaluation Board for $7.99 almost half the original price of $12.99. The LaunchPad highlights TI’s Cortex-M4 microcontroller's USB 2.0 device interface, hibernation module, BoosterPack XL headers, programmable user buttons and an RGB LED for custom applications. The BoosterPack XL headers allow users to add additional functionality to the LaunchPad by using TI and 3rd party BoosterPacks. What will you create?
-
PTB reacted to oPossum in [Aug-2013] TIDeals - EK-LM4F232 Development Board $30 Off
They should bundle it with a heat gun, solder paste, and a Tiva chip.
"Some assembly required"
-
PTB reacted to bluehash in Noritake 800b 128x64 VFD Interface - Stellaris Launchpad
I had a 128x64 Noritake VFD display at work, which is currently not being used. Did an extensive search for a driver until I found one by Henri Skippari. Code was ported from a a PIC16F877. Took a couple of hours for me to port and wire it up.
Below is the code which will need stellarisware.
/* * Noritake VFD 800B 128x64 Parallel Interface * Code courtesy : http://www.sourceboost.com/Products/C2C-plus/ExampleCode/noritake/noritake.c.html * Original author : Henri Skippari * Ported to Stellaris Launchpad : Gerard S, 12th August, 2013 */ #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_gpio.h" #include "driverlib/gpio.h" #include "driverlib/pin_map.h" #include "driverlib/sysctl.h" #include "driverlib/systick.h" #include "driverlib/gpio.h" #include "driverlib/sysctl.h" #include "utils/uartstdio.h" #include "utils/ustdlib.h" #define LAYER0_ON 1 #define LAYER0_OFF 0 #define LAYER1_ON 1 #define LAYER1_OFF 0 #define DISPLAY_ON 1 #define DISPLAY_OFF 0 #define REVERSE_ON 1 #define REVERSE_OFF 0 #define MODE_AND 0 #define MODE_EXOR 1 #define MODE_OR 2 #define VERTICAL_ON 1 #define VERTICAL_OFF 0 #define HORIZONTAL_ON 1 #define HORIZONTAL_OFF 0 #define D7 0x80 #define D6 0x40 #define D5 0x20 #define D4 0x10 #define D3 0x08 #define D2 0x04 #define D1 0x02 #define D0 0x01 #define VFD_CONTROL_PERIPH SYSCTL_PERIPH_GPIOA #define VFD_CONTROL_BASE GPIO_PORTA_BASE #define VFD_WR GPIO_PIN_2 #define VFD_CD GPIO_PIN_3 #define VFD_RD GPIO_PIN_4 #define VFD_CSS GPIO_PIN_5 #define VFD_WR_HI HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_WR << 2)) = VFD_WR #define VFD_WR_LO HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_WR << 2)) = 0 #define VFD_CD_HI HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_CD << 2)) = VFD_CD #define VFD_CD_LO HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_CD << 2)) = 0 #define VFD_RD_HI HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_RD << 2)) = VFD_RD #define VFD_RD_LO HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_RD << 2)) = 0 #define VFD_CSS_HI HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_CSS << 2)) = VFD_CSS #define VFD_CSS_LO HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_CSS << 2)) = 0 #define VFD_DATA_PERIPH SYSCTL_PERIPH_GPIOB #define VFD_DATA_BASE GPIO_PORTB_BASE #define VFD_DATA GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | \ GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | // Fonts, first part const unsigned char font5x7[]={ 0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xF2,0x00,0x00, 0x00,0xC0,0x00,0xC0,0x00, 0x28,0xFE,0x28,0xFE,0x28, 0x24,0x54,0xFE,0x54,0x48, 0xC4,0xC8,0x10,0x26,0x46, 0x6C,0x92,0x9A,0x64,0x0A, 0x00,0xA0,0xC0,0x00,0x00, 0x00,0x38,0x44,0x82,0x00, 0x00,0x82,0x44,0x38,0x00, 0x28,0x10,0x7C,0x10,0x28, 0x10,0x10,0x7C,0x10,0x10, 0x0A,0x0C,0x00,0x00,0x00, 0x10,0x10,0x10,0x10,0x10, 0x06,0x06,0x00,0x00,0x00, 0x04,0x08,0x10,0x20,0x40, 0x7C,0x8A,0x92,0xA2,0x7C, 0x00,0x42,0xFE,0x02,0x00, 0x42,0x86,0x8A,0x92,0x62, 0x84,0x82,0xA2,0xD2,0x8C, 0x18,0x28,0x48,0xFE,0x08, 0xE4,0xA2,0xA2,0xA2,0x9C, 0x3C,0x52,0x92,0x92,0x0C, 0x80,0x8E,0x90,0xA0,0xC0, 0x6C,0x92,0x92,0x92,0x6C, 0x60,0x92,0x92,0x94,0x78, 0x00,0x6C,0x6C,0x00,0x00, 0x00,0x6A,0x6C,0x00,0x00, 0x10,0x28,0x44,0x82,0x00, 0x28,0x28,0x28,0x28,0x28, 0x00,0x82,0x44,0x28,0x10, 0x40,0x80,0x8A,0x90,0x60, 0x4C,0x92,0x9E,0x82,0x7C, 0x3E,0x48,0x88,0x48,0x3E, 0xFE,0x92,0x92,0x92,0x6C, 0x7C,0x82,0x82,0x82,0x44, 0xFE,0x82,0x82,0x44,0x38, 0xFE,0x92,0x92,0x82,0x82, 0xFE,0x90,0x90,0x90,0x80, 0x7C,0x82,0x92,0x92,0x5C, 0xFE,0x10,0x10,0x10,0xFE, 0x00,0x82,0xFE,0x82,0x00, 0x04,0x02,0x82,0xFC,0x80, 0xFE,0x10,0x28,0x44,0x82, 0xFE,0x02,0x02,0x02,0x02, 0xFE,0x40,0x20,0x40,0xFE, 0xFE,0x20,0x10,0x08,0xFE, 0x7C,0x82,0x82,0x82,0x7C, 0xFE,0x90,0x90,0x90,0x60, 0x7C,0x82,0x8A,0x84,0x7A, 0xFE,0x90,0x98,0x94,0x62 // 50 }; // Fonts, second part const unsigned char font5x7_2[]={ 0x64,0x92,0x92,0x92,0x4C, 0x80,0x80,0xFE,0x80,0x80, 0xFC,0x02,0x02,0x02,0xFC, 0xF8,0x04,0x02,0x04,0xF8, 0xFC,0x02,0x0C,0x02,0xFC, 0xC6,0x28,0x10,0x28,0xC6, 0xE0,0x10,0x0E,0x10,0xE0, 0x86,0x8A,0x92,0xA2,0xC2, 0x00,0xFE,0x82,0x82,0x00, 0x40,0x20,0x10,0x08,0x04, 0x00,0x82,0x82,0xFE,0x00, 0x20,0x40,0x80,0x40,0x20, 0x02,0x02,0x02,0x02,0x02, 0x00,0x80,0x40,0x20,0x00, 0x04,0x2A,0x2A,0x2A,0x1E, 0xFE,0x12,0x12,0x12,0x0C, 0x1C,0x22,0x22,0x22,0x22, 0x0C,0x12,0x12,0x12,0xFE, 0x1C,0x2A,0x2A,0x2A,0x1A, 0x10,0x7E,0x90,0x40,0x00, 0x12,0x2A,0x2A,0x2A,0x3C, 0xFE,0x10,0x10,0x10,0x0E, 0x00,0x00,0x5E,0x00,0x00, 0x04,0x02,0x02,0xBC,0x00, 0xFE,0x08,0x14,0x22,0x00, 0x00,0x82,0xFE,0x02,0x00, 0x3E,0x20,0x18,0x20,0x3E, 0x3E,0x10,0x20,0x20,0x1E, 0x1C,0x22,0x22,0x22,0x1C, 0x3E,0x28,0x28,0x28,0x10, 0x10,0x28,0x28,0x28,0x3E, 0x3E,0x10,0x20,0x20,0x10, 0x12,0x2A,0x2A,0x2A,0x24, 0x20,0xFC,0x22,0x04,0x00, 0x3C,0x02,0x02,0x02,0x3C, 0x38,0x04,0x02,0x04,0x38, 0x3C,0x02,0x0C,0x02,0x3C, 0x22,0x14,0x08,0x14,0x22, 0x20,0x12,0x0C,0x10,0x20, 0x22,0x26,0x2A,0x32,0x22, 0x10,0x6C,0x82,0x82,0x00, 0x12,0x7E,0x92,0x82,0x42, 0x00,0x82,0x82,0x6C,0x10, 0x80,0x80,0x80,0x80,0x80, 0xFE,0xFE,0xFE,0xFE,0xFE}; // 44 /* Write data byte */ void VFD_WriteData(unsigned char data) { VFD_CD_LO; VFD_WR_LO; VFD_RD_HI; VFD_CSS_LO; GPIOPinWrite( VFD_DATA_BASE, 0xFF, data); VFD_CD_LO; VFD_WR_HI; VFD_RD_HI; VFD_CSS_LO; } /* Write command byte */ void VFD_WriteCtrl(unsigned char command) { VFD_CD_HI; VFD_WR_LO; VFD_RD_HI; VFD_CSS_LO; GPIOPinWrite( VFD_DATA_BASE, 0xFF, command); VFD_CD_HI; VFD_WR_HI; VFD_RD_HI; VFD_CSS_LO; } /* Horizontal and vertical address auto increment on/off */ void VFD_AddressIncrementMode(unsigned char h, unsigned char v) { unsigned char bit2=0, bit1=0; if(h==HORIZONTAL_ON) bit2 = 0x04; if(v==VERTICAL_ON) bit1 = 0x02; VFD_WriteCtrl(0x80+bit2+bit1); } void VFD_SetColumn(unsigned char column) { VFD_WriteCtrl(0x64); VFD_WriteCtrl(column); } void VFD_SetRow(unsigned char row) { VFD_WriteCtrl(0x60); VFD_WriteCtrl(row); } /* Display brightness 0-15 */ void VFD_SetBrightness(unsigned char brightness) { if(brightness>15) brightness=15; // Check for too big values if(brightness<0) brightness=0; // Check for too small values VFD_WriteCtrl(0x40+(0x0F-brightness)); // Delay for 100ms SysCtlDelay( (SysCtlClockGet()/(3*1000))*1 ); } void VFD_ClearDisplay(void) { VFD_WriteCtrl(0x5f); SysCtlDelay( (SysCtlClockGet()/(3*1000))*1 ); } /* Set layers on/off + other display attributes */ void VFD_DisplaySetup(char layer0, char layer1, char gfx_on_off, char reverse, char mode) { unsigned char l0=0, l1=0, gs=0, grv=0, and=0, exor=0; if(layer0==LAYER0_ON) l0 = D2; if(layer1==LAYER1_ON) l1 = D3; VFD_WriteCtrl(0x20+l0+l1); if(gfx_on_off==DISPLAY_ON) gs = D6; if(reverse==REVERSE_ON) grv = D4; if(mode==MODE_AND) and = D3; if(mode==MODE_EXOR) exor = D2; if(mode==MODE_OR) { } VFD_WriteCtrl(gs+grv+and+exor); } unsigned char swap(unsigned char x) { unsigned char result=0,mask1=1,mask2=128; int b; for(b=0;b<8;b++) { if ((x&mask1)==mask1) result=result+mask2; mask1=mask1<<1; mask2=mask2>>1; } return(result); } void VFD_PrintChar(unsigned char chr) { unsigned char data, i; VFD_AddressIncrementMode(HORIZONTAL_ON, VERTICAL_OFF); // Horizontal auto increment ON for font writing chr=chr-0x20; // Convert ascii code to Noritake code if(chr<51) // First font array { for(i=0;i<5;i++) { data = font5x7[chr*5+i]; data = swap(data); VFD_WriteData(data); } VFD_WriteData(0); } else if(chr<96) // Second font array { chr = chr-51; for(i=0;i<5;i++) { data = font5x7_2[chr*5+i]; data = swap(data); VFD_WriteData(data); } VFD_WriteData(0); } } void VFD_Init( void ) { unsigned char i; SysCtlPeripheralEnable(VFD_CONTROL_PERIPH); GPIOPinTypeGPIOOutput(VFD_CONTROL_BASE, VFD_WR | \ VFD_CD | \ VFD_RD | \ VFD_CSS); SysCtlPeripheralEnable(VFD_DATA_PERIPH); GPIOPinTypeGPIOOutput(VFD_DATA_BASE, 0xFF); for(i=0;i<8;i++) { // address area set VFD_WriteCtrl(0x62); VFD_WriteCtrl(i); VFD_WriteData(0xff); } VFD_AddressIncrementMode(HORIZONTAL_ON, VERTICAL_OFF); // Default to horizontal address increment ON VFD_SetColumn(0); // Set address pointer to (0,0) VFD_SetRow(0); // Set address pointer to (0,0) VFD_SetBrightness(0); // Set brightness to lowest possible VFD_DisplaySetup(LAYER0_OFF, LAYER1_OFF, DISPLAY_OFF, REVERSE_OFF, MODE_AND); // Set everything OFF VFD_ClearDisplay(); } /* Draw vertical bar. Used in the sample.*/ void DrawVertBar(unsigned char height, unsigned char pos) { unsigned char i; VFD_AddressIncrementMode(HORIZONTAL_OFF, VERTICAL_ON); // Vertical bars are drawn so vertical auto increment is enabled VFD_SetColumn(pos); VFD_SetRow(7-height); for(i=7-height;i<8;i++) { VFD_WriteData(254); // Draw vertical byte with one bit off: oxxxxxxx // Address pointer is incremented vertically after every byte written } } int main(void) { int i, j, c; // Setup the processor clock at 80Mhz. SysCtlClockSet( SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | \ SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); // Enable UART0 @115200bps N81. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTStdioInit(0); //Clear the terminal UARTprintf("\033[2J"); UARTprintf("\n\nNoritake VFD 800b test\n"); UARTprintf("-----------------------------------\n"); // Arrays to store height and current direction for moving bars unsigned char value[16]; // Height of bar, 0 to 8 unsigned char dir[16]; // 1=up, 0=down // Initialize values for bars for(i=0;i<8;i++) { value[i]=i; // 8 bars with values from 0 to 7 dir[i]=1; // Going up value[8+i]=(8-i); // 8 bars with values from 8 to 1 dir[8+i]=0; // Going down } VFD_Init(); VFD_DisplaySetup(LAYER0_ON, LAYER1_ON, DISPLAY_ON, REVERSE_OFF, MODE_OR); VFD_SetBrightness(15); // Set brightness to maximum // Write all available fonts to display // Change row after 20 characters c=32; for(i=0;i<5;i++) { VFD_SetColumn(0); VFD_SetRow(8+i); // Start from the beginning of second layer for(j=0;j<20;j++) { VFD_PrintChar(c++); } } SysCtlDelay( (SysCtlClockGet()/(3*1000))*1000 ); while( 1 ) { // Draw some moving bars on the display for(i=0;i<16;i++) { for(j=0;j<8;j++) { DrawVertBar(value[i], i*8); } if(value[i]>=8) dir[i]=0; else if(value[i]<=0) dir[i]=1; if(dir[i]==0) value[i]=value[i]-1; else if(dir[i]==1) value[i]=value[i]+1; } SysCtlDelay( (SysCtlClockGet()/(3*1000))*50 ); VFD_ClearDisplay(); } return 0; } -
PTB reacted to hvontres in Spreadsheet for planning pin usage
I have attached a simple spreadsheet I am using to plan out how to use the resources on a 430g2553 for a project. It is simply all of the functions for each pin in a seprate cell with a symbolic representation of the chip in the center. The color coding is completely up the the user. This way one can try to make decisions on which peripheral can be used and how it might need to be shared by other functions. I hope this helps
The .zip file has both a OpenOffice and an excel version, since I couldn't attache the sheets directly
430G2553_pin_plan.zip
-
PTB reacted to RobG in 2.2" Color LCD Booster Pack with Touch
Quick update, new version of this board coming in about 3 weeks.
-
PTB got a reaction from reaper7 in Spreadsheet for planning pin usage
hvontres's original post :thumbup: inspired me to finish(?) this thing off.
I haven't fully checked it for typos and mistakes but it should be pretty close.
If additional mcu's or booster packs are required just copy one of the existing tabs and edit.
You fill in the mcu and booster pack names along the top for your project and it will quickly show what pins are available or are clashing.
Cheers
PTB
Launchpad_Pinout_Planner.zip
-
PTB reacted to szymekrak1426459900 in Does progmem work with Stellaris ?
I think that static const should work. I have put 153600 bytes image inside the flash with this method. It worked just fine.
-
PTB reacted to jkabat in Stellaris fast analog reads
@@PTB,
in fast digital read:
Move GPIODirModeSet(ulPort, ucPins, GPIO_DIR_MODE_IN); to ant init routine. Ony dnnest to be done before the read.
use constants if possble in fast digial read:
For port a pin 2 PA2
#define PORT_A GPIOA_BASE
#define PIN2 ( (1<<2)<<2)
value = (HWREG( PORT_A + (GPIO_O_DATA +PIN2));
The you can build somthing like the following:
#define PORT_A GPIOA_BASE
#define PIN2 ((1<<2)
#define NUMBER_VALUES 4096
uint32_t pa2 _values[NUMBER_VALUES+1];
void fast_read_PA2(void)
{
int i;
uint32_t *pValues=&VALUES[0]
GPIODirModeSet(PORT_A,,PIN2, GPIO_DIR_MODE_OUT);
FOR =0;I<number_values;i++,pValues++)
{
*Pvalues = HWREG( PORT_A + (GPIO_O_DATA +PIN2));
}
Untested. Use at your ownrisk.
I am still traveling.
Johnk
-
PTB reacted to patolin_01 in Stellaris fast analog reads
Well, here is my 2 cents.
Im working on a kind of DSO using the stellaris launchpad, and visual basic 2010.
Right now, the stellaris can sample in 1 channel (pin PA7) at different speeds, selectable via serial port commands. Right now, it can sample at 1Msps (890Ksps real), 500Ksps, 250Ksps, 125Ksps using ADC interrupt, and 64ksps, 32ksps, 16ksps, 8ksps, and 2 ksps using timer interrupt.
My code samples a 4096 samples buffer, and when receives the "c" command, it sends the values stored in the buffer in ASCII over the serial port, and the its plotted on the VB app. pretty simple, but for me resulted very useful.
Here is my code
// stelarisDSO v1.0 // 2013-07-20 // buffer de 4096 muestras // #include "Energia.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_ints.h" #include "driverlib/debug.h" #include "driverlib/interrupt.h" #include "driverlib/sysctl.h" #include "driverlib/adc.h" #include "driverlib/timer.h" #define numDatos 4095 int i=0; int j=1; int adc[numDatos]; unsigned char dataReady=0; unsigned long ulADC0Value[1]; int datosListos=0; int datoActual=0; void setup() { int i; Serial.begin(115200); pinMode(RED_LED, OUTPUT); pinMode(BLUE_LED, OUTPUT); pinMode(GREEN_LED, OUTPUT); for (i=0;i<=4;i++) { digitalWrite(GREEN_LED,1); digitalWrite(RED_LED,1); digitalWrite(BLUE_LED,1); delay(100); digitalWrite(GREEN_LED,0); digitalWrite(RED_LED,0); digitalWrite(BLUE_LED,0); delay(100); } Serial.println("Stellaris DSO"); Serial.println("(c) 2013 www.patolin.com"); Serial.println("Inicio OK. "); Serial.print(SysCtlClockGet()); Serial.println(" hz"); initADC(0,0); ADCIntDisable(ADC0_BASE, 3); initTimer(500); } void loop() { int valor; unsigned timerADC=500; unsigned velADC=0; unsigned char serialIn; char tipoSampling=1; // 0=ADC int, 1=TIMER int // esperamos comando para la velocidad de muestreo while (1) { if (Serial.available()==1) { serialIn=Serial.read(); switch (serialIn) { case 's': // status Serial.println("Ok."); break; case 'c': // devuelve los datos del buffer // esperamos a los datos while (!datosListos) {} // paramos las interrupciones TimerIntDisable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); ADCIntDisable(ADC0_BASE, 3); datosListos=0; datoActual=0; //enviamos los datos por el puerto serie Serial.println(numDatos); for (i=0;i<=(numDatos-1);i++) { Serial.println(adc[i]); } // reiniciamos las interrupciones if (tipoSampling==1) { TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); } else { ADCIntEnable(ADC0_BASE, 3); } break; case '1': // 1ksps timerADC=500; tipoSampling=1; break; case '2': // 2ksps timerADC=1000; tipoSampling=1; break; case '3': // 4ksps timerADC=2000; tipoSampling=1; break; case '4': // 8ksps timerADC=4000; tipoSampling=1; break; case '5': // 16ksps timerADC=8000; tipoSampling=1; break; case '6': // 32ksps timerADC=16000; tipoSampling=1; break; case '7': // 64ksps timerADC=32000; tipoSampling=1; break; case '8': // 125ksps timerADC=0000; velADC=0; tipoSampling=0; break; case '9': // 250ksps timerADC=0000; velADC=1; tipoSampling=0; break; case 'A': // 500ksps timerADC=0000; velADC=2; tipoSampling=0; break; case 'B': // 1Msps timerADC=0000; velADC=3; tipoSampling=0; break; } // inicializamos el timer o el ADC segun el caso datosListos=0; datoActual=0; if (tipoSampling==0) { // ADC por interrupcion TimerIntDisable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); initADC(velADC,1); digitalWrite(RED_LED, 0x00); digitalWrite(BLUE_LED, 0x01); } else { ADCIntDisable(ADC0_BASE, 3); initTimer(timerADC); digitalWrite(RED_LED, 0x00); digitalWrite(BLUE_LED, 0x00); } } } } int capturaADC() { ADCIntClear(ADC0_BASE, 3); ADCProcessorTrigger(ADC0_BASE, 3); while(!ADCIntStatus(ADC0_BASE, 3, false)) { } ADCSequenceDataGet(ADC0_BASE, 3, ulADC0Value); return (int)ulADC0Value[0]; } void Timer0IntHandler() { TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT); digitalWrite(RED_LED, j&0x01); j++; adc[datoActual]=capturaADC(); datoActual++; if (datoActual>numDatos) { datosListos=1; datoActual=0; } } void ADC0IntHandler() { ADCIntClear(ADC0_BASE,3); ADCSequenceDataGet(ADC0_BASE, 3, ulADC0Value); adc[datoActual]=(int)ulADC0Value[0]; datoActual++; if (datoActual>numDatos) { datoActual=0; datosListos=1; ADCIntDisable(ADC0_BASE, 3);} } void initTimer(unsigned Hz) { SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); unsigned long ulPeriod = (SysCtlClockGet() / Hz) / 2; TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod -1); IntEnable(INT_TIMER0A); TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); TimerIntRegister(TIMER0_BASE, TIMER_A, Timer0IntHandler); TimerEnable(TIMER0_BASE, TIMER_A); } void initADC(int velocidad, int trigger) { /* Velocidad: 0=1msps,1=500ksps,2=250ksps,3=125ksps trigger: 0=processor, 1=always */ SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); switch(velocidad) { case 3: SysCtlADCSpeedSet(SYSCTL_ADCSPEED_1MSPS); break; case 2: SysCtlADCSpeedSet(SYSCTL_ADCSPEED_500KSPS); break; case 1: SysCtlADCSpeedSet(SYSCTL_ADCSPEED_250KSPS); break; case 0: SysCtlADCSpeedSet(SYSCTL_ADCSPEED_125KSPS); break; default: SysCtlADCSpeedSet(SYSCTL_ADCSPEED_1MSPS); break; } ADCSequenceDisable(ADC0_BASE, 3); if (trigger==0) { ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0); } else { ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_ALWAYS, 0); } ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END); //ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END); //Secuencia de ejemplo para el medidor de temperatura interno ADCIntRegister(ADC0_BASE, 3, ADC0IntHandler); ADCIntEnable(ADC0_BASE, 3); ADCSequenceEnable(ADC0_BASE, 3); ADCProcessorTrigger(ADC0_BASE, 3); } Im writing a detailed post for my blog, so I hope it can be useful for you guys. You can check a preview (in spanish) in http://patolin.com/blog/2013/07/07/osciloscopio-con-stellaris-launchpad-actualizacion/
Here is a capture image, of a RC transmitter PPM frame, at 125Ksps, 10 bits, using a 4096 sample buffer
-
PTB reacted to jkabat in Stellaris fast analog reads
@@PTB
Almost one microsecond per read is really gootd. Consider that 1usec is the limit of the hardware! The 3usec may be do to the overhead of the call to micros! Energia has a bain-damaged micros/and millis method anyhow.
Try sample1=micros(); sampe2=micros(); Serail.prntln(sample2-sample1;
This will give you an idea of the overhead.
I am sorry I will not be able to help as I am leaving on a business trip tomorrow morning. I will be back thursday.
If anyone is inerested here is my replacement for wiring.c to make timing more accurate. The old version had warp problems that limit the max value of millis to 65000 or so. I also only used 80mhz for the colck. I have enhanced it to used whatever frequency is defined by F_CPU.
changes are also needed to main and lm4fcpp.ld.
in main.c: Chare to call to timer_init:
int main(void){ // change timer_init to use requested clock frequency // this means we may be able to change it on the fly if needed timerInit(F_CPU); Lm4fcpp.ld needs to be changed so the long long functions don't produce an error!
/** * * lm4fcpp.ld - Linker configuration file for Energia c++ programs. * */ MEMORY { flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 }REGION_ALIAS("REGION_TEXT", flash);REGION_ALIAS("REGION_RAM", ram);SECTIONS { .text : { _text = .; KEEP(*(.isr_vector)) *(.text .text* .gnu.linkonce.t.*) } > REGION_TEXT .preinit_array : { . = ALIGN(4); __preinit_array_start = .; KEEP (*(SORT(.preinit_array*))) KEEP (*(.preinit_array)) __preinit_array_end = .; } > REGION_TEXT .init_array : { . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; } > REGION_TEXT .rodata : { . = ALIGN(4); *(.rodata .rodata* .gnu.linkonce.r.*) . = ALIGN(4); } > REGION_TEXT .ARM.exidx : { __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = .; } >REGION_TEXT _etext = .; .data : { . = ALIGN(4); _data = .; *(vtable) *(.data .data* .gnu.linkonce.d.*) _edata = .; } > REGION_RAM AT > REGION_TEXT .bss : { . = ALIGN(4); _bss = .; *(.bss .bss*) *(COMMON) . = ALIGN(4); _ebss = .; . = ALIGN(8); _end = .; } > REGION_RAM _jkend = .;}/* end of allocated ram is start of heap, heap grows up towards stack*/PROVIDE(end = _end);/* top of stack starts at end of ram, stack grows down towards heap */PROVIDE (_estack = ORIGIN(ram) + LENGTH(ram));
Wiring.c
/* ************************************************************************ * wiring.c * * Arduino core files for MSP430 * Copyright (c) 2012 Robert Wessels. All right reserved. * * *********************************************************************** Derived from: wiring.c - Partial implementation of the Wiring API for the ATmega8. Part of Arduino - http://www.arduino.cc/ Copyright (c) 2005-2006 David A. Mellis This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "Energia.h"#include <limits.h>#include "driverlib/rom_map.h"#include "driverlib/sysctl.h"#include "driverlib/timer.h"//// I have removed any frequency that is not an even number of MHZ// as this makes micros inaccurate//uint32_t freq_table[][2] ={ 80000000, SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ, // 80,000,000 80 50000000, SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ, // 50,000,000 50 40000000, SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ, // 40,000,000 40 25000000, SYSCTL_SYSDIV_8 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ, // 25,000,000 25 20000000, SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ, // 20,000,000 20 16000000, SYSCTL_SYSDIV_1 | SYSCTL_RCC_BYPASS | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ, // 16,000,000 16 raw osc 10000000, SYSCTL_SYSDIV_20 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ, // 10,000,000 10 8000000, SYSCTL_SYSDIV_2 | SYSCTL_RCC_BYPASS | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ, // 8,000,000 8 5000000, SYSCTL_SYSDIV_40 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ, // 5,000,000 5 4000000, SYSCTL_SYSDIV_4 | SYSCTL_RCC_BYPASS | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ, // 4,000,000 4 0, SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ // if not in table default to 80mhz};// these// no need to call SysCtlClockGetuint32_t System_Frequency;uint32_t System_Frequency_Mhz; // in Mhzvoid timerInit(uint32_t desiredFrequency){ uint16_t i; // search for the frequency wanted for (i=0;freq_table[i][0]!=0;i++) { if (desiredFrequency == freq_table[i][0] ) { break; } } // ok - got it (or the default) // set it SysCtlClockSet(freq_table[i][1]); System_Frequency = SysCtlClockGet(); System_Frequency_Mhz = System_Frequency / 1000000; // clocks per 1 us // we are not using this anymore but keep it around. // I may us it to give a time interrupt in my private OS/Supervisor if I need it // set periodic to 1 ms SysTickPeriodSet(System_Frequency / 10); //100ms 1/10 second SysTickEnable(); // //Initialize WTimer4 to be used as time-tracker since beginning of time // SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER4); //not tied to launchpad pin TimerConfigure(WTIMER4_BASE, TIMER_CFG_PERIODIC); TimerLoadSet64(WTIMER4_BASE, 0xFFFFFFFFFFFFFFFFl); //start at -1 and count down TimerEnable(WTIMER4_BASE, TIMER_A);}inline unsigned long micros(void){ // get the time value ond convert to positive unsigned long long cycles = ~ROM_TimerValueGet64(WTIMER4_BASE); // divide by clock in mhz - give micro seconds cycles /= System_Frequency_Mhz; return (cycles);}unsigned long millis(void){ unsigned long long cycles = ~ROM_TimerValueGet64(WTIMER4_BASE); cycles /= (System_Frequency / 1000ll); // note: that is LL at the end not 11! return (cycles);}/* Delay for the given number of microseconds. */void delayMicroseconds(unsigned int us){ unsigned long currTime; unsigned long endTime; endTime = micros() + us; do { currTime = micros(); } while (currTime <= endTime);}void delay(uint32_t milliseconds){ unsigned long i; for (i = 0; i < milliseconds; i++) { delayMicroseconds(1000); }} -
PTB got a reaction from jkabat in Stellaris fast analog reads
@JKabat @Rei Vilo @reaper7
I dunno John... Its still 3 microseconds too slow.
Sensational ! You definitely appear to know your stuff.
Number of Samples : 255 Sample Starttime : 11000011 Sample Endtime : 11000269 Sample Array Set Duration time in microseconds : 258 I also tried your "Late Edit" (Complete with disclaimer) but that slowed it down so I took it back out.
Number of Samples : 255 Sample Starttime : 27725011 Sample Endtime : 27727786 Sample Array Set Duration time in microseconds : 2775 I did a little more housekeeping taking out some comments and unused defines and faMask as it appears to not be used.
Latest Code Here.....
// // LM4F_ADC // A Stellarisiti Collaborative effort // JKabat, Rei Vilo, reaper7, PTB. // // Include application, user and local libraries // Define variables and constants /// /// @file Fast_Analog_Read.ino /// @brief Main sketch /// /// @details Fast Analog Read Investigations for Stellaris LM4F /// // // Stellaris Pin Assignments // ========================= //PE_3 //Sensor Analog Read //PA_5 //Trigger Analog Signal Pulse //PF_4 //Push Button to Start // // Libraries // ========= #include "Energia.h" #include "SPI.h" #include "inc/lm4f120h5qr.h" #include "inc/hw_adc.h" #include "inc/hw_gpio.h" #include "inc/hw_memmap.h" #include "inc/hw_sysctl.h" #include "driverlib/adc.h" #include "driverlib/gpio.h" #include "driverlib/sysctl.h" #include "driverlib/rom.h" // // Constants from adc.c // ==================== #define ADC_SEQ (ADC_O_SSMUX0) #define ADC_SEQ_STEP (ADC_O_SSMUX1 - ADC_O_SSMUX0) #define ADC_SSFIFO (ADC_O_SSFIFO0 - ADC_O_SSMUX0) #define ADC_SSFSTAT (ADC_O_SSFSTAT0 - ADC_O_SSMUX0) #define SEQUENCER 0 // // Global Constants // ================ const byte SampleQty = 255; // number of samples const uint16_t buttonPin = PUSH1; // the number of the pushbutton pin const uint16_t ledPin = GREEN_LED; // the number of the LED pin const uint16_t TriggerPin = PA_5; // Analog Signal Trigger connected to digital pin PA_5 // // Global Variables // ================ uint16_t SampleTest; uint16_t buttonState = 0; // variable for reading the pushbutton status uint16_t Sample[SampleQty]; // Array variable to store the value coming from the sensor unsigned long SampleStartTime; unsigned long SampleEndTime; unsigned long SampleDuration; unsigned long faBase; // // Prototypes // ========== uint16_t fast_analogInit(uint8_t pin); uint16_t fast_analogRead(void); ///************************************************************************** /// /// Setup code /// ///************************************************************************** void setup() { Serial.begin(9600) ; //Debugging initialize the serial communication: pinMode(ledPin, OUTPUT); // initialize the LED pin as an output: pinMode(buttonPin, INPUT_PULLUP); // initialize the pushbutton pin as an input: pinMode(TriggerPin, OUTPUT); // initialize the Trigger pin as an output: }//end setup ///************************************************************************** /// /// Loop code /// ///************************************************************************** void loop() { buttonState = digitalRead(buttonPin); // read the state of the pushbutton value: if (buttonState == LOW) { digitalWrite(ledPin, HIGH); // turn LED on: fast_analogInit(PE_3); SampleStartTime = micros(); digitalWrite(TriggerPin, HIGH); // Start the Analog Signal for (uint16_t i=0;i<SampleQty;i++) { Sample[i] = fast_analogRead(); } SampleEndTime = micros(); //Dump results to serial monitor for (uint16_t i=0;i<SampleQty;i++) { Serial.println(Sample[i]); } Serial.print("Number of Samples : "); Serial.println(SampleQty); Serial.print("Sample Starttime : "); Serial.println(SampleStartTime); Serial.print("Sample Endtime : "); Serial.println(SampleEndTime); SampleDuration = SampleEndTime - SampleStartTime; Serial.print("Sample Array Set Duration time in microseconds : "); Serial.println(SampleDuration); }// end if delay(1000); digitalWrite(ledPin, LOW); // turn LED off: }//end loop ///************************************************************************** /// /// Fast Analog Read Routine /// ///************************************************************************** uint16_t fast_analogRead(void) { uint32_t value[8]; unsigned long *pulBuffer = &value[0]; unsigned long ulCount; unsigned long ulBase = faBase; HWREG(ADC0_BASE + ADC_O_ISC) = 1 << SEQUENCER; HWREG(ADC0_BASE + ADC_O_PSSI) |= ((SEQUENCER & 0xffff0000) | (1 << (SEQUENCER & 0xf))); while (!(HWREG(ADC0_BASE + ADC_O_RIS) & (0x10000 | (1 << SEQUENCER)))) {} HWREG(ADC0_BASE + ADC_O_ISC) = 1 << SEQUENCER; ulBase = ADC0_BASE + (ADC_SEQ + (ADC_SEQ_STEP * SEQUENCER)); ulCount = 0; while(!(HWREG(ulBase + ADC_SSFSTAT) & ADC_SSFSTAT0_EMPTY) && (ulCount < 8)) { value[ulCount] = HWREG(ulBase + ADC_SSFIFO); ulCount++; } return value[0]; } ///************************************************************************** /// /// Fast Analog Init Routine /// ///************************************************************************** uint16_t fast_analogInit(uint8_t pin) { uint8_t port = digitalPinToPort(pin); uint16_t value[1]; uint32_t channel = digitalPinToADCIn(pin); if (pin == NOT_ON_ADC) { //invalid ADC pin return(0); } faBase = (uint32_t)portBASERegister(port); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); ROM_GPIOPinTypeADC((uint32_t)portBASERegister(port), digitalPinToBitMask(pin)); ROM_ADCSequenceConfigure(ADC0_BASE, SEQUENCER, ADC_TRIGGER_PROCESSOR, 0); ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 0, channel | ADC_CTL_IE); ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 1, channel | ADC_CTL_IE); ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 2, channel | ADC_CTL_IE); ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 3, channel | ADC_CTL_IE); ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 4, channel | ADC_CTL_IE); ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 5, channel | ADC_CTL_IE); ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 6, channel | ADC_CTL_IE); ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 7, channel | ADC_CTL_IE | ADC_CTL_END); ROM_ADCSequenceEnable(ADC0_BASE, SEQUENCER); ROM_SysCtlADCSpeedSet(SYSCTL_ADCSPEED_1MSPS); return(1); } I was hoping for one sample per microsecond.... I don't think you could get much closer than this.
Cheers
PTB
-
PTB reacted to jkabat in Stellaris fast analog reads
@@reaper7,
That is what I was going to suggest. Just overloaded here a work today.
@@PTB
one thing you may want to do after applying @@reaper7s fix is to place the code for fastAnalogRead in place of the call. Anlternativly you should move the read and init routines up befor loop and place the __inline__ attribute on them. Sorry I am at work preparing for a trip and am not sure of the exact format. If you copy the code in place of fast... assign the result to sample[i++]= HWREG(ulBase + ADC_SSFIFO); in place of value[ulcount].
If you switch to another sequencer (o has an 8 deep fifo) this will handle the results automatically. You may have to modify some setting in fastAdcInit(pin) to get multiple reads.
update:
Use sequencer 0.
I am not sure if all 8 steps need to be configured but you may need to add the following to init:
ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 0, channel | ADC_CTL_IE );
ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 1, channel | ADC_CTL_IE );
ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 2, channel | ADC_CTL_IE );
ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 3, channel | ADC_CTL_IE);
ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 4, channel | ADC_CTL_IE);
ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 5, channel | ADC_CTL_IE);
ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 6, channel | ADC_CTL_IE);
ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 7, channel | ADC_CTL_IE | ADC_CTL_END);
(late edit: You may (or may not) neet to remove the" | ACD_CTL_IE" from all but the last entry. Only use this for SEQUENCER 0)
Use at your own risk as I am unable to test this.
-
PTB reacted to Rei Vilo in Stellaris fast analog reads
Let's do a library and request a pull at Energia GitHub repository!
-
PTB reacted to reaper7 in Stellaris fast analog reads
This is my results:
Number of Samples : 255 Sample Starttime : 378625230 Sample Endtime : 378625913 Sample Array Set Duration time in microseconds : 683 1 Sample every ~2.68 microseconds
driverlib/sysctl.h - have function for ADC SPEED:
SysCtlADCSpeedSet(unsigned long ulSpeed)
available value:
#define SYSCTL_ADCSPEED_1MSPS 0x00000F00 // 1,000,000 samples per second #define SYSCTL_ADCSPEED_500KSPS 0x00000A00 // 500,000 samples per second #define SYSCTL_ADCSPEED_250KSPS 0x00000500 // 250,000 samples per second #define SYSCTL_ADCSPEED_125KSPS 0x00000000 // 125,000 samples per second Default is: SYSCTL_ADCSPEED_125KSPS 0x00000000 // 125,000 samples per second
so...You must add a one line:
ROM_SysCtlADCSpeedSet(SYSCTL_ADCSPEED_1MSPS);
before return(1);
in fast_analogInit(uint8_t pin):
... ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 0, channel | ADC_CTL_IE | ADC_CTL_END); ROM_ADCSequenceEnable(ADC0_BASE, SEQUENCER); ROM_SysCtlADCSpeedSet(SYSCTL_ADCSPEED_1MSPS); return(1); } -
PTB got a reaction from jkabat in Stellaris fast analog reads
And Here's the Code
// // LM4F_ADC // // Description of the project // Developed with [embedXcode](http://embedXcode.weebly.com) // // Author Rei VILO // Rei Vilo // // Date 21/07/13 09:42 // Version <#version#> // // Copyright (c) Rei VILO, 2013 // Licence CC = BY NC SA // // See ReadMe.txt for references // // Core library for code-sense #if defined(WIRING) // Wiring specific #include "Wiring.h" #elif defined(MAPLE_IDE) // Maple specific #include "WProgram.h" #elif defined(MPIDE) // chipKIT specific #include "WProgram.h" #elif defined(DIGISPARK) // Digispark specific #include "Arduino.h" #elif defined(ENERGIA) // LaunchPad, FraunchPad and StellarPad specific #include "Energia.h" #elif defined(CORE_TEENSY) // Teensy specific #include "WProgram.h" #elif defined(ARDUINO) && (ARDUINO >= 100) // Arduino 1.0 and 1.5 specific #include "Arduino.h" #elif defined(ARDUINO) && (ARDUINO < 100) // Arduino 23 specific #include "WProgram.h" #else // error #error Platform not defined #endif // Include application, user and local libraries // Define variables and constants /// /// @file Fast_Analog_Read.ino /// @brief Main sketch /// /// @details Fast Analog Read Investigations for Stellaris LM4F /// // // Stellaris Pin Assignments // ========================= //PE_3 //Sensor Analog Read //PA_5 //Trigger Analog Signal Pulse //PF_4 //Push Button to Start // // Libraries // ========= #include "Energia.h" #include "SPI.h" #include "inc/lm4f120h5qr.h" #include "inc/hw_adc.h" #include "inc/hw_gpio.h" #include "inc/hw_memmap.h" #include "inc/hw_sysctl.h" #include "driverlib/adc.h" #include "driverlib/gpio.h" #include "driverlib/sysctl.h" #include "driverlib/rom.h" // Constants from adc.c #define ADC_SEQ (ADC_O_SSMUX0) #define ADC_SEQ_STEP (ADC_O_SSMUX1 - ADC_O_SSMUX0) #define ADC_SSMUX (ADC_O_SSMUX0 - ADC_O_SSMUX0) #define ADC_SSEMUX (ADC_O_SSEMUX0 - ADC_O_SSMUX0) #define ADC_SSCTL (ADC_O_SSCTL0 - ADC_O_SSMUX0) #define ADC_SSFIFO (ADC_O_SSFIFO0 - ADC_O_SSMUX0) #define ADC_SSFSTAT (ADC_O_SSFSTAT0 - ADC_O_SSMUX0) #define ADC_SSOP (ADC_O_SSOP0 - ADC_O_SSMUX0) #define ADC_SSDC (ADC_O_SSDC0 - ADC_O_SSMUX0) #define SEQUENCER 3 // // Global Constants // ================ const byte SampleQty = 255; // number of samples const uint16_t buttonPin = PUSH1; // the number of the pushbutton pin const uint16_t ledPin = GREEN_LED; // the number of the LED pin const uint16_t TriggerPin = PA_5; // Analog Signal Trigger connected to digital pin PA_5 // // Global Variables // ================ uint16_t SampleTest; uint16_t buttonState = 0; // variable for reading the pushbutton status uint16_t Sample[SampleQty]; // Array variable to store the value coming from the sensor unsigned long SampleStartTime; unsigned long SampleEndTime; unsigned long SampleDuration; unsigned long faBase; uint16_t faMask; // // Prototypes // ========== uint16_t fast_analogInit(uint8_t pin); uint16_t fast_analogRead(void); ///************************************************************************** /// /// Setup code /// ///************************************************************************** void setup() { Serial.begin(9600) ; //Debugging initialize the serial communication: pinMode(ledPin, OUTPUT); // initialize the LED pin as an output: pinMode(buttonPin, INPUT_PULLUP); // initialize the pushbutton pin as an input: pinMode(TriggerPin, OUTPUT); // initialize the Trigger pin as an output: }//end setup ///************************************************************************** /// /// Loop code /// ///************************************************************************** void loop() { buttonState = digitalRead(buttonPin); // read the state of the pushbutton value: if (buttonState == LOW) { digitalWrite(ledPin, HIGH); // turn LED on: fast_analogInit(PE_3); // JKabat SampleStartTime = micros(); digitalWrite(TriggerPin, HIGH); // Start the Analog Signal for (uint16_t i=0;i<SampleQty;i++) { // Sample[i]=analogRead(PE_3); // Original Analog Read Sample[i] = fast_analogRead(); // JKabat } SampleEndTime = micros(); //Dump results to serial monitor for (uint16_t i=0;i<SampleQty;i++) { Serial.println(Sample[i]); } Serial.print("Number of Samples : "); Serial.println(SampleQty); Serial.print("Sample Starttime : "); Serial.println(SampleStartTime); Serial.print("Sample Endtime : "); Serial.println(SampleEndTime); SampleDuration = SampleEndTime - SampleStartTime; Serial.print("Sample Array Set Duration time in microseconds : "); Serial.println(SampleDuration); }// end if delay(1000); digitalWrite(ledPin, LOW); // turn LED off: }//end loop ///************************************************************************** /// /// Fast Analog Read Routine /// ///************************************************************************** uint16_t fast_analogRead(void) { uint32_t value[8]; unsigned long *pulBuffer = &value[0]; unsigned long ulCount; unsigned long ulBase = faBase; HWREG(ADC0_BASE + ADC_O_ISC) = 1 << SEQUENCER; HWREG(ADC0_BASE + ADC_O_PSSI) |= ((SEQUENCER & 0xffff0000) | (1 << (SEQUENCER & 0xf))); while (!(HWREG(ADC0_BASE + ADC_O_RIS) & (0x10000 | (1 << SEQUENCER)))) {} HWREG(ADC0_BASE + ADC_O_ISC) = 1 << SEQUENCER; ulBase = ADC0_BASE + (ADC_SEQ + (ADC_SEQ_STEP * SEQUENCER)); ulCount = 0; while(!(HWREG(ulBase + ADC_SSFSTAT) & ADC_SSFSTAT0_EMPTY) && (ulCount < 8)) { value[ulCount] = HWREG(ulBase + ADC_SSFIFO); ulCount++; } return value[0]; } ///************************************************************************** /// /// Fast Analog Init Routine /// ///************************************************************************** uint16_t fast_analogInit(uint8_t pin) { uint8_t port = digitalPinToPort(pin); uint16_t value[1]; uint32_t channel = digitalPinToADCIn(pin); if (pin == NOT_ON_ADC) { //invalid ADC pin return(0); } faBase = (uint32_t)portBASERegister(port); faMask = digitalPinToBitMask(pin); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); ROM_GPIOPinTypeADC((uint32_t)portBASERegister(port), digitalPinToBitMask(pin)); ROM_ADCSequenceConfigure(ADC0_BASE, SEQUENCER, ADC_TRIGGER_PROCESSOR, 0); ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 0, channel | ADC_CTL_IE | ADC_CTL_END); ROM_ADCSequenceEnable(ADC0_BASE, SEQUENCER); return(1); } Cheers
PTB
-
PTB got a reaction from Rei Vilo in Stellaris fast analog reads
And Here's the Code
// // LM4F_ADC // // Description of the project // Developed with [embedXcode](http://embedXcode.weebly.com) // // Author Rei VILO // Rei Vilo // // Date 21/07/13 09:42 // Version <#version#> // // Copyright (c) Rei VILO, 2013 // Licence CC = BY NC SA // // See ReadMe.txt for references // // Core library for code-sense #if defined(WIRING) // Wiring specific #include "Wiring.h" #elif defined(MAPLE_IDE) // Maple specific #include "WProgram.h" #elif defined(MPIDE) // chipKIT specific #include "WProgram.h" #elif defined(DIGISPARK) // Digispark specific #include "Arduino.h" #elif defined(ENERGIA) // LaunchPad, FraunchPad and StellarPad specific #include "Energia.h" #elif defined(CORE_TEENSY) // Teensy specific #include "WProgram.h" #elif defined(ARDUINO) && (ARDUINO >= 100) // Arduino 1.0 and 1.5 specific #include "Arduino.h" #elif defined(ARDUINO) && (ARDUINO < 100) // Arduino 23 specific #include "WProgram.h" #else // error #error Platform not defined #endif // Include application, user and local libraries // Define variables and constants /// /// @file Fast_Analog_Read.ino /// @brief Main sketch /// /// @details Fast Analog Read Investigations for Stellaris LM4F /// // // Stellaris Pin Assignments // ========================= //PE_3 //Sensor Analog Read //PA_5 //Trigger Analog Signal Pulse //PF_4 //Push Button to Start // // Libraries // ========= #include "Energia.h" #include "SPI.h" #include "inc/lm4f120h5qr.h" #include "inc/hw_adc.h" #include "inc/hw_gpio.h" #include "inc/hw_memmap.h" #include "inc/hw_sysctl.h" #include "driverlib/adc.h" #include "driverlib/gpio.h" #include "driverlib/sysctl.h" #include "driverlib/rom.h" // Constants from adc.c #define ADC_SEQ (ADC_O_SSMUX0) #define ADC_SEQ_STEP (ADC_O_SSMUX1 - ADC_O_SSMUX0) #define ADC_SSMUX (ADC_O_SSMUX0 - ADC_O_SSMUX0) #define ADC_SSEMUX (ADC_O_SSEMUX0 - ADC_O_SSMUX0) #define ADC_SSCTL (ADC_O_SSCTL0 - ADC_O_SSMUX0) #define ADC_SSFIFO (ADC_O_SSFIFO0 - ADC_O_SSMUX0) #define ADC_SSFSTAT (ADC_O_SSFSTAT0 - ADC_O_SSMUX0) #define ADC_SSOP (ADC_O_SSOP0 - ADC_O_SSMUX0) #define ADC_SSDC (ADC_O_SSDC0 - ADC_O_SSMUX0) #define SEQUENCER 3 // // Global Constants // ================ const byte SampleQty = 255; // number of samples const uint16_t buttonPin = PUSH1; // the number of the pushbutton pin const uint16_t ledPin = GREEN_LED; // the number of the LED pin const uint16_t TriggerPin = PA_5; // Analog Signal Trigger connected to digital pin PA_5 // // Global Variables // ================ uint16_t SampleTest; uint16_t buttonState = 0; // variable for reading the pushbutton status uint16_t Sample[SampleQty]; // Array variable to store the value coming from the sensor unsigned long SampleStartTime; unsigned long SampleEndTime; unsigned long SampleDuration; unsigned long faBase; uint16_t faMask; // // Prototypes // ========== uint16_t fast_analogInit(uint8_t pin); uint16_t fast_analogRead(void); ///************************************************************************** /// /// Setup code /// ///************************************************************************** void setup() { Serial.begin(9600) ; //Debugging initialize the serial communication: pinMode(ledPin, OUTPUT); // initialize the LED pin as an output: pinMode(buttonPin, INPUT_PULLUP); // initialize the pushbutton pin as an input: pinMode(TriggerPin, OUTPUT); // initialize the Trigger pin as an output: }//end setup ///************************************************************************** /// /// Loop code /// ///************************************************************************** void loop() { buttonState = digitalRead(buttonPin); // read the state of the pushbutton value: if (buttonState == LOW) { digitalWrite(ledPin, HIGH); // turn LED on: fast_analogInit(PE_3); // JKabat SampleStartTime = micros(); digitalWrite(TriggerPin, HIGH); // Start the Analog Signal for (uint16_t i=0;i<SampleQty;i++) { // Sample[i]=analogRead(PE_3); // Original Analog Read Sample[i] = fast_analogRead(); // JKabat } SampleEndTime = micros(); //Dump results to serial monitor for (uint16_t i=0;i<SampleQty;i++) { Serial.println(Sample[i]); } Serial.print("Number of Samples : "); Serial.println(SampleQty); Serial.print("Sample Starttime : "); Serial.println(SampleStartTime); Serial.print("Sample Endtime : "); Serial.println(SampleEndTime); SampleDuration = SampleEndTime - SampleStartTime; Serial.print("Sample Array Set Duration time in microseconds : "); Serial.println(SampleDuration); }// end if delay(1000); digitalWrite(ledPin, LOW); // turn LED off: }//end loop ///************************************************************************** /// /// Fast Analog Read Routine /// ///************************************************************************** uint16_t fast_analogRead(void) { uint32_t value[8]; unsigned long *pulBuffer = &value[0]; unsigned long ulCount; unsigned long ulBase = faBase; HWREG(ADC0_BASE + ADC_O_ISC) = 1 << SEQUENCER; HWREG(ADC0_BASE + ADC_O_PSSI) |= ((SEQUENCER & 0xffff0000) | (1 << (SEQUENCER & 0xf))); while (!(HWREG(ADC0_BASE + ADC_O_RIS) & (0x10000 | (1 << SEQUENCER)))) {} HWREG(ADC0_BASE + ADC_O_ISC) = 1 << SEQUENCER; ulBase = ADC0_BASE + (ADC_SEQ + (ADC_SEQ_STEP * SEQUENCER)); ulCount = 0; while(!(HWREG(ulBase + ADC_SSFSTAT) & ADC_SSFSTAT0_EMPTY) && (ulCount < 8)) { value[ulCount] = HWREG(ulBase + ADC_SSFIFO); ulCount++; } return value[0]; } ///************************************************************************** /// /// Fast Analog Init Routine /// ///************************************************************************** uint16_t fast_analogInit(uint8_t pin) { uint8_t port = digitalPinToPort(pin); uint16_t value[1]; uint32_t channel = digitalPinToADCIn(pin); if (pin == NOT_ON_ADC) { //invalid ADC pin return(0); } faBase = (uint32_t)portBASERegister(port); faMask = digitalPinToBitMask(pin); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); ROM_GPIOPinTypeADC((uint32_t)portBASERegister(port), digitalPinToBitMask(pin)); ROM_ADCSequenceConfigure(ADC0_BASE, SEQUENCER, ADC_TRIGGER_PROCESSOR, 0); ROM_ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 0, channel | ADC_CTL_IE | ADC_CTL_END); ROM_ADCSequenceEnable(ADC0_BASE, SEQUENCER); return(1); } Cheers
PTB
-
PTB reacted to jkabat in Stellaris fast analog reads
@@PTB,
I begin to see where I erred! I forgot to include the sequencer in the read of the fifo. The clue to this was the ucount was 8 not 1. this indicates the we were reading an 8 deep FIFO not a single one. (Sequencer 0) Also since value is only one entry were were overwriting something following it. That is why it never returned!
So one more fix:
change value to:
uint16_t value[8]; just to be safe.
change the end as follows:
// // Get the offset of the sequence to be read. // ulBase = ADC0_BASE + (ADC_SEQ + (ADC_SEQ_STEP * SEQUENCER)); // // Read samples from the FIFO until it is empty. // ulCount = 0; while(!(HWREG(ulBase + ADC_SSFSTAT) & ADC_SSFSTAT0_EMPTY) && (ulCount < 8)) { // // Read the FIFO and copy it to the destination. // value[ulcount] = HWREG(ulBase + ADC_SSFIFO); // // Increment the count of samples read. // ulCount++; } return(value[0];