Jump to content

Search the Community

Showing results for tags 'Forth'.



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.


Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Website URL


Location


Interests


Sparkfun


Github

Found 3 results

  1. SIMPL = Serial Interpreted Minimal Programming Language Hi, It's been about a year since I talked about SIMPL - a tiny language that allows you basic control of a microcontroller using serial commands. In the 6 months I have coded it up in MSP430 assembly language to make it super compact - and fast - with high level commands taking about 1uS to execute on the virtual machine interpreter. SIMPL is based on a jump table - so for any single, printable ascii character, the jump table will act on it and execute whatever function you choose to write. This technique gives amazing flexibility, and for under 1K of code it can offer a very powerful user interface to your latest MSP430 project. One example is using the jump table to interpret commands from a text file to control a CNC mill or drill - or even a 3D printer. The core routines can be applied to any MSP430 - you just have to change the initialisation routines to suit the DCO, GPIO and UART of the specific microcontroller Just this week, I have got the looping to work, so you can now do things like send square waves to port pins for flashing LEDs and creating musical tones. With the standard Launchpad (MSP430GR2553) clocked at 16MHz you can send a 1uS pulse to a port pin - just by typing hl (shorthand for high, low) at the serial terminal. SIMPL is coded up in just 872 bytes of program memory - and can handle up to 96 separate commands. Commands can be sent to the device from a text file - using teraterm or similar - or just typed manually at the keyboard. I have put the latest code (some recent changes) on this github gist https://gist.github.com/monsonite/6483a32404c1c53cd8027dd6f9dcea6e This is a work in progress - and there are still a few bugs - but the basics seem to work OK. regards Ken Here's some more info about the various routines that make up the kernel textRead 33 Instructions 90 bytes Receive characters from the serial uart and place them into a buffer in RAM. Two modes of operation are possible, immediate mode, where the characters are executed as instructions directly after a carriage return line feed is received, and compile mode, where the character sequences are preceded by a colon and stored in pre-calculated command buffers in RAM. number 16 instructions 42 bytes Number interprets sequences of consecutive digits as a 16-bit integer number and places the value in the register that is the top entry of the stack. next 5 instructions 12 bytes Next is the routine that all commands return the program flow back to once they have executed. It fetches the next character instruction from the RAM buffer and through a jump table technique passes program control to the code body that performs the task associated with that instruction. The jump table is used to direct the character to the areas of code that will treat them correctly - for example on encountering a numerical digit, program control is passed to the number routine, whilst for upper case alphabetical characters, program control is passed to a routine that handles these separately. jump_table 96 instructions 192 bytes Primitives 72 instructions 166 bytes SIMPL uses a collection of 32 instruction primitives from which other instructions can be synthesised. The code body of these primitives is some 100 instructions or so. Upper (called alpha in V1) 10 instructions 26 bytes Upper handles the capital letters - as these are user commands, and the user is able to write and store in RAM certain functionality based on these characters. When a capital letter is encountered in the instruction buffer, Upper directs control to the correct command buffer. Lower 86 bytes Lower is an area of program that interprets the lower case characters and provides a higher level of program complexity than is achievable form the primitives alone. printnum 30 instructions 106 bytes This takes a 16 bit integer number from the stack and prints a string of ascii digit characters to the terminal. Uart Routines 13 instructions 41 bytes Low level communication with the uart is by way of the get_c and put_c routines Initialisation 19 instructions 90 bytes Here the hardware such as the oscillator, GPIO and uart are initialised for correct operation. This is code specific to whichever microcontroller has been chosen Interpreter 4 instructions 16 bytes This is the main routine that runs the SIMPL interpreter combining textRead, next, number and Upper. Here's the code - as it stands. Code window has mess up the formatting - but it should still cut and paste ;------------------------------------------------------------------------------- ; SIMPL - a very small Forth Inspired Extensible Language ; Implementing the Initialisation, TextTead, TextEval and UART routines in MSP430 assembly language ; ; A Forth-Like Language in under 1024 bytes ; Ken Boak May 22nd/23rd 2017 ; Loops, I/O, Strings and Delays added ; This version 872 bytes ; Instructions take about 1uS cycle time - so about 1/16th of clockspeed ;------------------------------------------------------------------------------- .cdecls C,LIST,"msp430.h" ; Include device header file ;------------------------------------------------------------------------------- .def RESET ; Export program entry-point to ; make it known to linker. ;------------------------------------------------------------------------------- ; Variables ;------------------------------------------------------------------------------- .sect "vars" .bss parray, 256 .bss x, 2 .bss name, 2 ;------------------------------------------------------------------------------- ; Using the register model of CH Ting's Direct Thread Model of MSP430 eForth ; CPU registers ; Register Usage ; R0 MSP430 PC Program Counter ; R1 MSP430 SP Stack Pointer ; R2 MSP430 SR Status Register tos .equ R4 stack .equ R5 ip .equ R6 temp0 .equ R7 ; loop start temp1 .equ R8 ; loop counter k temp2 .equ R9 ; millisecond delay temp3 .equ R10 ; microsecond delay temp4 .equ R11 instr .equ R12 temp5 .equ R13 temp6 .equ R14 ; temp7 .equ R15 ; Return from alpha next IP ;------------------------------------------------------------------------------- ; Macros pops .macro ;DROP mov.w @stack +, tos .endm pushs .macro ;DUP decd.w stack mov.w tos, 0(stack) .endm; ; Constants $NEXT .macro jmp next ; mov @ip+, pc ; fetch code address into PC .endm $NEST .macro .align 2 call #DOLST ; fetch code address into PC, W = PFA .endm $CONST .macro .align 2 call #DOCON ; fetch code address into PC, W = PFA .endm ;------------------------------------------------------------------------------ ;; Assembler constants COMPO .equ 040H ;lexicon compile only bit IMEDD .equ 080H ;lexicon immediate bit MASKK .equ 07F1FH ;lexicon bit mask CELLL .equ 2 ;size of a cell BASEE .equ 10 ;default radix VOCSS .equ 8 ;depth of vocabulary stack BKSPP .equ 8 ;backspace LF .equ 10 ;line feed CRR .equ 13 ;carriage return ERR .equ 27 ;error escape TIC .equ 39 ;tick CALLL .equ 012B0H ;NOP CALL opcodes UPP .equ 200H DPP .equ 220H SPP .equ 378H ;data stack TIBB .equ 380H ;terminal input buffer RPP .equ 3F8H ;return stacl CODEE .equ 0C000H ;code dictionary COLDD .equ 0FFFEH ;cold start vector EM .equ 0FFFFH ;top of memory ;------------------------------------------------------------------------------- .text ; Assemble into program memory. .retain ; Override ELF conditional linking ; and retain current section. .retainrefs ; And retain any sections that have ; references to current section. ;------------------------------------------------------------------------------- ; This implements the SIMPL interpreter is MSP430 assembly Language ;------------------------------------------------------------------------------- ; textRead ; ------------------------------------------------------------------------------ ; Get a character from the UART and store it in the input buffer starting at 0x0200 ; Register Usage ; The input buffer - start is at 0x0200, which is pointed to by R14 ; R11 is a counter to ensure that we don't exceed 64 characters in input buffer ; R12 receives the character from the uart_get_c routine and puts in the buffer, pointed to by R14 ; R14 is the current character position in the input buffer ; 33 instructions textRead: MOV.W #0x0200,R14 ; R14 = start of input buffer in RAM CLR.B R11 ; i = 0 getChar: CALL #uart_getc ; char ch = uart_getc() CMP.B #0x000d,R12 ; is it carriage return? 0d JEQ textEnd CMP.B #0x000a,R12 ; Is it newline? 0a JEQ textEnd CMP.B #0x0020,R12 ; if (ch >= ' ' && ch <= '~') JLO nonValid CMP.B #0x007f,R12 JHS nonValid CMP.B #0x003A,R12 ; is it colon? 3A JNE notColon colon: ; If the input character is a colon CALL #uart_getc ; get the next character - which is the NAME MOV.B R12,R13 ; move the 1st character after the colon to "name" variable in R13 times_32: SUB.B #0x0041,R13 ; Calculate the destination address - subtract 65 to remove offset of letter A ADD.W R13,R13 ; Double R13 ; multiply by 2 ADD.W R13,R13 ; Double R13 ; multiply by 4 ADD.W R13,R13 ; Double R13 ; multiply by 8 ADD.W R13,R13 ; Double R13 ; multiply by 16 ADD.W R13,R13 ; Double R13 ; multiply by 32 ADD.W R13,R14 ; Add (32*R13) to the index pointer R14 ADD.W #0x020,R14 ; Add to array pointer 0x0220 MOV.B R12,0x0000(R14) ; Store character at RAM buffer indexed by R14 ; R14 now contains the destination address JMP incPointer notColon: INC.W R14 ; Increment buffer pointer MOV.B R12,0xffff(R14) ; Store character at RAM buffer indexed by R14 incPointer: INC.B R11 ; Increment the input buffer pointer i++; nonValid: CMP.B #0x003f,R11 ; If input pointer <64 loop back to start JLO getChar ; loop back and get next character textEnd: mov.b #0x00,0x0000(R14) ; Put a null terminating (0x80) zero on the end of the buffer ; MOV.B R11,0x0000(R14) ; Put a null terminating (0x80) zero on the end of the buffer RET ;------------------------------------------------------------------------------------------------------------------- ; We now come onto the textEval - where based on the value of the character we perform some action routine ; But first we need to determine whether the characers form part of a number - and these must be decoded separately ; and put on the stack ;------------------------------------------------------------------------------------------------------------------- ; Register Usage ; ip - instruction pointer to the current character in the input buffer ; R12 is the accumulator for the number - then stored in location #0x380 ; R13 Temporary - use in x10 multipication ; R14 ; 16 Instructions number: SUB.W #0x0030,R12 ; subtract 0x30 to get a decimal number number1: CMP.B #0x0030,0x0000(ip) ; >= '0' Is the next digit a number JLO endNumber ; break CMP.B #0x003a,0x0000(ip) ; <= '9' JHS endNumber ; break times_10: ; This multipies R12 by 10 ADDC.W R12,R12 ; R12 = 2 * R12 MOV.W R12,R13 ; R13 = 2 * R12 ADDC.W R12,R12 ; R12 = 4 * R12 ADDC.W R12,R12 ; R12 = 8 x R12 ADDC.W R13,R12 ; R12 = 10 x R12 MOV.B @ip+,R14 ; Increment the instruction pointer fetching the next digit SUB.W #0x0030,R14 ADD.W R14, R12 ; Add in the next digit JMP number1 ; process the next digit endNumber: MOV.W R12, tos ; Put in tos - the top of stack JMP next ; process the next character ; Character is either a primitive or an alpha - so form CALL address ; Restore R14 to start of RAM buffer ; Get the current character location ; If it's a primitive between 0x20 and 0x3F - point to a look-up table and fetch it's code segment address ; If its an Alpha, or character >0x40 calculate it's code address from (char - 65)x32 ; Character is in R13 so calculate the destination address ; ------------------------------------------------------------------------------------------------------------------- ; next fetches the next ascii character instruction from memory, decodes it into a jump address and executes the code ; found at that code address ; Each executed word jumps back to next ; Numbers are treated differenty - they are enummerated and put onto the stack by the number routine ; Now we need to decode the instructions using a jump table ; Jump table uses 2 bytes per instruction - so 2 x 96 = 192 bytes next: MOV.B @ip+,R12 ; Get the next character from the instruction memory MOV.W R12,R13 ; Copy into R13 - as needed to decode Jump Address SUB.w #0x0020,R13 ; subtract 32 to remove offset of space ADD.w R13,R13 ; double it for word address add.w R13,pc ; jump to table entry tabstart: jmp space ; SP jmp store ; ! jmp dup ; " jmp lit ; # jmp swap ; $ jmp over ; % jmp and ; & jmp drop ; ' jmp left_par ; ( jmp right_par ; ) jmp mult ; * jmp add ; + jmp push ; , jmp sub ; - jmp pop ; . jmp div ; / jmp number ; 0 jmp number ; 1 jmp number ; 2 jmp number ; 3 jmp number ; 4 jmp number ; 5 jmp number ; 6 jmp number ; 7 jmp number ; 8 jmp number ; 9 jmp colon ; : jmp semi ; ; jmp less ; < jmp equal ; = jmp greater ; > jmp query ; ? jmp fetch ; @ jmp alpha ; A jmp alpha ; B jmp alpha ; C jmp alpha ; D jmp alpha ; E jmp alpha ; F jmp alpha ; G jmp alpha ; H jmp alpha ; I jmp alpha ; J jmp alpha ; K jmp alpha ; L jmp alpha ; M jmp alpha ; N jmp alpha ; O jmp alpha ; P jmp alpha ; Q jmp alpha ; R jmp alpha ; S jmp alpha ; T jmp alpha ; U jmp alpha ; V jmp alpha ; W jmp alpha ; X jmp alpha ; Y jmp alpha ; Z jmp square_left ; [ jmp f_slash ; \ ; jmp square_right ; ] jmp xor ; ^ jmp underscore ; _ jmp tick ; ` jmp lower_a ; a jmp lower_b ; b jmp lower_c ; c jmp lower_d ; d jmp lower_e ; e jmp lower_f ; f jmp lower_g ; g jmp lower_h ; h jmp lower_i ; i jmp lower_j ; j jmp lower_k ; k jmp lower_l ; l jmp lower_m ; m jmp lower_n ; n jmp lower_o ; o jmp lower_p ; p jmp lower_q ; q jmp lower_r ; r jmp lower_s ; s jmp lower_t ; t jmp lower_u ; u jmp lower_v ; v jmp lower_w ; w jmp lower_x ; x jmp lower_y ; y jmp lower_z ; z jmp curly_left ; { jmp or ; | jmp curly_right ; } jmp inv ; ~ jmp delete ; del jmp textEval_end ; 0x80 is used as null terminator ;----------------------------------------------------------------------------------------- ; Handle the alpha and lower case chars alpha: SUB.B #0x0041,R12 ; subtract 65 to remove offset of letter A from original character MOV.W R12,R13 ; get it into R13 for multiplying ADD.W R13,R13 ; Double R13 ; multiply by 2 ADD.W R13,R13 ; Double R13 ; multiply by 4 ADD.W R13,R13 ; Double R13 ; multiply by 8 ADD.W R13,R13 ; Double R13 ; multiply by 16 ADD.W R13,R13 ; Double R13 ; multiply by 32 ADD.W #0x220,R13 ; Add (32*R13) to the index pointer R14 MOV.W ip,R15 ; Save the current ip on the return stack R15 ; R13 now contains the jump address for the alpha code MOV.W R13,ip ; instruction pointer JMP next ; process the next character ;----------------------------------------------------------------------------------------- ; Handle the primitive instructions space: pushs ; Move a 2nd number onto the stack $NEXT store: mov.w @stack +, 0(tos) pops $NEXT dup: pushs $NEXT lit: $NEXT swap: mov.w tos, temp0 mov.w @stack, tos mov.w temp0,0( stack) $NEXT over: mov.w tos, temp0 mov.w @stack, tos mov.w temp0,0( stack) $NEXT and: and @stack +, tos $NEXT drop: pops $NEXT left_par: ; code enters here on getting a left parenthesis MOV.W tos,R8 ; save tos to R8 (R8 is the loop counter k) MOV.W ip,R7 ; loop-start = ip the current instruction pointer at start of loop JMP next ; get the next character and execute it right_par: ; code enters here if instruction it's a right parenthesis ; TST.W R8 ; is loop counter zero ; JEQ next ; terminate loop DEC.W R8 ; decrement loop counter R8 JEQ next ; terminate loop MOV.W R7,ip ; set instruction pointer to the start of the loop JMP next ; go around loop again until loop counter = 0 mult: $NEXT add: add @stack +, tos $NEXT push: $NEXT sub: sub @stack +, tos ; jmp NEGAT NEGAT: inv tos inc tos $NEXT pop: jmp printNum ; go to decimal number print $NEXT div: $NEXT semi: ; On encountering a semicolon return program control to the next character in the input buffer MOV.W R15,ip ; restore the ip $NEXT query: $NEXT fetch: mov.w @tos, tos $NEXT square_right: f_slash: square_left: curly_right: curly_left: underscore: ; Print the enclosed text print_start: MOV.B @ip+,R12 ; Get the next character from the instruction memory CMP.B #0x005f,R12 ; is it an underscore jeq print_end CALL #uart_putc ; send it to uart jmp print_start print_end call #crlf ; line feed at end of text string $NEXT tick: ; tick allows access to the loop counter MOV.W R8,tos $NEXT delete: $NEXT or: bis @stack +, tos $NEXT xor: xor @stack +, tos $NEXT inv: inv tos $NEXT less: cmp @stack +, tos jz FALSE jge TRUE jmp FALSE equal: xor @stack +, tos jnz FALSE jmp TRUE greater: cmp @stack +, tos jge FALSE jmp TRUE FALSE: clr tos $NEXT TRUE: mov #0x01, tos $NEXT ;------------------------------------------------------------------------------------------------ ;lower case routines lower_a: $NEXT lower_b: $NEXT lower_c: $NEXT lower_d: $NEXT lower_e: $NEXT lower_f: $NEXT lower_g: $NEXT lower_h: MOV.B #0x0001,&P1OUT ; P1OUT = BIT0 LED1 on $NEXT lower_i: $NEXT lower_j: $NEXT lower_k: ; k allows access to the loop counter variable stored in R8 MOV.W R8,tos $NEXT lower_l: MOV.B #0x0000,&P1OUT ; P1OUT = BIT0 LED1 off $NEXT lower_m: ; millisecond delay MOV.W tos,R10 mS_loop: mov.w #5232,R9 ; 5232 gives 1mS at 16MHz uS3_loop: DEC.W R9 JNE uS3_loop DEC.W R10 JNE mS_loop $NEXT lower_n: $NEXT lower_o: $NEXT lower_p: JMP printNum $NEXT lower_q: $NEXT lower_r: $NEXT lower_s: $NEXT lower_t: $NEXT lower_u: ; 3 microsecond deelay MOV.W tos,R10 uS_loop: DEC.W R10 JNE uS_loop $NEXT lower_v: $NEXT lower_w: $NEXT lower_x: $NEXT lower_y: $NEXT lower_z: $NEXT ;------------------------------------------------------------------------------------------------ ; User Routines ;------------------------------------------------------------------------------------------------- printNum: ; Take the 16 bit value in R4 stack register and print to terminal as an integer ; do by repeated subtraction of powers of 10 ; Uses R10,11,12,13 ;------------------------------------------------------------------------------------------------- MOV.W #10000,R10 ; R10 used as the decimation register ; CLR.W R12 ; use R12 as a counter CLR.W R11 ; Use R11 as scratch CLR.W R13 MOV.W tos,R12 ; copy the top of stack into R12 CLRC ; clear the carry sub10K: SUB.W R10,R12 JLO end10K add10K: ADD.B #1,R11 ; increments the digit count add_zero: ADD.W R10,R13 ; R13 increases by the decimal value each time JMP sub10K end10K: ADD.B #0x30,R11 ; make it a number MOV.W R11,R12 CALL #uart_putc ; output character SUB.W R13,tos ; Decrement the stack count by n x 10 CLR.W R11 ; Use R11 as scratch CLR.W R13 MOV.W tos,R12 decimate: CMP.W #10000,R10 JEQ use1K CMP.W #1000,R10 JEQ use100 CMP.W #100,R10 JEQ use10 CMP.W #10,R10 JEQ use1 newline: MOV.W #0x0A, R12 CALL #uart_putc ; output CR MOV.W #0x0D, R12 CALL #uart_putc ; output LF JMP next use1K: MOV.W #1000,R10 JMP sub10K use100: MOV.W #100,R10 JMP sub10K use10: MOV.W #10,R10 JMP sub10K use1: MOV.W #1,R10 JMP sub10K ;------------------------------------------------------------------------------------------------- ;------------------------------------------------------------------------------------------------------------------- ; Uses R12 to send receive chars via the UART at 115200 baud. uart_getc: BIT.B #1,&IFG2 ; while (!(IFG2&UCA0RXIFG)) // USCI_A0 RX buffer ready? JEQ (uart_getc) MOV.B &UCA0RXBUF,R12 ; return UCA0RXBUF; RET uart_putc: BIT.B #2,&IFG2 ; while (!(IFG2&UCA0TXIFG)) // USCI_A0 TX buffer ready? JEQ (uart_putc) MOV.B R12,&UCA0TXBUF ; UCA0TXBUF = c; // TX RET crlf: MOV.W #0x0A, R12 CALL #uart_putc ; output CR MOV.W #0x0D, R12 CALL #uart_putc ; output LF RET ;------------------------------------------------------------------------------- ; Main loop here ;------------------------------------------------------------------------------- main: ;------------------------------------------------------------------------------- RESET: ; mov.w #03E0h,SP ; Initialize stackpointer mov #RPP, SP ; set up stack mov #SPP, stack clr tos StopWDT: mov.w #WDTPW|WDTHOLD,&WDTCTL ; Stop watchdog timer WDTCTL = WDTPW + WDTHOLD; Stop WDT OSC_GPIO_init: ; Run the CPU at full 16MHz with 11500baud UART MOV.B &CALBC1_16MHZ,&BCSCTL1 ;BCSCTL1 = CALBC1_16MHZ; Set DCO MOV.B &CALDCO_16MHZ,&DCOCTL ;DCOCTL = CALDCO_16MHZ; SetupP1: bis.b #041h,&P1DIR ;P1.0 P1.6 output as P1.0 and P1.6 are the red+green LEDs MOV.B #0x0000,&P1OUT ;P1OUT = BIT0 + BIT6; // All LEDs off uart_init: MOV.B #0x0006,&P1SEL ;Initialise the UART for 115200 baud MOV.B #0x0006,&P1SEL2 ;P1SEL2 = RXD + TXD; BIS.B #0x0080,&UCA0CTL1 ;UCA0CTL1 |= UCSSEL_2// SMCLK MOV.B #0x008A,&UCA0BR0 ;UCA0BR0 = 138 // 16MHz 115200 CLR.B &UCA0BR1 ;UCA0BR1 = 0 // 16MHz 115200 MOV.B #2,&UCA0MCTL ;UCA0MCTL = UCBRS0 // Modulation UCBRSx = 1 BIC.B #1,&UCA0CTL1 ;UCA0CTL1 &= ~UCSWRST Initialize USCI state machine MOV.W #0x4F, R12 CALL #uart_putc ; output "O" MOV.W #0x4B, R12 CALL #uart_putc ; output "K" ; Print OK ;------------------------------------------------------------------------------- interpreter: call #textRead MOV.W #0x0200,ip ; set ip (instruction pointer) - to start of input buffer in RAM at address 0x0200 jmp next ; get the next instruction textEval_end: jmp interpreter ; loop around ; Stack Pointer definition ;------------------------------------------------------------------------------- .global __STACK_END .sect .stack ;------------------------------------------------------------------------------- ; Interrupt Vectors ;------------------------------------------------------------------------------- .sect ".reset" ; MSP430 RESET Vector .short RESET .end
  2. WillemOuwerkerk

    Hello from The Netherlands

    Hi all on the 43oh forum community, I am Willem Ouwerkerk gving you greetings from the city from 'A bridge to far'. It is nice to get access here after quite a while, because my other email address is on a spam list here I program in Forth and especially noForth: http://home.hccnet.nl/anij/nof/noforth.html There is a website with a lot of documented examples too: http://noforth.bitbucket.org/site/egel%20for%20launchpad.html Hope it is of any help to this community. Kind regards, Willem ouwerkerk.
  3. Since my only 5529LP was confirmed no longer functioning properly and the likely cause is the USB hub module, there have been some thoughts going through my mind to salvage the core 5529 device on the LP for some good use. And this weekend I have decided to give it a try. As the USB host part is confirmed not functioning, the first step is to verify the F5529 is still good. The easiest way is to try program it and check if it can run new program. With a good F5529 LP (the new replacement board ordered after the old one retired), I removed all the jumpers between the ez-FET and the target device, and then wired the GND, 5V, 3V3, RXD, TXD, SBW RST, and SBW TST from the good ez-FET to the 5529 side of the old LP. This will also power up the old board from the new one as the USB host on the old board is dead and no longer powering it. Soon after an example Energia sketch of SerialCallResponseASCII is uploaded through the new, good board, the good news is displayed on the Serial console confirming the 5529 device is still working flawlessly. At this point, I came into realization that this board can no longer be a handy development board as it once was but only good for deployment, possibly permanently, to some project because I have to rely on that good LP every time for programming. But wait, I recall recently from the forum there are some posts mentioning Forth interpreter for MSP430, one of which by monsonite with comprehensive information on various Forth offerings. However, a common requirement for Forth is serial communication for the console that my old LP is no longer capable to provide with a dead USB hub. Even though I don't have serial to usb converter to bypass the on-board hub for direct serial connection, I remember there is an old Arduino Pro Mini laying around without much used. Combining these two, I could probably build a utility development board that provide ad hoc programming capability (in Forth) on the 5529LP provide the console access required by Forth on the 5529LP via the Arduino Pro Mini (forward the serial communication from the Arduino UART to the 5529LP TX/RX) power the 5529LP via the 5V and 3V3 pin from the Arduino Pro Mini All in all, the goal is to take the Arduino Pro Mini as the controller or programmer of the 5529LP that is programmed to run Forth only. I picked the Mecrisp as it provided out of the box support for the 5529LP and pre-compiled hex file. So the build begin by first flashing the Forth hex file to the 5529LP. Again it required a good 5529LP and I used the latest MSPFlasher for the job. The following is the command line (for Windows). MSP430Flasher.exe -w "forth-mecrisp-5529.hex" -v -g -z [VCC] For a more decent looking of this utility development board, the Pro Mini is mounted to a medium sized breadboard on one end, and with four metal pins (pulled from left over connectors), the 5529LP is somehow "mounted" to the other end. This is enough for some structural support for the 5529LP Now for the Arduino side. Since there is only one set of UART on the Pro Mini, the program on it make use of the SoftSerial library that will emulate another serial port by two digital pins to relay the serial messages from the real UART to the 5529LP. Finally the moment of truth, the serial console to the Arduino is opened for a test. Apart from the line feed being weird, the expression run (1 2 + .<cr>) is successful, so is the programming of the blinky program Moving forward, the Arduino can be programmed in such a way that not only merely relaying serial message, but parse special commands to initiate specific Forth programming to the 5529LP (the Forth programs themselves stored as program in the Arduino). Hopefully this will make the whole package more versatile and practical.
×