![](/media/cache/group/Future.jpg.50x50_q85.jpg)
Lab exercise code for FAE Summit 09/2019.
Diff: neo_iso_drv.cpp
- Revision:
- 58:cf54c181a632
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/neo_iso_drv.cpp Wed Sep 18 17:40:11 2019 +0000 @@ -0,0 +1,138 @@ +/* + * 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; +} + +}