Rickta59 589 Posted June 6, 2011 Share Posted June 6, 2011 I came across the Microchip 23K256 Serial RAM device a while back. It seems to fit the bill when you need more RAM but don't want to spend a lot of money to get it. These chips are inexpensive, (about $1,50 at time of this post 06/05/2011) and hold 32K worth of data. You access the memory using SPI. You can even put multiple 23K256 devices on your SPI bus and get even more buffer space. The arduino world already has a couple of libraries to access these devices. I adapted one of these to work with both CCS and the uniarch compiler. I used GRACE to help me configure the msp430g2452 USI in SPI Mode 1. This code might be also be useful as a starting point for any SPI Mode 1 device. This code is written for the USI device. It would be nice to have a USCI version that would work with the g2553 chip. Typical use for this device might be to buffer UART received data that is larger than the 128 bytes of SRAM available on the smaller G series chips. You might want to verify the pin setup, I think I have it correct, however you should always verify. One interesting item of note is my use of one of the GPIO pins to power the device. You may or may not want to use that in your setup. According to the datasheet the 23K256 uses somewhere between 2-10mA of power based on how fast you interface with it. I think the G series should handle that but I'm not 100% sure. Please comment if you know. https://gist.github.com/1009412 /** * testspi23K256.c - Interface Microchip 23K256 Serial RAM chip with MSP430G2452 USI SPI * * This code snippet show you how to configure the USI SPI in SPI Mode 1 to communicate with * the 23K256 chip at 4MHz. It takes about 98uSecs to write a single byte and 32K 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 #include 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(volatile 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(volatile uint8_t value) { USISRL = value; USICNT = 8; // initialize bit count, start transfer/read __delay_cycles(0); 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 = POWER_PIN; 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 powerOff; delay_1ms; 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() { volatile uint16_t i; volatile 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) { ; } } } } Mac, jsolarski, bluehash and 4 others 7 Quote Link to post Share on other sites
bluehash 1,581 Posted June 6, 2011 Share Posted June 6, 2011 Woah! 32kb of RAM. Thanks for sharing your code. Quote Link to post Share on other sites
Rickta59 589 Posted June 6, 2011 Author Share Posted June 6, 2011 I should mention that the code above should work fine with any value line chip that has a USI SPI peripheral ( msp430g2231 etc ... ) not just the msp430g2452 mentioned. -rick Quote Link to post Share on other sites
cubeberg 540 Posted January 12, 2012 Share Posted January 12, 2012 Have you used this in a project? I'm working on something where I need more memory and I'm wondering if this might fit the bill. I want to be able to draw lines on a Nokia 5110, and apparently you have to buffer the entire screen in memory because there's no way to draw on a single pixel. Quote Link to post Share on other sites
Rickta59 589 Posted January 12, 2012 Author Share Posted January 12, 2012 Have you used this in a project? I haven't yet. I'm planning on using as memory buffer for serial data. However, I mainly wrote it to figure out how SPI worked on the msp430 chips with USI peripherals. -rick Quote Link to post Share on other sites
Rickta59 589 Posted January 12, 2012 Author Share Posted January 12, 2012 I'm working on something where I need more memory and I'm wondering if this might fit the bill. I want to be able to draw lines on a Nokia 5110, and apparently you have to buffer the entire screen in memory because there's no way to draw on a single pixel. How many bytes do you need to send to the Nokia? How often are you updating that data? Can you feed the Nokia using SPI? The big question is can you update the memory then read it back faster than your screen refresh rate. When I was testing, I set my MCLK to 16MHz and then measured how long it took to read one byte and one 32k block. The one byte read has some minimum SPI protocol overhead but could be done in about 110ish uSecs. The 32k read took about 100mSecs. I think I was using a 4MHz SPI clock, you might be able to do better than that. -rick Quote Link to post Share on other sites
RobG 1,892 Posted January 12, 2012 Share Posted January 12, 2012 Are you planning on doing something fancy or simple read/write? I have some ideas on how to speed data transfer between SRAM and 5110. Quote Link to post Share on other sites
cubeberg 540 Posted January 12, 2012 Share Posted January 12, 2012 The project I'm working on is a digital "Etch-A-Sketch" for my kids. I've got an LCD coming on Tuesday (RobG - the one you found on eBay) that allows a much higher level of control, but I was trying to prototype with the Nokia I had on hand. Because graphics are written in blocks, it's not possible to paint a single pixel. The only other option would be to buffer the contents of the screen in memory, but there's not enough in the MCU. For this specific implementation - refresh rate wouldn't really be an issue. Honestly - I should probably just wait until the other LCD arrives I thought I had some 23K256 on hand, but I accidentally ordered samples of the low-power 23A256, so I'll have to wait for the 3v version to arrive. BUT - if the SRAM worked out - it could allow us to actually do graphics on the Nokia LCD similar to the FRAM project that someone made. You could obviously do a lot more with 32K of SRAM. Could be an interesting LP project. Quote Link to post Share on other sites
NullColaShip 14 Posted January 13, 2012 Share Posted January 13, 2012 I've just ordered a few of these, and I intend to use one to store pixel data for a display built from addressable RGB LED strips - I'll keep an eye on this thread and report back on progress once I have the chips, but I'll also be posting updates in my project thread. 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.