OpenCores
URL https://opencores.org/ocsvn/iicmb/iicmb/trunk

Subversion Repositories iicmb

[/] [iicmb/] [trunk/] [software/] [iicmb.c] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 sshuv2
 
2
/*******************************************************************************
3
**                                                                             *
4
**    Project: IIC Multiple Bus Controller (IICMB)                             *
5
**                                                                             *
6
**    File:    Several basic functions for IICMB core.                         *
7
**    Version:                                                                 *
8
**             1.0,     May 25, 2016                                           *
9
**                                                                             *
10
**    Author:  Sergey Shuvalkin, (sshuv2@opencores.org)                        *
11
**                                                                             *
12
********************************************************************************
13
********************************************************************************
14
** Copyright (c) 2016, Sergey Shuvalkin                                        *
15
** All rights reserved.                                                        *
16
**                                                                             *
17
** Redistribution and use in source and binary forms, with or without          *
18
** modification, are permitted provided that the following conditions are met: *
19
**                                                                             *
20
** 1. Redistributions of source code must retain the above copyright notice,   *
21
**    this list of conditions and the following disclaimer.                    *
22
** 2. Redistributions in binary form must reproduce the above copyright        *
23
**    notice, this list of conditions and the following disclaimer in the      *
24
**    documentation and/or other materials provided with the distribution.     *
25
**                                                                             *
26
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" *
27
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   *
28
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  *
29
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE    *
30
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR         *
31
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF        *
32
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    *
33
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN     *
34
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)     *
35
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  *
36
** POSSIBILITY OF SUCH DAMAGE.                                                 *
37
*******************************************************************************/
38
 
39
#include <stdio.h>
40
#include <io.h>
41
 
42
#include "iicmb.h"
43
 
44
 
45
/* Print responses */
46
void print_rsp(rsp_tt r)
47
{
48
  switch (r)
49
  {
50
    case rsp_done :
51
      printf("Done");
52
      break;
53
    case rsp_nak :
54
      printf("No acknowledge");
55
      break;
56
    case rsp_arb_lost :
57
      printf("Arbitration lost");
58
      break;
59
    case rsp_err :
60
      printf("Error");
61
      break;
62
  }
63
}
64
 
65
/* Initialize IICMB core */
66
void iicmb_init(void)    { IICMB_REG_WRITE(IICMB_CSR, IICMB_CSR_ENABLE); }
67
/* Disable IICMB core */
68
void iicmb_disable(void) { IICMB_REG_WRITE(IICMB_CSR, 0x00u); }
69
 
70
/* Waiting for a response after issuing a command */
71
rsp_tt iicmb_wait_response(void)
72
{
73
  int tmp;
74
  do
75
  {
76
    tmp = IICMB_REG_READ(IICMB_CMDR);
77
  } while ((tmp & IICMB_RSP_COMPLETED) == 0);
78
 
79
  if (tmp & IICMB_RSP_NAK)      { return rsp_nak; }
80
  if (tmp & IICMB_RSP_ARB_LOST) { return rsp_arb_lost; }
81
  if (tmp & IICMB_RSP_ERR)      { return rsp_err; }
82
 
83
  return rsp_done;
84
}
85
 
86
/* 'Wait' command */
87
rsp_tt iicmb_cmd_wait(unsigned char n)
88
{
89
  IICMB_REG_WRITE(IICMB_DPR, ((unsigned int)n & 0x000000FFu));
90
  IICMB_REG_WRITE(IICMB_CMDR, IICMB_CMD_WAIT);
91
  return iicmb_wait_response();
92
}
93
 
94
/* 'Write' command */
95
rsp_tt iicmb_cmd_write(unsigned char n)
96
{
97
  IICMB_REG_WRITE(IICMB_DPR, ((unsigned int)n & 0x000000FFu));
98
  IICMB_REG_WRITE(IICMB_CMDR, IICMB_CMD_WRITE);
99
  return iicmb_wait_response();
100
}
101
 
