int i2c_xfer(const imx_i2c_request_t *rq, int dir) { uint32_t reg; uint32_t ret = 0; uint16_t i2cr; uint8_t i; uint8_t data; uint32_t instance = i2c_get_request_instance(rq); uint8_t address = (rq->device ? rq->device->address : rq->dev_addr) << 1; if (rq->buffer_sz == 0 || rq->buffer == NULL) { debug_printf("Invalid register address size=%x, buffer size=%x, buffer=%x\n", rq->reg_addr_sz, rq->buffer_sz, (unsigned int)rq->buffer); return ERR_INVALID_REQUEST; } // clear the status register HW_I2C_I2SR_WR(instance, 0); // enable the I2C controller HW_I2C_I2CR_WR(instance, BM_I2C_I2CR_IEN); // Check if bus is free, if not return error if (is_bus_free(instance) != 0) { return -1; } // If the request has device info attached and it has a non-zero bit rate, then // change the clock to the specified rate. if (rq->device && rq->device->freq) { set_i2c_clock(instance, rq->device->freq); } // Step 1: Select master mode, assert START signal and also indicate TX mode HW_I2C_I2CR_WR(instance, BM_I2C_I2CR_IEN | BM_I2C_I2CR_MSTA | BM_I2C_I2CR_MTX); // make sure bus is busy after the START signal if (wait_till_busy(instance) != 0) { debug_printf("1\n"); return -1; } // Step 2: send slave address + read/write at the LSB data = address | I2C_WRITE; if ((ret = tx_byte(&data, instance)) != 0) { debug_printf("START TX ERR %d\n", ret); if (ret == ERR_NO_ACK) { return ERR_NO_ACK_ON_START; } else { return ret; } } // Step 3: send I2C device register address if (rq->reg_addr_sz > 4) { debug_printf("Warning register address size %d should less than 4\n", rq->reg_addr_sz); return ERR_INVALID_REQUEST; } reg = rq->reg_addr; for (i = 0; i < rq->reg_addr_sz; i++, reg >>= 8) { data = reg & 0xFF; #if TRACE_I2C debug_printf("sending I2C=%d device register: data=0x%x, byte %d\n", instance, data, i); #endif // TRACE_I2C if (tx_byte(&data, instance) != 0) { return -1; } } // Step 4: read/write data if (dir == I2C_READ) { // do repeat-start HW_I2C_I2CR(instance).B.RSTA = 1; // make sure bus is busy after the REPEATED START signal if (wait_till_busy(instance) != 0) { return ERR_TX; } // send slave address again, but indicate read operation data = address | I2C_READ; if (tx_byte(&data, instance) != 0) { return -1; } // change to receive mode i2cr = HW_I2C_I2CR_RD(instance) & ~BM_I2C_I2CR_MTX; // if only one byte to read, make sure don't send ack if (rq->buffer_sz == 1) { i2cr |= BM_I2C_I2CR_TXAK; } HW_I2C_I2CR_WR(instance, i2cr); // dummy read data = HW_I2C_I2DR_RD(instance); // now reading ... if (rx_bytes(rq->buffer, instance, rq->buffer_sz) != 0) { return -1; } } else { // I2C_WRITE for (i = 0; i < rq->buffer_sz; i++) { // send device register value data = rq->buffer[i]; if ((ret = tx_byte(&data, instance)) != 0) { break; } } } // generate STOP by clearing MSTA bit imx_send_stop(instance); // Check if bus is free, if not return error if (is_bus_free(instance) != 0) { debug_printf("WARNING: bus is not free\n"); } // disable the controller HW_I2C_I2CR_WR(instance, 0); return ret; }
int main(int argc, char *argv[]) { int sockfd; struct addrinfo hints, *servinfo, *p; int rv; int numbytes; struct sockaddr_storage their_addr; char buf[MAXBUFLEN]; socklen_t addr_len; char s[INET6_ADDRSTRLEN]; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4 hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; // use my IP if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // loop through all the results and bind to the first we can for(p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("listener: socket"); continue; } if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("listener: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "listener: failed to bind socket\n"); return 2; } freeaddrinfo(servinfo); printf("listener: waiting to recvfrom...\n"); int run = 1; while(run){ addr_len = sizeof their_addr; if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) { perror("recvfrom"); exit(1); } printf("listener: got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s)); printf("listener: packet is %d bytes long\n", numbytes); buf[numbytes] = '\0'; printf("listener: packet contains \"%s\"\n", buf); if(!strcmp(buf, "terminator")){ printf("> Shutting down client interface...\n"); run = 0; } else if(strcmp(buf, "name") == 0){ printf("> requesting hostname\n"); char name[256] = {'\0'}; get_hostname(name); printf("listener: hostname = %s\n", name); } else if(!strcmp(buf, "uptime")){ char name[128] = {'\0'}; get_uptime(name); printf("listener: uptime = %s\n", name); } else if(!strcmp(buf, "users")){ char buf[128] = {'\0'}; get_logged_in(buf); } else if(!strcmp(buf, "rxb")){ char buf[128] = {'\0'}; uint64_t bytes = rx_bytes("eth0"); printf("listener: rx bytes = %uld\n", bytes); } else{ printf("listener: unknown command: %s", buf); } } close(sockfd); printf("Good bye.\n"); return 0; }