Skip to content

Instantly share code, notes, and snippets.

Created March 5, 2016 23:37
Show Gist options
  • Save anonymous/cdf7df4d4f457a1703dd to your computer and use it in GitHub Desktop.
Save anonymous/cdf7df4d4f457a1703dd to your computer and use it in GitHub Desktop.
Interfaces low cost SPI SRAM (or FRAM) to a MSP430G2553 LaunchPad board
// Inspired by Rick Kimball's 23K256 Test for MSP430F2013
// This code was compiled using Energia and runs on a standard LaunchPad
// The basic SPI SRAM support fits into 290 bytes on MSP430G2553
// Increases to 422 bytes with streaming test
//#include <msp430.h>
//#include <stdint.h>
// Compiled using Energia
// Note the changes BIT0 is now the DEBUG_PIN and BIT4 is the SS_PIN.
// This was done to avoid conflict with P1.1 which is usually used as uart RxD
enum {
POWER_PIN = BIT0, // we power the 23K256 chip from one of our GPIO pins
SS_PIN = BIT4, // CS , active low
DEBUG_PIN = BIT0, // toggle on and off marking time to write
DUMMY_BYTE = 0xFF // byte we send when we just want to read slave data
};
static inline uint8_t RWData(uint8_t value);
void loop();
#define powerOn P1OUT |= POWER_PIN
#define powerOff P1OUT &= ~POWER_PIN
#define ssSelect P1OUT &= ~SS_PIN
#define ssDeselect P1OUT |= SS_PIN
#define delay_1ms __delay_cycles(16000)
#define SR_WRITE_STATUS 0x01
#define SR_WRITE 0x02
#define SR_READ 0x03
#define SR_READ_STATUS 0x05
int spi_rx_data = 0 ;
// 23K256 Serial Ram functions
uint8_t SR_getMode(void) { // Read the Mode of the 23K256
ssSelect;
RWData(SR_READ_STATUS); // 0x05
uint8_t mode = RWData(DUMMY_BYTE);
ssDeselect;
return mode;
}
void SR_setMode(uint8_t mode) { // Write Mode to 23K256
ssSelect;
RWData(SR_WRITE_STATUS); // 0x01
RWData(mode);
ssDeselect;
}
static inline void SR_writestream(uint16_t addr) { // Write a stream to 23K256
ssDeselect; // deselect if we are active
ssSelect;
RWData(0x02); // Send command
RWData(addr >> 8); // Send upper address
RWData(addr); // Send lower address
}
static inline void SR_readstream(uint16_t addr) { // Read a stream from 23K256
ssDeselect;
ssSelect;
RWData(0x03); // Send command
RWData(addr >> 8); // Send upper address
RWData(addr); // Send lower address
}
//-----------------------------------------------------------------
// SPI Send / Receive
static inline uint8_t RWData(uint8_t value)
{
UCB0TXBUF = value;
while (!(IFG2 & UCB0TXIFG)); // wait for buffer ready
{ }
while (!(IFG2 & UCB0RXIFG)); // USCI_A0 RX Received?
spi_rx_data = UCB0RXBUF; // Store received data
return spi_rx_data;
}
//-----------------------------------------------------------------
/*
int SPI_SR(int spi_tx_data)
{
P1OUT &= (~BIT5); // Select Device
while (!(IFG2 & UCB0TXIFG)); // USCI_A0 TX buffer ready?
UCB0TXBUF = spi_tx_data; // Send data over SPI to Slave
while (!(IFG2 & UCB0RXIFG)); // USCI_A0 RX Received?
spi_rx_data = UCB0RXBUF; // Store received data
P1OUT |= (BIT5); // Unselect Device
return spi_rx_data;
}
*/
//-----------------------------------------------------------------
// main
int main() {
// kill the watchdog timer
WDTCTL = WDTPW + WDTHOLD;
//----------------------------------------------------------------------------
// Configure the Clock for 16 MHz
BCSCTL1 = CALBC1_16MHZ;
DCOCTL = CALDCO_16MHZ;
//---------------------------------------------------------------------
// Configure Ports
P1SEL |= BIT5 + BIT6 + BIT7;
P1SEL2 |= BIT5 + BIT6 + BIT7;
P1DIR |= BIT0 + BIT4 + BIT5 + BIT7;
//---------------------------------------------------------------------
// Set UCSWRST
UCB0CTL1 = UCSWRST;
//---------------------------------------------------------------------
// Configure USCI B0
UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master, Mode 1 - check phase
UCB0CTL1 |= UCSSEL_2; // SMCLK
UCB0BR0 |= 2; // 8MHz maximum
UCB0BR1 = 0;
//---------------------------------------------------------------------
// activate
UCB0CTL1 &= ~UCSWRST;
//---------------------------------------------------------------------
// Previous USI Initialisation for 2452, 2013 etc - Rick Kimball
//---------------------------------------------------------------------
/*
// configure DCO clock to 16MHz
BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0;
if (CALBC1_16MHZ != 0xFF) {
DCOCTL = 0x00;
BCSCTL1 = CALBC1_16MHZ;
DCOCTL = CALDCO_16MHZ;
}
BCSCTL1 |= XT2OFF + DIVA_0;
BCSCTL3 = XT2S_0 + LFXT1S_2 + XCAP_1;
*/
//---------------------------------------------------------------------
// configure GPIO
// P1OUT = SS_PIN; // deselect CS, turn off power to 23K256
// P1DIR = SS_PIN + POWER_PIN + DEBUG_PIN;
//---------------------------------------------------------------------
/*
// configure USI - SPI Mode 1 @ 4MHz, clocked off SMCLK
USICTL0 |= USISWRST;
USICTL0 = USIPE7 + USIPE6 + USIPE5 + USIMST + USIOE + USISWRST;
USICTL1 |= USICKPH;
USICKCTL = USIDIV_1 + USISSEL_2;
*/
//---------------------------------------------------------------------
/*
// Enable USI
USICTL0 &= ~USISWRST;
__enable_interrupt(); // Set global interrupt enable
*/
//---------------------------------------------------------------------
// toggle the power for the 23K256
// powerOn;
// Assume power is permanenty on in this implementation
ssDeselect;
delay_1ms;
while (1) {
uint8_t chipMode;
// make sure there is a 23K256 chip and that
// is wired properly and in sequential mode
chipMode = SR_getMode();
if (chipMode != 0x41) {
SR_setMode(0x41);
} else {
while (1) {
loop();
}
}
}
}
#define BYTES_TO_STREAM 32768 // should be less <= 32768
#define PATTERN_BYTE_VALUE 0x55
//loop - write a test pattern and read it back
void loop() {
uint16_t i;
uint8_t storedValue = 0;
P1OUT |= DEBUG_PIN; // mark start of write for measurement with oscope
SR_writestream(0); // start writing at address 0
for (i = 0; i < BYTES_TO_STREAM; ++i) {
RWData(PATTERN_BYTE_VALUE);
}
P1OUT &= ~DEBUG_PIN; // mark end of write for measurement with oscope
// verify the bytes we wrote were stored and retreived properly
SR_readstream(0); // start reading at address 0
for (i = 0; i < BYTES_TO_STREAM; ++i) {
storedValue = RWData(DUMMY_BYTE);
// verify our test pattern
if (storedValue != PATTERN_BYTE_VALUE) {
// if values aren't the same an error occurred,
// turn off all leds, then sit and spin
P1OUT &= ~BIT6;
P1OUT &= ~DEBUG_PIN;
while (1) {
;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment