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

Subversion Repositories i2c

[/] [i2c/] [trunk/] [rtl/] [verilog/] [i2c_master_bit_ctrl.v] - Blame information for rev 57

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 rherveille
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  WISHBONE rev.B2 compliant I2C Master bit-controller        ////
4
////                                                             ////
5
////                                                             ////
6
////  Author: Richard Herveille                                  ////
7
////          richard@asics.ws                                   ////
8
////          www.asics.ws                                       ////
9
////                                                             ////
10
////  Downloaded from: http://www.opencores.org/projects/i2c/    ////
11
////                                                             ////
12
/////////////////////////////////////////////////////////////////////
13
////                                                             ////
14
//// Copyright (C) 2001 Richard Herveille                        ////
15
////                    richard@asics.ws                         ////
16
////                                                             ////
17
//// This source file may be used and distributed without        ////
18
//// restriction provided that this copyright statement is not   ////
19
//// removed from the file and that any derivative work contains ////
20
//// the original copyright notice and the associated disclaimer.////
21
////                                                             ////
22
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
23
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
24
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
25
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
26
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
27
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
28
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
29
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
30
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
31
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
32
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
33
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
34
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
35
////                                                             ////
36
/////////////////////////////////////////////////////////////////////
37
 
38
//  CVS Log
39 10 rherveille
//
40 57 rherveille
//  $Id: i2c_master_bit_ctrl.v,v 1.12 2006-09-04 09:08:13 rherveille Exp $
41 10 rherveille
//
42 57 rherveille
//  $Date: 2006-09-04 09:08:13 $
43
//  $Revision: 1.12 $
44 14 rherveille
//  $Author: rherveille $
45
//  $Locker:  $
46
//  $State: Exp $
47 10 rherveille
//
48 14 rherveille
// Change History:
49
//               $Log: not supported by cvs2svn $
50 57 rherveille
//               Revision 1.11  2004/05/07 11:02:26  rherveille
51
//               Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit.
52
//
53 52 rherveille
//               Revision 1.10  2003/08/09 07:01:33  rherveille
54
//               Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
55
//               Fixed a potential bug in the byte controller's host-acknowledge generation.
56
//
57 38 rherveille
//               Revision 1.9  2003/03/10 14:26:37  rherveille
58
//               Fixed cmd_ack generation item (no bug).
59
//
60 36 rherveille
//               Revision 1.8  2003/02/05 00:06:10  rherveille
61
//               Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
62
//
63 35 rherveille
//               Revision 1.7  2002/12/26 16:05:12  rherveille
64
//               Small code simplifications
65
//
66 30 rherveille
//               Revision 1.6  2002/12/26 15:02:32  rherveille
67
//               Core is now a Multimaster I2C controller
68
//
69 29 rherveille
//               Revision 1.5  2002/11/30 22:24:40  rherveille
70
//               Cleaned up code
71
//
72 27 rherveille
//               Revision 1.4  2002/10/30 18:10:07  rherveille
73
//               Fixed some reported minor start/stop generation timing issuess.
74
//
75 24 rherveille
//               Revision 1.3  2002/06/15 07:37:03  rherveille
76
//               Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
77
//
78 22 rherveille
//               Revision 1.2  2001/11/05 11:59:25  rherveille
79
//               Fixed wb_ack_o generation bug.
80
//               Fixed bug in the byte_controller statemachine.
81
//               Added headers.
82
//
83 10 rherveille
 
