...

суббота, 19 декабря 2020 г.

24x01 I2C на ATTINY13 без TWI

/*
        InDRIVE v4 Application (chip like: FT24C01, Selfprg Must Be Enabled!!! )

        Fuse BYTES
        Low(0x7A) :             High(0xEE) :
        SPIEN = 1               SELFPRGEN = 1
        EESAVE = 0              DWEN = 0
        WDTON = 0               BODLEVEL1 = 0
        CKDIV8 = 0              BODLEVEL0 = 0
        SUT1 = 0                RSTDISBL = 1
        SUT0 = 1
        CKSEL1 = 0
        CKSEL0 = 1

*/

.include "tn13def.inc"

/* On/Off Defines */
.equ    OFF                     =0
.equ    ON                      =1
/* Chip Pinouts */
.equ    FT24Cxx         =0
.equ    InDRIVE_v4      =1

/* Reset Controller Enable/Disable */
.equ    RESET_CNT       =OFF
/* Chip Pinouts Define: InDrivev4/Regular I2C Chip */
.equ    CHIP_PINOUTS    =FT24Cxx

.equ    DEBUG           =OFF
/* I2C Mode Define MODE 1/MODE 2 */
.equ    MODE_1          =1
.equ    MODE_2          =2
.EQU    I2C_MODE        =MODE_1

/* Define I2C Parameters */
/* Page Size for Write in BYTES 4/8/16 */
/* 128/256 Size in MODE 1 Protocol can't receive more than 128 Bytes */
.IF I2C_MODE == MODE_2
        .MESSAGE "Compile for I2C Mode 2"
.equ    I2C_PAGE_SIZE   =8
.equ    I2C_EEP_SIZE    =256
.ELSE
        .MESSAGE "Compile for I2C Mode 1"
.equ    I2C_PAGE_SIZE   =4
.equ    I2C_EEP_SIZE    =128
.ENDIF

/* 
Modes Define

        A - Address
        iD - Data From Master
        oD - Data To Master

        MODE 1
                Write - [START][AAAAAAA0][iD + 0]...[iD + I2C_PAGE_SIZE - 1][STOP]
                Read -  [START][AAAAAAA1][oD + 0]...[oD + I2C_EEP_SIZE - 1][STOP]
        MODE 2 
                Write - [START][10100000][AAAAAAAA][iD + 0]...[iD + I2C_PAGE_SIZE - 1][STOP]
                Read -  [START][10100001][oD + 0]...[oD + I2C_EEP_SIZE - 1][STOP]
*/

/*
        I2C slave, fSCL = 400kHz
        FULLY Implemented I2C Protocol for 24xx01/24xx02
        And RESET Controller FOR InDRIVE(v4)

**************************************************************   
        ATTINY13A I2C Configuration
**************************************************************   
        pin configuration InDRIVE v4:

                       ,---_---.
    (RESET/PB5)     nc |1     8| VCC
          (PB3)  inRST |2     7| SCL    (PB2)
          (PB4) outRST |3     6| EMU24X (PB1) SDA pin from CORE
                   GND |4     5| nc     (PB0) unused SDA pin
                       `-------'

        pin configuration FT24C01:

                       ,---_---.
    (RESET/PB5)     nc |1     8| VCC
                  (PB3)         nc |2     7| nc         (PB2)
            (PB4)       nc |3     6| SCL        (PB1) SCL pin I2C
                   GND |4     5| SDA    (PB0) SDA pin I2C
                       `-------'

        pin configuration FT24C02:

                       ,---_---.
    (RESET/PB5)     A0 |1     8| VCC
           (PB3)        A1 |2     7| nc         (PB2)
            (PB4)       A2 |3     6| SCL        (PB1) SCL pin I2C
                   GND |4     5| SDA    (PB0) SDA pin I2C
                       `-------'

*/
/* Pins Define */
.IF CHIP_PINOUTS == InDRIVE_v4
        .MESSAGE "Chip Pinouts: InDRIVE v4"
.equ    EMU24X  = 1
.equ    SCL     = 2
.ELSE
.equ    EMU24X  = 0
.equ    SCL     = 1
        .MESSAGE "Chip Pinouts: Regular 24Cxx"
.ENDIF
.equ    SDA     = EMU24X
.equ    ACK     = SDA
.equ    inRST   = 3
.equ    outRST  = 4


.def    TMPnoINT                =R19
.def    Counter                 =R3
.def    CounterInWrite  =R4
.def    SREGST                  =R5

