Created
June 5, 2011 20:56
-
-
Save RickKimball/1009412 to your computer and use it in GitHub Desktop.
Test driver for SPI 23K256 serial ram device
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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