43 #include <avr/interrupt.h>
44 #include <avr/pgmspace.h>
46 #include "dev/watchdog.h"
53 #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
63 #define PRINTF_CFS(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
65 #define PRINTF_CFS(...)
71 #include "lib/random.h"
74 #define FAIL(x) error = (x); goto end;
79 coffee_file_test(
void)
83 unsigned char buf[256], buf2[11];
84 int32_t r, i, j, total_read;
85 CFS_CONF_OFFSET_TYPE offset;
95 for(r = 0; r <
sizeof(buf); r++) {
106 r = cfs_write(wfd, buf,
sizeof(buf));
109 }
else if(r <
sizeof(buf)) {
114 r = cfs_read(wfd, buf,
sizeof(buf));
126 r = cfs_write(rfd, buf,
sizeof(buf));
132 memset(buf, 0,
sizeof(buf));
133 r = cfs_read(rfd, buf,
sizeof(buf));
136 }
else if(r <
sizeof(buf)) {
137 PRINTF_CFS(
"r=%d\n", r);
142 for(r = 0; r <
sizeof(buf); r++) {
144 PRINTF_CFS(
"r=%d. buf[r]=%d\n", r, buf[r]);
155 r = cfs_write(wfd, buf,
sizeof(buf));
158 }
else if(r <
sizeof(buf)) {
164 memset(buf, 0,
sizeof(buf));
165 r = cfs_read(rfd, buf,
sizeof(buf));
168 }
else if(r <
sizeof(buf)) {
173 for(r = 0; r <
sizeof(buf); r++) {
180 for(r = 0; r <
sizeof(buf); r++) {
181 buf[r] =
sizeof(buf) - r - 1;
186 r = cfs_write(wfd, buf,
sizeof(buf));
189 }
else if(r <
sizeof(buf)) {
198 memset(buf, 0,
sizeof(buf));
199 r = cfs_read(rfd, buf,
sizeof(buf));
202 }
else if(r <
sizeof(buf)) {
203 PRINTF_CFS(
"r = %d\n", r);
208 for(r = 0; r <
sizeof(buf); r++) {
209 if(buf[r] !=
sizeof(buf) - r - 1) {
222 for(r = 0; r < 100; r++) {
228 offset = random_rand() % FILE_SIZE;
230 for(r = 0; r <
sizeof(buf); r++) {
238 if(cfs_write(wfd, buf,
sizeof(buf)) !=
sizeof(buf)) {
246 memset(buf, 0,
sizeof(buf));
247 if(cfs_read(wfd, buf,
sizeof(buf)) !=
sizeof(buf)) {
251 for(i = 0; i <
sizeof(buf); i++) {
253 PRINTF_CFS(
"buf[%d] != %d\n", i, buf[i]);
259 #define APPEND_BYTES 3000
261 for (i = 0; i < APPEND_BYTES; i += BULK_SIZE) {
266 for (j = 0; j < BULK_SIZE; j++) {
267 buf[j] = 1 + ((i + j) & 0x7f);
269 if ((r = cfs_write(afd, buf, BULK_SIZE)) != BULK_SIZE) {
270 PRINTF_CFS(
"Count:%d, r=%d\n", i, r);
283 while((r = cfs_read(afd, buf2,
sizeof(buf2))) > 0) {
284 for(j = 0; j < r; j++) {
285 if(buf2[j] != 1 + ((total_read + j) & 0x7f)) {
292 PRINTF_CFS(
"FAIL:-35 r=%d\n",r);
295 if(total_read != APPEND_BYTES) {
296 PRINTF_CFS(
"FAIL:-35 total_read=%d\n",total_read);
305 #define APPEND_BYTES_1 2000
306 #define BULK_SIZE_1 10
307 for (i = 0; i < APPEND_BYTES_1; i += BULK_SIZE_1) {
312 for (j = 0; j < BULK_SIZE_1; j++) {
313 buf[j] = 1 + ((i + j) & 0x7f);
317 if ((r = cfs_write(afd, buf, BULK_SIZE_1)) != BULK_SIZE_1) {
318 PRINTF_CFS(
"Count:%d, r=%d\n", i, r);
329 while((r = cfs_read(afd, buf2,
sizeof(buf2))) > 0) {
330 for(j = 0; j < r; j++) {
331 if(buf2[j] != 1 + ((total_read + j) & 0x7f)) {
332 PRINTF_CFS(
"FAIL:-39, total_read=%d r=%d\n",total_read,r);
339 PRINTF_CFS(
"FAIL:-40 r=%d\n",r);
342 if(total_read != APPEND_BYTES_1) {
343 PRINTF_CFS(
"FAIL:-41 total_read=%d\n",total_read);
348 #define APPEND_BYTES_2 1000
349 #define BULK_SIZE_2 10
350 for (i = 0; i < APPEND_BYTES_2; i += BULK_SIZE_2) {
355 for (j = 0; j < BULK_SIZE_2; j++) {
356 buf[j] = 1 + ((i + j) & 0x7f);
359 if ((r = cfs_write(afd, buf, BULK_SIZE_2)) != BULK_SIZE_2) {
360 PRINTF_CFS(
"Count:%d, r=%d\n", i, r);
372 while((r = cfs_read(afd, buf2,
sizeof(buf2))) > 0) {
373 for(j = 0; j < r; j++) {
374 if(buf2[j] != 1 + ((total_read + j) & 0x7f)) {
375 PRINTF_CFS(
"FAIL:-45, total_read=%d r=%d\n",total_read,r);
382 PRINTF_CFS(
"FAIL:-46 r=%d\n",r);
385 if(total_read != APPEND_BYTES_2) {
386 PRINTF_CFS(
"FAIL:-47 total_read=%d\n",total_read);
402 #ifdef COFFEE_AVR_EEPROM
406 static const unsigned char nullb[COFFEE_SECTOR_SIZE];
412 avr_eeprom_erase(uint16_t sector)
414 eeprom_write(COFFEE_START + sector * COFFEE_SECTOR_SIZE,
415 (
unsigned char *)nullb,
sizeof(nullb));
419 #ifdef COFFEE_AVR_FLASH
427 avr_flash_read(CFS_CONF_OFFSET_TYPE addr, uint8_t *buf, CFS_CONF_OFFSET_TYPE size)
429 uint32_t addr32=COFFEE_START+addr;
432 unsigned char *bufo=(
unsigned char *)buf;
434 uint16_t w=addr32>>1;
435 PRINTF(
"r0x%04x(%u) ",w,size);
437 #ifndef FLASH_WORD_READS
438 for (;isize>0;isize--) {
439 #if FLASH_COMPLEMENT_DATA
440 *buf++=~(uint8_t)pgm_read_byte_far(addr32++);
442 *buf++=(uint8_t)pgm_read_byte_far(addr32++);
448 #if FLASH_COMPLEMENT_DATA
449 *buf++=~(uint8_t)pgm_read_byte_far(addr32++);
451 *buf++=(uint8_t)pgm_read_byte_far(addr32++);
455 for (;isize>1;isize-=2) {
456 #if FLASH_COMPLEMENT_DATA
457 *(uint16_t *)buf=~(uint16_t)pgm_read_word_far(addr32);
459 *(uint16_t *)buf=(uint16_t)pgm_read_word_far(addr32);
465 #if FLASH_COMPLEMENT_DATA
466 *buf++=~(uint8_t)pgm_read_byte_far(addr32);
468 *buf++=(uint8_t)pgm_read_byte_far(addr32);
486 void avr_flash_erase(coffee_page_t sector) {
489 #if FLASH_COMPLEMENT_DATA
491 volatile uint8_t sreg;
497 for (i = 0; i < COFFEE_SECTOR_SIZE / COFFEE_PAGE_SIZE; i++) {
498 for (addr32 = COFFEE_START + (((sector + i) * COFFEE_PAGE_SIZE)
499 & ~(COFFEE_PAGE_SIZE - 1)); addr32 < (COFFEE_START + (((sector
500 + i + 1) * COFFEE_PAGE_SIZE) & ~(COFFEE_PAGE_SIZE - 1))); addr32
502 boot_page_erase(addr32);
503 boot_spm_busy_wait();
511 for (i=0;i<COFFEE_SECTOR_SIZE/COFFEE_PAGE_SIZE;i++) {
512 avr_flash_write((sector+i)*COFFEE_PAGE_SIZE,0,0);
522 if ((sector+i)==COFFEE_PAGES-1) {
523 int j=(int)(COFFEE_START>>1),k=(int)((COFFEE_START>>1)+(COFFEE_SIZE>>1)),l=(int)(COFFEE_SIZE/1024UL);
524 printf_P(PSTR(
"\nTesting coffee filesystem [0x%08x -> 0x%08x (%uKb)] ..."),j,k,l);
525 int r= coffee_file_test();
527 printf_P(PSTR(
"\nFailed with return %d! :-(\n"),r);
529 printf_P(PSTR(
"Passed! :-)\n"));
542 char avr_httpd_fs_getchar(
char *addr) {
544 avr_flash_read((CFS_CONF_OFFSET_TYPE) addr, (uint8_t*) &r, 1);
547 int avr_httpd_fs_strcmp (
char *ram,
char *addr) {
548 uint8_t i,*in,buf[32];
549 avr_flash_read((CFS_CONF_OFFSET_TYPE)addr, buf,
sizeof(buf));
553 if (buf[i]==0)
return(0);
554 if (buf[i]!=*in)
break;
561 char * avr_httpd_fs_strchr (
char *addr,
int character) {
565 avr_flash_read((CFS_CONF_OFFSET_TYPE)addr, (uint8_t *) buf, 128);
566 pptr=strchr(buf, character);
567 if (pptr!=&buf[128]) {
568 if (pptr==0)
return 0;
569 return (addr+(pptr-buf));
585 avr_flash_write(CFS_CONF_OFFSET_TYPE addr, uint8_t *buf, CFS_CONF_OFFSET_TYPE size)
599 #if 0 //this is 8 bytes longer
600 uint16_t startpage=addr/COFFEE_PAGE_SIZE;
601 addr32=COFFEE_START+startpage*COFFEE_PAGE_SIZE;
603 addr32=(COFFEE_ADDRESS&~(SPM_PAGESIZE-1))+(addr&~(SPM_PAGESIZE-1));
605 bb=addr & (SPM_PAGESIZE-1);
606 ba=COFFEE_PAGE_SIZE-((addr+size)&0xff);
609 uint16_t startpage=addr/COFFEE_PAGE_SIZE;
612 PRINTF(
"w0x%04x %u %u %u",w,size,bb,ba);
614 PRINTF(
"e0x%04x %u ",w,startpage);
623 w=pgm_read_word_far(addr32);
624 boot_page_fill(addr32,w);
631 w=pgm_read_word_far(addr32);
632 #if FLASH_COMPLEMENT_DATA
642 #if FLASH_COMPLEMENT_DATA
645 boot_page_fill(addr32, w);
662 if ((addr32&0x000000ff)==0) {
665 boot_page_erase(addr32);
666 boot_spm_busy_wait();
667 boot_page_write(addr32);
668 boot_spm_busy_wait();
675 w=pgm_read_word_far(addr32);
678 #if FLASH_COMPLEMENT_DATA
685 boot_page_fill(addr32,w);
691 #if FLASH_COMPLEMENT_DATA
692 addr32+=2*SPM_PAGESIZE;
694 for (w=0;w<SPM_PAGESIZE;w++) {
695 boot_page_fill(addr32, 0);
702 boot_page_erase(addr32);
703 boot_spm_busy_wait();
704 #if FLASH_COMPLEMENT_DATA
706 boot_page_write(addr32);
707 boot_spm_busy_wait();
710 boot_page_write(addr32);
711 boot_spm_busy_wait();
724 #ifdef COFFEE_AVR_EXTERNAL
728 void external_flash_write_page(coffee_page_t page, CFS_CONF_OFFSET_TYPE offset, uint8_t * buf, CFS_CONF_OFFSET_TYPE size) {
729 PRINTF(
"external_flash_write_page(page %u, offset %u, buf %p, size %u) \n", page, offset, buf, size);
735 if( page > COFFEE_PAGES ) {
739 if( (size + offset) > COFFEE_PAGE_SIZE ) {
743 unsigned char buffer[COFFEE_PAGE_SIZE];
751 memcpy(buffer + offset, buf, size);
758 PRINTF(
"Page %u programmed with %u bytes (%u new)\n", page, COFFEE_PAGE_SIZE, size);
761 void external_flash_write(CFS_CONF_OFFSET_TYPE addr, uint8_t *buf, CFS_CONF_OFFSET_TYPE size) {
762 PRINTF(
">>>>> external_flash_write(addr %u, buf %p, size %u)\n", addr, buf, size);
764 if( addr > COFFEE_SIZE ) {
769 coffee_page_t current_page = addr / COFFEE_PAGE_SIZE;
770 CFS_CONF_OFFSET_TYPE written = 0;
772 while(written < size) {
774 CFS_CONF_OFFSET_TYPE page_start = current_page * COFFEE_PAGE_SIZE;
775 CFS_CONF_OFFSET_TYPE offset = 0;
777 if( addr > page_start ) {
779 offset = addr - page_start;
782 CFS_CONF_OFFSET_TYPE length = size - written;
784 if( length > (COFFEE_PAGE_SIZE - offset) ) {
785 length = COFFEE_PAGE_SIZE - offset;
788 external_flash_write_page(current_page, offset, buf + written, length);
796 for(g=0; g<size; g++) {
797 printf(
"%02X %c ", buf[g] & 0xFF, buf[g] & 0xFF);
803 void external_flash_read_page(coffee_page_t page, CFS_CONF_OFFSET_TYPE offset, uint8_t *buf, CFS_CONF_OFFSET_TYPE size) {
804 PRINTF(
"external_flash_read_page(page %u, offset %u, buf %p, size %u)\n", page, offset, buf, size );
806 if( page > COFFEE_PAGES ) {
816 for(g=0; g<size; g++) {
817 printf(
"%02X %c ", buf[g] & 0xFF, buf[g] & 0xFF);
823 void external_flash_read(CFS_CONF_OFFSET_TYPE addr, uint8_t *buf, CFS_CONF_OFFSET_TYPE size) {
824 PRINTF(
">>>>> external_flash_read(addr %u, buf %p, size %u)\n", addr, buf, size );
830 if( addr > COFFEE_SIZE ) {
835 coffee_page_t current_page = addr / COFFEE_PAGE_SIZE;
836 CFS_CONF_OFFSET_TYPE read = 0;
838 while( read < size ) {
840 CFS_CONF_OFFSET_TYPE page_start = current_page * COFFEE_PAGE_SIZE;
841 CFS_CONF_OFFSET_TYPE offset = 0;
843 if( addr > page_start ) {
845 offset = addr - page_start;
848 CFS_CONF_OFFSET_TYPE length = size - read;
850 if( length > (COFFEE_PAGE_SIZE - offset) ) {
851 length = (COFFEE_PAGE_SIZE - offset);
854 external_flash_read_page(current_page, offset, buf + read, length);
856 PRINTF(
"Page %u read with %u bytes (offset %u)\n", h, length, offset);
865 for(g=0; g<size; g++) {
866 printf(
"%02X %c ", buf[g] & 0xFF, buf[g] & 0xFF);
872 void external_flash_erase(coffee_page_t page) {
873 if( page > COFFEE_PAGES ) {
877 PRINTF(
"external_flash_erase(page %u)\n", page);