/alps/ipecamera

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

« back to all changes in this revision

Viewing changes to ipecamera.c

  • Committer: Suren A. Chilingaryan
  • Date: 2011-03-08 21:46:14 UTC
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: csa@dside.dyndns.org-20110308214614-g5v841m61jilcrm2
Initial support of IPECamera protocol

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#define _IPECAMERA_C
 
2
#include <sys/time.h>
 
3
#include <assert.h>
 
4
 
 
5
#include "tools.h"
2
6
#include "ipecamera.h"
3
 
 
4
 
 
 
7
#include "error.h"
 
8
 
 
9
#define ADDR_MASK 0x7F00
 
10
#define WRITE_BIT 0x8000
 
11
#define RETRIES 10
 
12
 
 
13
#define READ_READY_BIT 0x20000
 
14
#define READ_ERROR_BIT 0x40000
 
15
 
 
16
#define ipecamera_datacpy(dst, src, bank)   pcilib_datacpy(dst, src, 4, 1, bank->raw_endianess)
 
17
 
 
18
/*
 
19
int ipecamera_read_register_space(int handle, pcilib_model_t model, pcilib_register_t addr, pcilib_register_value_t *value) {
 
20
    //ipelib_write_
 
21
    //(void *buf, int handle, pcilib_bar_t bar, uintptr_t addr, size_t size);
 
22
    
 
23
}
 
24
 
 
25
int ipecamera_write_register_space(int handle, pcilib_model_t model, pcilib_register_t addr, pcilib_register_value_t value) {
 
26
}
 
27
 
 
28
 
 
29
static int ipecamera_read_byte(int handle, int reg, int bits, uint8_t *value) {
 
30
}
 
31
 
 
32
static int ipecamera_write_byte(int handle, int reg, int bits, uint8_t value) {
 
33
}
 
34
*/
 
35
 
 
36
static pcilib_register_value_t ipecamera_bit_mask[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
 
37
 
 
38
int ipecamera_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t *value) {
 
39
    uint32_t val;
 
40
    char *wr, *rd;
 
41
    struct timeval start, cur;
 
42
    int retries = RETRIES;
 
43
    
 
44
    assert(addr < 128);
 
45
    
 
46
    wr =  pcilib_resolve_register_address(ctx, bank->write_addr);
 
47
    rd =  pcilib_resolve_register_address(ctx, bank->read_addr);
 
48
    if ((!rd)||(!wr)) {
 
49
        pcilib_error("Error resolving addresses of read & write registers");
 
50
        return PCILIB_ERROR_INVALID_ADDRESS;
 
51
    }
 
52
 
 
53
retry:
 
54
    val = (addr << 8);
 
55
    
 
56
    //printf("%i %x %p %p\n", addr,  val, wr, rd);
 
57
    
 
58
    ipecamera_datacpy(wr, &val, bank);
 
59
    
 
60
    gettimeofday(&start, NULL);
 
61
 
 
62
    ipecamera_datacpy(&val, rd, bank);
 
63
    while ((val & READ_READY_BIT) == 0) {
 
64
        gettimeofday(&cur, NULL);
 
65
        if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > PCILIB_REGISTER_TIMEOUT) break;
 
66
        
 
67
        ipecamera_datacpy(&val, rd, bank);
 
68
    }
 
69
 
 
70
    if ((val & READ_READY_BIT) == 0) {
 
71
        pcilib_error("Timeout reading register value");
 
72
        return PCILIB_ERROR_TIMEOUT;
 
73
    }
 
74
    
 
75
    if (val & READ_ERROR_BIT) {
 
76
        pcilib_error("Error reading register value");
 
77
        return PCILIB_ERROR_FAILED;
 
78
    }
 
79
 
 
80
    if (((val&ADDR_MASK) >> 8) != addr) {
 
81
        if (--retries > 0) {
 
82
            pcilib_warning("Address verification failed during register read, retrying (try %i of %i)...", RETRIES - retries, RETRIES);
 
83
            goto retry;
 
84
        }
 
85
        pcilib_error("Address verification failed during register read");
 
86
        return PCILIB_ERROR_VERIFY;
 
87
    }
 
88
 
 
89
    
 
90
//    printf("%i\n", val&ipecamera_bit_mask[bits]);
 
91
 
 
92
    *value = val&ipecamera_bit_mask[bits];
 
93
 
 
94
    return 0;
 
95
}
 
96
 
 
97
int ipecamera_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t value) {
 
98
    uint32_t val;
 
99
    char *wr, *rd;
 
100
    struct timeval start, cur;
 
101
    int retries = RETRIES;
 
102
    
 
103
    assert(addr < 128);
 
104
    assert(value < 256);
 
105
    
 
106
    wr =  pcilib_resolve_register_address(ctx, bank->write_addr);
 
107
    rd =  pcilib_resolve_register_address(ctx, bank->read_addr);
 
108
    if ((!rd)||(!wr)) {
 
109
        pcilib_error("Error resolving addresses of read & write registers");
 
110
        return PCILIB_ERROR_INVALID_ADDRESS;
 
111
    }
 
112
 
 
113
retry:
 
114
    val = WRITE_BIT|(addr << 8)|(value&0xFF);
 
115
    
 
116
    //printf("%i %x %p %p\n", addr,  val, wr, rd);
 
117
    
 
118
    ipecamera_datacpy(wr, &val, bank);
 
119
    
 
120
    gettimeofday(&start, NULL);
 
121
 
 
122
    ipecamera_datacpy(&val, rd, bank);
 
123
    while ((val & READ_READY_BIT) == 0) {
 
124
        gettimeofday(&cur, NULL);
 
125
        if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > PCILIB_REGISTER_TIMEOUT) break;
 
126
        
 
127
        ipecamera_datacpy(&val, rd, bank);
 
128
    }
 
129
 
 
130
    if ((val & READ_READY_BIT) == 0) {
 
131
        pcilib_error("Timeout writting register value");
 
132
        return PCILIB_ERROR_TIMEOUT;
 
133
    }
 
134
    
 
135
    if (val & READ_ERROR_BIT) {
 
136
        pcilib_error("Error writting register value");
 
137
        return PCILIB_ERROR_FAILED;
 
138
    }
 
139
 
 
140
    if (((val&ADDR_MASK) >> 8) != addr) {
 
141
        if (--retries > 0) {
 
142
            pcilib_warning("Address verification failed during register read, retrying (try %i of %i)...", RETRIES - retries, RETRIES);
 
143
            goto retry;
 
144
        }
 
145
        pcilib_error("Address verification failed during register write");
 
146
        return PCILIB_ERROR_VERIFY;
 
147
    }
 
148
    
 
149
    if ((val&ipecamera_bit_mask[bits]) != value) {
 
150
        pcilib_error("Value verification failed during register read (%lu != %lu)", val&ipecamera_bit_mask[bits], value);
 
151
        return PCILIB_ERROR_VERIFY;
 
152
    }
 
153
 
 
154
    //printf("%i\n", val&ipecamera_bit_mask[bits]);
 
155
 
 
156
    return 0;
 
157
}