84
//
85
/////////////////////////////////////
86
// Bit controller section
87
/////////////////////////////////////
88
//
89
// Translate simple commands into SCL/SDA transitions
90
// Each command has 5 states, A/B/C/D/idle
91
//
92
// start:       SCL     ~~~~~~~~~~\____
93
//      SDA     ~~~~~~~~\______
94
//               x | A | B | C | D | i
95
//
96
// repstart     SCL     ____/~~~~\___
97
//      SDA     __/~~~\______
98
//               x | A | B | C | D | i
99
//
100
// stop SCL     ____/~~~~~~~~
101
//      SDA     ==\____/~~~~~
102
//               x | A | B | C | D | i
103
//
104
//- write       SCL     ____/~~~~\____
105
//      SDA     ==X=========X=
106
//               x | A | B | C | D | i
107
//
108
//- read        SCL     ____/~~~~\____
109
//      SDA     XXXX=====XXXX
110
//               x | A | B | C | D | i
111
//
112
 
113 24 rherveille
// Timing:     Normal mode      Fast mode
114 10 rherveille
///////////////////////////////////////////////////////////////////////
115 24 rherveille
// Fscl        100KHz           400KHz
116
// Th_scl      4.0us            0.6us   High period of SCL
117
// Tl_scl      4.7us            1.3us   Low period of SCL
118
// Tsu:sta     4.7us            0.6us   setup time for a repeated start condition
119
// Tsu:sto     4.0us            0.6us   setup time for a stop conditon
120
// Tbuf        4.7us            1.3us   Bus free time between a stop and start condition
121 10 rherveille
//
122
 
123 29 rherveille
// synopsys translate_off
124 10 rherveille
`include "timescale.v"
125 29 rherveille
// synopsys translate_on
126
 
127 10 rherveille
`include "i2c_master_defines.v"
128
 
129 29 rherveille
module i2c_master_bit_ctrl(
130
        clk, rst, nReset,
131
        clk_cnt, ena, cmd, cmd_ack, busy, al, din, dout,
132
        scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen
133
        );
134 10 rherveille
 
135
        //
136
        // inputs & outputs
137
        //
138
        input clk;
139
        input rst;
140
        input nReset;
141
        input ena;            // core enable signal
142
 
143
        input [15:0] clk_cnt; // clock prescale value
144
 
145
        input  [3:0] cmd;
146 29 rherveille
        output       cmd_ack; // command complete acknowledge
147 10 rherveille
        reg cmd_ack;
148 29 rherveille
        output       busy;    // i2c bus busy
149 10 rherveille
        reg busy;
150 29 rherveille
        output       al;      // i2c bus arbitration lost
151
        reg al;
152 10 rherveille
 
153
        input  din;
154
        output dout;
155
        reg dout;
156
 
157
        // I2C lines
158 29 rherveille
        input  scl_i;         // i2c clock line input
159
        output scl_o;         // i2c clock line output
160
        output scl_oen;       // i2c clock line output enable (active low)
161 10 rherveille
        reg scl_oen;
162 29 rherveille
        input  sda_i;         // i2c data line input
163
        output sda_o;         // i2c data line output
164
        output sda_oen;       // i2c data line output enable (active low)
165 10 rherveille
        reg sda_oen;
166
 
167
 
168
        //
169
        // variable declarations
170
        //
171
 
172 22 rherveille
        reg sSCL, sSDA;             // synchronized SCL and SDA inputs
173
        reg dscl_oen;               // delayed scl_oen
174 29 rherveille
        reg sda_chk;                // check SDA output (Multi-master arbitration)
175 10 rherveille
        reg clk_en;                 // clock generation signals
176
        wire slave_wait;
177 22 rherveille
//      reg [15:0] cnt = clk_cnt;   // clock divider counter (simulation)
178 10 rherveille
        reg [15:0] cnt;             // clock divider counter (synthesis)
179
 
180 52 rherveille
        // state machine variable
181
        reg [16:0] c_state; // synopsys enum_state
182
 
183 10 rherveille
        //
184
        // module body
185
        //
186
 
187 29 rherveille
        // whenever the slave is not ready it can delay the cycle by pulling SCL low
188 22 rherveille
        // delay scl_oen
189
        always @(posedge clk)
190 24 rherveille
          dscl_oen <= #1 scl_oen;
191 22 rherveille
 
