/alps/pcitool

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to ipecamera/image.c

  • Committer: Suren A. Chilingaryan
  • Date: 2011-04-12 00:57:02 UTC
  • Revision ID: csa@dside.dyndns.org-20110412005702-ir1cch0f1feop7ay
Infrastructure for event API

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#define _IPECAMERA_IMAGE_C
 
2
#define _BSD_SOURCE
 
3
 
 
4
#include <stdio.h>
 
5
#include <stdlib.h>
 
6
#include <unistd.h>
 
7
#include <string.h>
 
8
#include <sys/time.h>
 
9
#include <assert.h>
 
10
 
 
11
#include "../tools.h"
 
12
#include "../error.h"
 
13
 
 
14
#include "pcilib.h"
 
15
 
 
16
#include "model.h"
 
17
#include "image.h"
 
18
 
 
19
#define IPECAMERA_SLEEP_TIME 250000
 
20
 
 
21
struct ipecamera_s {
 
22
    pcilib_t *pcilib;
 
23
 
 
24
    char *data;
 
25
    size_t size;
 
26
 
 
27
    pcilib_callback_t cb;
 
28
    void *cb_user;
 
29
    
 
30
    int width;
 
31
    int height;
 
32
 
 
33
    pcilib_event_id_t event_id;
 
34
 
 
35
    pcilib_register_t control_reg, status_reg;
 
36
    pcilib_register_t start_reg, end_reg;
 
37
    pcilib_register_t lines_reg;
 
38
    pcilib_register_t exposure_reg;
 
39
 
 
40
    void *buffer;    
 
41
};
 
42
 
 
43
 
 
44
#define FIND_REG(var, bank, name)  \
 
45
        ctx->var = pcilib_find_register(pcilib, bank, name); \
 
46
        if (ctx->var ==  PCILIB_REGISTER_INVALID) { \
 
47
            err = -1; \
 
48
            pcilib_error("Unable to find a %s register", name); \
 
49
        }
 
50
    
 
51
 
 
52
#define GET_REG(reg, var) \
 
53
    err = pcilib_read_register_by_id(pcilib, ctx->reg, &var); \
 
54
    if (err) { \
 
55
        pcilib_error("Error reading %s register", ipecamera_registers[ctx->reg].name); \
 
56
        return err; \
 
57
    }
 
58
 
 
59
#define SET_REG(reg, val) \
 
60
    err = pcilib_write_register_by_id(pcilib, ctx->reg, val); \
 
61
    if (err) { \
 
62
        pcilib_error("Error writting %s register", ipecamera_registers[ctx->reg].name); \
 
63
        return err; \
 
64
    }
 
65
 
 
66
#define CHECK_REG(reg, check) \
 
67
    err = pcilib_read_register_by_id(pcilib, ctx->reg, &value); \
 
68
    if (err) { \
 
69
        pcilib_error("Error reading %s register", ipecamera_registers[ctx->reg].name); \
 
70
        return err; \
 
71
    } \
 
72
    if (!(check)) { \
 
73
        pcilib_error("Unexpected value (%li) of register %s", value, ipecamera_registers[ctx->reg].name); \
 
74
        return err; \
 
75
    }
 