/* Real ATTINY13A FLASH Page SIZE In Bytes */
.equ    PAGESIZEB               =(PAGESIZE*2)

/* SRAM Mapping */
.DSEG
.IF I2C_MODE == MODE_2
        _I2c_device_inaddr:  .BYTE 1    /* MODE 2 Region */
        _I2c_device_myaddr:  .BYTE 1
.ENDIF
        _valSPMCSR: .BYTE 1
        _I2c_data_buffer:       .BYTE I2C_PAGE_SIZE
        _I2c_FLASH_buffer:      .BYTE PAGESIZEB
.cseg

/* Read/Write Pointers */
.def    I2c_start_addr  =R16
.def    I2c_wr_counter  =R17
.def    I2c_wr_pointer  =R18
.def    I2c_rd_pointer  =R21

.def    _PINB                   =R20

.IF I2C_MODE != MODE_2
        .IF I2C_MODE != MODE_1
                .error "Invalid mode for I2C Selected, please correct I2C_MODE define"
        .ENDIF
.ENDIF

.cseg

.org 0//Reset
.IF RESET_CNT == ON
                rjmp    WaitinRSTHI             ;RESET
                reti                                    ;INT0addr       = 0x0001        ; External Interrupt 0
                rjmp    ResetInProcess  ;PCI0addr       = 0x0002        ; External Interrupt Request 0
.ELSE
                rjmp    main                    ;RESET
                reti                                    ;INT0addr       = 0x0001        ; External Interrupt 0
                reti                                    ;PCI0addr       = 0x0002        ; External Interrupt Request 0
.ENDIF
                reti                                    ;OVF0addr       = 0x0003        ; Timer/Counter0 Overflow
                reti                                    ;ERDYaddr       = 0x0004        ; EEPROM Ready
                reti                                    ;ACIaddr        = 0x0005        ; Analog Comparator
                reti                                    ;OC0Aaddr       = 0x0006        ; Timer/Counter Compare Match A
                reti                                    ;OC0Baddr       = 0x0007        ; Timer/Counter Compare Match B
                reti                                    ;WDTaddr        = 0x0008        ; Watchdog Time-out
                reti                                    ;ADCCaddr       = 0x0009        ; ADC Conversion Complete

// *******************************************************************************************
// **   Reset Processor                                                                                 **
// *******************************************************************************************
.IF RESET_CNT == ON
        .MESSAGE "Reset Controller Function is: ON"
ResetInProcess: ;Proccess reset
                sbic    pinb,inRST      ;Process reset on falling edge
                reti

WaitinRSTHI:
                cli

                ;Wait ~80 mS 0x04E360 on 9.6MHz
                ldi             R16,0x10
                ldi             R17,0xE3
                ldi             R18,0x60
                ;Set RESET Enable
                cbi             PORTB,outRST

_CntLO:
                dec             R18
                BRNE    _CntLO
_CntME:
                dec             R17
                BRNE    _CntLO
_CntHI:
                dec             R16
                BRNE    _CntLO

                ; And Clear Iterrupt flag for normal exit
                ldi             R16,(1 << PCIF)
                out             GIFR,R16
.ELSE
        .MESSAGE "Reset Controller Function is: OFF"
.ENDIF  // RESET_CNT == ON
                
// *******************************************************************************************************
// **   Main Programm                                                                                   **
// *******************************************************************************************************
main:
                ;init STACK
                ldi             TMPnoINT,low(RAMEND)
                out             SPL,TMPnoINT

                ;init IO
                ldi             TMPnoINT,0x00
                out             MCUCR,TMPnoINT
                ;Outputs to HI (Pull UP)
                ldi             TMPnoINT,0xFF
                out             PORTB,TMPnoINT
.IF RESET_CNT == ON
                ;Output enable for outRST, all other for input
                sbi             PORTB, outRST
                sbi             PINB, inRST
                sbi             DDRB,outRST     ; Output Enable
                ;Init Interrupt         
        ldi     TMPnoINT, (1 << inRST)    ; set pin change interrupt for inRST
        out     PCMSK, TMPnoINT         
                ldi             TMPnoINT, (1<<PCIE)               ; unmask interrupt PCIE
                out             GIMSK,TMPnoINT
                SEI                                     ;Enable PCIE Int Processing
.ELSE
                CLI             ; Disable Reset Controller
.ENDIF

.IF I2C_MODE == MODE_2
                /* Set I2C Device Address */
                ldi             TMPnoINT, 0xA0
                sts             _I2c_device_myaddr,TMPnoINT