192
        assign slave_wait = dscl_oen && !sSCL;
193 10 rherveille
 
194 29 rherveille
 
195 10 rherveille
        // generate clk enable signal
196 24 rherveille
        always @(posedge clk or negedge nReset)
197
          if(~nReset)
198
            begin
199
                cnt    <= #1 16'h0;
200
                clk_en <= #1 1'b1;
201
            end
202
          else if (rst)
203
            begin
204
                cnt    <= #1 16'h0;
205
                clk_en <= #1 1'b1;
206
            end
207 57 rherveille
          else if ( ~|cnt || !ena)
208
            begin
209
                cnt    <= #1 clk_cnt;
210
                clk_en <= #1 1'b1;
211
            end
212
          else if (slave_wait)
213
            begin
214
                cnt    <= #1 cnt;
215
                clk_en <= #1 1'b0;
216
            end
217 24 rherveille
          else
218
            begin
219 57 rherveille
                cnt    <= #1 cnt - 16'h1;
220 24 rherveille
                clk_en <= #1 1'b0;
221
            end
222 10 rherveille
 
223
 
224
        // generate bus status controller
225 29 rherveille
        reg dSCL, dSDA;
226 10 rherveille
        reg sta_condition;
227
        reg sto_condition;
228
 
229 29 rherveille
        // synchronize SCL and SDA inputs
230
        // reduce metastability risc
231 35 rherveille
        always @(posedge clk or negedge nReset)
232
          if (~nReset)
233
            begin
234
                sSCL <= #1 1'b1;
235
                sSDA <= #1 1'b1;
236 29 rherveille
 
237 35 rherveille
                dSCL <= #1 1'b1;
238
                dSDA <= #1 1'b1;
239
            end
240
          else if (rst)
241
            begin
242
                sSCL <= #1 1'b1;
243
                sSDA <= #1 1'b1;
244 29 rherveille
 
245 35 rherveille
                dSCL <= #1 1'b1;
246
                dSDA <= #1 1'b1;
247
            end
248
          else
249
            begin
250
                sSCL <= #1 scl_i;
251
                sSDA <= #1 sda_i;
252
 
253
                dSCL <= #1 sSCL;
254
                dSDA <= #1 sSDA;
255
            end
256
 
257 10 rherveille
        // detect start condition => detect falling edge on SDA while SCL is high
258
        // detect stop condition => detect rising edge on SDA while SCL is high
259 35 rherveille
        always @(posedge clk or negedge nReset)
260
          if (~nReset)
261
            begin
262
                sta_condition <= #1 1'b0;
263
                sto_condition <= #1 1'b0;
264
            end
265
          else if (rst)
266
            begin
267
                sta_condition <= #1 1'b0;
268
                sto_condition <= #1 1'b0;
269
            end
270
          else
271
            begin
272
                sta_condition <= #1 ~sSDA &  dSDA & sSCL;
273
                sto_condition <= #1  sSDA & ~dSDA & sSCL;
274
            end
275 10 rherveille
 
276 30 rherveille
        // generate i2c bus busy signal
277 24 rherveille
        always @(posedge clk or negedge nReset)
278
          if(!nReset)
279
            busy <= #1 1'b0;
280
          else if (rst)
281
            busy <= #1 1'b0;
282
          else
283 27 rherveille
            busy <= #1 (sta_condition | busy) & ~sto_condition;
284 10 rherveille
 
285 29 rherveille
        // generate arbitration lost signal
286
        // aribitration lost when:
287
        // 1) master drives SDA high, but the i2c bus is low
288
        // 2) stop detected while not requested
289 38 rherveille
        reg cmd_stop;
290 35 rherveille
        always @(posedge clk or negedge nReset)
291
          if (~nReset)
292 38 rherveille
            cmd_stop <= #1 1'b0;
293 35 rherveille
          else if (rst)
294 38 rherveille
            cmd_stop <= #1 1'b0;
