summaryrefslogtreecommitdiff
path: root/firmware/93c46.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/93c46.c')
-rw-r--r--firmware/93c46.c359
1 files changed, 359 insertions, 0 deletions
diff --git a/firmware/93c46.c b/firmware/93c46.c
new file mode 100644
index 0000000..4af0f45
--- /dev/null
+++ b/firmware/93c46.c
@@ -0,0 +1,359 @@
+/*
+ * Author: Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the FH Augsburg nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "common.h"
+#include "protocol.h"
+
+#include <util/delay.h>
+
+
+#include "93c46.h"
+
+void flash_93c46_parser(char *buf)
+{
+ //UARTWrite("flash parser\r\n");
+ switch(buf[3])
+ {
+ case CMD_93C46_INIT:
+ flash_93c46_init_usb();
+ break;
+ case CMD_93C46_DEINIT:
+ flash_93c46_deinit_usb();
+ break;
+ case CMD_93C46_READ:
+ // read addr, length, buffer
+ flash_93c46_read_usb((unsigned char)buf[4], (int)buf[5], &buf[6]);
+ break;
+ case CMD_93C46_WRITE:
+ flash_93c46_write_usb((unsigned char)buf[4], (int)buf[5], &buf[6]);
+ break;
+ default:
+ //UARTWrite("default\r\n");
+ answer[0] = buf[0];
+ answer[1] = RSP_UNKOWN_CMD;
+ answer[2] = 0;
+ CommandAnswer(3);
+ }
+}
+
+void flash_93c46_init_usb(void)
+{
+ answer[0] = CMD_93C46_INIT;
+ answer[1] = (unsigned char) flash_93c46_init();
+ answer[2] = 0;
+ CommandAnswer(3);
+}
+
+
+int flash_93c46_init(void)
+{
+ //UARTWrite("init\r\n");
+ SET_DDR_OUT(CS);
+ SET_DDR_OUT(SK);
+
+ SET_DDR_OUT(DI);
+ SET_DDR_IN(DO);
+
+ SET_DDR_OUT(DIN0);
+ SET_DDR_OUT(DIN1);
+
+ CLRPIN(DIN0);
+ CLRPIN(DIN1);
+
+ //SETPIN(DIN0) = D4 = low
+ //SETPIN(DIN1) = D4 = low
+
+ octopus.ports[19]=PIN_OUT;
+ octopus.ports[18]=PIN_OUT;
+ octopus.ports[17]=PIN_OUT;
+ octopus.ports[16]=PIN_IN;
+
+ return RSP_OK;
+}
+
+void flash_93c46_deinit_usb(void)
+{
+ answer[0]=CMD_93C46_DEINIT;
+ answer[1]=(unsigned char)flash_93c46_deinit();
+ answer[2]=0;
+ CommandAnswer(3);
+}
+
+int flash_93c46_deinit(void)
+{
+ octopus.ports[5]=PIN_OUT; // this is wrong!
+ octopus.ports[6]=PIN_OUT; // this is wrong!
+ octopus.ports[7]=PIN_OUT; // this is wrong!
+
+ return RSP_OK;
+}
+
+void flash_93c46_read_usb(unsigned char address, unsigned int length, char * buf)
+{
+ answer[0]=CMD_93C46_READ;
+ answer[1]=(unsigned char)flash_93c46_read(address,length,(char*)&answer[2]);
+ CommandAnswer(length+2);
+}
+
+int flash_93c46_read(unsigned char address, unsigned int length, char * buf)
+{
+ //UARTWrite("read\r\n");
+ //SendHex((uint8_t)address);
+ //SendHex(flash_93c46_read_word((uint8_t)address));
+ unsigned int i;
+ for(i = 0; i < length; i++)
+ buf[i] = (char)flash_93c46_read_word((uint8_t)address+i);
+
+ return RSP_OK;
+}
+
+
+void flash_93c46_write_usb(unsigned char address, unsigned int length, char * buf)
+{
+ answer[0]=CMD_93C46_WRITE;
+ answer[1]=(unsigned char)flash_93c46_write(address,length, buf);
+ answer[2]=0x00;
+ CommandAnswer(3);
+}
+
+int flash_93c46_write(unsigned char address, unsigned int length, char * buf)
+{
+ unsigned int i;
+ //UARTWrite("write\r\n");
+ //SendHex((uint8_t)address);
+ //SendHex(length);
+ //SendHex(buf[0]);
+
+ for(i=0;i<length;i++)
+ flash_93c46_write_word((uint8_t)address+i,buf[i]);
+
+ return RSP_OK;
+}
+
+
+
+// Write enable must precede all programming modes.
+
+
+
+void start_of_ins(void)
+{
+ CLRPIN(CS);
+ CLRPIN(SK);
+ CLRPIN(DI);
+
+ _delay_ms(5);
+ //SETPIN(DO);
+ SETPIN(CS);
+ //_delay_us(2);
+
+ _delay_us(2);
+ SETPIN(DI); //SB
+ SETPIN(SK);
+ _delay_us(2);
+}
+
+
+void send_sb_opcode(uint8_t ins)
+{
+ uint8_t i;
+ for( i =0; i <2; i ++)
+ {
+ CLRPIN(SK);
+ if ( ins & 0x80 ) SETPIN(DI); else CLRPIN(DI);
+ _delay_us(2);
+ SETPIN(SK);
+ _delay_us(2);
+ ins = ins <<1;
+ }
+}
+
+void send_address(uint8_t da)
+{
+ uint8_t i;
+ da = da << 1;
+ for( i = 0; i <7; i ++)
+ {
+ CLRPIN(SK);
+ if ( da & 0x80 ) SETPIN(DI); else CLRPIN(DI);
+ _delay_us(2);
+ SETPIN(SK);
+ _delay_us(2);
+ da = da << 1;
+ }
+}
+
+void send_data_byte(uint8_t da)
+{
+ uint8_t i;
+ for( i = 0; i <8; i ++)
+ {
+ CLRPIN(SK);
+ if ( da & 0x80 ) SETPIN(DI); else CLRPIN(DI);
+ _delay_us(2);
+ SETPIN(SK);
+ _delay_us(2);
+ da = da << 1;
+ }
+}
+
+
+uint8_t end_of_erase_write(void)
+{
+
+ uint8_t delay_tmp =0xff;
+ CLRPIN(SK);
+ CLRPIN(DI);
+ _delay_us(2);
+ SETPIN(SK);
+ _delay_us(2);
+ CLRPIN(SK);
+ CLRPIN(CS);
+ _delay_us(2);
+ SETPIN(SK);
+ _delay_us(2);
+ CLRPIN(SK);
+ _delay_us(2);
+ SETPIN(CS);
+
+ do{
+ if(delay_tmp-- > 0) return 0;
+ SETPIN(SK);
+ _delay_us(2);
+ CLRPIN(SK);
+ _delay_us(2);
+ } while (GETPIN(DO));
+
+ return 1;
+}
+
+void end_of_erase_write_disable(void)
+{
+ CLRPIN(SK);
+ CLRPIN(CS);
+ CLRPIN(DI);
+ SETPIN(DO);
+}
+
+void erase_write_enable(void)
+{
+ start_of_ins();
+ send_sb_opcode(CMD_EWEN);
+ send_address(0x60);
+}
+
+void erase_write_disable(void)
+{
+ start_of_ins();
+ send_sb_opcode(CMD_EWDS);
+ send_address(0x00);
+ end_of_erase_write_disable();
+}
+
+
+uint8_t write_word_step(uint8_t add,uint8_t wd)
+{
+ start_of_ins();
+ send_sb_opcode(CMD_WRITE);
+ send_address(add);
+ send_data_byte(wd);
+ return 1;
+ //return( end_of_erase_write() );
+}
+
+uint8_t erase_word(uint8_t add)
+{
+ start_of_ins();
+ send_sb_opcode(CMD_ERASE);
+ send_address(add);
+ return( end_of_erase_write() );
+}
+
+uint8_t recv_data_word(void)
+{
+ uint8_t i;
+ uint8_t da=0;
+ CLRPIN(SK);
+ _delay_us(2);
+ CLRPIN(DI);
+
+ for( i =0; i <8; i ++)
+ {
+ da *= 2;
+ SETPIN(SK);
+ _delay_us(2);
+ CLRPIN(SK);
+ if (GETPIN(DO)) da++;
+ _delay_us(2);
+ }
+
+ CLRPIN(CS);
+ SETPIN(SK);
+ _delay_us(2);
+ SETPIN(CS);
+ CLRPIN(SK);
+ _delay_us(2);
+ return da;
+}
+
+uint8_t flash_93c46_read_word(uint8_t add)
+{
+ //if(add < 0 && add > 127 )
+ // return 0;
+
+ start_of_ins();
+ send_sb_opcode(CMD_READ);
+ send_address(add);
+ return( recv_data_word() );
+}
+
+
+uint8_t flash_93c46_write_word(uint8_t add,uint8_t wd)
+{
+
+// if(add < 0 && add > 127 )
+// return 0;
+
+ erase_write_enable();
+ write_word_step(add,wd);
+ //_delay_ms(1);
+
+ return 1;
+ do
+ {
+ //write_word_step(add,wd);
+ _delay_us(10);
+ } while (flash_93c46_read_word(add)!=wd);
+ return 1;
+}
+