4141 CMD_NAND_SELECT = 0x06 ,
4242};
4343
44+ enum
45+ {
46+ ERR_ADDR_EXCEEDED = 0x00 ,
47+ ERR_ADDR_INVALID = 0x01 ,
48+ ERR_NAND_WR = 0x02 ,
49+ ERR_NAND_RD = 0x03 ,
50+ ERR_NAND_ERASE = 0x04 ,
51+ ERR_CHIP_NOT_SEL = 0x05 ,
52+ ERR_CHIP_NOT_FOUND = 0x06 ,
53+ ERR_CMD_DATA_SIZE = 0x07 ,
54+ ERR_BUF_OVERFLOW = 0x08 ,
55+ };
56+
4457typedef struct __attribute__((__packed__ ))
4558{
4659 uint8_t code ;
@@ -123,6 +136,12 @@ typedef struct __attribute__((__packed__))
123136 uint32_t bytes_ack ;
124137} resp_write_ack_t ;
125138
139+ typedef struct __attribute__((__packed__ ))
140+ {
141+ resp_t header ;
142+ uint8_t err_code ;
143+ } resp_err_t ;
144+
126145typedef struct
127146{
128147 uint32_t addr ;
@@ -221,9 +240,9 @@ static void usb_init(usb_t *usb)
221240 usb -> rx_buf_size = USB_BUF_SIZE ;
222241}
223242
224- static int make_status (usb_t * usb , int is_ok )
243+ static int make_ok_status (usb_t * usb )
225244{
226- resp_t status = { RESP_STATUS , is_ok ? STATUS_OK : STATUS_ERROR };
245+ resp_t status = { RESP_STATUS , STATUS_OK };
227246 size_t len = sizeof (status );
228247
229248 if (len > usb -> tx_buf_size )
@@ -238,6 +257,24 @@ static int make_status(usb_t *usb, int is_ok)
238257 return len ;
239258}
240259
260+ static int make_error_status (usb_t * usb , uint8_t err_code )
261+ {
262+ resp_t status = { RESP_STATUS , STATUS_ERROR };
263+ resp_err_t err_status = { status , err_code };
264+ size_t len = sizeof (err_status );
265+
266+ if (len > usb -> tx_buf_size )
267+ {
268+ ERROR_PRINT ("Status size %d is more then TX buffer size %d\r\n" , len ,
269+ usb -> tx_buf_size );
270+ return -1 ;
271+ }
272+
273+ memcpy (usb -> tx_buf , & err_status , len );
274+
275+ return len ;
276+ }
277+
241278static int send_bad_block_info (uint32_t addr )
242279{
243280 resp_t resp_header = { RESP_STATUS , STATUS_BAD_BLOCK };
@@ -262,13 +299,13 @@ static int cmd_nand_read_id(prog_t *prog)
262299 if (!chip_is_selected ())
263300 {
264301 ERROR_PRINT ("Chip is not selected\r\n" );
265- goto Error ;
302+ return make_error_status ( & prog -> usb , ERR_CHIP_NOT_SEL ) ;
266303 }
267304
268305 if (prog -> usb .tx_buf_size < resp_len )
269306 {
270307 ERROR_PRINT ("Response size is more then TX buffer size\r\n" );
271- goto Error ;
308+ return make_error_status ( & prog -> usb , ERR_BUF_OVERFLOW ) ;
272309 }
273310
274311 resp .header .code = RESP_DATA ;
@@ -278,9 +315,6 @@ static int cmd_nand_read_id(prog_t *prog)
278315 memcpy (prog -> usb .tx_buf , & resp , resp_len );
279316
280317 return resp_len ;
281-
282- Error :
283- return make_status (& prog -> usb , 0 );
284318}
285319
286320static int nand_erase (uint32_t page , uint32_t addr )
@@ -312,7 +346,7 @@ static int nand_erase(uint32_t page, uint32_t addr)
312346static int cmd_nand_erase (prog_t * prog )
313347{
314348 chip_info_t * chip_info ;
315- uint32_t addr , page , pages_in_block , ret = -1 ;
349+ uint32_t addr , page , pages_in_block ;
316350 erase_cmd_t * erase_cmd = (erase_cmd_t * )prog -> usb .rx_buf ;
317351
318352 DEBUG_PRINT ("Erase at 0x%lx %lx bytes command\r\n" , erase_cmd -> addr ,
@@ -321,7 +355,7 @@ static int cmd_nand_erase(prog_t *prog)
321355 if (!chip_is_selected ())
322356 {
323357 ERROR_PRINT ("Chip is not selected\r\n" );
324- goto Exit ;
358+ return make_error_status ( & prog -> usb , ERR_CHIP_NOT_SEL ) ;
325359 }
326360 chip_info = chip_info_selected_get ();
327361
@@ -337,11 +371,11 @@ static int cmd_nand_erase(prog_t *prog)
337371 {
338372 ERROR_PRINT ("Erase address 0x%lx is more then chip size 0x%lx\r\n" ,
339373 addr , chip_info -> size );
340- goto Exit ;
374+ return make_error_status ( & prog -> usb , ERR_ADDR_EXCEEDED ) ;
341375 }
342376
343377 if (nand_erase (page , addr ))
344- goto Exit ;
378+ return make_error_status ( & prog -> usb , ERR_NAND_ERASE ) ;
345379
346380 if (erase_cmd -> len >= chip_info -> block_size )
347381 erase_cmd -> len -= chip_info -> block_size ;
@@ -351,9 +385,7 @@ static int cmd_nand_erase(prog_t *prog)
351385 page += pages_in_block ;
352386 }
353387
354- ret = 0 ;
355- Exit :
356- return make_status (& prog -> usb , !ret );
388+ return make_ok_status (& prog -> usb );
357389}
358390
359391static int send_write_ack (uint32_t bytes_ack )
@@ -381,7 +413,7 @@ static int cmd_nand_write_start(prog_t *prog)
381413 {
382414 ERROR_PRINT ("Write address 0x%lx is more then chip size 0x%lx\r\n" ,
383415 write_start_cmd -> addr , chip_info -> size );
384- return -1 ;
416+ return make_error_status ( & prog -> usb , ERR_ADDR_EXCEEDED ) ;
385417 }
386418
387419 prog -> addr = write_start_cmd -> addr ;
@@ -394,7 +426,7 @@ static int cmd_nand_write_start(prog_t *prog)
394426 prog -> bytes_written = 0 ;
395427 prog -> bytes_ack = 0 ;
396428
397- return 0 ;
429+ return make_ok_status ( & prog -> usb ) ;
398430}
399431
400432static int nand_handle_status (prog_t * prog )
@@ -481,13 +513,13 @@ static int cmd_nand_write_data(prog_t *prog)
481513 prog -> usb .rx_buf_size )
482514 {
483515 ERROR_PRINT ("Data size is wrong %d\r\n" , write_data_cmd -> len );
484- return -1 ;
516+ return make_error_status ( & prog -> usb , ERR_CMD_DATA_SIZE ) ;
485517 }
486518
487519 if (!prog -> addr_is_valid )
488520 {
489521 ERROR_PRINT ("Write address is not set\r\n" );
490- return -1 ;
522+ return make_error_status ( & prog -> usb , ERR_ADDR_INVALID ) ;
491523 }
492524
493525 if (prog -> page .offset + write_data_cmd -> len > chip_info -> page_size )
@@ -501,7 +533,7 @@ static int cmd_nand_write_data(prog_t *prog)
501533 if (prog -> page .offset == chip_info -> page_size )
502534 {
503535 if (nand_write (prog , chip_info ))
504- return -1 ;
536+ return make_error_status ( & prog -> usb , ERR_NAND_WR ) ;
505537
506538 prog -> addr += chip_info -> page_size ;
507539 if (prog -> addr >= chip_info -> size )
@@ -537,29 +569,30 @@ static int cmd_nand_write_end(prog_t *prog)
537569 if (!prog -> addr_is_valid )
538570 {
539571 ERROR_PRINT ("Write address is not set\r\n" );
540- return -1 ;
572+ return make_error_status ( & prog -> usb , ERR_ADDR_INVALID ) ;
541573 }
542574
543575 prog -> addr_is_valid = 0 ;
544576
545577 if (!prog -> page .offset )
546- return 0 ;
578+ goto Exit ;
547579
548580 if (nand_write (prog , chip_info ))
549- return -1 ;
581+ return make_error_status ( & prog -> usb , ERR_NAND_WR ) ;
550582
551- return 0 ;
583+ Exit :
584+ return make_ok_status (& prog -> usb );
552585}
553586
554587static int cmd_nand_write (prog_t * prog )
555588{
556589 cmd_t * cmd = (cmd_t * )prog -> usb .rx_buf ;
557- int ret = -1 ;
590+ int ret = 0 ;
558591
559592 if (!chip_is_selected ())
560593 {
561594 ERROR_PRINT ("Chip is not selected\r\n" );
562- goto Exit ;
595+ return make_error_status ( & prog -> usb , ERR_CHIP_NOT_SEL ) ;
563596 }
564597
565598 switch (cmd -> code )
@@ -569,8 +602,6 @@ static int cmd_nand_write(prog_t *prog)
569602 break ;
570603 case CMD_NAND_WRITE_D :
571604 ret = cmd_nand_write_data (prog );
572- if (!ret )
573- return 0 ;
574605 break ;
575606 case CMD_NAND_WRITE_E :
576607 ret = cmd_nand_write_end (prog );
@@ -579,8 +610,7 @@ static int cmd_nand_write(prog_t *prog)
579610 break ;
580611 }
581612
582- Exit :
583- return make_status (& prog -> usb , !ret );
613+ return ret ;
584614}
585615
586616static int nand_read (uint32_t addr , page_t * page , chip_info_t * chip_info )
@@ -626,15 +656,15 @@ static int cmd_nand_read(prog_t *prog)
626656 if (!chip_is_selected ())
627657 {
628658 ERROR_PRINT ("Chip is not selected\r\n" );
629- goto Error ;
659+ return make_error_status ( & prog -> usb , ERR_CHIP_NOT_SEL ) ;
630660 }
631661 chip_info = chip_info_selected_get ();
632662
633663 if (read_cmd -> addr >= chip_info -> size )
634664 {
635665 ERROR_PRINT ("Read address 0x%lx is more then chip size 0x%lx\r\n" ,
636666 read_cmd -> addr , chip_info -> size );
637- goto Error ;
667+ return make_error_status ( & prog -> usb , ERR_ADDR_EXCEEDED ) ;
638668 }
639669
640670 addr = read_cmd -> addr ;
@@ -646,7 +676,7 @@ static int cmd_nand_read(prog_t *prog)
646676 while (read_cmd -> len )
647677 {
648678 if (nand_read (addr , & page , chip_info ))
649- goto Error ;
679+ return make_error_status ( & prog -> usb , ERR_NAND_RD ) ;
650680
651681 while (page .offset < chip_info -> page_size && read_cmd -> len )
652682 {
@@ -676,23 +706,19 @@ static int cmd_nand_read(prog_t *prog)
676706 {
677707 ERROR_PRINT ("Read address 0x%lx is more then chip size 0x%lx" ,
678708 addr , chip_info -> page_size );
679- goto Error ;
709+ return make_error_status ( & prog -> usb , ERR_ADDR_EXCEEDED ) ;
680710 }
681711 page .page ++ ;
682712 page .offset = 0 ;
683713 }
684714 }
685715
686716 return 0 ;
687-
688- Error :
689- return make_status (& prog -> usb , 0 );
690717}
691718
692719static int cmd_nand_select (prog_t * prog )
693720{
694721 select_cmd_t * select_cmd = (select_cmd_t * )prog -> usb .rx_buf ;
695- int ret = 0 ;
696722
697723 DEBUG_PRINT ("Chip select ID %lu command\r\n" , select_cmd -> chip_num );
698724
@@ -701,10 +727,10 @@ static int cmd_nand_select(prog_t *prog)
701727 else
702728 {
703729 ERROR_PRINT ("Chip ID %lu not found\r\n" , select_cmd -> chip_num );
704- ret = -1 ;
730+ return make_error_status ( & prog -> usb , ERR_CHIP_NOT_FOUND ) ;
705731 }
706732
707- return make_status (& prog -> usb , ! ret );
733+ return make_ok_status (& prog -> usb );
708734}
709735
710736static int usb_cmd_handler (prog_t * prog )
@@ -760,7 +786,7 @@ static void nand_handler(prog_t *prog)
760786 if (prog -> nand_wr_in_progress )
761787 {
762788 if (nand_handle_status (prog ))
763- send_status (prog , make_status (& prog -> usb , 0 ));
789+ send_status (prog , make_error_status (& prog -> usb , ERR_NAND_WR ));
764790 }
765791}
766792
0 commit comments