295
          else if (clk_en)
296
            cmd_stop <= #1 cmd == `I2C_CMD_STOP;
297
 
298
        always @(posedge clk or negedge nReset)
299
          if (~nReset)
300
            al <= #1 1'b0;
301
          else if (rst)
302
            al <= #1 1'b0;
303 35 rherveille
          else
304 52 rherveille
            al <= #1 (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
305 10 rherveille
 
306 29 rherveille
 
307
        // generate dout signal (store SDA on rising edge of SCL)
308
        always @(posedge clk)
309
          if(sSCL & ~dSCL)
310
            dout <= #1 sSDA;
311
 
312 10 rherveille
        // generate statemachine
313
 
314
        // nxt_state decoder
315 24 rherveille
        parameter [16:0] idle    = 17'b0_0000_0000_0000_0000;
316
        parameter [16:0] start_a = 17'b0_0000_0000_0000_0001;
317
        parameter [16:0] start_b = 17'b0_0000_0000_0000_0010;
318
        parameter [16:0] start_c = 17'b0_0000_0000_0000_0100;
319
        parameter [16:0] start_d = 17'b0_0000_0000_0000_1000;
320
        parameter [16:0] start_e = 17'b0_0000_0000_0001_0000;
321
        parameter [16:0] stop_a  = 17'b0_0000_0000_0010_0000;
322
        parameter [16:0] stop_b  = 17'b0_0000_0000_0100_0000;
323
        parameter [16:0] stop_c  = 17'b0_0000_0000_1000_0000;
324
        parameter [16:0] stop_d  = 17'b0_0000_0001_0000_0000;
325
        parameter [16:0] rd_a    = 17'b0_0000_0010_0000_0000;
326
        parameter [16:0] rd_b    = 17'b0_0000_0100_0000_0000;
327
        parameter [16:0] rd_c    = 17'b0_0000_1000_0000_0000;
328
        parameter [16:0] rd_d    = 17'b0_0001_0000_0000_0000;
329
        parameter [16:0] wr_a    = 17'b0_0010_0000_0000_0000;
330
        parameter [16:0] wr_b    = 17'b0_0100_0000_0000_0000;
331
        parameter [16:0] wr_c    = 17'b0_1000_0000_0000_0000;
332
        parameter [16:0] wr_d    = 17'b1_0000_0000_0000_0000;
333 10 rherveille
 
334 24 rherveille
        always @(posedge clk or negedge nReset)
335
          if (!nReset)
336
            begin
337
                c_state <= #1 idle;
338
                cmd_ack <= #1 1'b0;
339 27 rherveille
                scl_oen <= #1 1'b1;
340
                sda_oen <= #1 1'b1;
341 29 rherveille
                sda_chk <= #1 1'b0;
342 24 rherveille
            end
343 29 rherveille
          else if (rst | al)
344 24 rherveille
            begin
345
                c_state <= #1 idle;
346
                cmd_ack <= #1 1'b0;
347 27 rherveille
                scl_oen <= #1 1'b1;
348
                sda_oen <= #1 1'b1;
349 29 rherveille
                sda_chk <= #1 1'b0;
350 24 rherveille
            end
351
          else
352
            begin
353 27 rherveille
                cmd_ack   <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
354
 
355 24 rherveille
                if (clk_en)
356 52 rherveille
                  case (c_state) // synopsys full_case parallel_case
357 27 rherveille
                    // idle state
358
                    idle:
359
                    begin
360 52 rherveille
                        case (cmd) // synopsys full_case parallel_case
361 27 rherveille
                          `I2C_CMD_START:
362
                             c_state <= #1 start_a;
363 10 rherveille
 
364 27 rherveille
                          `I2C_CMD_STOP:
365
                             c_state <= #1 stop_a;
366 10 rherveille
 
