#include "msp430x54xA.h" #include "hal_MSP-EXP430F5438.h" #include "hal_lcd.h" #include #include "hal_pmm.h" #define SYSTEM_CLOCK 23986176 #define USB_PORT_OUT P5OUT #define USB_PORT_SEL P5SEL #define USB_PORT_DIR P5DIR #define USB_PORT_REN P5REN #define USB_PIN_TXD BIT6 #define USB_PIN_RXD BIT7 #define USB_PORT_BAUDRATE 57600 #define UART_A3_PSEL P10SEL #define UART_A3_PDIR P10DIR #define UART_A3_TXD_MASK BIT4 #define UART_A3_RXD_MASK BIT5 #define UART_A3_BAUDRATE 57600 char rxBuffer[256]; //Buffer to keep received messages/responses/events from module char rxReadIndex = 0; char rxWriteIndex = 0; volatile char dataReady = 0; //variable to declare is message is completely received (to be implemented) volatile unsigned int i; // volatile to prevent optimization unsigned int SetVCore (unsigned char level); void initSystemClock(); //unsigned char contrast = 0x66; //unsigned char backlight = 8; void lcdStart(); void portsInit(); /****************** HCI - RF module commands: ******************/ // Example commands present in the readme.docx char command[] = {"\xA5\x01\x01\x00"}; // 4 bytes char command2[] = {"\xA5\x01\x13\x01\x01"}; // 5 bytes char command3[] = {"\xA5\x01\x13\x01\x02"}; // 5 bytes char command4[] = {"\xA5\x01\x13\x01\x03"}; // 5 bytes char command5[] = {"\xA5\x01\x13\x01\x04"}; // 5 bytes char command6[] = {"\xA5\x01\x13\x01\x05"}; // 5 bytes char command7[] = {"\xA5\x02\x04\x05\x30\x31\x32\x33\x34"}; // 9 // Command sent by the Functional Test Tool app char command8[] = {"\xA5\x82\x01\x16\x00\x00\x00\x97\x00\x7F\x36\x01\xF1\x01\x02\x03\x00\x33\x30\x5D\x05\x41\x1F\x86\x15\xAA\x6E\x08"}; // 28 bytes /************************************** MAIN *****************************************/ /********************** sends command and keeps idle - stop **************************/ /********************** debugging and check memory contents **************************/ /********************** rxBuffer[] should contain response **************************/ unsigned char MST_Data = 0x80; // Initialize data values unsigned char MST_Data2 = 0xFF; unsigned char SLV_Data = 0xE5; // Slave-Data, Roko unsigned char tempvar; int j = 0; // SPI-Configurationfunction void spi_init (); // multiread function uint8_t multiread (void); // Code added by Roko uint8_t ADRESS_DATA_FORMAT=0x31; // 0x31; DATA_FORMAT, wake up from standby uint8_t ADRESS_BW_RATE=0x2C; // Address uint8_t ADRESS_FIFO_CTL=0x80; // Address uint8_t ADRESS_POWER_CTRL=0x2D; // Address // Code added by Roko uint8_t DATA_FORMAT=0x08; // 100 Hz output rate // 0x0A //SELF_TEST | SPI | INT_INVERT | 0 | FULL_RES | Justify | Range uint8_t BW_RATE=0x0A; // 0 | 0 | 0 | LOW_POWER | Rate | Rate | Rate Rate uint8_t FIFO_CTL=0x80; // FIFO_MODE | FIFO_MODE | Tigger | Samples | Samples | Samples | Samples | Samples uint8_t POWER_CTRL=0x08; // 0 | 0 | Link | AUTO_SLEEP | Measure | Sleep | Wakeup unint8_t POWER_CTRLstop=0x00; // setting Measurement Bit to 0 to stop measurement // Variables for measurement uint8_t DATAX0=0x32; // adress uint8_t DATAX1=0x33; // adress uint8_t DATAY0=0x34; // adress uint8_t DATAY1=0x35; // adress uint8_t DATAZ0=0x36; // adress uint8_t DATAZ1=0x37; // adress // Results measurements uint8_t X0; uint8_t X1; uint8_t Y0; uint8_t Y1; uint8_t Z0; uint8_t Z1; uint8_t x; uint8_t y; uint_8t z; // buffer for DATA unint8_t [10]; void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //initSystemClock(); // It's 4 wires, but in reality 3-wire mode for MSP430, since the CS is manually controlled. Still full duplex (and not half) P10DIR |= 0x40; // CS pin. P10SEL |= 0x0E; // or BIT1 + BIT2 + BIT3; UCB3CTL1 |= UCSWRST; // **Put state machine in reset** !!! UCB3CTL0 |= UCMST + UCSYNC + UCCKPL + UCMSB;// + UCCKPH; // 3-pin, 8-bit SPI master //UCB3CTL1 |= UCSSEL_1; // ACLK = ~32.768kHz, UCB3CTL1 |= UCSSEL_2; // SMCLK //UCB3BR0 = 0; // UCB3BR0 = 0x02; // UCB3BR1 = 0; // UCB3CTL1 &= ~UCSWRST; // **Initialize USCI state machine** UCB3IE |= UCRXIE; // Enable USCI_B3 RX interrupt P10OUT |= 0x40; //set high (CS active low) __delay_cycles(100); // Wait for slave to initialize //******* ROUTINE TO SEND //TEST_ID // P10OUT &= ~0x40; //select slave // // while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? // UCB3TXBUF = MST_Data; // Transmit first character // // spi_init(); multiread (void); __bis_SR_register(GIE); // enable global interrupts while(1) { } } #pragma vector=USCI_B3_VECTOR __interrupt void USCI_B3_ISR(void) { switch(__even_in_range(UCB3IV,12)) { case 0: break; // Vector 0 - no interrupt case 2: // Vector 2 - RXIFG P10OUT&=~0x40; // sending the adress to start conversation with POWER_CTL while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=ADRESS_POWER_CTRL; // Transmit first character, Address(ROKO) while (!(UCB3STAT&UCBUSY)==0); P10OUT|=0x40; __delay_cycles(40); //--------------------------------------- // sending 0x08 to the POWER_CTL Register to start the measurement P10OUT&=~0x40; while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=POWER_CTRL; // Transmit first character, Address(ROKO) while (!(UCB3STAT&UCBUSY)==0); P10OUT|=0x40; __delay_cycles(40); //****Measurements*************** UCB3TXBUF=DATAX0; // USCI_B0 TX buffer ready? while (!(UCB3IFG&UCTXIFG)); UCB3TXBUF=0xFF; while (!(UCB3IFG&UCRXIFG)); // USCI_B0 RX buffer ready? X0=UCB3RXBUF; buffer[0]=X0; // Putting Data from Variable X0 into the buffer while (!(UCB3STAT&UCBUSY)==0); // P10OUT|=0x40; // // __delay_cycles(40); // P10OUT&=~0x40; // UCB3TXBUF = MST_Data2; // Transmit first character, Address(ROKO) UCB3TXBUF=DATAX1; // Transmit first character, Address(ROKO) while (!(UCB3IFG&UCTXIFG)); UCB3TXBUF=0xFF; // Dummy-Byte while (!(UCB3IFG&UCRXIFG)); // USCI_B0 RX buffer ready?? X1=UCB3RXBUF; buffer[1]=X1; // Putting Data from Variable X1 into the buffer while (!(UCB3STAT&UCBUSY)==0); // // P10OUT&=~0x40; // // __delay_cycles(40); // P10OUT|=0x40; while (!(UCB3IFG&UCTXIFG)); UCB3TXBUF=DATAY0; // Transmit first character, Address(ROKO) while (!(UCB3IFG&UCTXIFG)); UCB3TXBUF=0xFF; // Dummy-Byte while (!(UCB3IFG&UCRXIFG)); // USCI_B0 TX buffer ready? Y0=UCB3RXBUF; buffer[2]=Y0; // Putting Data from Variable Y0 into the buffer while (!(UCB3STAT&UCBUSY)==0); // // P10OUT&=~0x40; // // __delay_cycles(40); // P10OUT|=0x40; while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=DATAY1; while (!(UCB3IFG&UCTXIFG)); UCB3TXBUF=0xFF; // Dummy-Byte while (!(UCB3IFG&UCRXIFG)); // USCI_B0 RX buffer ready? Y1=UCB3RXBUF; buffer[3]=Y1; // Putting Data from Variable Y1 into the buffer while (!(UCB3STAT&UCBUSY)==0); // Transmit first character, Address(ROKO) // // P10OUT&=~0x40; // // __delay_cycles(40); // P10OUT|=0x40; while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=DATAZ0; // Transmit first character, Address(ROKO) while (!(UCB3IFG&UCTXIFG)); UCB3TXBUF=0xFF; // Dummy-Byte while (!(UCB3IFG&UCRXIFG)); // USCI_B0 RX buffer ready? Z0=UCB3RXBUF; buffer[4]=Z0; // Putting Data from Variable Z0 into the buffer while (!(UCB3STAT&UCBUSY)==0); // P10OUT|=0x40; // P10OUT&=~0x40; // __delay_cycles(40); while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=DATAZ1; // Transmit first character, Address(ROKO) while (!(UCB3IFG&UCTXIFG)); UCB3TXBUF=0xFF; // Dummy-Byte while (!(UCB3IFG&UCRXIFG)); // USCI_B0 RX buffer ready? Z1=UCB3RXBUF; buffer[5]=Z1; // Putting Data from Variable Z1 into the buffer while (!(UCB3STAT&UCBUSY)==0); P10OUT|=0x40; // while (!(UCB3IFG&UCTXIFG)); // USCI_A0 TX buffer ready? // tempvar = UCB3RXBUF; // if (tempvar == SLV_Data) // Test for correct character RX'd // tempvar = 0xAA; //tempvar=0xAA; // else // UCB3TXBUF = MST_Data2; // Send next value (Roko, sending Dummy byte) // j++; // Zeile zum Debuggen // sending the adress to start conversation with POWER_CTL while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=ADRESS_POWER_CTRL; // Transmit first character, Address(ROKO) while (!(UCB3STAT&UCBUSY)==0); P10OUT|=0x40; __delay_cycles(40); //--------------------------------------- // sending 0x08 to the POWER_CTL Register to start the measurement P10OUT&=~0x40; while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=POWER_CTRLstop; // Transmit first character, Address(ROKO) while (!(UCB3STAT&UCBUSY)==0); P10OUT|=0x40; __delay_cycles(40); // Add time between transmissions to // make sure slave can process information (seems to avoid putting CS to high) // if(j==2) // tempvar++; break; case 4: break; // Vector 4 - TXIFG default: break; } } void spi_init () { //******** Configuration ***** Roko while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=ADRESS_DATA_FORMAT; // Transmit first character, Address(ROKO) while (!(UCB3STAT&UCBUSY)==0); while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=DATA_FORMAT; // Transmit second character, Address(ROKO) while (!(UCB3STAT&UCBUSY)==0); P10OUT|=0x40; __delay_cycles(40); //------------------------------- P10OUT&=~0x40; while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=ADRESS_BW_RATE; // Transmit first character, Address(ROKO) while (!(UCB3STAT&UCBUSY)==0); while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=BW_RATE; // Transmit second character, Address(ROKO) while (!(UCB3STAT&UCBUSY)==0); P10OUT|=0x40; __delay_cycles(40); //-------------------------------- P10OUT&=~0x40; while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=ADRESS_FIFO_CTL; // Transmit first character, Address(ROKO) while (!(UCB3STAT&UCBUSY)==0); while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=FIFO_CTL; // Transmit second character, Address(ROKO) while (!(UCB3STAT&UCBUSY)==0); P10OUT|=0x40; __delay_cycles(40); //--------------------------------- P10OUT&=~0x40; while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=ADRESS_POWER_CTRL; // Transmit first character, Address(ROKO) while (!(UCB3STAT&UCBUSY)==0); P10OUT|=0x40; __delay_cycles(40); //--------------------------------------- P10OUT&=~0x40; while (!(UCB3IFG&UCTXIFG)); // USCI_B0 TX buffer ready? UCB3TXBUF=POWER_CTRL; // Transmit first character, Address(ROKO) while (!(UCB3STAT&UCBUSY)==0); P10OUT|=0x40; __delay_cycles(40); //---------------------------------------- }; uint8_t multiread (void) { x = ((int)values[1]<<8)|(int)values[0]; y = ((int)values[3]<<8)|(int)values[2]; z = ((int)values[5]<<8)|(int)values[4]; } /******************************** UART Interrupt for response from RF module ***************/ #pragma vector=USCI_A3_VECTOR __interrupt void USCI_A3_ISR(void) { unsigned char data = UCA3RXBUF; rxBuffer[rxWriteIndex++] = data; // while (!(UCA1IFG&UCTXIFG)){ // UCA1TXBUF = data; // } if(data == 0x02) dataReady=1; // to signalize end of command received, but does not always work, because only a few end with 0x02 // so the best way to debug is Break operation and check memory registers, and variable "rxBuffer" } /************ Function to initialize system clock ***********/ /************ taken from steering wheel code ****************/ void initSystemClock (void) { SetVCore(PMMCOREV_3); // Set VCore to level3 (ca 1.9V) for 25MHz UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO UCSCTL4 |= SELA_2; // Set ACLK = REFO __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_6; // Select DCO range 48MHz operation UCSCTL2 = FLLD_1 + 731; // Set DCO Multiplier for 24MHz // (N + 1) * FLLRef = Fdco // (731 + 1) * 32768 = 24MHz // Set FLL Div = fDCOCLK/2 __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 24 MHz / 32,768 Hz = 750000 = MCLK cycles for DCO to settle __delay_cycles(750000); // Loop until XT1,XT2 & DCO fault flag is cleared do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag } /************ Function to initialize ports (UART3 and UART-USB) ***********/ void portsInit(void) { UART_A3_PSEL |= 0x30; // or |= BIT4 + BIT5; P3.4,5 = USCI_A0 TXD/RXD // YOU DON'T MESS WITH DIRECTION WHEN USING UART //UART_A3_PDIR &= ~UART_A3_RXD_MASK; //CHECK THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! and also in system.c //UART_A3_PDIR |= UART_A3_TXD_MASK; //WHY? because I think you don't mess with PxDIR when you want to receive and possibly send UCA3CTL1 |= UCSWRST; // 8-bit character UCA3CTL1 |= UCSSEL_2; // UCLK = SMCLK UCA3BR0 = (uint8_t)(SYSTEM_CLOCK / UART_A3_BAUDRATE); UCA3BR1 = (uint8_t)((SYSTEM_CLOCK / UART_A3_BAUDRATE) >> 8); UCA3MCTL = (uint8_t)((SYSTEM_CLOCK / UART_A3_BAUDRATE - (uint16_t)(SYSTEM_CLOCK / UART_A3_BAUDRATE))*8 + 0.5) << 1; // manually start reading of data UCA3CTL1 &= ~UCSWRST; // Initialize USART state machine UCA3IE |= UCRXIE; // Enable only USART0 RX interrupt (only possible if not in reset!!!) // GUERRA usb-serial port for debugging init(): USB_PORT_SEL |= USB_PIN_RXD + USB_PIN_TXD; USB_PORT_DIR |= USB_PIN_TXD; USB_PORT_DIR &= ~USB_PIN_RXD; UCA1CTL1 |= UCSWRST; //Reset State UCA1CTL0 = UCMODE_0; UCA1CTL0 &= ~UC7BIT; // 8bit char UCA1CTL1 |= UCSSEL_2; UCA1BR0 = (uint8_t)(SYSTEM_CLOCK / USB_PORT_BAUDRATE); // clock/57600=? UCA1BR1 = (uint8_t)((SYSTEM_CLOCK / USB_PORT_BAUDRATE) >> 8); UCA1MCTL = (uint8_t)((SYSTEM_CLOCK / USB_PORT_BAUDRATE - (uint16_t)(SYSTEM_CLOCK / USB_PORT_BAUDRATE))*8 + 0.5) << 1; UCA1CTL1 &= ~UCSWRST; UCA1IE |= UCRXIE; __bis_SR_register(GIE); } /************ Function to initialize LCD and backlight ***********/ /************ taken from user experience program by TI ***********/ void lcdStart(void) { halLcdInit(); halLcdBackLightInit(); halLcdSetBackLight(halLcdGetBackLight()); halLcdSetContrast(halLcdGetContrast()-6); halLcdClearScreen(); halLcdPrintLine("Hello world.", 0, 0); } /************ USB echo test ********************/ /* #pragma vector=USCI_A1_VECTOR __interrupt void USCI_A1_ISR(void) { UCA1TXBUF = UCA1RXBUF; //echoes _NOP(); } */