Libm2k includes bitbang implementations on a variety of protocols.
In the Select Additional Tasks window, select Install libm2k tools option.
Build and install libm2k. Instruction can be found here. Make sure to enable tools option.
~/libm2k/build$ cmake -DENABLE_TOOLS=ON ../
Check the ENABLE_TOOLS box in CMake GUI.
There is a common structure to use for all the protocols when trying to communicate with other device using libm2k:
Initialization of any protocol can be split into:
The structure that stores all ADALM-2000 specific attributes can be found in the extra header, while all generic attributes are found in the standard header. For example SPI generic attributes are found in <libm2k/tools/spi.hpp>, while SPI specific attributes of ADALM-2000 are found in <libm2k/tools/spi_extra.hpp>.
Initialization parameters:
Functions:
Examples:
#include <libm2k/m2k.hpp> #include <libm2k/contextbuilder.hpp> #include <libm2k/tools/spi.hpp> #include <libm2k/tools/spi_extra.hpp>
libm2k::contexts::M2k *context = libm2k::contexts::m2kOpen("ip:192.168.2.1"); // first step of initialization m2k_spi_init m2KSpiInit; m2KSpiInit.clock = 1; m2KSpiInit.mosi = 2; m2KSpiInit.miso = 7; m2KSpiInit.bit_numbering = MSB; m2KSpiInit.context = context; // second step of initialization spi_init_param spiInitParam; spi_init_param.max_speed_hz = 1000000; spi_init_param.mode = SPI_MODE_3; spi_init_param.chip_select = 0; spi_init_param.extra = (void*)&m2KSpiInit; // third step of initialization spi_desc *desc = nullptr; spi_init(&desc, &spiInitParam);
uint8_t data[2] = {0xAB, 0xFF}; spi_write_and_read(desc, data, 2);
spi_remove(desc); libm2k::contexts::contextClose(context, true);
Initialization parameters:
Functions:
Examples:
#include <libm2k/m2k.hpp> #include <libm2k/contextbuilder.hpp> #include <libm2k/tools/i2c.hpp> #include <libm2k/tools/i2c_extra.hpp>
libm2k::contexts::M2k *context = libm2k::contexts::m2kOpen("ip:192.168.2.1"); // first step of initialization m2k_i2c_init m2KI2CInit; m2KI2CInit.scl = 0; m2KI2CInit.sda = 1; m2KI2CInit.context = context; // second step of initialization i2c_init_param i2CInitParam; i2CInitParam.max_speed_hz = 100000; i2CInitParam.slave_address = 0x48; i2CInitParam.extra = (void*)&m2KI2CInit; // third step of initialization i2c_desc *desc = nullptr; i2c_init(&desc, &i2CInitParam);
uint8_t data_write[] = {0x0B}; uint8_t data_read[] = {0}; i2c_write(desc, data_write, sizeof(data_write), i2c_general_call | i2c_repeated_start); i2c_read(desc, data_read, sizeof(data_read), i2c_general_call);
i2c_remove(desc); libm2k::contexts::contextClose(context, true);
Initialization parameters:
Functions:
Examples:
#include <libm2k/m2k.hpp> #include <libm2k/contextbuilder.hpp> #include <libm2k/tools/uart.hpp> #include <libm2k/tools/uart_extra.hpp>
libm2k::contexts::M2k *context = libm2k::contexts::m2kOpen("ip:192.168.2.1"); // first step of initialization m2k_uart_init m2KUartInit; m2KUartInit.bits_number = 8; m2KUartInit.parity = NO_PARITY; m2KUartInit.stop_bits = ONE; m2KUartInit.context = context; // second step of initialization uart_init_param uartInitParam; uartInitParam.device_id = 0; uartInitParam.baud_rate = 9600; uartInitParam.extra = (void*)&m2KUartInit; // third step of initialization uart_desc *desc = nullptr; uart_init(&desc, &uartInitParam);
uint8_t dataWrite[] = {'A', 'D', 'I'}; uart_write(desc, dataWrite, sizeof(dataWrite));
uart_remove(desc); libm2k::contexts::contextClose(context, true);
Analog Devices offers a variety of No-OS drivers for a variety peripherals in a hardware agnostic format. These drivers can be interfaced with the libm2k in order to use the M2K as a master to configure/use the peripheral. Documentation for the drivers available here.
In order to integrate libm2k with no-OS drivers some standard steps must be followed:
Including all required driver files in the project is the first step in integrating libm2k with no-OS drivers.
The drivers will include some protocols, for example “i2c.h”. The afferent header of libm2k, <libm2k/tool/i2c.hpp>, does not match with the header included by the drivers (“i2c.h”). In order not to modify the drivers we are going to create a header named after the protocol (“i2c.h”) in which the libm2k header will be included. For example create the “i2c.h” header in which you will include <libm2k/tools/i2c.hpp>.
Each file that will call libm2k methods should be a C++ file. The inclusion of any driver in a C++ file has to be marked as an external C file inclusion.
Example:
AD5592r can be independently configured as DAC outputs, ADC inputs, digital outputs, or digital inputs. In this example we are going to generate ascending voltage values, communicating with the chip using SPI.
#include "delay.h" #include <unistd.h> void mdelay(uint32_t msecs) { usleep(msecs * 1000); }
//spi.h #include <libm2k/tools/spi.hpp>
//i2c.h #include <libm2k/tools/i2c.hpp>
#include <libm2k/m2k.hpp> #include <libm2k/contextbuilder.hpp> #include <libm2k/analog/m2kpowersupply.hpp> #include <libm2k/analog/m2kanalogin.hpp> #include <libm2k/tools/spi_extra.hpp> extern "C" { #include "ad5592r.h" } extern struct ad5592r_rw_ops ad5592r_rw_ops; //default operations int main() { struct ad5592r_init_param init_param; init_param.int_ref = true; // use the internal reference struct ad5592r_dev device; device.ops = &ad5592r_rw_ops; //initialize the operations libm2k::contexts::M2k *context = libm2k::contexts::m2kOpen("ip:192.168.2.1"); libm2k::analog::M2kPowerSupply *powerSupply = context->getPowerSupply(); libm2k::analog::M2kAnalogIn *analogIn = context->getAnalogIn(); std::cout << "Calibrating . . ." << std::endl; context->calibrateADC(); powerSupply->enableChannel(0, true); powerSupply->pushChannel(0, 5); // power up the chip // first step of initialization m2k_spi_init m2KSpiInit; // m2k specific attributes of SPI m2KSpiInit.clock = 0; m2KSpiInit.mosi = 1; m2KSpiInit.miso = 2; m2KSpiInit.bit_numbering = MSB; m2KSpiInit.context = context; // second step of initialization spi_init_param spiInitParam; // generic attributes of SPI spiInitParam.max_speed_hz = 2500000; spiInitParam.mode = SPI_MODE_2; spiInitParam.chip_select = 3; spiInitParam.extra = (void*)&m2KSpiInit; // third step of initialization spi_init(&device.spi, &spiInitParam); // initialize SPI communication device.channel_modes[0] = CH_MODE_DAC; // set the first channel as a DAC device.num_channels = 1; // enable just the first channel ad5592r_init(&device, &init_param ); //initialize AD5592r for(int i = 0; i < 0xfff; i+=0x0f) { ad5592r_write_dac(&device, 0, i); // generate voltage std::cout << analogIn->getVoltage(0) << std::endl; //read voltage } libm2k::contexts::contextClose(context, true); }
gcc -c delay.c gcc -c ad5592r-base.c gcc -c ad5592r.c g++ -c main.cpp g++ -o example delay.o ad5592r-base.o ad5592r.o main.o -lm2k ./example