BSP430  20141115
Board Support Package for MSP430 microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
utility/m25p/main.c
#include <bsp430/clock.h>
#include <ctype.h>
#include <string.h>
#ifndef WITH_W25Q80BV
#define WITH_W25Q80BV (BSP430_PLATFORM_EXP430F5529LP - 0)
#endif /* WITH_W25Q80BV */
#if (WITH_W25Q80BV - 0)
/* Winbond W25Q80BV is a 8 Mibit (1 MiBy) serial FLASH supporting 256
* 4 KiBy sub-sectors (sectors) or 16 64 KiBy sectors (blocks). PAGE
* WRITE and PAGE ERASE are not supported; (SUB) SECTOR ERASE is
* supported. */
#define BSP430_PLATFORM_M25P_SUPPORTS_SSE 1
#define BSP430_PLATFORM_M25P_SECTOR_COUNT 16
#define BSP430_PLATFORM_M25P_SECTOR_SIZE 0x10000
#define BSP430_PLATFORM_M25P_SUBSECTOR_SIZE 0x1000
#if (BSP430_PLATFORM_EXP430F5529LP - 0)
/* SPI on USCI_A0, CSn on P6.6, PWR and RSTn hard-wired */
#define BSP430_PLATFORM_M25P_CSn_PORT_PERIPH_HANDLE BSP430_PERIPH_PORT6
#define BSP430_PLATFORM_M25P_CSn_PORT_BIT BIT6
#endif
#endif /* WITH_W25Q80BV */
/* As-delivered TrxEB flash is completely erased except for the first
* sixteen bytes which have this useful test pattern. */
const uint8_t flashContents[] = {
0xAA, 0x55, 0x0F, 0xF0, 0xCC, 0x33, 0xC3, 0x3C,
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
};
uint8_t buffer[256];
int readFromAddress (hBSP430m25p m25p,
unsigned long addr,
unsigned int len)
{
int rc = -1;
if (len > sizeof(buffer)) {
len = sizeof(buffer);
}
rc = iBSP430m25pCompleteTxRx_rh(m25p, NULL, 0, len, buffer);
}
return rc;
}
int writeToAddress (hBSP430m25p m25p,
uint8_t cmd,
unsigned long addr,
const uint8_t * data,
unsigned int len)
{
unsigned long t0;
unsigned long t1;
int rc;
int sr;
if (0 == rc) {
rc = iBSP430m25pInitiateAddressCommand_rh(m25p, cmd, addr);
}
if (0 == rc) {
rc = iBSP430m25pCompleteTxRx_rh(m25p, data, len, 0, NULL);
}
do {
sr = iBSP430m25pStatus(m25p);
} while ((0 <= sr) && (BSP430_M25P_SR_WIP & sr));
cprintf("Write %d took %lu\n", len, t1 - t0);
return rc;
}
void main ()
{
int rc;
sBSP430m25p m25p_data;
unsigned long addr;
unsigned long t0;
unsigned long t1;
cputchar('\n');
cprintf("\nBuild " __DATE__ " " __TIME__ "\n");
cprintf("SPI is %s: %s\n",
#ifdef BSP430_PLATFORM_M25P_PWR_PORT_PERIPH_HANDLE
cprintf("PWR at %s.%u\n",
#else /* BSP430_PLATFORM_M25P_PWR_PORT_PERIPH_HANDLE */
cprintf("PWR is hard-wired\n");
#endif /* BSP430_PLATFORM_M25P_PWR_PORT_PERIPH_HANDLE */
#ifdef BSP430_PLATFORM_M25P_RSTn_PORT_PERIPH_HANDLE
cprintf("RSTn at %s.%u\n",
#else /* BSP430_PLATFORM_M25P_RSTn_PORT_PERIPH_HANDLE */
cprintf("RSTn is hard-wired\n");
#endif /* BSP430_PLATFORM_M25P_RSTn_PORT_PERIPH_HANDLE */
cprintf("CSn at %s.%u\n",
memset(&m25p_data, 0, sizeof(m25p_data));
#ifdef BSP430_PLATFORM_M25P_RSTn_PORT_PERIPH_HANDLE
#endif /* BSP430_PLATFORM_M25P_RSTn_PORT_PERIPH_HANDLE */
m25p = hBSP430m25pInitialize(&m25p_data,
UCSSEL_2, 1);
if (NULL == m25p) {
cprintf("M25P device initialization failed.\n");
return;
}
{
#if (BSP430_MODULE_USCI5 - 0)
#else
void * hpl = NULL;
#endif
int sm = -1;
if (hpl) {
sm = 0;
sm |= 0x02;
}
sm |= 0x01;
}
}
if (0 > sm) {
cprintf("Unable to extract SPI mode from %s\n",
} else {
cprintf("%s initialized in SPI mode %u\n", xBSP430serialName(BSP430_PLATFORM_M25P_SPI_PERIPH_HANDLE), sm);
}
}
#ifdef BSP430_PLATFORM_M25P_PWR_PORT_PERIPH_HANDLE
{
volatile sBSP430hplPORT * pwr_hpl;
/* Turn on power, then wait 10 ms for chip to stabilize before releasing RSTn. */
}
#endif /* BSP430_PLATFORM_M25P_PWR_PORT_PERIPH_HANDLE */
cprintf("Status register %d\n", iBSP430m25pStatus_rh(m25p));
cprintf("WREN got %d, status register %d\n", rc, iBSP430m25pStatus_rh(m25p));
cprintf("WRDI got %d, status register %d\n", rc, iBSP430m25pStatus_rh(m25p));
if (0 == rc) {
rc = iBSP430m25pCompleteTxRx_rh(m25p, NULL, 0, 20, buffer);
}
cprintf("READ_IDENTIFICATION got %d\n", rc);
if (0 <= rc) {
}
cprintf("Config identified %u sectors of %lu bytes each: %lu bytes total\n",
BSP430_PLATFORM_M25P_SECTOR_COUNT * (unsigned long)BSP430_PLATFORM_M25P_SECTOR_SIZE);
#if (BSP430_PLATFORM_M25P_SUBSECTOR_SIZE - 0)
cprintf("Config supports access as %u sub-sectors of %u bytes each\n",
(unsigned int)(BSP430_PLATFORM_M25P_SECTOR_COUNT * (BSP430_PLATFORM_M25P_SECTOR_SIZE / BSP430_PLATFORM_M25P_SUBSECTOR_SIZE)),
#else /* BSP430_PLATFORM_M25P_SUBSECTOR_SIZE */
cprintf("Config indicates device is not sub-sector addressable\n");
#endif /* BSP430_PLATFORM_M25P_SUBSECTOR_SIZE */
cprintf("RDID identified %lu bytes total capacity\n", 0x1UL << buffer[2]);
addr = 0;
rc = readFromAddress(m25p, addr, sizeof(flashContents));
if (sizeof(flashContents) != rc) {
cprintf("ERROR %d reading initial block\n", rc);
} else {
vBSP430consoleDisplayMemory(buffer, rc, addr);
if (0 == memcmp(flashContents, buffer, rc)) {
cprintf("Found expected contents.\n");
} else {
cprintf("Did NOT find expected contents.\n");
}
}
cprintf("\nTest pattern (expected contents):");
vBSP430consoleDisplayMemory(flashContents, sizeof(flashContents), 0);
#if (BSP430_PLATFORM_M25P_SUPPORTS_PE - 0)
rc = writeToAddress(m25p, BSP430_M25P_CMD_PE, addr, NULL, 0);
cprintf("PAGE_ERASE got %d\n", rc);
#else /* BSP430_PLATFORM_M25P_SUPPORTS_PE */
rc = writeToAddress(m25p, BSP430_M25P_CMD_SE, addr, NULL, 0);
cprintf("SECTOR_ERASE got %d\n", rc);
#endif /* BSP430_PLATFORM_M25P_SUPPORTS_PE */
rc = readFromAddress(m25p, addr, sizeof(buffer));
if (0 < rc) {
vBSP430consoleDisplayMemory(buffer, rc, addr);
}
rc = writeToAddress(m25p, BSP430_M25P_CMD_PP, addr, flashContents, sizeof(flashContents));
cprintf("PAGE_PROGRAM got %d\n", rc);
rc = readFromAddress(m25p, addr, sizeof(buffer));
if (0 < rc) {
vBSP430consoleDisplayMemory(buffer, rc, addr);
}
/* PAGE PROGRAM is the one that only clears 1s to 0s so needs a
* prior page or sector erase */
rc = writeToAddress(m25p, BSP430_M25P_CMD_PP, addr, flashContents + 4, 4);
cprintf("PAGE_PROGRAM to %lx returned %d\n", addr, rc);
rc = readFromAddress(m25p, 0, sizeof(flashContents));
/*
Write 4 took 8
PAGE_PROGRAM to 0 returned 4
00000000 88 11 03 30 cc 33 c3 3c 01 23 45 67 89 ab cd ef ...0.3.<.#Eg....
*/
/* PAGE_WRITE is the one that does not need a prior erase cycle */
addr = 8;
#if (BSP430_PLATFORM_M25P_SUPPORTS_PW - 0)
rc = writeToAddress(m25p, BSP430_M25P_CMD_PW, addr, flashContents + 4, 4);
cprintf("PAGE_WRITE to %lx returned %d\n", addr, rc);
#else
rc = writeToAddress(m25p, BSP430_M25P_CMD_PP, addr, flashContents + 4, 4);
cprintf("overwrite PAGE_PROGRAM to unerased %lx returned %d\n", addr, rc);
#endif
rc = readFromAddress(m25p, 0, sizeof(flashContents));
/*
Write 4 took 204
PAGE_WRITE to 8 returned 4
00000000 88 11 03 30 cc 33 c3 3c cc 33 c3 3c 89 ab cd ef ...0.3.<.3.<....
*/
cprintf("Initiating bulk erase...");
t0 = t1 = 0;
if (0 == rc) {
}
if (0 == rc) {
int sr;
do {
} while ((0 <= sr) && (BSP430_M25P_SR_WIP & sr));
}
cprintf("\nBULK_ERASE got %d\n", rc);
if (0 == rc) {
cprintf("Bulk erase took %lu utt = %s\n", t1-t0, xBSP430uptimeAsText(t1 - t0, tstr));
}
rc = readFromAddress(m25p, 0, sizeof(flashContents));
rc = writeToAddress(m25p, BSP430_M25P_CMD_PP, 0, flashContents, sizeof(flashContents));
cprintf("Restore got %d\n", rc);
addr = 0;
while (addr < (256 * 1025L)) {
rc = readFromAddress(m25p, addr, sizeof(buffer));
if (0 > rc) {
break;
}
vBSP430consoleDisplayMemory(buffer, rc, addr);
addr += rc;
break;
}
}