367 27 rherveille
                          `I2C_CMD_WRITE:
368
                             c_state <= #1 wr_a;
369 10 rherveille
 
370 27 rherveille
                          `I2C_CMD_READ:
371
                             c_state <= #1 rd_a;
372 10 rherveille
 
373 27 rherveille
                          default:
374
                            c_state <= #1 idle;
375
                        endcase
376 10 rherveille
 
377 27 rherveille
                        scl_oen <= #1 scl_oen; // keep SCL in same state
378
                        sda_oen <= #1 sda_oen; // keep SDA in same state
379 29 rherveille
                        sda_chk <= #1 1'b0;    // don't check SDA output
380 27 rherveille
                    end
381 10 rherveille
 
382 27 rherveille
                    // start
383
                    start_a:
384
                    begin
385
                        c_state <= #1 start_b;
386
                        scl_oen <= #1 scl_oen; // keep SCL in same state
387
                        sda_oen <= #1 1'b1;    // set SDA high
388 29 rherveille
                        sda_chk <= #1 1'b0;    // don't check SDA output
389 27 rherveille
                    end
390 10 rherveille
 
391 27 rherveille
                    start_b:
392
                    begin
393
                        c_state <= #1 start_c;
394
                        scl_oen <= #1 1'b1; // set SCL high
395
                        sda_oen <= #1 1'b1; // keep SDA high
396 29 rherveille
                        sda_chk <= #1 1'b0; // don't check SDA output
397 27 rherveille
                    end
398 10 rherveille
 
399 27 rherveille
                    start_c:
400
                    begin
401
                        c_state <= #1 start_d;
402
                        scl_oen <= #1 1'b1; // keep SCL high
403
                        sda_oen <= #1 1'b0; // set SDA low
404 29 rherveille
                        sda_chk <= #1 1'b0; // don't check SDA output
405 27 rherveille
                    end
406 10 rherveille
 
407 27 rherveille
                    start_d:
408
                    begin
409
                        c_state <= #1 start_e;
410
                        scl_oen <= #1 1'b1; // keep SCL high
411
                        sda_oen <= #1 1'b0; // keep SDA low
412 29 rherveille
                        sda_chk <= #1 1'b0; // don't check SDA output
413 27 rherveille
                    end
414 10 rherveille
 
415 27 rherveille
                    start_e:
416
                    begin
417
                        c_state <= #1 idle;
418
                        cmd_ack <= #1 1'b1;
419
                        scl_oen <= #1 1'b0; // set SCL low
420
                        sda_oen <= #1 1'b0; // keep SDA low
421 29 rherveille
                        sda_chk <= #1 1'b0; // don't check SDA output
422 27 rherveille
                    end
423 10 rherveille
 
424 27 rherveille
                    // stop
425
                    stop_a:
426
                    begin
427
                        c_state <= #1 stop_b;
428
                        scl_oen <= #1 1'b0; // keep SCL low
429
                        sda_oen <= #1 1'b0; // set SDA low
430 29 rherveille
                        sda_chk <= #1 1'b0; // don't check SDA output
431 27 rherveille
                    end
432 10 rherveille
 
433 27 rherveille
                    stop_b:
434
                    begin
435
                        c_state <= #1 stop_c;
436
                        scl_oen <= #1 1'b1; // set SCL high
437
                        sda_oen <= #1 1'b0; // keep SDA low
438 29 rherveille
                        sda_chk <= #1 1'b0; // don't check SDA output
439 27 rherveille
                    end
440 10 rherveille
 
441 27 rherveille
                    stop_c:
442
                    begin
443
                        c_state <= #1 stop_d;
444
                        scl_oen <= #1 1'b1; // keep SCL high
445
                        sda_oen <= #1 1'b0; // keep SDA low
446 29 rherveille
                        sda_chk <= #1 1'b0; // don't check SDA output
447 27 rherveille
                    end
448 10 rherveille
 
449 27 rherveille
                    stop_d:
