Future Electronics
/
lorawan-neoiso-lab
Lab exercise code for FAE Summit 09/2019.
neo_iso_drv.cpp@59:4628ef4b0d52, 2019-09-18 (annotated)
- Committer:
- lru
- Date:
- Wed Sep 18 18:52:39 2019 +0000
- Revision:
- 59:4628ef4b0d52
- Parent:
- 58:cf54c181a632
Fixed lorawan configuration.; Removed leftover DummySensor file.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lru | 58:cf54c181a632 | 1 | /* |
lru | 58:cf54c181a632 | 2 | * Mbed OS device driver for Semtech TS13401 Neo-Iso SSR driver. |
lru | 58:cf54c181a632 | 3 | * |
lru | 58:cf54c181a632 | 4 | * Copyright (c) 2019 Future Electronics |
lru | 58:cf54c181a632 | 5 | * |
lru | 58:cf54c181a632 | 6 | * Licensed under the Apache License, Version 2.0 (the "License"); |
lru | 58:cf54c181a632 | 7 | * you may not use this file except in compliance with the License. |
lru | 58:cf54c181a632 | 8 | * You may obtain a copy of the License at |
lru | 58:cf54c181a632 | 9 | * |
lru | 58:cf54c181a632 | 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
lru | 58:cf54c181a632 | 11 | * |
lru | 58:cf54c181a632 | 12 | * Unless required by applicable law or agreed to in writing, software |
lru | 58:cf54c181a632 | 13 | * distributed under the License is distributed on an "AS IS" BASIS, |
lru | 58:cf54c181a632 | 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
lru | 58:cf54c181a632 | 15 | * See the License for the specific language governing permissions and |
lru | 58:cf54c181a632 | 16 | * limitations under the License. |
lru | 58:cf54c181a632 | 17 | */ |
lru | 58:cf54c181a632 | 18 | |
lru | 58:cf54c181a632 | 19 | #include "neo_iso_drv.h" |
lru | 58:cf54c181a632 | 20 | |
lru | 58:cf54c181a632 | 21 | namespace neoiso { |
lru | 58:cf54c181a632 | 22 | |
lru | 58:cf54c181a632 | 23 | NeoIso::NeoIso( PinName clk_pin, PinName data_pin, uint8_t address) : |
lru | 58:cf54c181a632 | 24 | _spi(clk_pin, data_pin, NC), |
lru | 58:cf54c181a632 | 25 | _address(address), |
lru | 58:cf54c181a632 | 26 | _on(0), |
lru | 58:cf54c181a632 | 27 | _buffer_index(0) |
lru | 58:cf54c181a632 | 28 | { |
lru | 58:cf54c181a632 | 29 | MBED_ASSERT(address < 8); |
lru | 58:cf54c181a632 | 30 | // Round frequency up a bit: |
lru | 58:cf54c181a632 | 31 | // To emulate CLK of 1MHz we need actual SPI clock of 2MHz. |
lru | 58:cf54c181a632 | 32 | // However, on Sequana default i/o frequency is 50MHz, and SPI peripheral |
lru | 58:cf54c181a632 | 33 | // needs actual clock 4x of its output. This gives nearest SPI frequency |
lru | 58:cf54c181a632 | 34 | // available from main clock of (50MHz/4)/6 = 2083kHz. |
lru | 58:cf54c181a632 | 35 | // If we would request exactly 2MHz, the driver would set up the divider |
lru | 58:cf54c181a632 | 36 | // as 7 (to not have clock faster that required) resulting in SPI clock |
lru | 58:cf54c181a632 | 37 | // of 1.79MHz |
lru | 58:cf54c181a632 | 38 | _spi.frequency(2100000); |
lru | 58:cf54c181a632 | 39 | _spi.format(16, 0); |
lru | 58:cf54c181a632 | 40 | } |
lru | 58:cf54c181a632 | 41 | |
lru | 58:cf54c181a632 | 42 | NeoIso::~NeoIso() |
lru | 58:cf54c181a632 | 43 | { |
lru | 58:cf54c181a632 | 44 | } |
lru | 58:cf54c181a632 | 45 | |
lru | 58:cf54c181a632 | 46 | int NeoIso::send_command(page_t page, command_t command) |
lru | 58:cf54c181a632 | 47 | { |
lru | 58:cf54c181a632 | 48 | // Clear buffer, this also embeds RESET/START command into the buffer. |
lru | 58:cf54c181a632 | 49 | _clear_buffer(); |
lru | 58:cf54c181a632 | 50 | |
lru | 58:cf54c181a632 | 51 | // Insert PAGE bits. |
lru | 58:cf54c181a632 | 52 | uint8_t mask = 0x04; |
lru | 58:cf54c181a632 | 53 | for(int i = 0 ; i < 3 ; ++i) { |
lru | 58:cf54c181a632 | 54 | _buffer_put_bit(page & mask); |
lru | 58:cf54c181a632 | 55 | mask >>= 1; |
lru | 58:cf54c181a632 | 56 | } |
lru | 58:cf54c181a632 | 57 | // Insert ADDRESS bits. |
lru | 58:cf54c181a632 | 58 | mask = 0x04; |
lru | 58:cf54c181a632 | 59 | for(int i = 0 ; i < 3 ; ++i) { |
lru | 58:cf54c181a632 | 60 | _buffer_put_bit(_address & mask); |
lru | 58:cf54c181a632 | 61 | mask >>= 1; |
lru | 58:cf54c181a632 | 62 | } |
lru | 58:cf54c181a632 | 63 | // Insert COMMAND bits. |
lru | 58:cf54c181a632 | 64 | mask = 0x08; |
lru | 58:cf54c181a632 | 65 | for(int i = 0 ; i < 4 ; ++i) { |
lru | 58:cf54c181a632 | 66 | _buffer_put_bit(command & mask); |
lru | 58:cf54c181a632 | 67 | mask >>= 1; |
lru | 58:cf54c181a632 | 68 | } |
lru | 58:cf54c181a632 | 69 | |
lru | 58:cf54c181a632 | 70 | // Insert dummy '1' bits for status read out. |
lru | 58:cf54c181a632 | 71 | for(int i = 0 ; i < 10 ; ++i) { |
lru | 58:cf54c181a632 | 72 | _buffer_put_bit(1); |
lru | 58:cf54c181a632 | 73 | } |
lru | 58:cf54c181a632 | 74 | |
lru | 58:cf54c181a632 | 75 | return _send_buffer(); |
lru | 58:cf54c181a632 | 76 | } |
lru | 58:cf54c181a632 | 77 | |
lru | 58:cf54c181a632 | 78 | int NeoIso::get_status(uint8_t &status) |
lru | 58:cf54c181a632 | 79 | { |
lru | 58:cf54c181a632 | 80 | if (send_command(PAGE_COMMAND, COMMAND_POOL_STATE) == 0) |
lru | 58:cf54c181a632 | 81 | { |
lru | 58:cf54c181a632 | 82 | uint8_t temp = 0; |
lru | 58:cf54c181a632 | 83 | int s_idx = RESET_LENGTH + 3 + 3 + 4 + 1; |
lru | 58:cf54c181a632 | 84 | for (int i = s_idx; i < s_idx + 8; ++i) { |
lru | 58:cf54c181a632 | 85 | temp <<= 1; |
lru | 58:cf54c181a632 | 86 | temp |= (_rx_buffer[i] & 0x0f00) > 0; |
lru | 58:cf54c181a632 | 87 | } |
lru | 58:cf54c181a632 | 88 | status = temp; |
lru | 58:cf54c181a632 | 89 | return 0; |
lru | 58:cf54c181a632 | 90 | } |
lru | 58:cf54c181a632 | 91 | return (-1); |
lru | 58:cf54c181a632 | 92 | } |
lru | 58:cf54c181a632 | 93 | |
lru | 58:cf54c181a632 | 94 | int NeoIso::set_output(bool on) |
lru | 58:cf54c181a632 | 95 | { |
lru | 58:cf54c181a632 | 96 | int status; |
lru | 58:cf54c181a632 | 97 | |
lru | 58:cf54c181a632 | 98 | if (on) { |
lru | 58:cf54c181a632 | 99 | status = send_command(PAGE_COMMAND, COMMAND_ON_IMMEDIATE_WITH_DITHERING); |
lru | 58:cf54c181a632 | 100 | } else { |
lru | 58:cf54c181a632 | 101 | status = send_command(PAGE_COMMAND, COMMAND_OFF_IMMEDIATE); |
lru | 58:cf54c181a632 | 102 | } |
lru | 58:cf54c181a632 | 103 | |
lru | 58:cf54c181a632 | 104 | if (status == 0) { |
lru | 58:cf54c181a632 | 105 | _on = on; |
lru | 58:cf54c181a632 | 106 | } |
lru | 58:cf54c181a632 | 107 | return status; |
lru | 58:cf54c181a632 | 108 | } |
lru | 58:cf54c181a632 | 109 | |
lru | 58:cf54c181a632 | 110 | |
lru | 58:cf54c181a632 | 111 | void NeoIso::_clear_buffer() |
lru | 58:cf54c181a632 | 112 | { |
lru | 58:cf54c181a632 | 113 | size_t i = 0; |
lru | 58:cf54c181a632 | 114 | for (i = 0; i < RESET_LENGTH; ++i) { |
lru | 58:cf54c181a632 | 115 | _tx_buffer[i] = BIT_RESET; |
lru | 58:cf54c181a632 | 116 | } |
lru | 58:cf54c181a632 | 117 | for (; i < MAX_COMMAND_LENGTH; ++i) { |
lru | 58:cf54c181a632 | 118 | _tx_buffer[i] = BIT_ONE; |
lru | 58:cf54c181a632 | 119 | } |
lru | 58:cf54c181a632 | 120 | _buffer_index = RESET_LENGTH; |
lru | 58:cf54c181a632 | 121 | } |
lru | 58:cf54c181a632 | 122 | |
lru | 58:cf54c181a632 | 123 | void NeoIso::_buffer_put_bit(bool bit) |
lru | 58:cf54c181a632 | 124 | { |
lru | 58:cf54c181a632 | 125 | MBED_ASSERT(_buffer_index < MAX_COMMAND_LENGTH); |
lru | 58:cf54c181a632 | 126 | |
lru | 58:cf54c181a632 | 127 | _tx_buffer[_buffer_index++] = bit ? BIT_ONE : BIT_ZERO; |
lru | 58:cf54c181a632 | 128 | } |
lru | 58:cf54c181a632 | 129 | |
lru | 58:cf54c181a632 | 130 | int NeoIso::_send_buffer() |
lru | 58:cf54c181a632 | 131 | { |
lru | 58:cf54c181a632 | 132 | if (_spi.write((char*)_tx_buffer, 2*_buffer_index, (char*)_rx_buffer, 2*_buffer_index) != (int)(2*_buffer_index)) { |
lru | 58:cf54c181a632 | 133 | return (-1); |
lru | 58:cf54c181a632 | 134 | } |
lru | 58:cf54c181a632 | 135 | return 0; |
lru | 58:cf54c181a632 | 136 | } |
lru | 58:cf54c181a632 | 137 | |
lru | 58:cf54c181a632 | 138 | } |