Popular Content

Showing most liked content since 05/22/2017 in all areas

  1. 4 likes
    I went to Sears yesterday to get my new lawn mower and I got a free gift, Kenmore Alfie Voice-Controlled Intelligent Shopper. The regular price of Alfie is $49, but they are now on sale for $25. However, if you are SYW member and you spend more than $25, you get one for free (expires 7/1/17!) BTW, I also found Alfie for $7.95 on Amazon (with free Prime shipping, even cheaper from other vendors.) What's the big deal about Alfie? Crack one open and you will find the following: CC3200R1 Single-Chip Wireless MCU (with W25Q32JV (32M-bit) serial Flash memory from Winbond and a chip antenna) TLV320AIC3100 Low-Power Audio Codec With Audio Processing and Mono Class-D Amplifier 3.7V 500mAh LiPo battery 12 WS2812B LEDs Other useful things are microphone, large speaker, 2 LEDs, 2 switches, and USB port In other words, IoT experimenter's treasure chest! Can't wait to hack that thing (there's what appears to be programming header on the board.)
  2. 4 likes
    Now here's a set of fancy booster packs! It's a fully integrated automotive radar. http://www.ti.com/lsds/ti/sensing-products/mmwave-sensors/awr/awr-tools-software.page#tools Those rectangles on the right with wiggly traces to the IC are the radar antenna. RF magic! The "CAUTION HOT SURFACE" warning label also promises excitement. Too bad they will cost $299 according to the press release. Posting in the ARM sub-forum as the radar IC features an R4F ARM core. Though the booster packs probably work with beefier MSP430 LaunchPads too. Edit: Here's the mmWave landing page. The AWR also has the non-automotive sibling IWR, including similar booster packs. http://www.ti.com/lsds/ti/sensing-products/mmwave-sensors/mmwave-overview.page
  3. 4 likes
    Came across this while browsing. MSP430 Analog Gauge Clock
  4. 3 likes
    Receiver Prototype Working After some stop and start I am back on this project and making progress. Here is the latest iteration: The wearable IR receiver and WS2812 controller at bottom runs off of a single 2032 battery. With only one LED lit at a time it is capable of easily running for an hour since current is down in the 10-15 mA range. It also transmits and receives with high reliability at 10 meters with two IR LEDs as shown. The transmitter is battery driven at the moment. I have a large number of IR LEDs on order so as to build a transmitter with a larger array of LEDs. It uses 2400 Baud UART for transmission. The transmitter code was written with CCS and is done in software with two timers. One timer maintains 2400 baud. To transmit a 1 bit the second timer is turned on and outputs a 38 KHz square wave over the IR LEDs until time for the next bit. For a 0 bit nothing is transmitted. The LEDs are rated for 100 mA each continuous but are being driven here at about 70 mA each with a NPN transistor hidden behind the jumper wires on the breadboard. On the receiver side the IR receiver turns the transmission into input that can be directly input into the UART peripheral on the MSP430G2553. A single byte is used to select the color and display mode of the WS2812 LEDs. The driver for the WS2812s uses the SPI method which I have posted elsewhere. There are some areas for improvement in the receiver PCB which I will incorporate in the next board spin but everything is working. A feature of this approach is that the receiver uses Energia with no tricks and even works on an Arduino Uno without modification other than pin changes. For the transmitter, I am still thinking about how best to implement. One approach would be to continue using a microcontroller such as the MSP430F5529 I am currently using with a keypad and display. Something like this mock-up: Alternatively, I could use something like a Raspberry Pi 3 and use Python to give Bluetooth LE access control over a phone.
  5. 2 likes
    First off, welcome to the forum. A couple of ideas come to mind. The first is that you might want to consider controlling the power to the SD card with a free I/O line and a transistor, only powering it up when you need to write to it. The other idea is to store multiple samples in an array (which should survive going into low power mode and back) and write them to the SD card every hour or more. How many samples to store between writes to the SD card would depend on your confidence that you wouldn't lose power or have a reset condition before having a chance to move them to the card.
  6. 2 likes
    I know this is an older post, but it struck a "pet peeve" nerve. I recently went back to school, I had to learn how to use a calculator because they were not allowed in math class when I was in high school, and was surprised at how often people did not bother to even copy things by hand. When we had peer reviews, or otherwise were able to see each other's code, there was always at least one that was a direct c&p of code that did not even work. Had they copied it by hand, and read it in the process, they would have realized that it did not work. Keep in mind, these are simple school problems that have numerous examples on the internet. I have also seen, many times, where the code seems to have been intentionally written wrong, but someone who actually reads it will be able to fix it easily. When I have problems with code, I am often reluctant to ask questions because I do not want someone to just write it for me. I appreciate answers that simply point me in the right direction. On the other hand, with electronics, I tend to look for a more definitive answer. This is usually something like what size cap should I use, because I am trying to copy something that did not give the value, and I am just trying to get it to work, without ordering "one of each" or frying something. Personally, I appreciate everyone who tries to help me.
  7. 2 likes
    @makiyang614 Glad to see your level of excitement. I've used the F2013 extensively, and have also worked with the FG4618. You won't find launchpads version for either of these devices, though you can find the eZ430-F2013, which preceeded the launchpads as an inexpensive introductory development tool. The FG4618 was/is intended to be a one-stop LCD driver chip, with multiple peripherals to allow interaction with the "real world." The F2013 has significantly less capability, but it does feature a 16-bit SigmaDelta ADC (you'll find some inexpensive IR motion detector projects built around this chip). I agree with @Rei Vilo regarding the F5529 launchpad - it's very versatile, and includes a built-in USB capability. I suspect the first major difference you'll see between the Arduino and the '430 is the interrupt-driven approach used to attain very low power requirements. (Oh, almost forgot, the '430 is NOT 5V tolerant... - 3.3V) Traditional programming approach is the devices are normally "asleep" and wake in response to either timer events or external inputs. You'll find many, many code examples where main() code appears to stop at a low power mode entry point with no further main->executable code, nor a return statement. Others will feature a while(true) "forever" loop, but which also halts at a low power mode statement, and only executes subsequent statement in response to an interrupt event. FWIW, the LP line is inexpensive, very capable, and Energia allows an entry point for programming. As you progress you may find yourself moving to more traditional, programmer-oriented tools such as the IAR, CCS and GCC compilers, assemblers, and related linkers. This is a good forum is a good place to seek answers, as is https://e2e.ti.com/ Have fun! Bob
  8. 2 likes
    Did you read the limitations of the Petit FS? ... Petit FatFs Limitations: Petitfs specifically uses as little flash and stack as possible. This, however, comes at the expense of some functionality. Files are not able be created or increased in size, and only one file can be accessed at a time. ... So if you create a zero length file (open a file in a text editor and save it without adding anything to it), it isn't going to do what you want. If you search the forum or google this is expressed in thousands of posts. The comment above comes from this document: http://www.atmel.com/Images/Atmel-42776-Using-the-Petit-FAT-File-System-Module-with-AVR_ApplicationNote_AVR42776.pdf http://elm-chan.org/fsw/ff/pf/write.html ... Description The write function has some restrictions listed below: Cannot create file. Only existing file can be written. Cannot expand file size. Cannot update time stamp of the file. Write operation can start/stop on the sector boundary only. Read-only attribute of the file cannot block write operation. File write operation must be done in following sequence. pf_lseek(ofs); read/write pointer must be moved to sector bundary prior to initiate the write operation, or it will be rounded-down to the sector boundary at first write operation. pf_write(buff, btw, &bw); Initiate write operation. Write first data to the file. pf_write(buff, btw, &bw); Write next data. Any other file function cannot be used while a write operation is in progress. pf_write(0, 0, &bw); Finalize the current write operation. If read/write pointer is not on the sector boundary, left bytes in the sector will be filled with zero. The read/write pointer in the file system object advances in number of bytes written. After the function succeeded, *bw should be checked to detect end of file. In case of *bw is less than btw, it means the read/write pointer reached end of file during the write operation. Once a write operation is initiated, it must be finalized properly, or the written data can be lost.
  9. 2 likes
    MISO should be connected with MISO, MOSI with MOSI, not crossed. MISO means Master In Slave Out, and MOSI means Master Out Slave In. Master & slave are always the same, no crossing is needed.
  10. 2 likes
    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
  11. 2 likes
    Hi, for the projects I need to access from multiple places (and needing some privacy) I've configured a small git server and put gogit/gogs *) on top of it. Because the core is git, I can use it from command line and gogit gives me the possibility to use it in a way similar to github and (the reason I use it) allows me to define "virtual users" - I can allow other people to access the private repositories without sharing my (main) credentials. I have luck with a good hosting offering all needed tools. Cheers, Liviu *) I suppose any "interface" will do the same, I've used gogs because I found a tutorial (in German) about the installation on my server.
  12. 2 likes
    It was a bit of a mind bender for me at first but then I just read the I2C spec and it did not specify that the communication *had* to be at 100kHz. The way I choose to understand things is that the I2C slave device has a communication state machine inside of it. All I have to do is put in one bit and turn the crank once. Then repeat. Over and over. Then the slave device will just do its job merrily.
  13. 1 like
    I am using micro SD card to log reading from four force sensors connected to the microcontroller (MSP430G2553). Controller logs reading to the SD card every 15 minutes and goes to sleep. I am using 1000 mAh battery, which is lasting over a week. Is it possible to reduce the power consumption as to make it last over a month. (#) Even if the microcontroller is sleeping for 15 minute, SD card is continuously consuming power. (#) It takes couple of mA to write. Help with any suggestion to reduce to power consumption drastically. Schematic and code (attached). Code_Datalogger_msp430g2553.txt
  14. 1 like
    That's a nice mock-up. Took me a while to realize that the keypad and display just sit on top of a tin box.
  15. 1 like
    I am not sure what you are trying to ask, or what processor you are working with, but it appears that you don't have a good understanding of fixed point representations The value from the DS18B20 is a signed (2's complement) fixed point, 16 bit value. Cutting off the last four bits using a right shift that shifts zeros in to the left removes the sign. The shift can be done so as to preserve the sign by using the appropriate arithmetic right shift (arithmetic right shift RRA in assembler on the MSP430, or right shift operator in C on CSS). This will give an integer in 16 bit 2's complement. The rounding will ALWAYS be the floor (truncate to smaller value; round down) operation. To get round towards zero, you can use a condition such as (in C): if (t<0) t+=16; t=t>>4; or t=t>>4; if (t<0) t++; to do the job. If you want 'conventional' (grammar school) rounding (round down for the fraction <1/2, up for fractions >=1/2), then t+=8; t=t>>4; would be the cannonical way. If you want symmetrical rounding such that if the fraction of |t| < 1/2 is toward zero, and if hte fraction of |t|>=1/2, round away from zero, then, again, the easiest way is a condition: if (t<0) {t+=7;} else {t+=8;} Really, you need to know the desired behaviour. There are a lot of reasons why the default action is desirable (always round to negative infinity), in particular because then each count represents a range of one degree, rather than the range for zero being two degrees.
  16. 1 like
    LE I'm almost "thrilled" by the amount of details people asking for help is giving. We all have crystal bowls at home.
  17. 1 like
    Hi, it seems, the Arduino's SPI library has an SPISettings class and Energia's SPI library not. Some older version of the mfr522 library (version=1.1.8, for example) don't use the SPISettings class and compiles for TivaC. class SPISettings { public: SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { if (__builtin_constant_p(clock)) { init_AlwaysInline(clock, bitOrder, dataMode); } else { init_MightInline(clock, bitOrder, dataMode); } } SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); } private: void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { init_AlwaysInline(clock, bitOrder, dataMode); } void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) { // Clock settings are defined as follows. Note that this shows SPI2X ...
  18. 1 like
    MSP430F51x2 are 5V tolerant. FET-430UIF is stone age device, extremely slow, with FET same as on G2 LP. TI is working right now on hardware revision of MSP-FET, so if you want to buy one, be sure that this one is with new hardware revision. For low cost entry to MSP430 world, my advice is always for MSP430F5529 LP with updatable and open software / hardware design. Never for old and slow, closed and not updatable G2 LP (or any other board version with integrated this old FET).
  19. 1 like
    Some references of the extended MSP430 family are available on affordable boards (typically USD10~30), called LaunchPad. See http://www.ti.com/lsds/ti/tools-software/launchpads/launchpads.page and http://www.ti.com/lsds/ti/tools-software/launchpads/launchpads.page#low_power for MSP430-based LaunchPad boards. I like the MSP-EXP430F5529LP with 128 kB Flash and 10 kB RAM, priced at USD13. Good news, most of the LaunchPads (including the MSP430F5529) are supported by Energia, an Arduino-compatible IDE with the same framework. Learn more at and download from http://energia.nu.
  20. 1 like
    Have you read the answer @Rickta59 gave you on your (other) thread? I mean the part:
  21. 1 like
  22. 1 like
    The problem with old MacBooks is whether they can handle the last release of macOS, numbered 10.12.5 and named Sierra. Apple modifies the USB quite often, resulting with bugs coming and going.
  23. 1 like
    Have you tried to write something in the file in Linux? In the movie you are just showing us the file is empty.
  24. 1 like
    Yes, it will be in the next release. Unfortunately this is taking a lot longer than anticipated due to the fact that we are making it compatible with both the new (msp430-elf-gcc and the old msp430-gcc).
  25. 1 like
    Have you read the first post in the topic? Is your card maybe hard locked? May you in Linux/Windows delete the file/create a new file on the card?
  26. 1 like
    Yes, I've seen, I've read the wrong documentation. Should work without mode qualifiers.
  27. 1 like
    LE I've read the examples coming with PetitFS and they aren't using the mode specifier neither. No idea why it doesn't work for you.
  28. 1 like
    Hi, nice to see that making the connection properly bring it to work. Carefully reading the replies you receive may even accelerate the success. For your last problem - writing without writing - maybe you should open the file in the correct mode. In this case the mode should be FA_WRITE. Try to replace with rc = FatFs.open("T_WRITE.TXT", FA_WRITE); or rc = FatFs.open("T_WRITE.TXT", FA_WRITE | FA_READ); for read & write access.
  29. 1 like
    Have you tried with the last version of the library, mentioned on the https://hmario.home.xs4all.nl/arduino/LiquidCrystal_I2C/?
  30. 1 like
    Sorry for beeing a bit terse again, OR'ing NVIC_APINT_VECTKEY with the bits you want to set is the trick to make it work since NVIC_APINT_VECTKEY is the "password" or "guard" bits to allow the other bits to be changed. My point was that some other registers are similarily protected so it is something to be generally aware of. Read the documentation carefully is my motto - and do not expect details like this to be found in the context where you might think it should be mentioned.
  31. 1 like
    TI Store Geek Week 2017! 10% off on selected items and free shipping! http://app.marketing.ti.com/e/es.aspx?s=441910513&e=123094&elq=3195d88a3376467490cb0607fdefe72c Regards Amaze1
  32. 1 like
    As long you receive "can't open port" messages, I see two possibilities: - wrong port - bad hardware.
  33. 1 like
  34. 1 like
    If they can be setup as a point-to-point link then there shouldn't be any problem setting up a data link between end points. Carefully selected and aligned Yagi antennas ought to overcome foliage loss.
  35. 1 like
    Whoops. I forgot that detail. I must be getting old. So this is I2C over CANBUS then. Sorta. I have never worked with CANBUS. Can it cover that distance at that speed?
  36. 1 like
    My gut instincts tell me that your cable will have to be 50 ohm coaxial to get 100kHz over 300 meters. Only super slow speeds can go long distances i.e.: RS-485. I would be inclined to use an msp430 on your cape to be the I2C interface master. You could talk to it with the BBB as if it was a slave serial device. That would isolate the BBB from the slow speed pathway. The BBB could just poll the MSP430 for any new data.
  37. 1 like
    Just in case I didn't make it clear, the speed of the simulated I2C-over-1Wire ends up being about 15kHz. It's not fast but it does work over long lengths of cable and that is pretty darn cool.
  38. 1 like
    In the post I've linked above the solution was to replace the twi.c & twi_sw.c with new ones, found in the e2e forum. Have you also replaced them?
  39. 1 like
    As @@chicken mentioned make sure you have a ground connection between the 2 LaunchPads. Could you also post the 2 Sketch so that we can have a look at that as well?
  40. 1 like
    Hi @@brelliott18, There are some known problems with i2c on 2553 Launchpads, mentioned in various posts over this forum. One of them is mentioned in http://forum.43oh.com/topic/2641-i2c-lcd/page-2#entry75927; in this post is also a link to a solution http://e2e.ti.com/support/development_tools/code_composer_studio/f/81/p/529036/1924562#1924562 Have you already seen this posts? Have you tried the solutions presented in them? Regards, Liviu
  41. 1 like
    Edit 09.12.2016: I added Arial_16x24.h and Arial_24x40 (really a 24x36, but I had to keep a multiple of 8), digits only, created with GLCD Font Creator (I had to edit the result slightly manually). See images below. So I can confirm that adding any further fonts created with GLCD Font Creator works (I run it on Linux on wine BTW) and is only limited by how much fits into the SSD1306_OLED_5x8_11x16_16x24_24x36_fonts.zip
  42. 1 like
    Hi, Glad to hear it's working for you. Since the changed library seems to work (I've also updated the example and replaced the library in the post above), maybe Calin or a moderator can update the download on the first post of the topic. Liviu
  43. 1 like
    Try to locate (I suppose even Macs have a search program ) the PFatFs directory and delete it. Unzip and put the content of the changed library in place of it.
  44. 1 like
    I've changed the DIR with FSDIR in the PFatFs library; I'm attaching the changed library here. Just replace the one on your PC with the attached one. On my PC I've put it in ../energia-1.6.10E18/libraries/PFatFs/ You should probably change your sketches too. Regards, Liviu EDIT: updated the library (fixed the examples too). PFatFs.zip
  45. 1 like
    Hi, fount it. It seems, the DIR definition in energia-1.6.10E18/hardware/tools/msp430/msp430/include/msp430f5529.h /* USBCTL Control Bits */ #define DIR (0x0001) /* USB - Data Response Bit */ conflicts with the DIR in the energia-1.6.10E18/libraries/PFatFs/utility/pff.h: /* Directory object structure */ typedef struct { WORD index; /* Current read/write index number */ BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ CLUST sclust; /* Table start cluster (0:Static table) */ CLUST clust; /* Current cluster */ DWORD sect; /* Current sector */ } DIR; No idea where it will be better to change to remove the conflict, but probably in the PFatFs. Regards, Liviu
  46. 1 like
    Hi, it seems the file energia-1.6.10E18/hardware/tools/msp430/msp430/include/msp430f5529.h has a problem in the USB definition part. I don't know exactly what for a problem, but I was able to compile the above mentioned sketch after commenting out the USB part in msp430f5529.h (between rows ~3430 and ~4227). Maybe it helps you. Regards, Liviu
  47. 1 like
    Hi, which board are you using? I've tested now the "PFatFsFileTest" (library) example and it compiles for the launchpads installed by default by Energia (+TivaC), except MSP-EXP430G5529LP. Regards, Liviu
  48. 1 like
    Hi Spineless, I think you should install it as a library. Liviu
  49. 1 like
    Not sure what you are trying to do.. but there is an example here: http://elm-chan.org/fsw/ff/pf/lseek.html
  50. 1 like
    Hi, I'm trying to use an SDCard as a datalogger. I can write to the card using the sample. I want to append the data and for that I'm using a 4 byte header in the file. It seems that when I want to update the header after a logging session all the data is missing from the file as well. What am I doing wrong: ... rc = FatFs.open("T_WRITE.TXT"); if (rc) die(rc); char buffer[4]; rc = FatFs.read(buffer, sizeof(buffer), &br); /* Read a chunk of file */ if (rc || !br) die(rc); /* Error or end of file */ for (uint16_t i = 0; i < br; i++){ fileIndex.myByte[i]=buffer[i]; } rc = FatFs.lseek(fileIndex.myLong+4); if (rc) die(rc); for (uint16_t i=0;i<20;i++) { // simulate write of data int val[4]; val[0]=random(2000); val[1]=random(2000); val[2]=random(2000); val[3]=random(2000); String reading; reading+=val[0]; reading+=" "; reading+=val[1]; reading+=" "; reading+=val[2]; reading+=" "; reading+=val[3]; reading+="\n\t"; char buf[reading.length()]; reading.toCharArray(buf, reading.length()); rc = FatFs.write(buf, reading.length(), &bw); // update index value fileIndex.myLong+=reading.length(); if (rc) break; } if (rc) die(rc); rc = FatFs.write(0, 0, &bw); //Finalize write if (rc) die(rc); //update fileindex rc=FatFs.lseek(0); rc = FatFs.write(fileIndex.myByte,4,&bw); if (rc) die(rc); rc = FatFs.write(0, 0, &bw); //Finalize write if (rc) die(rc); rc=FatFs.close(); if (rc) die(rc); Serial.println(); Serial.print("Test completed."); regards Bob