Future Electronics
/
lorawan-neoiso-lab
Lab exercise code for FAE Summit 09/2019.
neo_iso_drv.cpp
- Committer:
- lru
- Date:
- 2019-09-18
- Revision:
- 59:4628ef4b0d52
- Parent:
- 58:cf54c181a632
File content as of revision 59:4628ef4b0d52:
/* * Mbed OS device driver for Semtech TS13401 Neo-Iso SSR driver. * * Copyright (c) 2019 Future Electronics * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "neo_iso_drv.h" namespace neoiso { NeoIso::NeoIso( PinName clk_pin, PinName data_pin, uint8_t address) : _spi(clk_pin, data_pin, NC), _address(address), _on(0), _buffer_index(0) { MBED_ASSERT(address < 8); // Round frequency up a bit: // To emulate CLK of 1MHz we need actual SPI clock of 2MHz. // However, on Sequana default i/o frequency is 50MHz, and SPI peripheral // needs actual clock 4x of its output. This gives nearest SPI frequency // available from main clock of (50MHz/4)/6 = 2083kHz. // If we would request exactly 2MHz, the driver would set up the divider // as 7 (to not have clock faster that required) resulting in SPI clock // of 1.79MHz _spi.frequency(2100000); _spi.format(16, 0); } NeoIso::~NeoIso() { } int NeoIso::send_command(page_t page, command_t command) { // Clear buffer, this also embeds RESET/START command into the buffer. _clear_buffer(); // Insert PAGE bits. uint8_t mask = 0x04; for(int i = 0 ; i < 3 ; ++i) { _buffer_put_bit(page & mask); mask >>= 1; } // Insert ADDRESS bits. mask = 0x04; for(int i = 0 ; i < 3 ; ++i) { _buffer_put_bit(_address & mask); mask >>= 1; } // Insert COMMAND bits. mask = 0x08; for(int i = 0 ; i < 4 ; ++i) { _buffer_put_bit(command & mask); mask >>= 1; } // Insert dummy '1' bits for status read out. for(int i = 0 ; i < 10 ; ++i) { _buffer_put_bit(1); } return _send_buffer(); } int NeoIso::get_status(uint8_t &status) { if (send_command(PAGE_COMMAND, COMMAND_POOL_STATE) == 0) { uint8_t temp = 0; int s_idx = RESET_LENGTH + 3 + 3 + 4 + 1; for (int i = s_idx; i < s_idx + 8; ++i) { temp <<= 1; temp |= (_rx_buffer[i] & 0x0f00) > 0; } status = temp; return 0; } return (-1); } int NeoIso::set_output(bool on) { int status; if (on) { status = send_command(PAGE_COMMAND, COMMAND_ON_IMMEDIATE_WITH_DITHERING); } else { status = send_command(PAGE_COMMAND, COMMAND_OFF_IMMEDIATE); } if (status == 0) { _on = on; } return status; } void NeoIso::_clear_buffer() { size_t i = 0; for (i = 0; i < RESET_LENGTH; ++i) { _tx_buffer[i] = BIT_RESET; } for (; i < MAX_COMMAND_LENGTH; ++i) { _tx_buffer[i] = BIT_ONE; } _buffer_index = RESET_LENGTH; } void NeoIso::_buffer_put_bit(bool bit) { MBED_ASSERT(_buffer_index < MAX_COMMAND_LENGTH); _tx_buffer[_buffer_index++] = bit ? BIT_ONE : BIT_ZERO; } int NeoIso::_send_buffer() { if (_spi.write((char*)_tx_buffer, 2*_buffer_index, (char*)_rx_buffer, 2*_buffer_index) != (int)(2*_buffer_index)) { return (-1); } return 0; } }