Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 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. |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 12 | */ |
| 13 | |
| 14 | #ifndef __EM100_H__ |
| 15 | #define __EM100_H__ |
| 16 | |
| 17 | #include <libusb.h> |
Stefan Reinauer | ed59fc8 | 2020-11-21 16:11:40 -0800 | [diff] [blame] | 18 | #include <signal.h> |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 19 | |
Stefan Reinauer | 6a5ed5b | 2019-11-19 14:52:16 -0800 | [diff] [blame] | 20 | #define __unused __attribute__((unused)) |
| 21 | #define __packed __attribute__((packed)) |
| 22 | |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 23 | struct em100 { |
| 24 | libusb_device_handle *dev; |
| 25 | libusb_context *ctx; |
| 26 | uint16_t mcu; |
| 27 | uint16_t fpga; |
| 28 | uint32_t serialno; |
Stefan Reinauer | 98eb753 | 2019-11-13 18:42:07 -0800 | [diff] [blame] | 29 | uint8_t hwversion; |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 30 | }; |
| 31 | |
Stefan Reinauer | db126f4 | 2019-11-18 18:25:45 -0800 | [diff] [blame] | 32 | #define NUM_INIT_ENTRIES 212 |
| 33 | #define BYTES_PER_INIT_ENTRY 4 |
| 34 | typedef struct { |
| 35 | const char *vendor; |
| 36 | const char *name; |
| 37 | unsigned int size; |
| 38 | uint8_t init[NUM_INIT_ENTRIES][BYTES_PER_INIT_ENTRY]; |
| 39 | int init_len; |
| 40 | } chipdesc; |
| 41 | |
Stefan Reinauer | fc22de3 | 2019-11-13 19:14:12 -0800 | [diff] [blame] | 42 | /* Hardware versions */ |
Stefan Reinauer | bd8e1d0 | 2019-11-28 15:48:51 -0800 | [diff] [blame] | 43 | #define HWVERSION_EM100PRO_EARLY 0xff |
| 44 | #define HWVERSION_EM100PRO 0x04 |
| 45 | #define HWVERSION_EM100PRO_G2 0x06 |
Stefan Reinauer | fc22de3 | 2019-11-13 19:14:12 -0800 | [diff] [blame] | 46 | |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 47 | #define BULK_SEND_TIMEOUT 5000 /* sentinel value */ |
| 48 | |
| 49 | /* usb.c */ |
| 50 | int send_cmd(libusb_device_handle *dev, void *data); |
| 51 | int get_response(libusb_device_handle *dev, void *data, int length); |
| 52 | |
Stefan Reinauer | a2b67d3 | 2015-09-01 16:30:43 -0700 | [diff] [blame] | 53 | /* firmware.c */ |
Martin Roth | b54d6ba | 2015-09-29 14:49:37 -0600 | [diff] [blame] | 54 | int firmware_dump(struct em100 *em100, const char *filename, |
| 55 | int firmware_is_dpfw); |
Stefan Reinauer | a2b67d3 | 2015-09-01 16:30:43 -0700 | [diff] [blame] | 56 | int firmware_update(struct em100 *em100, const char *filename, int verify); |
| 57 | |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 58 | /* fpga.c */ |
| 59 | int reconfig_fpga(struct em100 *em100); |
| 60 | int check_fpga_status(struct em100 *em100); |
| 61 | int read_fpga_register(struct em100 *em100, int reg, uint16_t *val); |
| 62 | int write_fpga_register(struct em100 *em100, int reg, int val); |
Simon Glass | 98cd62c | 2018-12-26 14:31:20 -0700 | [diff] [blame] | 63 | int fpga_set_voltage(struct em100 *em100, int voltage_code); |
| 64 | int fpga_get_voltage(struct em100 *em100, int *voltage_codep); |
| 65 | int fpga_reconfigure(struct em100 *em100); |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 66 | |
Patrick Rudolph | 8b557a9 | 2019-10-10 10:15:14 +0200 | [diff] [blame] | 67 | /* Guessed register names */ |
| 68 | #define FPGA_REG_DEVID 0x40 |
| 69 | #define FPGA_REG_VENDID 0x42 |
| 70 | |
Stefan Reinauer | 14d3512 | 2015-09-03 16:02:55 -0700 | [diff] [blame] | 71 | /* hexdump.c */ |
| 72 | void hexdump(const void *memory, size_t length); |
| 73 | |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 74 | /* sdram.c */ |
| 75 | int read_sdram(struct em100 *em100, void *data, int address, int length); |
| 76 | int write_sdram(struct em100 *em100, unsigned char *data, int address, |
| 77 | int length); |
| 78 | |
| 79 | /* spi.c */ |
Stefan Reinauer | f70ff25 | 2019-11-13 18:58:16 -0800 | [diff] [blame] | 80 | uint32_t get_spi_flash_id(struct em100 *em100); |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 81 | int erase_spi_flash(struct em100 *em100); |
| 82 | int poll_spi_flash_status(struct em100 *em100); |
Stefan Reinauer | 7953388 | 2019-11-22 00:57:29 -0800 | [diff] [blame] | 83 | int read_spi_flash_page(struct em100 *em100, int address, unsigned char *blk); |
Stefan Reinauer | 65559f1 | 2015-08-28 16:28:51 -0700 | [diff] [blame] | 84 | int write_spi_flash_page(struct em100 *em100, int address, unsigned char *data); |
Stefan Reinauer | 40cba33 | 2015-08-28 20:03:05 -0700 | [diff] [blame] | 85 | int unlock_spi_flash(struct em100 *em100); |
| 86 | int erase_spi_flash_sector(struct em100 *em100, unsigned int sector); |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 87 | int read_ht_register(struct em100 *em100, int reg, uint8_t *val); |
| 88 | int write_ht_register(struct em100 *em100, int reg, uint8_t val); |
Stefan Reinauer | 7953388 | 2019-11-22 00:57:29 -0800 | [diff] [blame] | 89 | int write_dfifo(struct em100 *em100, size_t length, unsigned int timeout, |
Stefan Reinauer | 42dfb82 | 2015-08-28 16:59:42 -0700 | [diff] [blame] | 90 | unsigned char *blk); |
Stefan Reinauer | 7953388 | 2019-11-22 00:57:29 -0800 | [diff] [blame] | 91 | int read_ufifo(struct em100 *em100, size_t length, unsigned int timeout, |
Stefan Reinauer | 42dfb82 | 2015-08-28 16:59:42 -0700 | [diff] [blame] | 92 | unsigned char *blk); |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 93 | |
| 94 | /* system.c */ |
| 95 | typedef enum { |
| 96 | out_trigger_vcc = 0, |
| 97 | out_reset_vcc = 1, |
| 98 | out_ref_plus = 2, |
| 99 | out_ref_minus = 3, |
| 100 | out_buffer_vcc = 4 |
| 101 | } set_voltage_channel_t; |
| 102 | |
| 103 | typedef enum { |
| 104 | in_v1_2 = 0, |
| 105 | in_e_vcc = 1, |
| 106 | in_ref_plus = 2, |
| 107 | in_ref_minus = 3, |
| 108 | in_buffer_vcc = 4, |
| 109 | in_trigger_vcc = 5, |
| 110 | in_reset_vcc = 6, |
| 111 | in_v3_3 = 7, |
| 112 | in_buffer_v3_3 = 8, |
| 113 | in_v5 = 9 |
| 114 | } get_voltage_channel_t; |
| 115 | |
| 116 | typedef enum { |
| 117 | both_off = 0, |
| 118 | green_on = 1, |
| 119 | red_on = 2, |
| 120 | both_on = 3 |
| 121 | } led_state_t; |
| 122 | |
| 123 | int get_version(struct em100 *em100); |
| 124 | int set_voltage(struct em100 *em100, set_voltage_channel_t channel, int mV); |
| 125 | int get_voltage(struct em100 *em100, get_voltage_channel_t channel); |
| 126 | int set_led(struct em100 *em100, led_state_t led_state); |
| 127 | |
| 128 | /* trace.c */ |
Stefan Reinauer | 146eeba | 2020-12-17 19:26:02 -0800 | [diff] [blame] | 129 | extern int trace_brief; |
Martin Roth | dfdff3e | 2015-09-18 09:42:03 -0600 | [diff] [blame] | 130 | #define EM100_SPECIFIC_CMD 0x11 |
| 131 | #define EM100_MSG_SIGNATURE 0x47364440 |
| 132 | |
| 133 | typedef enum { |
| 134 | status_reg = 0, |
| 135 | dfifo_bytes_reg = 1, |
| 136 | ufifo_bytes_reg = 2, |
| 137 | em100_id_reg = 3, |
| 138 | ufifo_data_fmt_reg = 4, |
| 139 | timestamp_reg = 5 |
| 140 | } ht_register_t; |
| 141 | |
| 142 | /* Status register bits */ |
| 143 | #define UFIFO_OVERFLOW (1 << 0) |
| 144 | #define BIT8_UFIFO_BYTES (1 << 3) |
| 145 | #define START_SPI_EMULATION (1 << 4) |
| 146 | #define PAUSE_SPI_EMULATION (0 << 4) |
| 147 | #define UFIFO_EMPTY (1 << 5) |
| 148 | #define DFIFO_EMPTY (1 << 6) |
| 149 | |
| 150 | struct em100_msg_header{ |
| 151 | uint32_t signature; |
| 152 | uint8_t data_type; |
| 153 | uint8_t data_length; |
| 154 | } __attribute__ ((packed)); |
| 155 | |
| 156 | struct em100_msg{ |
| 157 | struct em100_msg_header header; |
| 158 | uint8_t data[255]; |
| 159 | } __attribute__ ((packed)); |
| 160 | |
| 161 | typedef enum { |
| 162 | ht_checkpoint_1byte = 0x01, |
| 163 | ht_checkpoint_2bytes = 0x02, |
| 164 | ht_checkpoint_4bytes = 0x03, |
| 165 | ht_hexadecimal_data = 0x04, |
| 166 | ht_ascii_data = 0x05, |
| 167 | ht_timestamp_data = 0x06, |
| 168 | ht_lookup_table = 0x07 |
| 169 | } ht_msg_type_t; |
| 170 | |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 171 | int reset_spi_trace(struct em100 *em100); |
Martin Roth | 712262a | 2015-09-18 14:01:18 -0600 | [diff] [blame] | 172 | int read_spi_trace(struct em100 *em100, int display_terminal, |
| 173 | unsigned long addr_offset); |
Martin Roth | dfdff3e | 2015-09-18 09:42:03 -0600 | [diff] [blame] | 174 | int read_spi_terminal(struct em100 *em100, int print_counter); |
| 175 | int init_spi_terminal(struct em100 *em100); |
Stefan Reinauer | cafd151 | 2020-12-11 17:36:28 -0800 | [diff] [blame] | 176 | int read_spi_trace_console(struct em100 *em100, unsigned long addr_offset, |
| 177 | unsigned long addr_len); |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 178 | |
Stefan Reinauer | db126f4 | 2019-11-18 18:25:45 -0800 | [diff] [blame] | 179 | /* Archive handling */ |
| 180 | typedef struct { |
| 181 | unsigned char *address; |
| 182 | size_t length; |
| 183 | int alloc; |
| 184 | } TFILE; |
Stefan Reinauer | 7953388 | 2019-11-22 00:57:29 -0800 | [diff] [blame] | 185 | TFILE *tar_find(TFILE *tfile, const char *name, int casesensitive); |
Stefan Reinauer | db126f4 | 2019-11-18 18:25:45 -0800 | [diff] [blame] | 186 | TFILE *tar_load_compressed(char *filename); |
| 187 | int tar_for_each(TFILE *tfile, int (*run)(char *, TFILE *, void *, int), void *data); |
| 188 | int tar_close(TFILE *tfile); |
| 189 | int tar_ls(TFILE *tfile); |
| 190 | int test_tar(void); |
| 191 | |
Stefan Reinauer | dfd556c | 2019-11-20 17:57:40 -0800 | [diff] [blame] | 192 | /* Network */ |
| 193 | void download(const char *name, const char *id); |
| 194 | int update_all_files(void); |
| 195 | |
Stefan Reinauer | f70ff25 | 2019-11-13 18:58:16 -0800 | [diff] [blame] | 196 | /* Misc. */ |
| 197 | |
| 198 | #define MB * 1024 * 1024 |
Stefan Reinauer | db126f4 | 2019-11-18 18:25:45 -0800 | [diff] [blame] | 199 | #define FILENAME_BUFFER_SIZE 1024 |
Stefan Reinauer | 3b92108 | 2019-11-26 16:56:26 -0800 | [diff] [blame] | 200 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) |
Stefan Reinauer | 7953388 | 2019-11-22 00:57:29 -0800 | [diff] [blame] | 201 | char *get_em100_file(const char *name); |
Stefan Reinauer | b20610e | 2019-12-06 11:14:33 -0800 | [diff] [blame] | 202 | extern int debug; |
Stefan Reinauer | dfb107d | 2020-12-10 19:22:40 -0800 | [diff] [blame] | 203 | extern int address_mode; |
Stefan Reinauer | ed59fc8 | 2020-11-21 16:11:40 -0800 | [diff] [blame] | 204 | extern volatile sig_atomic_t exit_requested; |
Stefan Reinauer | db126f4 | 2019-11-18 18:25:45 -0800 | [diff] [blame] | 205 | |
| 206 | /* Chips */ |
| 207 | int parse_dcfg(chipdesc *chip, TFILE *dcfg); |
Stefan Reinauer | f70ff25 | 2019-11-13 18:58:16 -0800 | [diff] [blame] | 208 | |
Stefan Reinauer | 3b92108 | 2019-11-26 16:56:26 -0800 | [diff] [blame] | 209 | /* Images */ |
| 210 | int autocorrect_image(struct em100 *em100, char *image, size_t size); |
| 211 | |
Stefan Reinauer | c566d20 | 2015-08-25 09:52:42 -0700 | [diff] [blame] | 212 | #endif |