Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Test driver for SPI 23K256 serial ram device
#
# Makefile - testspi23k256
#
# this code is written for uniarch, however it will probably compile with CCS
#
# License: Do with this code what you want. However, don't blame
# me if you connect it to a heart pump and it stops. This source
# is provided as is with no warranties. It probably has bugs!!
# You have been warned!
#
# Author: Rick Kimball
# email: rick@kimballsoftware.com
# Version: 1.00 Initial version 06-05-2011
#MCU=msp430g2231
MCU=msp430g2452
CC=msp430-gcc
CXX=msp430-g++
CFLAGS=-mmcu=$(MCU) -O3 -g -Wall
LDFLAGS=-Wl,-Map,$(TARGET)/$(APP).map
APP=testspi23k256
TARGET=.
all: $(TARGET)/$(APP).elf
$(TARGET)/$(APP).elf: $(TARGET)/$(APP).o
$(CC) $(CFLAGS) -o $(TARGET)/$(APP).elf $(TARGET)/$(APP).o $(LDFLAGS)
msp430-objdump -Sww $(TARGET)/$(APP).elf >$(TARGET)/$(APP).lss
msp430-size $(TARGET)/$(APP).elf
$(TARGET)/$(APP).o: $(APP).c
$(CC) $(CFLAGS) -c -o $(TARGET)/$(APP).o $< $(OBJ00)
install: all
mspdebug -q --force-reset rf2500 "erase" "prog $(TARGET)/$(APP).elf"
gdb: all
mspdebug -q --force-reset rf2500 gdb
clean:
rm -f $(TARGET)/$(APP).o $(TARGET)/$(APP).elf $(TARGET)/$(APP).lss $(TARGET)/$(APP).map
/**
* testspi23K256.c - Interface Microchip 23K256 Serial RAM chip with MSP430G2452 USI SPI
*
* This code snippet demonstrates how to configure the USI SPI peripheral for
* SPI Mode 1 to enable communication with the 23K256 chip at 4MHz. Writing a
* single byte to the 23K256 takes about ~98uSecs and 32Kbytes takes about 100ms.
*
* msp430g2452 - http://focus.ti.com/docs/prod/folders/print/msp430g2452.html
* 23K256 - http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en539039
*
* Pin Connections:
*
* MSP430 SCLK P1.5 -> PIN 6(SCK) 23K256
* MSP430 MISO P1.7 -> PIN 2(SO) 23K256
* MSP430 MOSI P1.6 -> PIN 5(SI) 23K256
* MSP430 GPIO P1.1 -> PIN 1(CS) 23K256
* MSP430 GPIO P1.4 -> PIN 8(VCC) 23K256
*
* 23K256 PIN 7 Pullup resistor
* 23K256 PIN 8 Pulldown resistor
*
* Linux build:
*
* $ msp430-gcc -mmcu=msp430g2452 -O3 -g -Wall -I. -c testspi23K256.c
* $ msp430-gcc -mmcu=msp430g2452 -O3 -g -Wall -I. -o ./testspi23K256.elf ./testspi23K256.o -Wl,-Map,./testspi23K256.map
* $ msp430-objdump -Sww ./testspi23K256.elf >./testspi23K256.lss
* $ msp430-size ./testspi23K256.elf
* $ mspdebug -q --force-reset rf2500 "erase" "prog ./testspi23K256.elf"
*
* This code was inspired from this code:
*
* http://sourceforge.net/projects/mysudoku/files/
* http://hackaday.com/2009/03/02/parts-32kb-spi-sram-memory-23k256/
*
*/
#include <msp430.h>
#include <stdint.h>
enum {
POWER_PIN = BIT4, // we power the 23K256 chip from one of our GPIO pins
SS_PIN = BIT1, // 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
// 23K256 Serial Ram functions
uint8_t SR_getMode(void) {
ssSelect;
RWData(SR_READ_STATUS); // 0x05
uint8_t mode = RWData(DUMMY_BYTE);
ssDeselect;
return mode;
}
void SR_setMode(uint8_t mode) {
ssSelect;
RWData(SR_WRITE_STATUS); // 0x01
RWData(mode);
ssDeselect;
}
static inline void SR_writestream(uint16_t addr) {
ssDeselect; // deselect if we are active
ssSelect;
RWData(0x02);
RWData(addr >> 8);
RWData(addr);
}
static inline void SR_readstream(uint16_t addr) {
ssDeselect;
ssSelect;
RWData(0x03);
RWData(addr >> 8);
RWData(addr);
}
static inline uint8_t RWData(uint8_t value) {
USISRL = value;
USICNT = 8; // initialize bit count, start transfer/read
while (!(USIIFG & USICTL1)) {
; // wait for SPI flag to trip
}
return USISRL;
}
/**
* main
*/
int main() {
// kill the watchdog timer
WDTCTL = WDTPW + WDTHOLD;
// 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;
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
You can’t perform that action at this time.