1/*
2 * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3 * Copyright (c) 2014 Intel Corporation.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#include <iostream>
26#include <string>
27#include <stdexcept>
28#include <unistd.h>
29#include <stdlib.h>
30
31#include "my9221.h"
32
33using namespace upm;
34
35MY9221::MY9221 (uint8_t di, uint8_t dcki)
36                    : m_clkPinCtx(dcki), m_dataPinCtx(di) {
37    mraa::Result error = mraa::SUCCESS;
38
39    // set direction (out)
40    error = m_clkPinCtx.dir(mraa::DIR_OUT);
41    if (error != mraa::SUCCESS) {
42        mraa::printError(error);
43    }
44
45    // set direction (out)
46    error = m_dataPinCtx.dir(mraa::DIR_OUT);
47    if (error != mraa::SUCCESS) {
48        mraa::printError(error);
49    }
50}
51
52mraa::Result
53MY9221::setBarLevel (uint8_t level, bool direction) {
54    if (level > 10) {
55        return mraa::ERROR_INVALID_PARAMETER;
56    }
57
58    send16bitBlock (CMDMODE);
59    if (direction) {
60        level += 3;
61        for(uint8_t block_idx = 12; block_idx > 0; block_idx--) {
62            uint32_t state = (block_idx < level) ? BIT_HIGH : BIT_LOW;
63            send16bitBlock (state);
64        }
65    } else {
66        for(uint8_t block_idx = 0; block_idx < 12; block_idx++) {
67            uint32_t state = (block_idx < level) ? BIT_HIGH : BIT_LOW;
68            send16bitBlock (state);
69        }
70    }
71    return lockData ();
72}
73
74mraa::Result
75MY9221::lockData () {
76    mraa::Result error = mraa::SUCCESS;
77    error = m_dataPinCtx.write(LOW);
78    usleep(100);
79
80    for(int idx = 0; idx < 4; idx++) {
81        error = m_dataPinCtx.write(HIGH);
82        error = m_dataPinCtx.write(LOW);
83    }
84    return error;
85}
86
87mraa::Result
88MY9221::send16bitBlock (short data) {
89    mraa::Result error = mraa::SUCCESS;
90    for (uint8_t bit_idx = 0; bit_idx < MAX_BIT_PER_BLOCK; bit_idx++) {
91        uint32_t state = (data & 0x8000) ? HIGH : LOW;
92        error = m_dataPinCtx.write(state);
93        state = m_clkPinCtx.read();
94
95        if (state) {
96            state = LOW;
97        } else {
98            state = HIGH;
99        }
100
101        error = m_clkPinCtx.write(state);
102
103        data <<= 1;
104    }
105    return error;
106}
107