.ENDIF

                /* Clear Buffer Pointers */
                clr             I2c_wr_counter
                clr             I2c_wr_pointer
                clr             I2c_start_addr
                clr             I2c_rd_pointer


main_loop:

lI2c_get:
        sbi portb,ack
        sbis pinb,scl                                            ;wait for SCL&SDA=1
        rjmp lI2c_get
        sbis pinb,sda
        rjmp lI2c_get
lI2c_wait_for_start:
        sbis pinb,scl                                            ;wait for SCL=1,SDA=0 (START)
        rjmp lI2c_get
        sbic pinb,sda
        rjmp lI2c_wait_for_start
lI2c_get_0:                                                  ;clear receive area
.IF I2C_MODE == MODE_2
        clr r22
        sts _I2c_device_inaddr,r22
.ENDIF
lI2c_get_1:                                                  ;get 1st byte
        sbi portb,ack
lI2c_10:                                                     ;wait for SCL=0
        sbic pinb,scl
        rjmp lI2c_10
        ldi r22,8                                                ;bits to receive=8
.IF I2C_MODE == MODE_2
        lds r23,_I2c_device_myaddr                               ;I2C address->R23
.ENDIF
lI2c_11:
        in      _PINB, pinb
        sbrs _PINB,scl                                            ;wait for SCL=1
        rjmp lI2c_11
        sbrc _PINB,sda
        rjmp lI2c_13
lI2c_12:                                                     ;if SDA=0
        sbic pinb,sda
        rjmp lI2c_wait_for_start                                  ;  SDA 0->1? I2CSTOP! (unexpected: wait for next start)
        sbic pinb,scl
        rjmp lI2c_12                                              ;  loop while SCL=1
        clc                                                      ;  SDA=0->C
        rjmp lI2c_15
lI2c_13:                                                     ;if SDA=1
        sbis pinb,sda
        rjmp lI2c_get_1                                           ;  SDA 1->0? I2CSTART! (repeated start)
        sbic pinb,scl
        rjmp lI2c_13                                              ;  loop while SCL=1
        sec                                                      ;  SDA=1->C
lI2c_15:
        rol r24
        dec r22
        brne lI2c_11                                              ;loop to next bit

.IF I2C_MODE == MODE_2
        sts _I2c_device_inaddr,r24
        SUB r24,r23                                              ;my address?
        cpi r24,2
        brlo lI2c_ack_1
        rjmp lI2c_exit                                            ;  no: exit and wait for next start
.ENDIF

lI2c_ack_1:                                                  ;  yes: generate ack

        clr             I2c_wr_counter                                                          ; Clear Write Buffer Pointers
        clr             I2c_wr_pointer
        clr             I2c_start_addr
        cbi portb,ack
        sbi ddrb,ack                                             ;pinb.ack = output (ACK)
lI2c_ack_10:
        sbis pinb,scl                                            ;wait for SCL=1
        rjmp lI2c_ack_10
lI2c_ack_11:
        sbic pinb,scl                                            ;wait for SCL=0
        rjmp lI2c_ack_11
/*************************************************************************
*               Select Read/Write
**************************************************************************/
.IF I2C_MODE == MODE_2
        cpi r24,0
        breq lI2c_get_2
.ELSE
        mov     I2c_start_addr,r24                              ; Extract Received Address
        lsr I2c_start_addr                                      ; And Read/Write BIT
        mov I2c_rd_pointer,I2c_start_addr       ; Upadate Read Address
        brcs lI2c_send_new_byte 
        rjmp    lI2c_ack_25
.ENDIF
/*************************************************************************
*               Sending Data to Master
**************************************************************************/
lI2c_send_new_byte:                                             ;read address received
        sbi ddrb,sda                                             ;pinb.sda = output (will send data)
/* Read From Flash */
        andi I2c_rd_pointer, (I2C_EEP_SIZE - 1)
        LDI     ZH,high(MemoryBlockFLASH<<1)
        LDI     ZL,low(MemoryBlockFLASH<<1)
        add ZL,I2c_rd_pointer
        inc I2c_rd_pointer
        lpm     R24, Z
        ldi r22,8

.IF DEBUG == 1
        rjmp lI2c_s1    
/* Read From SRAM */
ReadFromSram:
        andi I2c_rd_pointer, (I2C_EEP_SIZE - 1)
        LDI     ZH,high(_I2c_device_inaddr)
        LDI     ZL,low(_I2c_device_inaddr)
        add ZL,I2c_rd_pointer
        inc I2c_rd_pointer
        ld      R24, Z
        ldi r22,8
