Rickta59 589 Posted April 25, 2013 Share Posted April 25, 2013 I've been trying out the LPC1114 chip from NXP. It is an arm cortex-m0 chip with 32k of flash and 4k of ram. Quantity 1 pricing is < $3. Did I mention this is available in dip-28 packaging, very friendly to breadboards? Well it is. http://octopart.com/lpc1114fn28%2F102%2C12-nxp+semiconductors-22360689 I was going to post this on our sister site, however this chip is more like an msp430 than the cortex-m4 you find on the stellaris launchpad. Others have posted tutorials to get you going. http://www.meatandnetworking.com/tutorials/lpc1114fn28-with-open-source-tools/ - how to setup on a breadboad http://www.embeddedrelated.com/showarticle/101.php?articleid=101- getting started with C++ and the lpc1114 http://www.blacksphere.co.nz/main/blackmagic - an open source SWD debugger that can run on an stm32f4 discovery board. I'm rounding out my fabooh framework with chips other than the just the msp430. This seemed like a good hobbyistfriendly chip to add.I'm not ready to release anything but just wanted to let people know I'm working with it so you may see some code at some point. In the meantime, I mostly wanted to share this Rei Vilo style breakout for the pins and get a dialog going with others who might be interested in using this chip. So if you have interest in this chip, speak up! http://bit.ly/11GTwWb - LPC1114DIP pin break out. Hover over the cells for a more detailed description of the pin functions. -rick spirilis, xpg, simpleavr and 2 others 5 Quote Link to post Share on other sites
bluehash 1,581 Posted April 25, 2013 Share Posted April 25, 2013 Awesome! good luck... another Spirilis type "My time with.." Quote Link to post Share on other sites
simpleavr 399 Posted April 25, 2013 Share Posted April 25, 2013 good find, would be nicer if it's narrow dip though. Quote Link to post Share on other sites
Rickta59 589 Posted April 25, 2013 Author Share Posted April 25, 2013 If you have a CNC machine, some epoxy, and way too much time on your hands: -rick tingo 1 Quote Link to post Share on other sites
Rickta59 589 Posted April 25, 2013 Author Share Posted April 25, 2013 A lot has changed recently with regard to arm toolchains. No longer do you have to build one yourself. You can easily get a fully featured arm compiler binary for all 3 platforms. (win32/linux/osx). Since last December you can find the linaro gcc available from here: https://launchpad.net/gcc-arm-embedded/+download You want to grab the one that says arm-none-eabi-... for your OS. The 'none-eabi'means it is a compiler for 'bare-metal' chips without any OS support. EABI means the libraries conform to the standard ELF ABI for arm chips. They update these files every quarter with new versions, new features and fixes. Make sure you read the release notes to see what is new and any cautions. Once you have a compiler, you can use it with Fredie Chopin's lpc1114_led_blink example that has a fully featured makefile. http://www.freddiechopin.info/en/download/category/6-examples The lpc1114 is a cortex-m0 chip and has full support. They provide newlib librariesthat you can link against although if you are concerned about small code you might want to avoid that stuff. -rick yyrkoon, ike, oPossum and 1 other 4 Quote Link to post Share on other sites
rockets4kids 204 Posted April 25, 2013 Share Posted April 25, 2013 I have been told that the reason for the wide packaging is to allow for more PCB traces to be routed underneath the chip. Apparently, there *is* still a section of the commercial market using single-sided, through-hole boards, and that is the target market for this chip, not hobbyists. spirilis 1 Quote Link to post Share on other sites
spirilis 1,265 Posted April 25, 2013 Share Posted April 25, 2013 That seems plausible. More room for SMD passives too. Quote Link to post Share on other sites
xpg 127 Posted April 25, 2013 Share Posted April 25, 2013 Thanks for that information Rick. I have heard about the Linaro toolchain, but haven't really tried it yet. Maybe it's time to do so :-) Quote Link to post Share on other sites
Rickta59 589 Posted April 25, 2013 Author Share Posted April 25, 2013 The lpc chips have a built in bootloader much like bsl on the msp430 chips. I think there is a sanctioned flash loader. However, I'm just partial to opensource and things that run on linux. You'll find a lot of different versions of the lpc21isp code out there. The first one I tried (from the meatandnetworking.com article) was just plain broken. I'm using this version of lpc21isp I found on github. https://github.com/Senseg/lpc21isp It was missing support for our chip. So, I did have to patch it so it knows aboutthe 28 pin version of the lpc1114. I think g0rdon provide me those patches. Thanks g0rdon! Basically the changes add the 28 pin dip chip id and provides the proper smaller ram size (4k) to the device table. At startup, lpc21isp interrogates the chip and then decides if it knows about the chip or not. $ git diff lpcprog.c diff --git a/lpcprog.c b/lpcprog.c index ccf6c41..3fc5471 100644 --- a/lpcprog.c +++ b/lpcprog.c @@ -111,6 +111,8 @@ static LPC_DEVICE_TYPE LPCtypes[] = { 0x2532902B, "1113.../202", 24, 4, 6, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX { 0x0434102B, "1113.../301", 24, 8, 6, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX { 0x2532102B, "1113.../302", 24, 8, 6, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX + { 0x0A40902B, "1114.../102", 32, 4, 8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX + { 0x1A40902B, "1114.../102", 32, 4, 8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX { 0x0444502B, "1114.../201", 32, 4, 8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX { 0x2540902B, "1114.../202", 32, 4, 8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX { 0x0444102B, "1114.../301", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX (END) When I first started with electronics I had paid full price for a 3.3V FTDI breakoutboard from SparkFun, ouch! However, it actually came in handy with this chip as it supports the full set of modem signals. I use RX/TX/RTS/DTR. This allows me to use the lpc21isp program to toggle the boot pin and reset for me. No hands loading. FTDI->LPC TX-> Pin 15 (LPX RX) RX-> Pin 16 (LPC TX) DTR-> Pin 23 (RESET) RTS-> Pin 24 (BOOTISP)/P0.1 GND-> Pin 22 (GND) To load new code i just use make and use the control flags argument to have it automatically reset the chip, erase it, and then reset the chip when the code is loading. $ make clean all ... lpc21isp -wipe -control -postreset lpc1114fn28_release/blink.hex /dev/ttyUSB0 115200 12000 ... ike and xpg 2 Quote Link to post Share on other sites
Rickta59 589 Posted April 25, 2013 Author Share Posted April 25, 2013 OK, so now you have all the prerequistes to get going. Now I'd like to talk a bit about my stuff. First off, let me say I'm very new at ARM programming and this chip. However, I do have a vision of being able to write efficient C++ templated code that runs cross chip. I call this vision fabooh. http://fabooh.com It is very early in the stage of working and this ARM code is being added to make sure that the API is flexible enough to add multiple chip architectures. I've checked in some very preliminary code that will provides a general framework for building example programs. The makefile take care of setting all the gcc options for the lpc1114. It is based on the Fredie Chopin and customized to fit into the fabooh directory structure. I'll merge in the msp430 version as I get further along. I didn't want to break the msp430 version as I experiment with the arm version. https://github.com/RickKimball/fabooh If you git clone that, you can type make clean all from the top and build arm firmware for this lpc1114 chip. I'm assuming you have added the arm-none-eabi-gcc and the lpc21isp programs to your path. $ cd fabooh/examples/basic/blink $ make clean all install Removing all generated output files from output directory: lpc1114fn28_release/ rm -f lpc1114fn28_release/blink.bin lpc1114fn28_release/blink.d lpc1114fn28_release/crt0.d lpc1114fn28_release/blink.dmp lpc1114fn28_release/blink.elf lpc1114fn28_release/blink.hex lpc1114fn28_release/blink.lss lpc1114fn28_release/blink.map lpc1114fn28_release/blink.o lpc1114fn28_release/crt0.o Compiling file: ../../..//board/lpc1114fn28/crt0.c arm-none-eabi-g++ -c -mcpu=cortex-m0 -mthumb -Os -ffunction-sections -fdata-sections -Wall -Wextra -std=gnu++98 -g -ggdb3 -fno-rtti -fno-exceptions -fverbose-asm -DCORE_M0 -MD -MP -MF lpc1114fn28_release/crt0.d -I../../..//. -I../../..//include/cortex-m0/core -I../../..//board/lpc1114fn28 -I../../..//board/lpc1114fn28/chip_11xx -I../../..//board/lpc1114fn28/lpc_ip -I../../..//board/lpc1114fn28/chip_common ../../..//board/lpc1114fn28/crt0.c -o lpc1114fn28_release/crt0.o Compiling file: blink.cpp arm-none-eabi-g++ -c -mcpu=cortex-m0 -mthumb -Os -ffunction-sections -fdata-sections -Wall -Wextra -std=gnu++98 -g -ggdb3 -fno-rtti -fno-exceptions -fverbose-asm -DCORE_M0 -MD -MP -MF lpc1114fn28_release/blink.d -I../../..//. -I../../..//include/cortex-m0/core -I../../..//board/lpc1114fn28 -I../../..//board/lpc1114fn28/chip_11xx -I../../..//board/lpc1114fn28/lpc_ip -I../../..//board/lpc1114fn28/chip_common blink.cpp -o lpc1114fn28_release/blink.o Linking target: lpc1114fn28_release/blink.elf arm-none-eabi-g++ -mcpu=cortex-m0 -mthumb -T../../..//board/lpc1114fn28/lpc1114.ld -g -Wl,-Map=lpc1114fn28_release/blink.map,--cref,--no-warn-mismatch -Wl,--gc-sections -nostartfiles -L../../..//board/lpc1114fn28 lpc1114fn28_release/crt0.o lpc1114fn28_release/blink.o -o lpc1114fn28_release/blink.elf calling Creating extended listing: lpc1114fn28_release/blink.lss arm-none-eabi-objdump -S lpc1114fn28_release/blink.elf > lpc1114fn28_release/blink.lss Creating memory dump: lpc1114fn28_release/blink.dmp arm-none-eabi-objdump -x --syms lpc1114fn28_release/blink.elf > lpc1114fn28_release/blink.dmp Creating IHEX image: lpc1114fn28_release/blink.hex arm-none-eabi-objcopy -O ihex lpc1114fn28_release/blink.elf lpc1114fn28_release/blink.hex Creating binary image: lpc1114fn28_release/blink.bin arm-none-eabi-objcopy -O binary lpc1114fn28_release/blink.elf lpc1114fn28_release/blink.bin Size of modules: arm-none-eabi-size -B -t --common lpc1114fn28_release/crt0.o lpc1114fn28_release/blink.o text data bss dec hex filename 340 0 0 340 154 lpc1114fn28_release/crt0.o 224 0 4 228 e4 lpc1114fn28_release/blink.o 564 0 4 568 238 (TOTALS) lpc21isp -wipe -control -postreset lpc1114fn28_release/blink.hex /dev/ttyUSB0 115200 12000 Reset after flashing. lpc21isp version 1.83 File lpc1114fn28_release/blink.hex: loaded... Start Address = 0x000000C1 converted to binary format... image size : 556 Image size : 556 Synchronizing (ESC to abort). OK Read bootcode version: 1 7 Read part ID: LPC1114.../102, 32 kiB ROM / 4 kiB SRAM (0x1A40902B) Read Unique ID: succeeded Will start programming at Sector 1 if possible, and conclude with Sector 0 to ensure that checksum is written last. Wiping Device. OK Sector 0: .................. Download Finished... taking 0 seconds Now launching the code $ That is what it looks like to compile and load a blink program onto the lpc1114. If you poke around you can see a ctr0.c and lpc1114.ld script are provided that handle the power on reset and setting up the c runtime environment initialization. These work without using any of the compilers startup code. This should make it easier to use different toolchains. Note that the startup code also takes care of initializing the c++ global objects. This feature is often left off on sample code you find on the net that is only using straight 'C'. Yes, I'm coding in C++. That is a key feature of fabooh, it is a C++ peripheral template framework. The code itself is really simple, in fact it looks very similar to the msp430 blink version #include <fabooh.h> #include <main.h> void setup(void) { RED_LED::setmode_output(); } void loop(void) { const uint32_t freq = 2; const uint32_t msec_delay = 1000 / freq / 2; while (1) { RED_LED::toggle(); delay(msec_delay); } } I've setup RED_LED in the pins.h to map to pin 17 (P1.8) on the lpc1114. Just provide the chip with power some decoupling caps, a resistor for the led and you are done. See the meatandnetworking breadboard article for a schematic. Then poke around in the directory tree. It is pretty small and simple at this point. It needs a lot more fleshing out. However, the general overall structure is there and the various examples that are checked in should work. Try the serial examples. The print code was taken from the msp430 version and mostly worked without change. I'll be adding more examples as I go along. If you are inspired, you might want to fork fabooh and submit some of your code for inclusion. -rick Quote Link to post Share on other sites
Rickta59 589 Posted April 26, 2013 Author Share Posted April 26, 2013 One of the stumbling blocks for fans of open source development tools with the lpc1114 is the lack of a supported gdb server for cortex-m0 chips. You can buy an NXP development board. However, they are more expensive than their competitor's boards. In addition, they really expect you to use a commercial IDE. Openocd is a broken option as it doesn't really deal with the cortex-m0 chip unless you are using an STM32 chip.To the rescue comes a newly minted gem, it is a tool called BlackMagic Probe (BMP). The developer offers an open source hardware and software solution that provides ARM Serial Wire Debug (SWD) as a gdb debug server. It is unique in that you connect to it over a standard tty device. This greatly simplifies operating system support as most host systems support usb tty devices without much hassle. Because it is open source, others have added support for off the shelf hardware many of you might already have.Last year I got one of those STM32F4-Discovery boards. It is a great little dev board that has an on-board programmer along with USB connected to the target side of the board. You can build BMP to use this board. Just clone BMP from github.com.gsmcmullin/blackmagic and then build it with a special target: make PROBE_HOST=f4discovery clean all This will produce a blackmagic.bin that can be loaded on the target chip on the STM32F4-Discovery board and used as a gdb server. You will have to use openocd to load it into flash. The next time you power cycle the STM32F4-discovery board, it will appear as a new /dev/ttyACMX device. Just wire up the pins from the discovery board to the SWD pins on the LPC1114 along with ground and you will end up with working gdb server than can be used to debug your cortex-m0. To start an lpc1114 debug session try this: arm-none-eabi-gdb -b 115200 -ex 'target remote /dev/ttyACM0' blink.elf bingo, bango, and you are on your way to writing and debugging code like a pro.Things are really looking up for those seeking a decent open source development environment that supports the lpc1114fn28.NXP has an interesting post here that discusses SWD:http://lpcware.com/content/blog/introduction-cortex-serial-wire-debugging-part-one-rick Quote Link to post Share on other sites
Rickta59 589 Posted April 28, 2013 Author Share Posted April 28, 2013 So I spent some more time with BMP (BlackMagic Probe). I was able to use it to debug code loaded on the chip using lpc21isp. However, using gdb to load code wasn't working properly. I cranked up arm-none-eabi-gdb and did a little debugging on the BMP code. Turns out that the chip id code for the lpc1114/102 fn28 wasn't in the list of lpc11xx devices. When BMP probes the chip it wasn't finding it in the list and so it had no idea how much flash or ram it had. This patch: http://dpaste.com/1076138/ has the small changes I made to have it detect our chip. btw here is the final command line startup i use to debug. $ arm-none-eabi-gdb -b 115200 -ex 'target extended-remote /dev/ttyACM0' -ex 'mon sw' -ex 'attach 1' lpc1114fn28_release/blink.elf GNU gdb (GNU Tools for ARM Embedded Processors) 7.4.1.20130312-cvs Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=i686-linux-gnu --target=arm-none-eabi". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home2/kimballr/lpc1114_ws/fabooh/examples/basic/blink/lpc1114fn28_release/blink.elf...done. Remote debugging using /dev/ttyACM0 Target voltage: ABSENT! Available Targets: No. Att Driver 1 LPC1114/102 (0x1A40902B) Attached to Remote target 0x00000196 in delay_msec (msec=250) at ../../../include/cortex-m0/core/cpu_lpc11xx.h:110 110 while (tickcount < t) (gdb) load Loading section .text, size 0x234 lma 0x0 Start address 0xc1, load size 564 Transfer rate: 3 KB/sec, 564 bytes/write. (gdb) run The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home2/kimballr/lpc1114_ws/fabooh/examples/basic/blink/lpc1114fn28_release/blink.elf ^C Program received signal SIGINT, Interrupt. 0x00000196 in delay_msec (msec=250) at ../../../include/cortex-m0/core/cpu_lpc11xx.h:110 110 while (tickcount < t) (gdb) p tickcount $1 = 14804 (gdb) You get a (gdb) command prompt if all goes well. You just 'load' the code and then 'run'. BMP will automatically erase sectors on the lpc1114 as need to accommodate the new code with the load command. When you run it automatically resets the chip and starts the new code. [EDIT: BMP has been updated with this change in the latest source, got to love OSS!] -rick Quote Link to post Share on other sites
zborgerd 62 Posted May 1, 2013 Share Posted May 1, 2013 A lot has changed recently with regard to arm toolchains. No longer do you have to build one yourself. You can easily get a fully featured arm compiler binary for all 3 platforms. (win32/linux/osx). Since last December you can find the linaro gcc available from here: https://launchpad.net/gcc-arm-embedded/+download You want to grab the one that says arm-none-eabi-... for your OS. The 'none-eabi'means it is a compiler for 'bare-metal' chips without any OS support. EABI means the libraries conform to the standard ELF ABI for arm chips. They update these files every quarter with new versions, new features and fixes. Make sure you read the release notes to see what is new and any cautions. I have also been using this toolchain on Linux, with all of my ARM boards, and have been pleased with it. I used to build my own but got sick of dealing with dependencies. Quote Link to post Share on other sites
Rickta59 589 Posted May 1, 2013 Author Share Posted May 1, 2013 Building your own toolchain and getting working ldscripts used to be the biggest stumbling block to using these low cost arm chips. I'm happy we are leaving that era behind us. I just read today that NXP acquired the company behind CodeRed. Some people are speculating that this will lower the cost and lock up the tool chain to just NXP chips. www.nxp.com/news/press-releases/2013/05/nxp-acquires-code-red-technologies.html I continue to forge ahead learning about the LPC1114 chip. I'm trying to understand the PLL clock system. The PLL allows you to use a lower speed XTAL to achieve a higher speed system clock. At reset the chip comes up using its interal 12MHz internal oscillator (IRC). If you do nothing that is what you get a 12MHz system clock. You can turn on the PLL subsystem and source it with the IRC. This allows you to run at 24MHZ, 36MHz and 48MHz. It is just a matter of setting the right registers. NXP provides a really nice excel spreadsheet with macros that is wasted on me as I don't have excel. When I tried to import it into google spreadsheets, it didn't work. However, I found an old version someone else did and imported it into google spreadsheets. The spread sheet lets you enter an input clock and then play with the PSEL and MSEL variables to produce a new FCLKOUT. You can try out the spreadsheet here: LPC1114 PLL Ratio Calculator One nice things about these chips compared to the msp430 value line chips is that you can actually use an external crystal. I had a salvaged 12MHz xtal I found on an old ISA PC board. I plopped it on my breadboard and added a few capacitors and some twisty wire. After setting up the PLL subsystem I was able to dial it in to exactly 36.0000MHz .. not bad for a breadboard setup: Links regarding "twisty wires" gimmik capacitor video gimmik capacitor -rick spirilis and xpg 2 Quote Link to post Share on other sites
Rickta59 589 Posted May 4, 2013 Author Share Posted May 4, 2013 Now that I'm able to successfully manipulate the system clock using both the internal and external oscillators, I've been looking at the SSP peripheral. My goal was to learn enough about SPP to be able use it to drive 4 pixels of a WS2811 led strip at the full 800kHz clock rate. I've attached some code you can look at and I'll walk through it below. /* * spiws2811.cpp - send grb (Green,Red,Blue) data to 4 ws2811 pixels using lpc1114 SPI peripheral * * note: assumes 48MHz to support 800kHz data stream, 24MHz or 12MHz use 400kHz */ #include <fabooh.h> #include <main.h> const uint8_t frames[][12] = { { 0x05,0x05,0x05 /* white 20% */ ,0x00,0x05,0x00 /* red 20% */ ,0x05,0x00,0x00 /* green 20% */ ,0x00,0x00,0x05 /* blue 20% */ } ,{ 0x5f,0x5f,0x5f /* white 37d% */ ,0x00,0x5f,0x00 /* red 37% */ ,0x5f,0x00,0x00 /* green 37% */ ,0x00,0x00,0x5f /* blue 37% */ } ,{ 0xff,0xff,0xff /* white 100% */ ,0x00,0xff,0x00 /* red 100% */ ,0xff,0x00,0x00 /* green 100% */ ,0x00,0x00,0xff /* blue 100% */ } ,{ 0x00,0x00,0x00 /* turn them all off */ ,0x00,0x00,0x00 ,0x00,0x00,0x00 ,0x00,0x00,0x00 } }; void setup (void) { LPC_SYSCON->PRESETCTRL |= (1 << 0); // clear SPI reset, SPI held in reset by default (3.5.2) LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 11 | 1 << 16); // enable clock to SPI0 block (3.5.14) // reset the ws2811 // make MOSI a pull-down pin, then wait at least 50us LPC_IOCON->PIO0_9 = (LPC_IOCON->PIO0_9 & ~(0b11<<3) | (0b01 << 3)); delay(2); // 1000ns // SPI configuration LPC_IOCON->PIO0_9 = (LPC_IOCON->PIO0_9 & ~(0x3)) | 0x01; // enable MOSI function (7.4.23) // optional don't really need to output the clock, however, it is useful for debugging the SPI speed #if 1 LPC_IOCON->SCK_LOC = 0x02; // Selects SCK0 function in pin location PIO0_6/SCK0 LPC_IOCON->PIO0_6 = 0x02; // SCK function (sec. 7.4.9) #endif // 800kHz = F_CPU=48000000/SSP0CLKDIV=1/CPSR=2/(SCR=1)+1/BITS=15 // 400kHz = F_CPU=24000000/SSP0CLKDIV=1/CPSR=2/(SCR=1)+1/BITS=15 // 400kHz = F_CPU=12000000/SSP0CLKDIV=1/CPSR=2/(SCR=0)+1/BITS=15 LPC_SYSCON->SSP0CLKDIV = 1; // enable SPI clk by writing non-zero clk divisor (3.5.15) LPC_SSP0->CPSR = 0x2; // spi clock prescaler (14.6.5) static const unsigned SCR=(F_CPU == 12000000UL) ? 0 : 1; // 15 bit transfer, SPI frame format, CPOL=0 + CPHA=1, SCR=1 (14.6.1) LPC_SSP0->CR0 = 15-1 | (0b00 << 4) | (0b10 << 6) | (SCR << 8); LPC_SSP0->CR1 |= 0x01 << 1; // enable SPI (14.6.2) volatile unsigned int i = 0; unsigned bit_mask; const unsigned fcnt = 4; while (1) { unsigned cnt=fcnt*4; unsigned bits; uint8_t *pdata = &frames[i++][0]; i = ( i < fcnt) ? i : 0; __disable_irq(); do { bit_mask = 1 << 7; do { if (*pdata & bit_mask ) { // ~600ns high / ~625ns low at 800kHz bits = 0b111111100000000; } else { // ~250ns high / ~1000ns low at 800kHz bits = 0b111000000000000; } while ( !(LPC_SSP0->SR & (1<<1)) ); // wait until !TNF (Transmit Not Full) (14.6.4) LPC_SSP0->DR = bits; // push this pixel data into the SPI FIFO bit_mask >>= 1; } while(bit_mask); pdata++; } while(--cnt); while ( !(LPC_SSP0->SR & (1<<4)) ); // wait until ! BSY (Busy) (14.6.4) meaning all bits transmitted __enable_irq(); delay(1000); } } void loop() {} I've set this up so that it works with a system clock of (12MHz,24MHz) and 48MHz. The fastest you can drive the SPI peripheral is at F_CPU/2. The most you are going to get out of it is 24MHz. As the ws2811 chips can run at either 800kHz or 400kHz we just need to divide the SPI clock to be succesful. I'm not going to go in depth in how the ws2811 works, as you can already find lots of info on this site with the details. (Check out oPossums code). The key thing is we need to generate 2 different on off patterns. A '0' bit needs to be 250ns high/ 1000ns low and the '1' bit needs to be 600ns high / 625ns low. You send each bit to the DIN pin of the ws2811 8 bits at a time using MSB order. To set the width of the bits I found 15 bits of SPI data allows me to set the timing very close to what we need. If we take the total width of the bits 1250 nanaseconds / 15 bits that turns out to be 83.3 nanoseconds per bit. So to send the '0' bit we need to send 0b111000000000000. or 3*83.3 (249.999ns) and 12*83.3333 (999.999ns). For the '1' bit we send 0b111111100000000, or 7*83.3 (583.333ns) and 8*83.3 (666.666ns). These seem to be close enough to work. A nice feature of the LPC1114 SPI peripheral is that it has an 8 frame FIFO. This allows you to send a continous stream of bits with no gaps. It took me a while to get this working as I overlooked one important feature of the LPC1114 GPIO pins. Most of them have a pull-up pin set by default. Before I noticed this fasct, I had just used a 1k resistor on the P0_9 pin to gnd to pull it down. However, it wasn't going down all the way. Once, I changed the default from pull-up to pull-down, the code just worked. I added lots of comments in the code above. Hopefully, that will explain most of what I did. Note: the section reference in the code refer to the LPC1114 user manual # UM10398 -rick oPossum 1 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.