diff options
Diffstat (limited to 'firmware/93c46.c')
-rw-r--r-- | firmware/93c46.c | 359 |
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; +} + |