i2c_core.c (3575B)
1 /* Copyright 2014 Brian Swetland <swetland@frotz.net> 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <unistd.h> 19 20 #include "jtag.h" 21 #include "zynq.h" 22 23 #include "i2c.h" 24 25 #define TRACE_TXN 0 26 27 static JTAG *jtag; 28 29 void jconnect(void) { 30 if (!(jtag = jtag_open())) { 31 fprintf(stderr, "jconnect: cannot open usb jtag ifc\n"); 32 exit(-1); 33 } 34 if (jtag_enumerate(jtag) <= 0) { 35 fprintf(stderr, "jconnect: cannot enumerate jtag devices\n"); 36 exit(-1); 37 } 38 if (jtag_select(jtag, 0x13722093)) { 39 fprintf(stderr, "jconnect: cannot connect to ZYNQ\n"); 40 exit(-1); 41 } 42 43 jtag_ir_wr(jtag, XIL_USER4); 44 } 45 46 u32 jrd(void) { 47 u64 u; 48 jtag_dr_io(jtag, 32, 0, &u); 49 return (u32) u; 50 } 51 52 u32 jwr(u32 n) { 53 u64 u; 54 u = n; 55 u |= 0x100000000ULL; 56 jtag_dr_io(jtag, 33, u, &u); 57 return (u32) u; 58 } 59 60 // 0x00XX // wo - data to write 61 // 0x00XX // ro - last data read 62 #define STA 0x0100 // rw - issue start on next rd or wr 63 #define STP 0x0200 // rw - issue stop 64 #define WR 0x0400 // rw - issue write 65 #define RD 0x0800 // rw - issue read 66 #define RACK 0x1000 // wo - master ACK/NAK state for reads 67 #define TIP 0x1000 // ro - transaction in progress 68 #define ACK 0x2000 // ro - slave ACK/NAK received on write 69 #define LOST 0x4000 // ro - arbitration lost 70 #define BUSY 0x8000 // ro - I2C bus busy 71 72 static int i2c_txn(unsigned cmd, unsigned *_status) { 73 unsigned timeout = 0; 74 unsigned status; 75 jwr(cmd); 76 while ((status = jrd()) & TIP) { 77 timeout++; 78 if (timeout == 10000) { 79 #if TRACE_TXN 80 fprintf(stderr,"txn: %04x XXXX\n",cmd); 81 #endif 82 fprintf(stderr, "i2c: txn timeout\n"); 83 return -1; 84 } 85 } 86 #if TRACE_TXN 87 fprintf(stderr,"txn: %04x %04x\n",cmd, status); 88 #endif 89 *_status = status; 90 return 0; 91 } 92 93 static int i2c_start(unsigned saddr) { 94 unsigned status; 95 if (i2c_txn((saddr & 0xFF) | STA | WR, &status)) 96 return -1; 97 if (status & ACK) { 98 fprintf(stderr, "i2c: slave NAK'd\n"); 99 return -1; 100 } 101 return 0; 102 } 103 104 static int i2c_stop(void) { 105 unsigned status; 106 return i2c_txn(STP, &status); 107 } 108 109 static int i2c_write(unsigned data) { 110 unsigned status; 111 if (i2c_txn((data & 0xFF) | WR, &status)) 112 return -1; 113 if (status & ACK) { 114 fprintf(stderr, "i2c: slave NAK'd\n"); 115 return -1; 116 } 117 return 0; 118 } 119 120 static int i2c_read(unsigned *data, unsigned send_nak) { 121 unsigned status; 122 if (i2c_txn(RD | (send_nak ? RACK : 0), &status)) 123 return -1; 124 *data = status & 0xFF; 125 return 0; 126 } 127 128 int i2c_wr16(unsigned saddr, unsigned addr, unsigned val) { 129 if (i2c_start(saddr)) return -1; 130 if (i2c_write(addr >> 8)) return -1; 131 if (i2c_write(addr)) return -1; 132 if (i2c_write(val >> 8)) return -1; 133 if (i2c_write(val)) return -1; 134 return i2c_stop(); 135 } 136 137 int i2c_rd16(unsigned saddr, unsigned addr, unsigned *val) { 138 unsigned a, b; 139 if (i2c_start(saddr)) return -1; 140 if (i2c_write(addr >> 8)) return -1; 141 if (i2c_write(addr)) return -1; 142 if (i2c_start(saddr | 1)) return -1; 143 if (i2c_read(&a, 0)) return -1; 144 if (i2c_read(&b, 1)) return -1; 145 *val = (a << 8) | b; 146 return i2c_stop(); 147 } 148 149 void i2c_init(void) { 150 jconnect(); 151 }