2

I'm playing around with reading in analogue inputs from an MCP3208 ADC via SPI. However, reading multiple inputs seems to cause a seg fault unless I reinitialise the SPI on each read/write.

I've attached my 3208 interface code (which is heavily based off Adafruit's 3008 library). I haven't been able to setup a debug environment, so I don't have any insights on what goes on when it crashes. Is there anything I'm missing?

#include "mcp3208.hpp"
#include "hardware/gpio.h"

MCP3208::MCP3208(spi_inst_t *spi, int cs, int sck, int miso, int mosi) { //spi_init(spi, 1000000);

gpio_set_function(sck, GPIO_FUNC_SPI);
gpio_set_function(miso, GPIO_FUNC_SPI);
gpio_set_function(mosi, GPIO_FUNC_SPI);

gpio_init(cs);
gpio_set_dir(cs, GPIO_OUT);
cs_deselect();

_cs = cs;
_sck = sck;
_miso = miso;
_mosi = mosi;
_spi = spi;
_baudrate = 1000000;

}

MCP3208::~MCP3208() { spi_deinit(_spi); }

void MCP3208::cs_select() { asm volatile("nop \n nop \n nop"); gpio_put(_cs, 0); // Active low asm volatile("nop \n nop \n nop"); }

void MCP3208::cs_deselect() { asm volatile("nop \n nop \n nop"); gpio_put(_cs, 1); asm volatile("nop \n nop \n nop"); }

uint16_t MCP3208::scale(uint16_t scale_in, uint16_t old_min, uint16_t old_max, uint16_t new_min, uint16_t new_max) { //Scales to 16 bit by default return (((scale_in - old_min) * (new_max - new_min)) / (old_max - old_min)) + new_min; }

uint16_t MCP3208::read_adc(int channel) { if (channel < 0 || channel > 7) { return 0; }

uint8_t command = 0b11 &lt;&lt; 6;
command |= (channel &amp; 0x07) &lt;&lt; 3;

uint8_t write_buff[3] = {command, 0x0, 0x0};
uint8_t read_buff[3];

// may need to fix this requirement to init then deinit deinit
spi_init(_spi, _baudrate); //todo: remove

cs_select();
spi_write_read_blocking(_spi, write_buff, read_buff, 3);
cs_deselect();

spi_deinit(_spi); //todo: remove

uint16_t result = (read_buff[0] &amp; 0x01) &lt;&lt; 11;
result |= (read_buff[1] &amp; 0xFF) &lt;&lt; 3;
result |= (read_buff[2] &amp; 0xE0) &gt;&gt; 5;

return result;

}

user151296
  • 29
  • 1

0 Answers0