static inline uint32_t fl_x32(struct bankdesc *b, union bconv *pv) { if ( 4 == FLASH_STRIDE(b) ) return pv->u; else if ( 2 == FLASH_STRIDE(b) ) return pv->s[0]; else return pv->c[0]; }
STATIC uint32_t flash_write_line_s160(struct bankdesc *b, uint32_t a, char *s, uint32_t N) { uint32_t sta, nxt, j, v; union bconv buf; if ( 0 == N ) return -11; if ( N & (FLASH_STRIDE(b) - 1) ) { fprintf(stderr,"flash_write_line_s160: invalid byte count (not multiple of stride\n"); return -10; } unlk(b, a); /* address block */ fl_wr32_cmd(b, a, 0, WRBUF_DATA); /* (16-bit) word count per device */ N /= FLASH_STRIDE(b); fl_wr32_cmd(b, a, 0, N-1); /* silence compiler warning about uninitialized var (N > 0 at this point) */ v = 0; /* fill buffer */ for (nxt = a; N>0; N--) { #if (DEBUG > 4) printf("Writing DAT *0x%08"PRIx32" = 0x%08"PRIx32"\n", nxt, *(uint32_t*)s); #endif /* deal with misaligned sources */ for ( j=0; j<FLASH_STRIDE(b); j++ ) { buf.c[j] = *s++; } v = fl_x32(b, &buf); fl_wr32(b, nxt, v); nxt += FLASH_STRIDE(b); } /* burn buffer */ fl_wr32_cmd(b, a, 0, PGBUF_DATA); /* pend */ sta = flash_pend(b, nxt - FLASH_STRIDE(b), WRITE_TIMEOUT, v); return sta; }
static inline uint32_t fl_splat32(struct bankdesc *b, uint32_t x) { if ( 4 == FLASH_STRIDE(b) ) { if ( 1 == b->width ) { x = (x << 8) | x; } x = (x<<16) | x; } else if ( 2 == FLASH_STRIDE(b) ) { if ( 1 == b->width ) x = (x << 8) | x; } return x; }
static inline void fl_wr32(struct bankdesc *b, uint32_t a, uint32_t v) { volatile union bconv *p = (volatile union bconv*)a; if ( 4 == FLASH_STRIDE(b) ) { p->u = v; IOSYNC(p->u); } else if ( 2 == FLASH_STRIDE(b) ) { p->s[0] = v; IOSYNC(p->s[0]); } else { p->c[0] = v; IOSYNC(p->c[0]); } }
STATIC uint32_t flash_write_line_intel(struct bankdesc *b, uint32_t a, char *s, uint32_t N) { uint32_t sta, Nspla, nxt, j; union { uint32_t u; char c[sizeof(uint32_t)]; } buf; /* address block */ if ( STA_RDYRDY != (sta = BSP_flashReadRaw(F_CMD_WR_BUF, a)) ) { return sta; } /* count per device */ N /= FLASH_STRIDE(b); /* splat out */ Nspla = (N<<8) | N; Nspla = (Nspla<<16) | Nspla; BSP_flashWriteRaw(Nspla - 0x01010101, a); /* fill buffer */ for (nxt = a; N>0; N--) { #if defined(TESTING) || (DEBUG > 4) printf("Writing DAT *0x%08"PRIx32" = 0x%08"PRIx32"\n", nxt, *(uint32_t*)s); #endif /* deal with misaligned sources */ for ( j=0; j<sizeof(buf.u); j++ ) { buf.c[j] = *s++; } *(A32)nxt = buf.u; nxt += FLASH_STRIDE(b); } BSP_flashReadRaw(F_CMD_WR_CMD, a); sta = flash_pend(b, a, TIMEOUT_US); return sta; }
STATIC int flash_get_id_intel(struct bankdesc *b, uint32_t addr, uint32_t *pVendorId, uint32_t *pDeviceId) { uint16_t v,d; if ( 4 != FLASH_STRIDE(b) ) { fprintf(stderr,"intel flash programmer: Strides other than 4 not implemented yet\n"); return -1; } /* Try to read ID */ v = BSP_flashReadRaw(F_CMD_RD_ID, addr); d = BSP_flashReadRaw(F_CMD_RD_ID, addr + FLASH_STRIDE(b)); /* switch to array mode */ flash_array_mode_intel(b, addr); *pVendorId = v; *pDeviceId = d; return 0; }
static inline uint32_t fl_rd32(struct bankdesc *b, uint32_t a, uint32_t off) { volatile union bconv *p; uint32_t rval; if ( 1 == b->width ) off <<= 1;; a = ADDR32(b, a, off); p = (volatile union bconv *)a; if ( 4 == FLASH_STRIDE(b) ) { rval = p->u; IOSYNC(p->u); } else if ( 2 == FLASH_STRIDE(b) ) { rval = p->s[0]; IOSYNC(p->s[0]); } else { rval = p->c[0]; IOSYNC(p->c[0]); } return rval; }
STATIC int flash_get_id_s160(struct bankdesc *b, uint32_t addr, uint32_t *pVendorId, uint32_t *pDeviceId) { uint32_t dev_id[3], x, i; if ( 4 != FLASH_STRIDE(b) ) fprintf(stderr,"Warning: strides other than 4 untested\n(%s at %d)\n", __FILE__,__LINE__); if ( 2 != b->width ) fprintf(stderr,"Warning: device width other than 2 untested\n(%s at %d)\n", __FILE__,__LINE__); addr &= ~ (ADDR32(b, 0, 0x1000) - 1); unlk(b, addr); fl_wr32_cmd(b, addr, UNLK1_ADDR_16, ASEL_DATA); *pVendorId = fl_rd32(b, addr, VEND_ID_ADDR_16) & 0xff; dev_id [0] = fl_rd32(b, addr, DEV1_ID_ADDR_16); dev_id [1] = fl_rd32(b, addr, DEV2_ID_ADDR_16); dev_id [2] = fl_rd32(b, addr, DEV3_ID_ADDR_16); #ifdef DEBUG printf("Vendor Id 0x%08"PRIx32", Dev Ids: 0x%08"PRIx32", 0x%08"PRIx32", 0x%08"PRIx32"\n", *pVendorId, dev_id[0], dev_id[1], dev_id[2]); #endif flash_array_mode_s160(b, addr); for ( x=0, i=0; i<3; i++ ) { x = (x<<8) | (dev_id[i] & 0xff); } *pDeviceId = x; return 0; }