102
/* 'Read With Ack' command */
103
rsp_tt iicmb_cmd_read_ack(unsigned char * n)
104
{
105
  rsp_tt ret;
106
 
107
  IICMB_REG_WRITE(IICMB_CMDR, IICMB_CMD_READ_ACK);
108
  ret = iicmb_wait_response();
109
  if (ret == rsp_done) { *n = (unsigned char)IICMB_REG_READ(IICMB_DPR); }
110
 
111
  return ret;
112
}
113
 
114
/* 'Read With Nak' command */
115
rsp_tt iicmb_cmd_read_nak(unsigned char * n)
116
{
117
  rsp_tt ret;
118
 
119
  IICMB_REG_WRITE(IICMB_CMDR, IICMB_CMD_READ_NAK);
120
  ret = iicmb_wait_response();
121
  if (ret == rsp_done) { *n = (unsigned char)IICMB_REG_READ(IICMB_DPR); }
122
 
123
  return ret;
124
}
125
 
126
/* 'Start' command */
127
rsp_tt iicmb_cmd_start(void)
128
{
129
  IICMB_REG_WRITE(IICMB_CMDR, IICMB_CMD_START);
130
  return iicmb_wait_response();
131
}
132
 
133
/* 'Stop' command */
134
rsp_tt iicmb_cmd_stop(void)
135
{
136
  IICMB_REG_WRITE(IICMB_CMDR, IICMB_CMD_STOP);
137
  return iicmb_wait_response();
138
}
139
 
140
/* 'Set Bus' command */
141
rsp_tt iicmb_cmd_set_bus(unsigned char n)
142
{
143
  IICMB_REG_WRITE(IICMB_DPR, ((unsigned int)n & 0x000000FFu));
144
  IICMB_REG_WRITE(IICMB_CMDR, IICMB_CMD_SET_BUS);
145
  return iicmb_wait_response();
146
}
147
 
148
 
149
/* Read a single byte */
150
rsp_tt iicmb_read_bus(unsigned char sa, unsigned char a, unsigned char * d)
151
{
152
  rsp_tt ret;
153
 
154
  /* Start condition */
155
  ret = iicmb_cmd_start();
156
  if (ret != rsp_done) return ret;
157
 
158
  do {
159
    /* Write slave address and write bit */
160
    ret = iicmb_cmd_write((sa << 1) | 0x00u);
161
    if (ret != rsp_done) break;
162
    /* Write byte address */
163
    ret = iicmb_cmd_write(a);
164
    if (ret != rsp_done) break;
165
    /* Repeated start */
166
    ret = iicmb_cmd_start();
167
    if (ret != rsp_done) return ret;
168
    /* Write slave address and read bit */
169
    ret = iicmb_cmd_write((sa << 1) | 0x01u);
170
    if (ret != rsp_done) break;
171
    /* Read byte of data with not-acknowledge */
172
    ret = iicmb_cmd_read_nak(d);
173
    if (ret != rsp_done) return ret;
174
  } while (0);
175
 
176
  /* Stop condition */
177
  (void)iicmb_cmd_stop();
178
 
179
  return ret;
180
}
181
 
182
/* Reading several bytes */
183
rsp_tt iicmb_read_bus_mul(unsigned char sa, unsigned char a, unsigned char * d, int n)
184
{
185
  rsp_tt ret;
186
  int i;
187
 
188
  /* Start condition */
189
  ret = iicmb_cmd_start();
190
  if (ret != rsp_done) return ret;
191
 
192
  do {
193
    /* Write slave address and write bit */
194
    ret = iicmb_cmd_write((sa << 1) | 0x00u);
195
    if (ret != rsp_done) break;
196
    /* Write byte address */
197
    ret = iicmb_cmd_write(a);
198
    if (ret != rsp_done) break;
199
    /* Repeated start */
200
    ret = iicmb_cmd_start();
201
    if (ret != rsp_done) return ret;
202
    /* Write slave address and read bit */
203
    ret = iicmb_cmd_write((sa << 1) | 0x01u);
204
    if (ret != rsp_done) break;
205
    for (i = 0; i < (n - 1); i++)
206
    {
207
      /* Read byte of data with acknowledge */
208
      ret = iicmb_cmd_read_ack(d + i);
209
      if (ret != rsp_done) return ret;
210
    }
211
    /* Read byte of data with not-acknowledge */
212
    ret = iicmb_cmd_read_nak(d + i);
213
    if (ret != rsp_done) return ret;
214
  } while (0);
215
 
216
  /* Stop condition */
217
  (void)iicmb_cmd_stop();
218
 
219
  return ret;
220
}
221
 