.ENDIF

lI2c_s1:
        cbi portb,sda
        sbrc r24,7
        sbi portb,sda
lI2c_s2:
        sbis pinb,scl                                            ;wait for SCL=1
        rjmp lI2c_s2
        lsl r24
lI2c_s3:
        sbic pinb,scl                                            ;wait for SCL=0
        rjmp lI2c_s3
        dec r22
        brne lI2c_s1
        sbi portb,sda                                            ;pinb.sda = 0 (will generate ACK)
        cbi ddrb,sda                                             ;pinb.sda = input (will receive data)

lI2c_s4:                                                                ;wait acknowloge receive
        sbis pinb,scl                                            ;wait for SCL=1
        rjmp lI2c_s4
lI2c_s5:
        sbic pinb,scl                                            ;wait for SCL=0
        rjmp lI2c_s5
        
        sbis pinb,sda                                                                                   ;if answer received, - continue
        rjmp    lI2c_send_new_byte

        rjmp lI2c_wait_for_start_stop                             ;wait for next start/stop

/*************************************************************************
*               Receiving Data from Master
**************************************************************************/
.IF I2C_MODE == MODE_2
lI2c_get_2:                                                  ;write address received: get 2nd byte
        cbi ddrb,ack                                             ;pinb.ack = output (ACK)
lI2c_20:                                                     ;wait for SCL=0
        sbic pinb,scl
        rjmp lI2c_20
        ldi r22,8                                                ;bits to receive=8
lI2c_21:
        sbis pinb,scl                                            ;wait for SCL=1
        rjmp lI2c_21
        sbic pinb,sda
        rjmp lI2c_23
lI2c_22:                                                     ;if SDA=0
        sbic pinb,sda
        rjmp lI2c_stop                                            ;  SDA 0->1? I2CSTOP! (finish this sequence)
        sbic pinb,scl
        rjmp lI2c_22                                              ;  loop while SCL=1
        clc                                                      ;  SDA=0->C
        rjmp lI2c_25
lI2c_23:                                                     ;if SDA=1
        sbis pinb,sda
        rjmp lI2c_get_1                                           ;  SDA 1->0? I2CSTART! (repeated start)
        sbic pinb,scl
        rjmp lI2c_23                                              ;  loop while SCL=1
        sec                                                      ;  SDA=1->C
lI2c_25:
        rol r24
        dec r22
        brne lI2c_21                                              ;loop to next bit
        mov I2c_start_addr,r24                                         ;store received I2C address
        mov I2c_rd_pointer,I2c_start_addr                                               ; Upadate Read Address
.ENDIF

ReceiveAcknowloge:
        cbi     portb,sda
        sbi     ddrb,sda
lI2c_ack_21:
        sbis pinb,scl                                            ;wait for SCL=1
        rjmp lI2c_ack_21
        sbic pinb,sda
        rjmp lI2c_ack_23
lI2c_ack_22:                                                     ;if SDA=0
        sbic pinb,sda
        rjmp lI2c_stop                                            ;  SDA 0->1? I2CSTOP! (finish this sequence)
        sbic pinb,scl
        rjmp lI2c_ack_22                                              ;  loop while SCL=1
        rjmp lI2c_ack_25
lI2c_ack_23:                                                     ;if SDA=1
        sbis pinb,sda
        rjmp lI2c_get_1                                           ;  SDA 1->0? I2CSTART! (repeated start)
        sbic pinb,scl
        rjmp lI2c_ack_23                                              ;  loop while SCL=1
lI2c_ack_25:

        cbi ddrb,ack                                             ;pinb.ack = input
        LDI     ZH,high(_I2c_data_buffer)
        LDI     ZL,low(_I2c_data_buffer)
lI2c_get_3:                                                  ;get 3rd byte
lI2c_30:                                                     ;wait for SCL=0
        sbic pinb,scl
        rjmp lI2c_30
        ldi r22,8                                                ;bits to receive=8
        mov     TMPnoINT, I2c_wr_pointer
        andi TMPnoINT, (I2C_PAGE_SIZE - 1)
        add ZL,TMPnoINT
lI2c_31:
        sbis pinb,scl                                            ;wait for SCL=1
        rjmp lI2c_31
        sbic pinb,sda
        rjmp lI2c_33_
