BOOTLOADER
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
iic.c
Go to the documentation of this file.
1 /******************************************************
2 * Function: s3c2440 iic driver
3 *
4 * File: iic.c
5 * Author: Book Chen
6 * Date: 2008.07.18
7 *******************************************************
8 */
9 #include "Includes.h"
10 
11 #define IicIdleState 0
12 #define IicTxStartState 1
13 #define IicTxDataState 2
14 #define IicTxStopState 3
15 #define IicRxStartState 4
16 #define IicRxStopState 5
17 
19 void F_IicPowerOnInit(void);
20 void F_IicSvc(void);
21 void F_IicEnable(INT8U Enable);
23 INT8U F_IicAllocate(INT16U UserId);
24 INT8U F_IicRelease(INT16U UserId);
25 INT8U F_IicReset(INT16U UserId);
26 INT8U F_IicWrite(INT16U UserId);
27 INT8U F_IicRead(INT16U UserId);
28 INT8U F_IicSlaveAddressSet(INT16U UserId,INT8U SlaveAddress);
29 INT8U F_IicDataSet(INT16U UserId,INT8U Data);
30 INT8U F_IicDataCountSet(INT16U UserId,INT8U DataCount);
31 void __irq IicIsr(void);
32 
33 void F_IicInit(){
34  // hardware initial
35  rGPEUP|=0xc000; // disable pull up resistor
36  rGPECON&=~0xf0000000;
37  rGPECON|= 0xa0000000; // GPE15:IICSDA,GPE14:IICSCL
38  // IIC control register
39  // bit 7. acknowledge generation
40  // bit 6. tx clock source selection 0.Fplck/16,1 Fpclk/512
41  // bit 5. tx/rx interrupt enable
42  // bit 4. interrupt pending
43  // bit 3~0 prescaler
44  rIICCON=0xaf; // enable ack, iicclk=Fpclk/16,enable iic int,prescaler=0x1111
45  // IIC bus address register
46  // bit [7:1] slave address
47  // bit 0 not mapped
48  rIICADD = 0x10; //2410 slave address = [7:1]
49  // IIC control and status register
50  // bit 7.6 00 slave rx,01 slave tx,10 master rx,11 master tx
51  // bit 5 write0 stop condition, write1 start condition
52  // bit 4 tx.rx output enable
53  rIICSTAT = 0x10; // slave rx, enable tx.rx
54  pISR_IIC = (INT32U)IicIsr; // set isr function
55  //rINTMSK &= ~(BIT_IIC); // enable iic irq
58  // variable initial
59  IicCtrl.State=IicIdleState;
60  IicCtrl.Status=0;
61  IicCtrl.Mode=IIC_MODE_NONE;
62  IicCtrl.Index=0;
63  IicCtrl.DataCount=0;
64  IicCtrl.InUse=FALSE;
65  IicCtrl.InTransmit=FALSE;
66  IicCtrl.Id=ID_IIC;
67 }
68 void F_IicSvc(void){
69  INT8U i;
70 
71  switch(IicCtrl.State){
72  case IicIdleState:
73  break;
74  case IicTxStartState:
75  IicCtrl.InTransmit=TRUE;
76  rIICCON=0xaf; // rIICCON^4=1...clear pending & resume operation
77  rIICDS=IicCtrl.SlaveAddress; // bit[7:1] is slave address
78  // bit 6.7 11 iic master tx mode
79  // bit 5. 1 start signal generation
80  // bit 4. 1 enable tx.rx
81  rIICSTAT=0xf0; // iic master tx start
82  IicCtrl.State=IicTxDataState;
83  break;
84  case IicTxDataState:
85  if(IicCtrl.InTransmit==TRUE) return;
86  if(IicCtrl.DataCount>IicCtrl.Index){
87  IicCtrl.InTransmit=TRUE;
88  rIICDS=IicCtrl.Data[IicCtrl.Index++]; // write new data transmitted to IICDS
89  for(i=0;i<50;i++); // wait untill the stop condition takes effect
90  rIICCON=0xaf; // rIICCON^4=1...clear pending & resume operation
91  }
92  else{
93  IicCtrl.Status|=IIC_TX_FINISH;
94  rIICSTAT=0xd0; // send iic stop condition
95  for(i=0;i<50;i++); // wait untill the stop condition takes effect
96  rIICCON=0xaf; // rIICCON^4=1...clear pending & resume operation
97  for(i=0;i<50;i++); // wait untill the stop condition takes effect
98  IicCtrl.State=IicTxStopState;
99  }
100  break;
101  case IicTxStopState:
102  if(IicCtrl.Status&IIC_TX_FINISH){
103  IicCtrl.Status&=~IIC_TX_FINISH;
104  IicCtrl.State=IicIdleState;
105  }
106  break;
107  case IicRxStartState:
108  rIICCON=0xaf; // configure iic master receive mode
109  rIICDS=IicCtrl.SlaveAddress; // bit[7:1] is slave address
110  // bit 6.7 10 iic master rx mode
111  // bit 5. 1 start signal generation
112  // bit 4. 1 enable tx.rx
113  rIICSTAT=0xb0; // iic master rx start
114  IicCtrl.State=IicRxStopState;
115  break;
116  case IicRxStopState:
117  if(IicCtrl.Status&IIC_RX_FINISH){ // data done in isr
118  IicCtrl.Status&=~IIC_RX_FINISH;
119  IicCtrl.State=IicIdleState; // resume IicCtrl to idle state
120  }
121  break;
122  default:
123  break;
124  }
125 }
126 void F_IicIsrEnable(INT16U UserId,INT8U Enable){
127  if((IicCtrl.InUse==TRUE)&&(IicCtrl.UserId==UserId)){
128  if(Enable==TRUE){
129  rINTMSK&=~(BIT_IIC); // enable iic interrupt
130  }
131  else{
132  rINTMSK|=BIT_IIC; // disable iic interrupt
133  }
134  }
135 }
137  if(IicCtrl.State==IicIdleState) return TRUE;
138  else return FALSE;
139 }
141  if(IicCtrl.InUse==TRUE) return TRUE; // resource is in use
142  else return FALSE; // resource is not in use
143 }
145  if(IicCtrl.InUse==TRUE) return FALSE;
146  else{
147  IicCtrl.InUse=TRUE;
148  IicCtrl.UserId=UserId;
149  return TRUE; // resource is allocated
150  }
151 }
153  if(IicCtrl.InUse==TRUE){
154  if(IicCtrl.UserId==UserId){
155  IicCtrl.InUse=FALSE;
156  return TRUE; // resource is relased
157  }
158  else return FALSE; // resource is not relased
159  }
160  else return TRUE; // resource is relased before
161 }
163  if((IicCtrl.InUse==TRUE)&&(IicCtrl.UserId==UserId)){
164  IicCtrl.State=IicIdleState;
165  IicCtrl.DataCount=0;
166  IicCtrl.Index=0;
167  return TRUE;
168  }
169  else return FALSE;
170 }
172  if((IicCtrl.InUse==TRUE)&&(IicCtrl.UserId==UserId)){
173  IicCtrl.State=IicTxStartState;
174  IicCtrl.Mode=IIC_MODE_MASTER_WRITE;
175  IicCtrl.Index=0;
176  return TRUE;
177  }
178  else return FALSE;
179 }
181  if((IicCtrl.InUse==TRUE)&&(IicCtrl.UserId==UserId)){
182  IicCtrl.State=IicRxStartState;
183  IicCtrl.Mode=IIC_MODE_MASTER_READ;
184  IicCtrl.Index=0;
185  return TRUE;
186  }
187  else return FALSE;
188 }
189 INT8U F_IicSlaveAddressSet(INT16U UserId,INT8U SlaveAddress){
190  if((IicCtrl.InUse==TRUE)
191  &&(IicCtrl.UserId==UserId)){
192  IicCtrl.SlaveAddress=SlaveAddress;
193  return TRUE;
194  }
195  else return FALSE;
196 }
198  if((IicCtrl.InUse==TRUE)&&(IicCtrl.UserId==UserId)){
199  IicCtrl.Data[IicCtrl.Index++]=Data;
200  return TRUE;
201  }
202  else return FALSE;
203 }
205  if((IicCtrl.InUse==TRUE)&&(IicCtrl.UserId==UserId)){
206  IicCtrl.DataCount=DataCount;
207  return TRUE;
208  }
209  else return FALSE;
210 }
211 void __irq IicIsr(void){
212  //INT32U IicStatus;
213  INT8U i;
214 
215  ClearPending(BIT_IIC); //Clear pending bit
216  //rSRCPND=BIT_IIC; // Clear pending bit
217  //rINTPND=BIT_IIC; // Clear pending bit
218  //IicStatus=rIICSTAT; // get IIC status
219  //if(IicStatus&0x8){} // When bus arbitration is failed.
220  //if(IicStatus&0x4){} // When a slave address is matched with IICADD
221  //if(IicStatus&0x2){} // When a slave address is 0000000b
222  //if(IicStatus&0x1){} // When ACK isn't received
223  switch(IicCtrl.Mode){
224  case IIC_MODE_MASTER_WRITE:
225  IicCtrl.InTransmit=FALSE;
226  break;
227  case IIC_MODE_MASTER_READ:
228  if(IicCtrl.DataCount>=IicCtrl.Index){
229  IicCtrl.Data[IicCtrl.Index]=rIICDS; // Data[0] is nothing,[1] is 1st byte
230  IicCtrl.Index++;
231  for(i=0;i<50;i++); // wait untill the stop condition takes effect
232  if(IicCtrl.DataCount==IicCtrl.Index){ // last byte
233  //rIICCON=0x2f; // set send nack
234  rIICCON=0xaf; // set send ack
235  }
236  else if((IicCtrl.DataCount+1)==IicCtrl.Index){ // rx finished
237  // do nothing
238  }
239  else{ // bytes before last byte
240  rIICCON=0xaf; // set send ack
241  }
242  for(i=0;i<50;i++); // wait untill the stop condition takes effect
243  }
244  if((IicCtrl.DataCount+1)==IicCtrl.Index){
245  IicCtrl.Status|=IIC_RX_FINISH;
246  rIICSTAT=0x90; // send stop condition
247  for(i=0;i<50;i++); // wait untill the stop condition takes effect
248  rIICCON=0xaf; // rIICCON^4=1...clear pending & resume operation
249  for(i=0;i<50;i++); // wait untill the stop condition takes effect
250  }
251  break;
252  case IIC_MODE_SLAVE_READ:
253  case IIC_MODE_SLAVE_WRITE:
254  case IIC_MODE_NONE:
255  default:
256  break;
257  }
258 }