222
/* Write single byte */
223
rsp_tt iicmb_write_bus(unsigned char sa, unsigned char a, unsigned char d)
224
{
225
  rsp_tt ret;
226
 
227
  /* Start condition */
228
  ret = iicmb_cmd_start();
229
  if (ret != rsp_done) return ret;
230
 
231
  do {
232
    /* Write slave address and write bit */
233
    ret = iicmb_cmd_write((sa << 1) | 0x00000000);
234
    if (ret != rsp_done) break;
235
    /* Write byte address */
236
    ret = iicmb_cmd_write(a);
237
    if (ret != rsp_done) break;
238
    /* Write byte of data */
239
    ret = iicmb_cmd_write(d);
240
    if (ret != rsp_done) break;
241
  } while (0);
242
 
243
  /* Stop condition */
244
  (void)iicmb_cmd_stop();
245
 
246
  return ret;
247
}
248
 
249
/* Writing several bytes */
250
rsp_tt iicmb_write_bus_mul(unsigned char sa, unsigned char a, unsigned char * d, int n)
251
{
252
  rsp_tt ret;
253
  int i;
254
 
255
  /* Start condition */
256
  ret = iicmb_cmd_start();
257
  if (ret != rsp_done) return ret;
258
 
259
  do {
260
    /* Write slave address and write bit */
261
    ret = iicmb_cmd_write((sa << 1) | 0x00000000);
262
    if (ret != rsp_done) break;
263
    /* Write byte address */
264
    ret = iicmb_cmd_write(a);
265
    if (ret != rsp_done) break;
266
    for (i = 0; i < n; i++)
267
    {
268
      /* Write byte of data */
269
      ret = iicmb_cmd_write(*(d + i));
270
      if (ret != rsp_done) break;
271
    }
272
  } while (0);
273
 
274
  /* Stop condition */
275
  (void)iicmb_cmd_stop();
276
 
277
  return ret;
278
}
279
 
