-
Content Count
141 -
Joined
-
Last visited
-
Days Won
2
Reputation Activity
-
rampadc got a reaction from LariSan in New MSP430F5529 USB Launchpad Released
Did you guys notice TI's selling their new MSP430F5529 USB Launchpad board? I found an old announcement back in 2012 on 43oh main page that TI's working on it but haven't seen any on it being sold. I just found out today and apparently it's sold out. :-(
TI also changed the descriptor tool by making the interface a bit prettier but they removed the definition USB_MCLK_FREQ which will break all the code in their last USB API so now there's a new USB API 4.0 that requires CCS 5.5 to be installed, though there are workarounds so it will work with existing CCS.
-
rampadc got a reaction from jazz in New MSP430F5529 USB Launchpad Released
Did you guys notice TI's selling their new MSP430F5529 USB Launchpad board? I found an old announcement back in 2012 on 43oh main page that TI's working on it but haven't seen any on it being sold. I just found out today and apparently it's sold out. :-(
TI also changed the descriptor tool by making the interface a bit prettier but they removed the definition USB_MCLK_FREQ which will break all the code in their last USB API so now there's a new USB API 4.0 that requires CCS 5.5 to be installed, though there are workarounds so it will work with existing CCS.
-
rampadc got a reaction from Automate in New MSP430F5529 USB Launchpad Released
Did you guys notice TI's selling their new MSP430F5529 USB Launchpad board? I found an old announcement back in 2012 on 43oh main page that TI's working on it but haven't seen any on it being sold. I just found out today and apparently it's sold out. :-(
TI also changed the descriptor tool by making the interface a bit prettier but they removed the definition USB_MCLK_FREQ which will break all the code in their last USB API so now there's a new USB API 4.0 that requires CCS 5.5 to be installed, though there are workarounds so it will work with existing CCS.
-
rampadc reacted to semicolo in PS2 mouse timing debugging
SPI is a synchronous serial protocol.
But I just had a quick glance at the datasheets, you don't get the start and stop bits in synchronous mode, so you can't use the hardware as is (you'd have to generate these bits in software, not really useful).
It's kinda strange in fact that PS2 needs these bits, you must have them with asynchronous serial but they're useless if you have a clock.
Well, sorry for giving you false hope.
-
rampadc reacted to pabigot in [Q] Using Launchpad to use UART with 5xx MCU
Review your UCS configuration. 16MHz isn't supported by the F5510 at the default RSEL (2) in UCSCTL1. See the data sheet for RSEL ranges, and look for examples of how to configure for a particular speed in the MCU sample code jazz referenced and elsewhere. Use the secondary feature of P2.2 to bring SMCLK to a GPIO and verify your configuration with a frequency meter (e.g. a DMM or scope) before relying on the clock configuration for UART baud rate sourcing: if SMCLK isn't truly at 8MHz (or if your UART baud rate configuration isn't right) you'll never see any characters even if everything else is right.
BTW: Your code would be much more clear if you simply assigned values to peripheral registers like the UCS ones rather than assuming that certain bits in them are set or unset and using bitwise or to set some of them.
-
rampadc reacted to jazz in [Q] Using Launchpad to use UART with 5xx MCU
Problem is that you have 2 sides comunication, and they are not configured on same baud rate. Baud rate on MSP430 is depending on UART clock (UCSSEL -> BRCLK), so if the BRCLK or/and baud rate is changed, USCI must be reconfigured again.
You don't need to use assembly. It can be done in C with simple UART loging. Depending what you want to debbug, 9600 bps can be slow.
-
rampadc reacted to jsolarski in Sample code for Rob's f5510 usb dev board
Printf from the forums,
http://forum.43oh.com/topic/396-getting-printf-working/page__hl__printf
Main Clock runs at 8Mhz, in the end it will go into a while loop, printing "hello world" over and over again
Tested and works
//****************************************************************************** //****************************************************************************** #include <msp430f5510.h> #include "cust_def.h" #include "stdarg.h" void Uart_Init1(void); //***************************************************************************** /* Printf functions */ void Clk_Init(void); void putchar(unsigned char byte); void linesUp(unsigned char lines); int prints(char *string, unsigned char width, unsigned char pad); int printi(long int i, unsigned char b, unsigned char sg, unsigned char width, unsigned char pad, unsigned char letbase); int printf(char *format, ...); //***************************************************************************** /* printf defines */ #define PAD_RIGHT 0x01 #define PAD_ZERO 0x02 #define PRINT_BUF_LEN 12 //***************************************************************************** char *s; char c; int i; unsigned u; long int l; long unsigned n; unsigned x; void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT Clk_Init(); P4SEL = BIT5+BIT4; Uart_Init1(); __bis_SR_register( GIE); // Enter LPM3 printf("%s", "\r\n*** printf() test ***\r\n"); putchar(c); s = "test"; c = 'X'; i = -12345; u = 12345; l = -1234567890; n = 1234567890; x = 0xABCD; printf("String %s\r\n", s); __delay_cycles(250000); printf("Char %c\r\n", c); __delay_cycles(250000); printf("Integer %i\r\n", i); __delay_cycles(250000); printf("Unsigned %u\r\n", u); __delay_cycles(250000); printf("Long %l\r\n", l); __delay_cycles(250000); printf("uNsigned loNg %n\r\n", n); __delay_cycles(250000); printf("heX %x\r\n", x); __delay_cycles(250000); printf("multiple args %s %c %i %u %l %n %x\r\n", s, c, i, u, l, n, x); __delay_cycles(250000); printf("\r\n*** Done ***\r\n"); __delay_cycles(250000); while(1) { printf(" hello world ","\n"); __delay_cycles(250000); } __bis_SR_register(LPM0_bits + GIE); // Enter LPM3 __no_operation(); // For debugger } //********************************************************************************* void Clk_Init(void) { UCSCTL3 = SELREF_2; // Set DCO FLL reference = REFO UCSCTL4 |= SELA_2; // Set ACLK = REFO UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx // Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation UCSCTL2 |= 249; // Set DCO Multiplier for 8MHz // (N + 1) * FLLRef = Fdco // (249 + 1) * 32768 = 8MHz __bic_SR_register(SCG0); // Enable the FLL control loop // Worst-case settling time for the DCO when the DCO range bits have been // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx // UG for optimization. // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle __delay_cycles(250000); } //********************************************************************************* //init uart 1 void Uart_Init1(void) { UCA1CTL1 |= UCSWRST; // **Put state machine in reset** UCA1CTL1 |= UCSSEL_2; // SMCLK UCA1BR0 = 65; // 8MHz 9600 (see User's Guide) UCA1BR1 = 3; // 8MHz 9600 UCA1MCTL = UCBRS_2 + UCBRF_0; // Modln UCBRSx=0, UCBRFx=0, + UCOS16 // over sampling UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine** //UCA1IE |= UCRXIE; // Enable USCI_A0 RX interrupt } //********************************************************************************* //printf source from http://forum.43oh.com/topic/396-getting-printf-working/page__hl__printf /*------------------------------------------------------------------- DESCRIPTION: Send one char in TX buffer, if it is not busy. Wait until not busy. INPUTS: One char. OUTPUTS: Send all the char in TX buffer. RETURNS: None. ---------------------------------------------------------------------*/ // Modify this routine so that it points to YOUR UART (zeke) void putchar(unsigned char byte) { while (!(UCA1IFG&UCTXIFG)); //while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA1TXBUF = byte; // Load Tx register that clear UCA0TXIFG } /*------------------------------------------------------------------- DESCRIPTION: Move numbers of lines up in the HyperTerminal. INPUTS: None. OUTPUTS: Line up to TX buffer. RETURNS: None. ---------------------------------------------------------------------*/ void linesUp(unsigned char lines) { unsigned char i; for (i = 0; i < lines; ++i) { putchar(0x1b); putchar(0x5b); putchar(0x41); } } /*------------------------------------------------------------------- DESCRIPTION: Send out charater strings with defined width, justification and padding. Width = 0 or width < string length means unlimited width. Normal padding is space and left justification, but it can pad '0' or pad to the right side, depending on pad value. pad justification padding char bxxxxxx00 left ' ' bxxxxxx1x right ' ' or '0' bxxxxxxx1 left or right '0' INPUTS: Valid string and special charater in form of "\n" for example refered by pointer *string. Output field width. Justification and padding flag pad. OUTPUTS: Sent formated string to com port output. RETURNS: Total of chars sent. ---------------------------------------------------------------------*/ int prints(char *string, unsigned char width, unsigned char pad) { int pc = 0; unsigned char padchar = ' '; // The pading char is space normally if (width > 0) // If output width is defined { unsigned char len = 0; char *ptr; for (ptr = string; *ptr; ++ptr) ++len; // Calculate string length and put it in len if (len >= width) width = 0; // If string is longer than width, then width is not applicable define as zero else width -= len; // Else redefine width as padding spaces if (pad & PAD_ZERO) padchar = '0'; // If padding char is zero, then get padchar as zero ready instead of original space } if (!(pad & PAD_RIGHT)) // If not right padding - left justification { for (; width > 0; --width) // If ther is padding width. Output padding char as '0' or ' '. { putchar (padchar); ++pc; } } for (; *string ; ++string) // Output the full string { putchar (*string); ++pc; } for (; width > 0; --width) { // Write padding char to the right if normal left justification putchar (padchar); ++pc; } return pc; // Return the output char number } /*------------------------------------------------------------------- * DESCRIPTION: Print 32 bit signed interger in dec or hex. In specific * width, padding and justification using prints(). Use 12 byte buffer * which is enough for 32 bit int. * INPUTS: Up to 32 byte signed interger i. Counting base: 10 or 16. * Sign flag sg. Output string width. padding and justification flag. * Leter base for number conversion. * OUTPUTS: Sent formated interger as string to com port output. * RETURNS: Total of chars sent. ---------------------------------------------------------------------*/ int printi(long int i, unsigned char b, unsigned char sg, unsigned char width, unsigned char pad, unsigned char letbase) { char print_buf[PRINT_BUF_LEN]; // Interger as string array char *s; char neg = 0; unsigned long int t; unsigned long int u = i; int pc = 0; if (i == 0) // If output char is 0, then just output it with padding and width. { print_buf[0] = '0'; print_buf[1] = '\0'; // Always remenber to put string end return prints(print_buf, width, pad); //Print out zero and done. } if (sg && (b == 10) && (i < 0)) // If it is a negative int, then record the '-' and number as positive { neg = 1; u = -i; } s = print_buf + PRINT_BUF_LEN-1; // Point s to the end of the output buffer and put a null there. *s = '\0'; while (u) // Convert the positive int to string with whatever counting base, dec, or hex. { t = u % b; if( t >= 10 ) t += letbase - '0' - 10; *--s = t + '0'; u /= b; } if (neg) { // If it is a negative number if( width && (pad & PAD_ZERO) ) { // If there is width, right justified and pad with zero, output negative sign. putchar ('-'); ++pc; --width; } else *--s = '-'; // Otherwise put the '-' to string buffer. } return pc + prints (s, width, pad); // Output the string buffer and return the output counter. } /*------------------------------------------------------------------- * DESCRIPTION: short form of printf. Print argument strings with mixed * varables (string or interger)inside formated. * INPUTS: Argument string pointer. * OUTPUTS: print out the argument with style using prints() and printi(). * RETURNS: Total of chars sent. * Warning!!! varables and constant numbers even 0, must casted with * (long int)in printf(), if it is going to print out using * format "u", "d", "X" and "x"! Or the complier will assigned * 16-bit for data smaller than 16 bit and the argument pointer * will fetch a wrong 32-bit data and the argument point * increament will be in wrong size. * Limitations: 1) It treats all interger as 32 bit data only. * 2) No floating point data presentation. * 3) Has left/right alignment with 0 padding. * 4) Has format code "s", "d", "X", "x", "u" and "c" only. ---------------------------------------------------------------------*/ int printf(char *format, ...) { int width, pad; int pc = 0; char scr[2]; va_list args; va_start(args, format); for (; *format != 0; ++format) { if (*format == '%') { ++format; width = pad = 0; if (*format == '\0') break; if (*format == '%') goto out; if (*format == '-') { ++format; pad = PAD_RIGHT; } while (*format == '0') { ++format; pad |= PAD_ZERO; } for ( ; *format >= '0' && *format <= '9'; ++format) { width *= 10; width += *format - '0'; } if( *format == 's' ) { char *s = (char *)va_arg( args, int ); pc += prints (s?s:"(null)", width, pad); continue; } if( *format == 'd' ) { pc += printi (va_arg( args, long int ), 10, 1, width, pad, 'a'); continue; } if( *format == 'x' ) { pc += printi (va_arg( args, long int ), 16, 0, width, pad, 'a'); continue; } if( *format == 'X' ) { pc += printi (va_arg( args, long int ), 16, 0, width, pad, 'A'); continue; } if( *format == 'u' ) { pc += printi (va_arg( args, long int ), 10, 0, width, pad, 'a'); continue; } if( *format == 'c' ) { // char are converted to int then pushed on the stack scr[0] = (char)va_arg( args, int ); scr[1] = '\0'; pc += prints (scr, width, pad); continue; } } else { out: putchar(*format); ++pc; } } va_end( args ); return pc; } //#pragma vector=USCI_A1_VECTOR //__interrupt void USCI_A1_ISR(void) //{ //nop(); //}
-
rampadc reacted to roadrunner84 in Passing ports as parameters to functions
I think it is tricky (to be polite):
Assumed is that a pointer is a 16-bit integer Assumed is that writing to the base address (8-bit reference) of PORTJ does indeed do what it's supposed to do Since PJOUT does have a type (either uint8_t or uint16_t probably) the type of the constant reference should be a pointer to that type, not an integer; saying that it is an integer promises that you can write values to it, while it is actually a pointer!
//PORTJ_OUT is defined as being of the type uint16_t, so we can treat it as a uint16_t uint16_t my_var; myvar = 20; PORTJ_OUT = 20; // the compiler won't complain; you may write to a uint16_t. In reality you're trying to write to a constant pointer to PJOUT! Then it is assumed that this pointer does indeed fit in a 16-bit integer, which is not good practice. When using an MSP430 with a CPU peripheral, it does hold. When your MSP430 does have a CPUX it may not work as expected, since pointers are actually 20-bit integers.
Then this 16-bit integer is casted (totally unnecessarily) to a uint8_t*; a pointer to a uint8_t. This cast is a signal that there is a design error; in this case that the type of PORTJ_OUT was defined incorrectly.
Better designs that should work identical are:
void portJPinToHigh(uint8_t pin) { PJOUT |= pin; // why use pointery magic when this function can only write to a single location? } or
uint8_t* const PortJ_Out = &PJOUT; // using a constant instead of a define will enable type checking, plus we use the right type void portJPinToHigh(uint8_t pin) { *PortJ_Out |= pin; } -
rampadc reacted to roadrunner84 in Passing ports as parameters to functions
Typecasting is in many cases a signal that your design is wrong. Is you can see in my examples, I don't do typecasting. Typecasting is useful when you need to "tunnel" a memory pointer from one library to another, with a predefined structure (eg: read a bitmap from flash as a series of bytes, and then interpret them as an array of R,G,B structs). But mostly (and firstly) you should consider why your compiler is complaining about type conflicts.
In C a pointer is just a pointer, the type it points to is just a convenience to help you to not accidentally pass the wrong pointer type to a function. The tricky part is void pointers, any pointer can be assigned a void pointer and vice versa. This means that whenever a void pointer comes into play, any type checking is bypassed.
int a[20]; int* p; void* q; char* r; p = a; // GOOD: let int pointer point to array of int q = p; // TRICKY: discard the pointer type by assigning to void pointer r = q; // BAD: assign a void pointer (that used to point to integers) to a char pointer r = p; // WRONG: type conflict; int* and char* are not compatible types In C++ there are several type cast options, which are intentionally "ugly".
int a; char b = static_cast<char>(a); // take the value of a and try to fit it in b char c = dynamic_cast<char>(a); // same as above, but do run-time verification char d = reinterpret_cast<char>(a); // don't convert anything, just dump the memory over Too bad in the later additions to C++, the same form was used for templates, thus making the ugliness of type casts less visible.
int a = square_root<int>(64); // perform the square_root specialisation to int on the value 64 To come back to your comment: since numbered ports are 8 bit, make sure to use unsigned char or uint8_t and their pointer type everywhere. You might get away with using 16 bit types, but you'd better not try it!
void set_all_to_act_on_rising_edge(unsigned short* p_ies) { *p_ies = 0; } P1IE |= BIT3; // P1.3 is an interrupt line unsigned short* my_ies = (unsigned short*)&P1IES; // BAD: assign P1IES as if it were a 16 bit word pointer set_all_to_act_on_rising_edge(my_ies); //P1.3 never fires Why does this go bad in the last line? The cause is that P1IES is at memory location 0x24, while P1IE is at location 0x25. So when I write an all zero 16-bit integer to 0x24, it will overwrite 0x25 as well, thus clearing P1IE!
These kinds of errors are best avoided by not using casts, since casts almost always are root of bad design.
-
rampadc got a reaction from roadrunner84 in Error #10056 when including headers
The error complains that the symbol is redefined in main.c. I found that if I removed the included header file that was causing the problem from the main.c source file, the error disappear so my guess was that the variable was not defined properly. Reading through C tutorials on scope and linkage, the recommended way to declare and define a global variable is as follows:
For example, if I want to make a new constant integer variable called queues. The variable should be declared in a header file once and only once, and defined in a source file once:
Header1.h
//#include guards extern const int queues; //... Source1.c
#include "Header1.h" //or whichever header the variable was declared in const int queues = 5; //the rest of the source file -
rampadc reacted to RobG in Passing ports as parameters to functions
Try this:
void goHigh(volatile unsigned char * dir, volatile unsigned char * out, unsigned int pin) { *dir |= pin; *out |= pin; } goHigh(&P1DIR, &P1OUT, BIT1); -
rampadc reacted to spirilis in Passing ports as parameters to functions
Pointers are 16 bits no matter what because the MSP430 uses a 16-bit address bus.
But the pointer "type" is instructive to the compiler about what size of data underlies that pointer. In the case of these SFRs (special function registers, like P1DIR or P2OUT) they are only 8-bit wide and any operations you perform on them need to be limited to 8 bit data (else you might inadvertently clobber or set a different SFR adjacent to that one).
Sent from my Galaxy Note II with Tapatalk
-
rampadc reacted to roadrunner84 in Passing ports as parameters to functions
I've done so with C++ objects, but it keeps feeling a little clumsy, since each port is always a little different. For example, P2SEL defaults to 0xC0, while all other ports default to 0x00.
Since numbered ports (P1, P2, etc.) are 8 bits wide (lettered ports are 16 bits wide, like PA, PB, etc.), you could assume P1IN to be a volatile unsigned char. This means that to access the content by reference (required to actually edit it, instead of editing a copy of the value in it) you must take a pointer reference to it.
void toggleBit(unsigned char* pout, const char pin) { *pout ^= pin; } unsigned char* my_port; myport = &P1OUT; toggleBit(my_port, BIT6); // toggle 1.6 toggleBit(&P2OUT, BIT0); // toggle 2.0 -
rampadc reacted to jazz in [Q] USB HID learning resources
Yes, these files are included in project, and you can see them present on compiled file list (for example with IAR)...
...
UsbCdc.c
UsbHid.c
UsbHidReq.c
UsbIsr.c
UsbMscReq.c
UsbMscScsi.c
UsbMscStateMachine.c
UsbPHDC.c
descriptors.c
dma.c
main.c
usb.c
usbConstructs.c
usbEventHandling.c
Linking
Total number of errors: 0
Total number of warnings: 0
There are commented description... //use REFO for FLL and ACLK
If you click on SELREF__REFOCLK or SELA__REFOCLK in source code, it will lead you to msp430f510.h where this values are defined...
#define SELREF__REFOCLK (0x0020u) /* Multiply Selected Loop Freq. By REFOCLK */
#define SELA__REFOCLK (0x0200u) /* ACLK Source Select REFOCLK */
As you can see SELREF__REFOCLK is SELREF_2 so REF0CLK is selected as FLL reference. With SELA__REFOCLK is REF0 selected for ACLK source.
~SELREF_7 and ~SELA_7 are used for clearing all selection bits for UCSCTL3/4.
-
rampadc reacted to oPossum in Four digit seven segment blinking problem
There must be some delay between the displaySingle() calls.
Best way to do that is to use an interrupt just fast enough to prevent flicker. Probably about 200 Hz for a 4 digit display.
Quick fix is to use _delay_cycles();
-
rampadc reacted to roadrunner84 in Four digit seven segment blinking problem
Don't do blocking! try something like this
set timer interval to 1 second for(;{ display(counter); } void timer_isr(){ counter += 1; } -
rampadc got a reaction from cubeberg in Button not working on TI Launchpad (beginner)
Fantastic! Thanks for the help.
-
rampadc reacted to RobG in Button not working on TI Launchpad (beginner)
Also, this will never evaluate to true:
if(P1IN & BIT3 == 1) // should be if(P1IN & BIT3 == BIT3) Try this instead:
if(P1IN & BIT3) -
rampadc reacted to cubeberg in Button not working on TI Launchpad (beginner)
Are you using code composer? You can right-click on the breakpoint and choose Breakpoint Properties. You have the option to have it halt operation, or another option is to have it refresh a view. I believe you have to set that up while debugging (not sure why it's only available at run time).