1# Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http:#www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""
16Internal use only.
17
18This file provide method to control programmable attenuator.
19"""
20
21import codecs
22import time
23
24import serial
25
26
27def set_att(port, att, att_fix=False):
28    """
29    set attenuation value on the attenuator
30
31    :param port: serial port for attenuator
32    :param att: attenuation value we want to set
33    :param att_fix: fix the deviation with experience value
34    :return: True or False
35    """
36
37    assert 0 <= att <= 62
38    # fix att
39    if att_fix:
40        if att >= 33 and (att - 30 + 1) % 4 == 0:
41            att_t = att - 1
42        elif att >= 33 and (att - 30) % 4 == 0:
43            att_t = att + 1
44        else:
45            att_t = att
46    else:
47        att_t = att
48
49    serial_port = serial.Serial(port, baudrate=9600, rtscts=False, timeout=0.1)
50    if serial_port.isOpen() is False:
51        raise IOError('attenuator control, failed to open att port')
52
53    cmd_hex = '7e7e10{:02x}{:x}'.format(att_t, 0x10 + att_t)
54    exp_res_hex = '7e7e20{:02x}00{:x}'.format(att_t, 0x20 + att_t)
55
56    cmd = codecs.decode(cmd_hex, 'hex')
57    exp_res = codecs.decode(exp_res_hex, 'hex')
58
59    serial_port.write(cmd)
60    res = b''
61
62    for i in range(5):
63        res += serial_port.read(20)
64        if res == exp_res:
65            result = True
66            break
67        time.sleep(0.1)
68    else:
69        result = False
70
71    serial_port.close()
72    return result
73