David Bender 28 Posted April 16, 2015 Share Posted April 16, 2015 The following code accepts over the SPI bus a byte from the master to control 8 relays, and returns the state of 8 inputs. I am running into an issue where the slave always responds to the SCLK, driving MISO, even when the STE (pin 1.4) is not asserted low. Any ideas why? #include "msp430g2553.h" #include <string.h> enum { /* Port 1 */ LED1 = BIT0 ,LED2 = BIT1 }; int main(void){ WDTCTL = WDTPW | WDTHOLD; BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; /* SMCLK = DCO / DIVS = nMHz */ /* ACLK = VLO = ~ 12 KHz */ BCSCTL2 &= ~(DIVS_0); BCSCTL3 |= LFXT1S_2; P2SEL &= ~(BIT6 | BIT7); /* Enable SPI */ P1SEL |= BIT4 | BIT5 | BIT6 | BIT7; P1SEL2 |= BIT4 | BIT5 | BIT6 | BIT7; UCB0CTL1 = UCSWRST; UCB0CTL0 = UCSYNC | UCMODE_2 | UCMSB | UCCKPH; UCB0BR0 = 0; UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; IE2 |= UCB0RXIE | UCB0TXIE; P1DIR = LED1 | LED2; P2OUT = 0xFF; P2REN |= 0xFF; P1IFG = 0; P2IFG = 0; /* Default state is to output. */ P3OUT = 0xFF; P3DIR = 0xFF; __eint(); LPM0; } __attribute__((interrupt(USCIAB0RX_VECTOR))) void USCI0RX_ISR(void) { P1OUT ^= LED2; uint8_t relays = UCB0RXBUF; P3OUT = relays; } __attribute__((interrupt(USCIAB0TX_VECTOR))) void USCI0TX_ISR(void) { P1OUT ^= LED1; UCB0TXBUF = P2IN; } Quote Link to post Share on other sites
roadrunner84 466 Posted April 16, 2015 Share Posted April 16, 2015 Your code seems to be fine. Do you leave STE floating or do you actively drive it high when you do not want to address the msp430? Quote Link to post Share on other sites
David Bender 28 Posted April 17, 2015 Author Share Posted April 17, 2015 The master is talking to 8 slaves using chip select pins on P3. Only 1 pin is pulled low at a time using the ~ operator, so STE is NOT floating. I think I mostly solved my issue with the following code: (By mostly solved I mean I am seeing garbage on MISO when a slave is not present on the active chip select, but that seems to be a checksum issue now) #include <msp430g2553.h> #include <string.h> #include "stdarg.h" enum { /* Port 1 */ LED1 = BIT0 ,LED2 = BIT1 ,CHIP_SELECT = BIT3 }; int main(void){ WDTCTL = WDTPW | WDTHOLD; /* TODO Check if -mdisable-watchdog set. */ BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; /* SMCLK = DCO / DIVS = nMHz */ /* ACLK = VLO = ~ 12 KHz */ BCSCTL2 &= ~(DIVS_0); BCSCTL3 |= LFXT1S_2; /* Disable TX hardware (if applicable) * Disable external crystal. */ P1SEL &= ~(BIT1 | BIT2); P1SEL2 &= ~(BIT1 | BIT2); P2SEL &= ~(BIT6 | BIT7); /* Enable SPI */ UCB0CTL1 = UCSWRST; P1SEL |= BIT4 | BIT5 | BIT6 | BIT7; P1SEL2 |= BIT4 | BIT5 | BIT6 | BIT7; UCB0CTL0 = UCSYNC | UCMODE_2 | UCMSB | UCCKPH; UCB0BR0 = 0; UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; //IE2 |= UCB0RXIE | UCB0TXIE; P1DIR = LED1 | LED2; P1OUT = CHIP_SELECT; P1REN |= CHIP_SELECT; P1IES |= CHIP_SELECT; P1IE |= CHIP_SELECT; P2OUT = 0xFF; P2REN |= 0xFF; P1IFG = 0; P2IFG = 0; /* Default state is to output. */ P3OUT = 0xFF; P3DIR = 0xFF; __eint(); LPM0; } __attribute((interrupt(PORT1_VECTOR))) void Port_1(void){ unsigned snap = P1IFG; P1IFG &= ~snap; P1OUT ^= LED2; if(snap & CHIP_SELECT){ P1IES ^= CHIP_SELECT; if(P1IES & CHIP_SELECT){ IE2 &= ~(UCB0RXIE | UCB0TXIE); /* Rising edge, CS is over; reset SPI state. */ UCB0CTL1 |= UCSWRST; UCB0CTL1 &= ~UCSWRST; } else{ UCB0CTL1 |= UCSWRST; UCB0CTL1 &= ~UCSWRST; UCB0TXBUF = P2IN; IE2 |= UCB0RXIE; } snap &= ~CHIP_SELECT; } } __attribute__((interrupt(USCIAB0RX_VECTOR))) void USCI0RX_ISR(void) { P1OUT ^= LED1; uint8_t relays = UCB0RXBUF; P3OUT = relays; } Quote Link to post Share on other sites
roadrunner84 466 Posted April 17, 2015 Share Posted April 17, 2015 SPI isn't a really smart protocol; if there is no slave, you'll always read data, even when there is no slave. If you consider usin pull-up/down resistors on the bus or in the master, you might enforce reading all zeroes or all ones. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.