76
 
 
77
 
 
78
void *ipecamera_init(pcilib_t *pcilib) {
 
79
    int err = 0; 
 
80
    
 
81
    ipecamera_t *ctx = malloc(sizeof(ipecamera_t));
 
82
 
 
83
    if (ctx) {
 
84
        ctx->pcilib = pcilib;
 
85
 
 
86
        ctx->data = pcilib_resolve_data_space(pcilib, 0, &ctx->size);
 
87
        if (!ctx->data) {
 
88
            err = -1;
 
89
            pcilib_error("Unable to resolve the data space");
 
90
        }
 
91
        
 
92
        ctx->buffer = malloc(1088 * 2048 * 2);
 
93
        if (!ctx->buffer) {
 
94
            err = -1;
 
95
            pcilib_error("Unable to allocate ring buffer");
 
96
        }
 
97
        
 
98
        FIND_REG(status_reg, "fpga", "status");
 
99
        FIND_REG(control_reg, "fpga", "control");
 
100
        FIND_REG(start_reg, "fpga", "start_address");
 
101
        FIND_REG(end_reg, "fpga", "end_address");
 
102
 
 
103
        FIND_REG(lines_reg, "cmosis", "number_lines");
 
104
        FIND_REG(exposure_reg, "cmosis", "exp_time");
 
105
 
 
106
        if (err) {
 
107
            free(ctx);
 
108
            return NULL;
 
109
        }
 
110
    }
 
111
    
 
112
    return (void*)ctx;
 
113
}
 
114
 
 
115
void ipecamera_free(void *vctx) {
 
116
    if (vctx) {
 
117
        ipecamera_t *ctx = (ipecamera_t*)vctx;
 
118
        
 
119
        if (ctx->buffer) free(ctx->buffer);
 
120
        free(ctx);
 
121
    }
 
122
}
 
123
 
 
124
int ipecamera_reset(void *vctx) {
 
125
    int err;
 
126
    pcilib_t *pcilib;
 
127
    ipecamera_t *ctx = (ipecamera_t*)vctx;
 
128
 
 
129
    pcilib_register_t control, status;
 
130
    pcilib_register_value_t value;
 
131
    
 
132
    if (!ctx) {
 
133
        pcilib_error("IPECamera imaging is not initialized");
 
134
        return PCILIB_ERROR_NOTINITIALIZED;
 
135
    }
 
136
    
 
137
    pcilib = ctx->pcilib;
 
138
    control = ctx->control_reg;
 
139
    status = ctx->status_reg;
 
140
 
 
141
        // Set Reset bit to CMOSIS
 
142
    err = pcilib_write_register_by_id(pcilib, control, 5);
 
143
    if (err) {
 
144
        pcilib_error("Error setting CMOSIS reset bit");
 
145
        return err;
 
146
    }
 
147
    usleep(IPECAMERA_SLEEP_TIME);
 
148
 
 
149
        // Remove Reset bit to CMOSIS
 
150
    err = pcilib_write_register_by_id(pcilib, control, 1);
 
151
    if (err) {
 
152
        pcilib_error("Error reseting CMOSIS reset bit");
 
153
        return err;
 
154
    }
 
155
    usleep(IPECAMERA_SLEEP_TIME);
 
156
 
 
157
        // Special settings for CMOSIS v.2
 
158
    value = 01; err = pcilib_write_register_space(pcilib, "cmosis", 115, 1, &value);
 
159
    if (err) {
 
160
        pcilib_error("Error setting CMOSIS configuration");
 
161
        return err;
 
162
    }
 
163
    usleep(IPECAMERA_SLEEP_TIME);
 
164
    
 
165
    value = 07; err = pcilib_write_register_space(pcilib, "cmosis", 82, 1, &value);
 
166
    if (err) {
 
167
        pcilib_error("Error setting CMOSIS configuration");
 
168
        return err;
 
169
    }
 
170
    usleep(IPECAMERA_SLEEP_TIME);
 
171
 
 
172
        // This is temporary for verification purposes
 
173
    memset(ctx->data, 0, ctx->size);
 
174
 
 
175
    err = pcilib_read_register_by_id(pcilib, status, &value);
 
176
    if (err) {
 
177
        pcilib_error("Error reading status register");
 
178
        return err;
 
179
    }
 
180
 
 
181
    if (value != 0x0849FFFF) {
 
182
        pcilib_error("Unexpected value (%lx) of status register", value);
 
183
        return PCILIB_ERROR_VERIFY;
 
184
    }
 
185
 
 
186
    return 0;    
 
187
}
 
