Jump to content
43oh

G2553 4 wire SPI Slave always seems enabled


Recommended Posts

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;
}
Link to post
Share on other sites

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;
}
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...