450
                    begin
451
                        c_state <= #1 idle;
452 36 rherveille
                        cmd_ack <= #1 1'b1;
453 27 rherveille
                        scl_oen <= #1 1'b1; // keep SCL high
454
                        sda_oen <= #1 1'b1; // set SDA high
455 29 rherveille
                        sda_chk <= #1 1'b0; // don't check SDA output
456 27 rherveille
                    end
457 10 rherveille
 
458 27 rherveille
                    // read
459
                    rd_a:
460
                    begin
461
                        c_state <= #1 rd_b;
462
                        scl_oen <= #1 1'b0; // keep SCL low
463
                        sda_oen <= #1 1'b1; // tri-state SDA
464 29 rherveille
                        sda_chk <= #1 1'b0; // don't check SDA output
465 27 rherveille
                    end
466 10 rherveille
 
467 27 rherveille
                    rd_b:
468
                    begin
469
                        c_state <= #1 rd_c;
470
                        scl_oen <= #1 1'b1; // set SCL high
471
                        sda_oen <= #1 1'b1; // keep SDA tri-stated
472 29 rherveille
                        sda_chk <= #1 1'b0; // don't check SDA output
473 27 rherveille
                    end
474 10 rherveille
 
475 27 rherveille
                    rd_c:
476
                    begin
477
                        c_state <= #1 rd_d;
478
                        scl_oen <= #1 1'b1; // keep SCL high
479 29 rherveille
                        sda_oen <= #1 1'b1; // keep SDA tri-stated
480
                        sda_chk <= #1 1'b0; // don't check SDA output
481 27 rherveille
                    end
482 10 rherveille
 
483 27 rherveille
                    rd_d:
484
                    begin
485
                        c_state <= #1 idle;
486 36 rherveille
                        cmd_ack <= #1 1'b1;
487 27 rherveille
                        scl_oen <= #1 1'b0; // set SCL low
488 29 rherveille
                        sda_oen <= #1 1'b1; // keep SDA tri-stated
489
                        sda_chk <= #1 1'b0; // don't check SDA output
490 27 rherveille
                    end
491 10 rherveille
 
492 27 rherveille
                    // write
493
                    wr_a:
494
                    begin
495
                        c_state <= #1 wr_b;
496
                        scl_oen <= #1 1'b0; // keep SCL low
497
                        sda_oen <= #1 din;  // set SDA
498 29 rherveille
                        sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
499 27 rherveille
                    end
500 10 rherveille
 
501 27 rherveille
                    wr_b:
502
                    begin
503
                        c_state <= #1 wr_c;
504
                        scl_oen <= #1 1'b1; // set SCL high
505
                        sda_oen <= #1 din;  // keep SDA
506 29 rherveille
                        sda_chk <= #1 1'b1; // check SDA output
507 27 rherveille
                    end
508 10 rherveille
 
509 27 rherveille
                    wr_c:
510
                    begin
511
                        c_state <= #1 wr_d;
512
                        scl_oen <= #1 1'b1; // keep SCL high
513
                        sda_oen <= #1 din;
514 29 rherveille
                        sda_chk <= #1 1'b1; // check SDA output
515 27 rherveille
                    end
516 24 rherveille
 
517 27 rherveille
                    wr_d:
518
                    begin
519
                        c_state <= #1 idle;
520
                        cmd_ack <= #1 1'b1;
521
                        scl_oen <= #1 1'b0; // set SCL low
522
                        sda_oen <= #1 din;
523 29 rherveille
                        sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
524 27 rherveille
                    end
525 24 rherveille
 
526 27 rherveille
                  endcase
527
            end
528 24 rherveille
 
529 27 rherveille
 
530
        // assign scl and sda output (always gnd)
531
        assign scl_o = 1'b0;
532
        assign sda_o = 1'b0;
533
 
534 10 rherveille
endmodule

powered by: WebSVN 2.1.0

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