188
 
 
189
int ipecamera_start(void *vctx, pcilib_event_t event_mask, pcilib_callback_t cb, void *user) {
 
190
    ipecamera_t *ctx = (ipecamera_t*)vctx;
 
191
 
 
192
    if (!ctx) {
 
193
        pcilib_error("IPECamera imaging is not initialized");
 
194
        return PCILIB_ERROR_NOTINITIALIZED;
 
195
    }
 
196
    
 
197
    ctx->cb = cb;
 
198
    ctx->cb_user = user;
 
199
    
 
200
    
 
201
    ctx->event_id = 0;
 
202
    
 
203
    ctx->width = 1270;
 
204
    ctx->height = 1088; //GET_REG(lines_reg, lines);
 
205
 
 
206
    // allocate memory
 
207
    
 
208
    return 0;
 
209
}
 
210
 
 
211
 
 
212
int ipecamera_stop(void *vctx) {
 
213
    ipecamera_t *ctx = (ipecamera_t*)vctx;
 
214
 
 
215
    if (!ctx) {
 
216
        pcilib_error("IPECamera imaging is not initialized");
 
217
        return PCILIB_ERROR_NOTINITIALIZED;
 
218
    }
 
219
    
 
220
    return 0;
 
221
}
 
222
 
 
223
 
 
224
static int ipecamera_get_line(ipecamera_t *ctx, int line) {
 
225
    int err;
 
226
    pcilib_t *pcilib = ctx->pcilib;
 
227
    pcilib_register_value_t ptr, size, value;
 
228
 
 
229
    ipecamera_reset((void*)ctx);
 
230
 
 
231
    SET_REG(lines_reg, 1);
 
232
    
 
233
    SET_REG(control_reg, 149);
 
234
    usleep(IPECAMERA_SLEEP_TIME);
 
235
    CHECK_REG(status_reg, 0x0849FFFF);
 
236
    
 
237
    GET_REG(start_reg, ptr);
 
238
    GET_REG(end_reg, size);
 
239
    size -= ptr;
 
240
 
 
241
    printf("%i: %i %i\n", line, ptr, size);    
 
242
    
 
243
    SET_REG(control_reg, 141);
 
244
    usleep(IPECAMERA_SLEEP_TIME);
 
245
    CHECK_REG(status_reg, 0x0849FFFF);
 
246
}
 
247
 
 
248
 
 
249
static int ipecamera_get_image(ipecamera_t *ctx) {
 
250
    int err;
 
251
    int i;
 
252
    pcilib_t *pcilib = ctx->pcilib;
 
253
 
 
254
    for (i = 0; i < 1088; i++) {
 
255
        ipecamera_get_line(ctx, i);
 
256
    }
 
257
    
 
258
    ctx->event_id++;
 
259
}
 
260
 
 
261
 
 
262
int ipecamera_trigger(void *vctx, pcilib_event_t event, size_t trigger_size, void *trigger_data) {
 
263
    int err;
 
264
    pcilib_t *pcilib;
 
265
    ipecamera_t *ctx = (ipecamera_t*)vctx;
 
266
 
 
267
    if (!ctx) {
 
268
        pcilib_error("IPECamera imaging is not initialized");
 
269
        return PCILIB_ERROR_NOTINITIALIZED;
 
270
 
 
271
    }
 
272
    
 
273
    err = ipecamera_get_image(ctx);
 
274
    if (!err) err = ctx->cb(event, ctx->event_id, ctx->cb_user);
 
275
 
 
276
    return err;
 
277
}
 
278
 
 
279
 
 
280
void* ipecamera_get(void *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size) {
 
281
    if (size) *size = ctx->width * ctx->height * 2;
 
282
    return ctx->buffer;
 
283
}
 
284
 
 
285
int ipecamera_return(void *ctx, pcilib_event_id_t event_id) {
 
286
    return 0;
 
287
}