📄 twi_master_drv.s
字号:
.module twi_master_drv.c
.area text(rom, con, rel)
.dbfile F:\zzz\i2c-master\twi_master_drv.c
.dbfunc e twi_lib_init _twi_lib_init fV
.even
_twi_lib_init::
.dbline -1
.dbline 19
; /*头文件*/
; #include "twi_master_drv.h"
;
; /*全局变量定义*/
; uchar twi_busy; //=FALSE,TWI通讯空闲;=TRUE,TWI通讯忙
; uchar twi_err; //TWI通讯状态
; uchar twi_nb_transmited; //收发字节数
; //uchar twi_recptr;
;
; TWI_MSG twi_message; //TWI数据结构
;
; /*****************************************************************************
; 函数介绍:TWI初始化,设置通讯波特率和启动通讯
; 输入参数:
; 输出参数:
; 返回值:无
; *****************************************************************************/
; void twi_lib_init(void)
; {
.dbline 24
; //Twi_set_baudrate(0xf9); //8MOSC 1K
; //Twi_set_status(0x02);
; //Twi_set_baudrate(0x62); //8MOSC 10K
; //Twi_set_status(0x01);
; Twi_set_baudrate(0x20); //8MOSC 100K
ldi R24,32
sts 184,R24
.dbline 25
; Twi_set_status(0x00);
clr R2
sts 185,R2
.dbline 28
;
; //Twi_set_address(0x51);
; Twi_init_hw(TWI_CONFIG);
ldi R24,4
sts 188,R24
.dbline -2
L2:
.dbline 0 ; func end
ret
.dbend
.dbfunc e twi_decode_status _twi_decode_status fV
.even
_twi_decode_status::
.dbline -1
.dbline 39
; }
;
; /*****************************************************************************
; 函数介绍:在从机或主机模式下,TWI信息的收发的主流程状态。
; 此函数在TWI通讯事件发生时,对各个状态进行解码,查询和中断方式都可以。
; 输入参数:
; 输出参数:
; 返回值:无
; *****************************************************************************/
; void twi_decode_status()
; {
.dbline 40
; switch ( Twi_get_status()&0xF8 ) // switch (SSTA)
lds R16,185
clr R17
andi R16,248
andi R17,0
cpi R16,40
ldi R30,0
cpc R17,R30
brne X2
xjmp L22
X2:
ldi R24,40
ldi R25,0
cp R24,R16
cpc R25,R17
brlt L46
L45:
cpi R16,16
ldi R30,0
cpc R17,R30
brne X3
xjmp L12
X3:
ldi R24,16
ldi R25,0
cp R24,R16
cpc R25,R17
brlt L48
L47:
cpi R16,0
cpc R16,R17
brne X4
xjmp L7
X4:
X0:
cpi R16,0
ldi R30,0
cpc R17,R30
brge X5
xjmp L4
X5:
L49:
cpi R16,8
ldi R30,0
cpc R17,R30
brne X6
xjmp L8
X6:
xjmp L4
L48:
cpi R16,24
ldi R30,0
cpc R17,R30
brne X7
xjmp L16
X7:
cpi R16,24
ldi R30,0
cpc R17,R30
brge X8
xjmp L4
X8:
L50:
cpi R16,32
ldi R30,0
cpc R17,R30
brne X9
xjmp L21
X9:
xjmp L4
L46:
cpi R16,64
ldi R30,0
cpc R17,R30
brne X10
xjmp L30
X10:
ldi R24,64
ldi R25,0
cp R24,R16
cpc R25,R17
brlt L52
L51:
cpi R16,48
ldi R30,0
cpc R17,R30
brne X11
xjmp L28
X11:
cpi R16,48
ldi R30,0
cpc R17,R30
brge X12
xjmp L4
X12:
L53:
cpi R16,56
ldi R30,0
cpc R17,R30
brne X13
xjmp L29
X13:
xjmp L4
L52:
cpi R16,80
ldi R30,0
cpc R17,R30
brne X14
xjmp L38
X14:
ldi R24,80
ldi R25,0
cp R24,R16
cpc R25,R17
brlt L55
L54:
cpi R16,72
ldi R30,0
cpc R17,R30
brne X15
xjmp L37
X15:
xjmp L4
L55:
cpi R16,88
ldi R30,0
cpc R17,R30
brne X16
xjmp L43
X16:
xjmp L4
X1:
.dbline 41
; {
L7:
.dbline 45
; // STATE 00h: Bus Error has occurred
; // ACTION: Enter not addressed SLV mode and release bus
; case 0x00 :
; twi_busy = FALSE;
clr R2
sts _twi_busy,R2
.dbline 46
; twi_err = TWI_BUS_ERROR;
ldi R24,2
sts _twi_err,R24
.dbline 47
; break;
xjmp L5
L8:
.dbline 53
;
;
; //STATE 08h: A start condition has been sent
; //ACTION: SLR+R/W are transmitted, ACK bit received
; case 0x08 :
; Twi_clear_start(); //Pas besoin fait en hard ???
lds R24,188
andi R24,95
sts 188,R24
.dbline 54
; Twi_set_data(twi_message.address<<1);
lds R2,_twi_message
lsl R2
sts 187,R2
.dbline 55
; if ( twi_message.rw == TWI_READ )
lds R24,_twi_message+1
cpi R24,1
brne L9
.dbline 56
; {
.dbline 57
; Twi_set_data(Twi_get_data()+1); // Add 1 for Read bit in AdrWord modify by zmq
lds R24,187
subi R24,255 ; addi 1
sts 187,R24
.dbline 58
; }
L9:
.dbline 59
; Twi_set_aa(); //from here to 0x18 transmit or 0x40 receive
lds R24,188
ori R24,64
sts 188,R24
.dbline 60
; break;
xjmp L5
L12:
.dbline 65
;
; //STATE 10h: A repeated start condition has been sent
; //ACTION: SLR+R/W are transmitted, ACK bit received
; case 0x10 :
; Twi_clear_start(); // Reset STA bit in SSCON
lds R24,188
andi R24,95
sts 188,R24
.dbline 66
; Twi_set_data(twi_message.address<<1);
lds R2,_twi_message
lsl R2
sts 187,R2
.dbline 67
; if ( twi_message.rw == TWI_READ )
lds R24,_twi_message+1
cpi R24,1
brne L13
.dbline 68
; {
.dbline 69
; Twi_set_data(Twi_get_data()+1); // Add 1 for Read bit in AdrWord modify by zmq
lds R24,187
subi R24,255 ; addi 1
sts 187,R24
.dbline 70
; }
L13:
.dbline 71
; Twi_set_aa(); // wait on ACK bit
lds R24,188
ori R24,64
sts 188,R24
.dbline 72
; break;
xjmp L5
L16:
.dbline 78
;
; //STATE 18h: SLR+W was transmitted, ACK bit received
; //ACTION: Transmit data byte, ACK bit received
; //PREVIOUS STATE: 0x08 or 0x10
; case 0x18 : // master transmit, after sending
; twi_nb_transmited=0; // slave address, now load data
clr R2
sts _twi_nb_transmited,R2
.dbline 79
; Twi_set_data(*(twi_message.buf)); // byte and send it
lds R30,_twi_message+3
lds R31,_twi_message+3+1
ldd R2,z+0
sts 187,R2
.dbline 81
;
; if (twi_message.nbbytes==0) // no datas to transmit
lds R2,_twi_message+2
tst R2
brne L18
.dbline 82
; {
.dbline 83
; Twi_set_stop();
lds R24,188
ori R24,16
sts 188,R24
.dbline 84
; twi_err = TWI_TRANSFER_OK;
clr R2
sts _twi_err,R2
.dbline 85
; twi_busy = FALSE; // transfer complete, clear twi_busy
sts _twi_busy,R2
.dbline 86
; }
L18:
.dbline 87
; Twi_clear_si();
lds R24,188
ori R24,128
sts 188,R24
.dbline 88
; break;
xjmp L5
L21:
.dbline 93
;
; //STATE 20h: SLR+W was transmitted, NOT ACK bit received
; //ACTION: Transmit STOP
; case 0x20 :
; Twi_set_stop(); // Twi_set_stop will also clear twiint flag
lds R24,188
ori R24,16
sts 188,R24
.dbline 94
; twi_busy = FALSE;
clr R2
sts _twi_busy,R2
.dbline 95
; twi_err = TWI_HOST_ADR_NACK;
ldi R24,3
sts _twi_err,R24
.dbline 96
; break;
xjmp L5
L22:
.dbline 101
;
; //STATE 28h: DATA was transmitted, ACK bit received
; //ACTION: If last byte, send STOP, else send more data bytes
; case 0x28: // master transmit, after sending ; data byte, ACK received
; twi_nb_transmited++; // inc nb data transmit on message
lds R24,_twi_nb_transmited
subi R24,255 ; addi 1
sts _twi_nb_transmited,R24
.dbline 102
; twi_message.buf++; // inc pointer ti data to be transmited
lds R24,_twi_message+3
lds R25,_twi_message+3+1
adiw R24,1
sts _twi_message+3+1,R25
sts _twi_message+3,R24
.dbline 103
; if ( twi_nb_transmited < twi_message.nbbytes ) // if there are still bytes to send
lds R2,_twi_message+2
lds R3,_twi_nb_transmited
cp R3,R2
brsh L24
.dbline 104
; {
.dbline 105
; Twi_set_data(*(twi_message.buf));
movw R30,R24
ldd R2,z+0
sts 187,R2
.dbline 106
; Twi_set_aa(); // wait on ACK bit
lds R24,188
ori R24,64
sts 188,R24
.dbline 107
; }
xjmp L5
L24:
.dbline 109
; else
; { //run out of data, send stop,
.dbline 110
; Twi_set_stop(); // Twi_set_stop will also clear twiint flag
lds R24,188
ori R24,16
sts 188,R24
.dbline 111
; twi_err = TWI_TRANSFER_OK;
clr R2
sts _twi_err,R2
.dbline 112
; twi_busy = FALSE; //transfer complete, clear twi_busy
sts _twi_busy,R2
.dbline 113
; }
.dbline 114
; break;
xjmp L5
L28:
.dbline 119
;
; //STATE 30h: DATA was transmitted, NOT ACK bit received
; //ACTION: Transmit STOP
; case 0x30 :
; Twi_set_stop(); // Twi_set_stop will also clear twiint flag
lds R24,188
ori R24,16
sts 188,R24
.dbline 120
; twi_busy = FALSE;
clr R2
sts _twi_busy,R2
.dbline 121
; twi_err = TWI_HOST_ADR_NACK;
ldi R24,3
sts _twi_err,R24
.dbline 122
; break;
xjmp L5
L29:
.dbline 128
;
; //STATE 38h: Arbitration lost in SLA+W or DATA.
; //ACTION: Release bus, enter not addressed SLV mode
; // Wait for bus lines to be free
; case 0x38 :
; twi_busy = FALSE;
clr R2
sts _twi_busy,R2
.dbline 129
; twi_err = TWI_ARBITRATION_LOST;
ldi R24,5
sts _twi_err,R24
.dbline 130
; Twi_clear_si();
lds R24,188
ori R24,128
sts 188,R24
.dbline 134
; // #ifdef USER_TWI_FCT_ARBITRATION_LOST_IN_SLA+W_OR_DATA
; // TWI_fct_arb_lostinSLAorDATA();
; // #endif
; break;
xjmp L5
L30:
.dbline 141
;
; //MASTER RECEIVER MODE FOLLOWS
; //STATE 40h: SLA+R transmitted, ACK received
; //ACTION: Receive DATA, ACK to be returned
; //PREVIOS STATE: 0x08 or 0x10
; case 0x40 : //master receive, after sending
; if ( twi_message.nbbytes == 1 )
lds R24,_twi_message+2
cpi R24,1
brne L31
.dbline 142
; {
.dbline 143
; Twi_clear_aa(); // only one data to receive, noACK to be send after the fisrt incoming data
lds R24,188
andi R24,63
sts 188,R24
.dbline 144
; Twi_clear_si();
lds R24,188
ori R24,128
sts 188,R24
.dbline 145
; }
xjmp L5
L31:
.dbline 146
; else if (!twi_message.nbbytes ) Twi_set_stop(); // special case: no data to read ! clear also twint
lds R2,_twi_message+2
tst R2
brne L34
.dbline 146
lds R24,188
ori R24,16
sts 188,R24
xjmp L5
L34:
.dbline 148
; else
; {
.dbline 149
; Twi_set_aa(); //wait on ACK bit
lds R24,188
ori R24,64
sts 188,R24
.dbline 150
; twi_nb_transmited=0; //data byte to be received, NOT ACK bit to follow --> 0x58
clr R2
sts _twi_nb_transmited,R2
.dbline 151
; }
.dbline 152
; break;
xjmp L5
L37:
.dbline 157
;
; //STATE 48h: SLA+R transmitted, NOT ACK received
; //ACTION: Transmit STOP
; case 0x48 :
; Twi_set_stop(); //clear also twint
lds R24,188
ori R24,16
sts 188,R24
.dbline 158
; twi_busy = FALSE;
clr R2
sts _twi_busy,R2
.dbline 159
; twi_err = TWI_HOST_ADR_NACK;
ldi R24,3
sts _twi_err,R24
.dbline 160
; break;
xjmp L5
L38:
.dbline 166
;
; //STATE 50h: Data has been received, ACK returned
; //ACTION: Read DATA. If expecting more continue else STOP
; case 0x50 : //master receive, received data
; //byte and ACK, copy it into
; *(twi_message.buf+twi_nb_transmited) = Twi_get_data(); //buffer
lds R2,_twi_message+3
lds R3,_twi_message+3+1
lds R30,_twi_nb_transmited
clr R31
add R30,R2
adc R31,R3
lds R2,187
std z+0,R2
.dbline 167
; twi_nb_transmited++;
lds R24,_twi_nb_transmited
subi R24,255 ; addi 1
sts _twi_nb_transmited,R24
.dbline 168
; if ( twi_nb_transmited < (twi_message.nbbytes-1) ) Twi_set_aa(); // get more bytes
lds R24,_twi_message+2
subi R24,1
lds R2,_twi_nb_transmited
cp R2,R24
brsh L40
.dbline 168
lds R24,188
ori R24,64
sts 188,R24
xjmp L5
L40:
.dbline 170
; else
; {
.dbline 171
; Twi_clear_aa(); //only one more byte to come
lds R24,188
andi R24,63
sts 188,R24
.dbline 172
; Twi_clear_si();
lds R24,188
ori R24,128
sts 188,R24
.dbline 173
; }
.dbline 174
; break;
xjmp L5
L43:
.dbline 179
;
; //STATE 58h: Data has been received, NOT ACK returned
; //ACTION: Read DATA. Generate STOP
; case 0x58 :
; *(twi_message.buf+twi_nb_transmited) = Twi_get_data();
lds R2,_twi_message+3
lds R3,_twi_message+3+1
lds R30,_twi_nb_transmited
clr R31
add R30,R2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -