/alps/ipecamera

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/ipecamera

« back to all changes in this revision

Viewing changes to cmosis.c

  • Committer: Suren A. Chilingaryan
  • Date: 2015-08-05 19:18:05 UTC
  • Revision ID: csa@suren.me-20150805191805-jvjyydc9951awsr5
Serialize access to CMOSIS registers

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#define _BSD_SOURCE
2
2
#define _IPECAMERA_MODEL_C
 
3
#include <stdio.h>
 
4
#include <stdlib.h>
3
5
#include <sys/time.h>
4
6
#include <unistd.h>
5
7
#include <assert.h>
7
9
#include <pcilib.h>
8
10
#include <pcilib/tools.h>
9
11
#include <pcilib/error.h>
 
12
#include <pcilib/locking.h>
 
13
#include <pcilib/model.h>
10
14
 
11
15
#include "cmosis.h"
12
16
#include "private.h"
25
29
//#define IPECAMERA_RETRY_ERRORS
26
30
#define IPECAMERA_MULTIREAD
27
31
 
28
 
int ipecamera_cmosis_read(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t *value) {
 
32
 
 
33
typedef struct ipecamera_cmosis_context_s ipecamera_cmosis_context_t;
 
34
 
 
35
struct ipecamera_cmosis_context_s {
 
36
    pcilib_register_bank_context_t bank_ctx;    /**< the bank context associated with the software registers */
 
37
    pcilib_lock_t *lock;                        /**< the lock to serialize access through GPIO */
 
38
};
 
39
 
 
40
void ipecamera_cmosis_close(pcilib_t *ctx, pcilib_register_bank_context_t *reg_bank_ctx) {
 
41
        ipecamera_cmosis_context_t *bank_ctx = (ipecamera_cmosis_context_t*)reg_bank_ctx;
 
42
 
 
43
        if (bank_ctx->lock)
 
44
            pcilib_return_lock(ctx, PCILIB_LOCK_FLAGS_DEFAULT, bank_ctx->lock);
 
45
        free(bank_ctx);
 
46
}
 
47
 
 
48
pcilib_register_bank_context_t* ipecamera_cmosis_open(pcilib_t *ctx, pcilib_register_bank_t bank, const char* model, const void *args) {
 
49
        int err;
 
50
        ipecamera_cmosis_context_t *bank_ctx;
 
51
 
 
52
        bank_ctx = calloc(1, sizeof(ipecamera_cmosis_context_t));
 
53
        if (!bank_ctx) {
 
54
            pcilib_error("Memory allocation for bank context has failed");
 
55
            return NULL;
 
56
        }
 
57
 
 
58
        bank_ctx->lock = pcilib_get_lock(ctx, PCILIB_LOCK_FLAGS_DEFAULT, "cmosis");
 
59
        if (!bank_ctx->lock) {
 
60
            ipecamera_cmosis_close(ctx, (pcilib_register_bank_context_t*)bank_ctx);
 
61
            pcilib_error("Failed to initialize a lock to protect CMOSIS register bank");
 
62
            return NULL;
 
63
        }
 
64
 
 
65
        return (pcilib_register_bank_context_t*)bank_ctx;
 
66
}
 
67
 
 
68
int ipecamera_cmosis_read(pcilib_t *ctx, pcilib_register_bank_context_t *reg_bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t *value) {
 
69
    int err;
29
70
    uint32_t val, tmp[4];
30
71
    char *wr, *rd;
31
72
    struct timeval start;
32
73
    int retries = RETRIES;
33
 
    const pcilib_register_bank_description_t *bank = bank_ctx->bank;
34
 
 
 
74
    ipecamera_cmosis_context_t *bank_ctx = (ipecamera_cmosis_context_t*)reg_bank_ctx;
 
75
    const pcilib_register_bank_description_t *bank = reg_bank_ctx->bank;
 
76
    
35
77
    assert(addr < 128);
36
78
    
37
79
    wr =  pcilib_resolve_register_address(ctx, bank->bar, bank->write_addr);
42
84
    }
43
85
 
44
86
retry:
 
87
    err = pcilib_lock(bank_ctx->lock);
 
88
    if (err) {
 
89
        pcilib_error("Error (%i) obtaining a lock to serialize access to CMOSIS registers ", err);
 
90
        return err;
 
91
    }
 
92
 
45
93
    val = (addr << 8);
46
94
 
47
95
    ipecamera_datacpy(wr, &val, bank);
71
119
    }
72
120
#endif /* IPECAMERA_MULTIREAD */
73
121
 
 
122
    pcilib_unlock(bank_ctx->lock);
 
123
 
74
124
    if ((val & READ_READY_BIT) == 0) {
75
125
        if (--retries > 0) {
76
126
            pcilib_warning("Timeout reading register value (CMOSIS %lu, status: %lx), retrying (try %i of %i)...", addr, val, RETRIES - retries, RETRIES);
77
127
            goto retry;
78
128
        }
 
129
 
79
130
        pcilib_error("Timeout reading register value (CMOSIS %lu, status: %lx)", addr, val);
80
131
        return PCILIB_ERROR_TIMEOUT;
81
132
    }
82
 
    
 
133
 
83
134
    if (val & READ_ERROR_BIT) {
84
135
#ifdef IPECAMERA_RETRY_ERRORS
85
136
        if (--retries > 0) {
109
160
    return 0;
110
161
}
111
162
 
112
 
int ipecamera_cmosis_write(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t value) {
 
163
int ipecamera_cmosis_write(pcilib_t *ctx, pcilib_register_bank_context_t *reg_bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t value) {
 
164
    int err;
113
165
    uint32_t val, tmp[4];
114
166
    char *wr, *rd;
115
167
    struct timeval start;
116
168
    int retries = RETRIES;
117
 
    const pcilib_register_bank_description_t *bank = bank_ctx->bank;
 
169
    ipecamera_cmosis_context_t *bank_ctx = (ipecamera_cmosis_context_t*)reg_bank_ctx;
 
170
    const pcilib_register_bank_description_t *bank = reg_bank_ctx->bank;
118
171
 
119
172
    assert(addr < 128);
120
173
    assert(value < 256);
127
180
    }
128
181
 
129
182
retry:
 
183
    err = pcilib_lock(bank_ctx->lock);
 
184
    if (err) {
 
185
        pcilib_error("Error (%i) obtaining a lock to serialize access to CMOSIS registers ", err);
 
186
        return err;
 
187
    }
 
188
 
130
189
    val = WRITE_BIT|(addr << 8)|(value&0xFF);
131
190
    ipecamera_datacpy(wr, &val, bank);
132
191
 
154
213
    }
155
214
#endif /* IPECAMERA_MULTIREAD */
156
215
 
 
216
    pcilib_unlock(bank_ctx->lock);
 
217
 
157
218
    if ((val & READ_READY_BIT) == 0) {
158
219
#ifdef IPECAMERA_RETRY_ERRORS
159
220
        if (--retries > 0) {
186
247
        pcilib_error("Address verification failed during register write (CMOSIS %lu, value: %lu, status: %lx)", addr, value, val);
187
248
        return PCILIB_ERROR_VERIFY;
188
249
    }
189
 
    
 
250
 
190
251
    if ((val&0xFF) != value) {
191
252
        pcilib_error("Value verification failed during register read (CMOSIS %lu, value: %lu != %lu)", addr, val/*&ipecamera_bit_mask[bits]*/, value);
192
253
        return PCILIB_ERROR_VERIFY;