lI2c_32:                                                     ;if SDA=0
        sbic pinb,sda
        rjmp lI2c_stop_                                            ;  SDA 0->1? I2CSTOP! (finish this sequence)
        sbic pinb,scl
        rjmp lI2c_32                                              ;  loop while SCL=1
        clc                                                      ;  SDA=0->C
        rjmp lI2c_35
lI2c_33_:
lI2c_33:                                                     ;if SDA=1
        sbis pinb,sda
        rjmp lI2c_start_                                           ;  SDA 1->0? I2CSTART! (repeated start)
        sbic pinb,scl
        rjmp lI2c_33                                              ;  loop while SCL=1
        sec                                                      ;  SDA=1->C
lI2c_35:
        rol r24
        dec r22
        brne lI2c_31                                              ;loop to next bit

        inc I2c_wr_counter
        inc I2c_wr_pointer
        inc I2c_rd_pointer
        st      Z,R24

        rjmp ReceiveAcknowloge

lI2c_wait_for_start_stop:                                    ;wait for start/stop
lI2c_ss_1:
        sbis pinb,scl                                            ;wait for SCL=1
        rjmp lI2c_ss_1
        sbic pinb,sda
        rjmp lI2c_ss_3
lI2c_ss_2:                                                   ;if SDA=0
        sbic pinb,sda
        rjmp lI2c_stop                                            ;  SDA 0->1? I2CSTOP! (finish this sequence)
        sbic pinb,scl
        rjmp lI2c_ss_2                                            ;  loop while SCL=1
        rjmp lI2c_ss_1
lI2c_ss_3:                                                   ;if SDA=1
        sbis pinb,sda
        rjmp lI2c_get_1                                           ;  SDA 1->0? I2CSTART! (repeated start)
        sbic pinb,scl
        rjmp lI2c_ss_3                                            ;  loop while SCL=1
        rjmp lI2c_ss_1                                            ;  SDA=1->C

lI2c_stop_:
lI2c_stop:                                                   ;if stop,
        cbi     ddrb, sda
        cpi     I2c_wr_counter,0x00
        brne WriteFlashRom
lI2c_exit:
        rjmp lI2c_get

lI2c_start_:
        rjmp lI2c_get_1

WriteFlashRom:
        cli                                                     ; Disable INTERRUPTS
        rcall WriteReceivedData
        clr             I2c_wr_counter                                                          ; Clear Write Buffer Pointers
        clr             I2c_wr_pointer
        sei                                                     ; Enable INTERRUPTS
        rjmp lI2c_get
/***********************************************************
*                       Write internal FLASH by page
************************************************************/
//--------- Erase/Program Page FROM FLASH to SRAM
BackupFlashPage:
        ldi             YH,high(_I2c_FLASH_buffer) ; Load SRAM Buffer 
        ldi             YL,low(_I2c_FLASH_buffer)

        mov             TMPnoINT, I2c_start_addr
        andi    TMPnoINT, ((I2C_EEP_SIZE - 1) & ~(PAGESIZEB - 1))

        ldi             ZH,high(MemoryBlockFLASH << 1)
        ldi             ZL,low(MemoryBlockFLASH << 1)

        adc             ZL,TMPnoINT
        brcc    NoIncBackupPage
        inc             ZH
NoIncBackupPage:

        ldi             R22, PAGESIZEB
BackupPageLoop:
        lpm             TMPnoINT,Z+
        st              Y+,TMPnoINT
        dec             R22
        brne    BackupPageLoop
        ret
//--------- Add received data to SRAM Page
WriteReceivedData:
        /* Have Data For Write ? */
        cpi             I2c_wr_counter,0x00
        brne    DataForWritePresent
        ret
DataForWritePresent:

        rcall BackupFlashPage

        ldi             YH,high(_I2c_FLASH_buffer) ; Load SRAM Backup Buffer Address
        ldi             YL,low(_I2c_FLASH_buffer)

        ldi             XH,high(_I2c_data_buffer) ; Load SRAM Receive Buffer Address
        ldi             XL,low(_I2c_data_buffer)

        mov             TMPnoINT, I2c_start_addr
        andi    TMPnoINT, (PAGESIZEB - 1)

        adc             YL,TMPnoINT
        brcc    NoIncPreparePage
        inc             YH
NoIncPreparePage:

        mov             CounterInWrite,TMPnoINT
        /* Make PAGE SIZE Window */
        cpi             I2c_wr_counter, I2C_PAGE_SIZE
        brlo    PreparePageLoop
        ldi             I2c_wr_counter, I2C_PAGE_SIZE
