blob: d7f52dc66513e7609710ad89b0291e5ec4450c93 [file] [log] [blame]
Stefan Reinauerc566d202015-08-25 09:52:42 -07001/*
2 * Copyright 2012-2015 Google Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18#include <stdio.h>
19#include <string.h>
20#include <unistd.h>
21#include "em100.h"
22
23/* SPI flash related operations */
24
25int get_spi_flash_id(struct em100 *em100)
26{
27 unsigned char cmd[16];
28 unsigned char data[512];
29 memset(cmd, 0, 16);
30 cmd[0] = 0x30; /* Get SPI flash ID */
31 if (!send_cmd(em100->dev, cmd)) {
32 return 0;
33 }
34 int len = get_response(em100->dev, data, 512);
35 if (len == 3) {
36 int id = (data[0] << 16) | (data[1] << 8) | data[2];
37 return id;
38 }
39 return 0;
40}
41
42int erase_spi_flash(struct em100 *em100)
43{
44 unsigned char cmd[16];
45 memset(cmd, 0, 16);
46 cmd[0] = 0x31; /* Erase SPI flash */
47 if (!send_cmd(em100->dev, cmd)) {
48 return 0;
49 }
50 /* Specification says to wait 5s before
51 * issuing another USB command
52 */
53 sleep(5);
54 return 1;
55}
56
57int poll_spi_flash_status(struct em100 *em100)
58{
59 unsigned char cmd[16];
60 unsigned char data[1];
61 memset(cmd, 0, 16);
62 cmd[0] = 0x32; /* Poll SPI flash status */
63 if (!send_cmd(em100->dev, cmd)) {
64 return 0;
65 }
66 int len = get_response(em100->dev, data, 1);
67 if ((len == 1) && (data[0] == 1)) {
68 /* ready */
69 return 1;
70 }
71 /* busy (or read unsuccessful) */
72 return 0;
73}
74
75/**
76 * read_spi_flash_page: fetch SPI flash page
77 * @param em100: initialized em100 device structure
78 *
79 * out(16 bytes): 0x33 addr addr addr .. 0
80 * in(len + 255 bytes): 0xff ?? serno_lo serno_hi ?? ?? .. ??
81 */
82int read_spi_flash_page(struct em100 *em100, int addr, unsigned char *blk)
83{
84 unsigned char cmd[16];
85 unsigned char data[256];
86 memset(cmd, 0, 16);
Stefan Reinauerae4dcd02015-08-28 16:26:03 -070087 cmd[0] = 0x33; /* read SPI flash page */
Stefan Reinauerc566d202015-08-25 09:52:42 -070088 cmd[1] = (addr >> 16) & 0xff;
89 cmd[2] = (addr >> 8) & 0xff;
90 cmd[3] = addr & 0xff;
91 if (!send_cmd(em100->dev, cmd)) {
92 return 0;
93 }
94 int len = get_response(em100->dev, data, 256);
95
96 if (len == 256) {
97 memcpy(blk, data, 256);
98 return 1;
99 }
100 return 0;
101}
102
103int write_spi_flash_page(struct em100 *em100, unsigned char *data, int address)
104{
105 int length = 256;
106 int actual;
107 int bytes_sent=0;
108 int bytes_left;
109 unsigned char cmd[16];
110 memset(cmd, 0, 16);
111 cmd[0] = 0x34; /* host-to-em100 eeprom data */
112 cmd[2] = (address >> 16) & 0xff;
113 cmd[3] = (address >> 8) & 0xff;
114 cmd[4] = address & 0xff;
115
116 if (!send_cmd(em100->dev, cmd)) {
Stefan Reinauer54474a62015-08-28 16:27:30 -0700117 printf("Error: Could not initiate host-to-EM100 transfer.\n");
Stefan Reinauerc566d202015-08-25 09:52:42 -0700118 return 0;
119 }
120
121 while ( bytes_sent < length) {
122 actual = 0;
123
124 bytes_left = length - bytes_sent;
125
126 libusb_bulk_transfer(em100->dev, 1 | LIBUSB_ENDPOINT_OUT,
127 data + bytes_sent, bytes_left, &actual, BULK_SEND_TIMEOUT);
128 bytes_sent += actual;
129 if (actual < bytes_left) {
130 printf("Tried sending %d bytes, sent %d\n", bytes_left, actual);
131 break;
132 }
133
134 printf("Sent %d bytes of %d\n", bytes_sent, length);
135 }
136
137 printf ("Transfer %s\n",bytes_sent == length ? "Succeeded" : "Failed");
138 return (bytes_sent == length);
139}
140
141/* SPI HyperTerminal related operations */
142
143/**
144 * read_ht_register: Read HT registers
145 * @param em100: initialized em100 device structure
146 *
147 * out(2 bytes): 0x50 RegAddr .. 0
148 * in(len + 1 byte): 0x02 val
149 */
150int read_ht_register(struct em100 *em100, int reg, uint8_t *val)
151{
152 unsigned char cmd[16];
153 unsigned char data[2];
154
155 memset(cmd, 0, 16);
156 cmd[0] = 0x50; /* read fpga register */
157 cmd[1] = reg;
158 if (!send_cmd(em100->dev, cmd)) {
159 return 0;
160 }
161 int len = get_response(em100->dev, data, 2);
162 if ((len == 2) && (data[0] == 1)) {
163 *val = data[1];
164 return 1;
165 }
166 return 0;
167}
168
169/**
170 * write_ht_register: Write HT registers
171 * @param em100: initialized em100 device structure
172 *
173 * out(3 bytes): 0x51 RegAddr Val .. 0
174 */
175int write_ht_register(struct em100 *em100, int reg, uint8_t val)
176{
177 unsigned char cmd[16];
178 memset(cmd, 0, 16);
179 cmd[0] = 0x51; /* write fpga registers */
180 cmd[1] = reg;
181 cmd[2] = val;
182 if (!send_cmd(em100->dev, cmd)) {
183 return 0;
184 }
185 return 1;
186}