280
/* Report registers */
281
void iicmb_report_registers(FILE *fp)
282
{
283
  int uuu;
284
 
285
  fprintf(fp, "\n--------------------------------------------------------\n");
286
  fprintf(fp, "IICMB state:\n\n");
287
 
288
  uuu = IICMB_REG_READ(IICMB_CSR);
289
  fprintf(fp, "CSR  = 0x%02x\n", uuu);
290
  fprintf(fp, "  Core is ");
291
  if (uuu & 0x00000080) { fprintf(fp, "enabled\n"); } else { fprintf(fp, "disabled\n"); }
292
  fprintf(fp, "  Interrupts are ");
293
  if (uuu & 0x00000040) { fprintf(fp, "enabled\n"); } else { fprintf(fp, "disabled\n"); }
294
  fprintf(fp, "  Selected bus #%d is ", uuu & 0x0000000F);
295
  if (uuu & 0x00000020) { fprintf(fp, "busy and "); } else { fprintf(fp, "free and "); }
296
  if (uuu & 0x00000010) { fprintf(fp, "captured\n"); } else { fprintf(fp, "not captured\n"); }
297
 
298
  uuu = IICMB_REG_READ(IICMB_DPR);
299
  fprintf(fp, "DPR  = 0x%02x\n", uuu);
300
  uuu = IICMB_REG_READ(IICMB_CMDR);
301
  fprintf(fp, "CMDR = 0x%02x\n", uuu);
302
  fprintf(fp, "  Last command was ");
303
  switch (uuu & 0x0000000F)
304
  {
305
    case IICMB_CMD_WAIT     : fprintf(fp, "'Wait'");          break;
306
    case IICMB_CMD_WRITE    : fprintf(fp, "'Write'");         break;
307
    case IICMB_CMD_READ_ACK : fprintf(fp, "'Read with Ack'"); break;
308
    case IICMB_CMD_READ_NAK : fprintf(fp, "'Read with Nak'"); break;
309
    case IICMB_CMD_START    : fprintf(fp, "'Start'");         break;
310
    case IICMB_CMD_STOP     : fprintf(fp, "'Stop'");          break;
311
    case IICMB_CMD_SET_BUS  : fprintf(fp, "'Set bus'");       break;
312
    default                 : fprintf(fp, "'STRANGE!!!'");    break;
313
  }
314
  fprintf(fp, " and response is: ");
315
  switch (uuu & 0x000000F0)
316
  {
317
    case IICMB_RSP_DONE     : fprintf(fp, "'Done'\n");             break;
318
    case IICMB_RSP_NAK      : fprintf(fp, "'No acknowledge'\n");   break;
319
    case IICMB_RSP_ARB_LOST : fprintf(fp, "'Arbitration lost'\n"); break;
320
    case IICMB_RSP_ERR      : fprintf(fp, "'Error'\n");            break;
321
    default                 : fprintf(fp, "STRANGE!!!\n");         break;
322
  }
323
 
324
  uuu = IICMB_REG_READ(IICMB_FSMR);
325
  fprintf(fp, "FSMR = 0x%02x\n", uuu);
326
  fprintf(fp, "  Byte-level FSM state is ");
327
  switch (uuu & 0x000000F0)
328
  {
329
    case 0x00000000 : fprintf(fp, "'(Idle)'\n");           break;
330
    case 0x00000010 : fprintf(fp, "'(Bus is taken)'\n");   break;
331
    case 0x00000020 : fprintf(fp, "'Start is pending'\n"); break;
332
    case 0x00000030 : fprintf(fp, "'Start'\n");            break;
333
    case 0x00000040 : fprintf(fp, "'Stop'\n");             break;
334
    case 0x00000050 : fprintf(fp, "'Byte Write'\n");       break;
335
    case 0x00000060 : fprintf(fp, "'Byte Read'\n");        break;
336
    case 0x00000070 : fprintf(fp, "'Waiting'\n");          break;
337
    default         : fprintf(fp, "'STRANGE!!!'\n");       break;
338
  }
339
  fprintf(fp, "  Bit-level FSM state is ");
340
  switch (uuu & 0x0000000F)
341
  {
342
    case 0x00000000 : fprintf(fp, "'(Idle)'\n");           break;
343
    case 0x00000001 : fprintf(fp, "'Start A'\n");          break;
344
    case 0x00000002 : fprintf(fp, "'Start B'\n");          break;
345
    case 0x00000003 : fprintf(fp, "'(Start C)'\n");        break;
346
    case 0x00000004 : fprintf(fp, "'Read/Write A'\n");     break;
347
    case 0x00000005 : fprintf(fp, "'Read/Write B'\n");     break;
348
    case 0x00000006 : fprintf(fp, "'Read/Write C'\n");     break;
349
    case 0x00000007 : fprintf(fp, "'Read/Write D'\n");     break;
350
    case 0x00000008 : fprintf(fp, "'(Read/Write E)'\n");   break;
351
    case 0x00000009 : fprintf(fp, "'Stop A'\n");           break;
352
    case 0x0000000a : fprintf(fp, "'Stop B'\n");           break;
353
    case 0x0000000b : fprintf(fp, "'Stop C'\n");           break;
354
    case 0x0000000c : fprintf(fp, "'Repeated Start A'\n"); break;
355
    case 0x0000000d : fprintf(fp, "'Repeated Start B'\n"); break;
356
    case 0x0000000e : fprintf(fp, "'Repeated Start C'\n"); break;
357
    default         : fprintf(fp, "'STRANGE!!!'\n");       break;
358
  }
359
  fprintf(fp, "--------------------------------------------------------\n");
360
  fprintf(fp, "\n");
361
}
362
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.