PreparePageLoop:
        ld              R22,X+
        st              Y+,R22

        dec             I2c_wr_counter
        breq    NormalPageWrite

        mov             TMPnoINT,CounterInWrite
        cpi             TMPnoINT, (PAGESIZEB - 1)
        brne    NoWritePageSizeExceeded

        rcall   Erase_page_by_SPM
        rcall   Write_Current_Page

        inc             CounterInWrite
        inc             I2c_start_addr
        dec             I2c_wr_pointer

        rjmp    WriteReceivedData

NoWritePageSizeExceeded:

        inc             CounterInWrite
        inc             I2c_start_addr
        dec             I2c_wr_pointer

        rjmp    PreparePageLoop

NormalPageWrite:
        rcall   Erase_page_by_SPM
        rcall   Write_Current_Page

        inc             I2c_start_addr
        dec             I2c_wr_pointer
        ret
//--------- Erase page
Erase_page_by_SPM:
        ldi             ZH,high(MemoryBlockFLASH << 1)
        ldi             ZL,low(MemoryBlockFLASH << 1)

        mov             TMPnoINT,I2c_start_addr
        andi    TMPnoINT, ((I2C_EEP_SIZE - 1) & ~(PAGESIZEB - 1)) /* Mask Maximum Data Size and Mask Out Real Flash Page Size */
        adc             ZL,TMPnoINT
        brcc    NoIncErasePage
        inc             ZH
NoIncErasePage:
        /* Load Erase Instruction */
        ldi             TMPnoINT, (1<<PGERS) | (1<<SPMEN)
        sts             _valSPMCSR, TMPnoINT
        rcall   Wait_spm        ;CPU Halted while erase
        ret

//Wite page
Write_Current_Page:
        ldi             XH,high(_I2c_FLASH_buffer) ; Load SRAM Backup Buffer Address
        ldi             XL,low(_I2c_FLASH_buffer)

        ldi             ZH,high(MemoryBlockFLASH << 1)
        ldi             ZL,low(MemoryBlockFLASH << 1)

        mov             TMPnoINT,I2c_start_addr
        andi    TMPnoINT, ((I2C_EEP_SIZE - 1) & ~(PAGESIZEB - 1)) /* Mask Maximum Data Size and Mask Out Real Flash Page Size */
        adc             ZL,TMPnoINT
        brcc    NoIncWritePage
        inc             ZH
NoIncWritePage:

        ldi             TMPnoINT, (PAGESIZE)
        mov             Counter, TMPnoINT

        movw    Y,Z                     ; Store Z in Y reg
        clr             ZL                      ;Clear Z
        clr             ZH
Fill_Page_Buffer_loop:
        ld              R0, X+
        ld              R1, X+

        ldi             TMPnoINT, (1<<SPMEN)      ;Write word into page buffer
        sts             _valSPMCSR, TMPnoINT
        rcall   Wait_spm        ;CPU Halted while erase

        adiw    Z, 2
        dec             Counter
        brne    Fill_Page_Buffer_loop   

        movw    Z,Y                     ; Restore Z from Y reg

        ldi     TMPnoINT, (1<<PGWRT) | (1<<SPMEN)
        sts             _valSPMCSR, TMPnoINT
        rcall   Wait_spm        ;CPU Halted while erase
        ret

Do_spm:
; check for previous SPM complete
Wait_spm:
        in      TMPnoINT, SPMCSR
        sbrc TMPnoINT, SPMEN
        rjmp Wait_spm
Wait_ee:
        sbic EECR, EEWE
        rjmp Wait_ee
; SPM timed sequence
        lds     TMPnoINT, _valSPMCSR
        out SPMCSR, TMPnoINT
        spm
        ret

.cseg
.org    (0x200 - (I2C_EEP_SIZE/2))
MemoryBlockFLASH:          ; Bytes in Flash
   .DB 0x55, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
   .DB 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
   .DB 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F
   .DB 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
   .DB 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F
   .DB 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
   .DB 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F
   .DB 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D
   ; Mark End of EEP DATA
.org    (0x1FF)
        .db 0x7E,0x7F

.MESSAGE "I2C For Read/Write Processing SELFPRGEN FUSE Must Be Enabled!!!"

.eseg
MemoryBlockEEP:          ; Bytes in EEP
   .DB 0x55, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
   .DB 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
   .DB 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F
   .DB 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F

Let's block ads! (Why?)

Комментариев нет:

Отправить комментарий