MCP 3008 using spi in Hifive rev b


(Jishnu Chakrabarti) #1

Hi…
Has anyone used MCP3008 with hifive1 rev b and if so…can u please share the code.

Thank u in advance


(Jishnu Chakrabarti) #2

Hi,
I am trying for SPI code for first time in HiFive reb B board.

and this is the SPI code, I am using for my board Hifive Rev b board and code is given below…

#include <stdio.h>
#include <metal/spi.h>

int main() {
printf(“METAL SPI Driver Demonstration.\n”);
printf("-------------------------------\n");

struct metal_spi *spi;

/* Get SPI 1 */
spi = metal_spi_get_device(1);

/* Fallback to SPI 0 */
if (spi == NULL) {
	spi = metal_spi_get_device(0);
}

if (spi == NULL) {
	printf("Failed to get spi device\n");
	return 1;
}

/* Initialize the SPI device to 100_000 baud */
metal_spi_init(spi, 100000);

/* CPOL = 0, CPHA = 0, MSB-first, CS active low */
struct metal_spi_config config = { .protocol = METAL_SPI_SINGLE, .polarity =
		0, .phase = 0, .little_endian = 0, .cs_active_high = 0, .csid = 0, };

/* Transfer three bytes */
char tx_buf[3] = { 0x55, 0xff, 0x80 };
char rx_buf[3] = { 0 };
char result[3];
int count;
for(count = 0; count <=3 ; count++)
{
	//printf("%X ", metal_spi_transfer(spi, &config, 3, tx_buf[count], rx_buf[count]) & 0xff);
	printf("%x ",  metal_spi_transfer(spi, &config, 3, tx_buf[count],rx_buf) & 0xff);
	fflush(stdout);
}

return 0;

}

I have connected pin#11 and pin# 12 with jumpers and I am not seeing output of
three bytes in Serial Terminal…

can anyone advise where am I going wrong?


(Jishnu Chakrabarti) #3

Hello…tried today still the above code isnt working. Unable figure what’s going wrong here?

metal_spi_transfer(spi, &config, 3, tx_buf,rx_buf);
The above code is used for spi transfer. My question is that data being read or write…how to print in serial terminal ?

Need help. And if some one has successful spi example…please share as it will help me to understand how the spi is working in hifive 1 rev b board.

My goal is use spi (mcp 3008) for analog reading from sensor.

Thanks.


(Daniel kirubakaran) #4

Have you called the UART initialization function with the baud rate value? Check it once.


(Jishnu Chakrabarti) #5

Hello Daniel,

thanks for the suggestion and accordingly, I have modified my code. But problem still remains the same.

the modified code is given below:

#include <stdio.h>
#include <metal/spi.h>
#include <metal/uart.h>

int main() {

printf("METAL SPI protocol Demonstration.\n");
printf("---------------------------------\n");
char ch = 0xff;
printf("0x%x", ch);
fflush(stdout);

struct metal_spi *spi;
/* Get SPI 1 */
spi = metal_spi_get_device(0);
/* Fallback to SPI 0 */
if (spi == NULL) {
	spi = metal_spi_get_device(1);
}

if (spi == NULL) {
	printf("Failed to get spi device\n");
	return 1;
}

/* Initialize the SPI device to 100_000 baud */
metal_spi_init(spi, 100000);

/* CPOL = 0, CPHA = 0, MSB-first, CS active low */
struct metal_spi_config config = { .protocol = METAL_SPI_SINGLE, .polarity =
		0, .phase = 0, .little_endian = 0, .cs_active_high = 0, .csid = 0 };

//---------------------------changed made as suggested Daniel kirubakaran--------------------------------------------
struct metal_uart *uart;
metal_uart_init(uart, 115200);

/* Transfer three bytes */
char tx_buf[] = { 0x55 };
int rx_buf[] = { 0x0 };
int result[] = { metal_spi_transfer(spi, &config, 1, tx_buf, rx_buf) };
metal_uart_getc(uart, result);  //Read a character sent over the UART.
printf("done\n");
return 0;

}

/*
char ch = 0xC0;
printf("%x", ch & 0xff);

MCP3008 UNO
VDD 5V 3V
VREF 5V
AGND GND
CLK 13 SCLK
DOUT 12 MI
DIN 11 MO
CS 10
DGND GND
*/

as seen in the picture…after the title and hex number 0xff… it prints nothing. Any idea why this is still not working.

thanks


(Daniel kirubakaran) #6

Try to debug the code.
I have only worked with hifive1 in arduino ide environment , also did a temperature sensing project using mcp3008 in hifive1 but i have used software spi and i think freedom studio is similar to eclipse ide. So try debugging.


(Jishnu Chakrabarti) #7

As advised, I have tried to analyse metal_spi_transfer() function by using saleae to check the data transfer from MOSI (Hifive1 Rev b) to MISO (MCP3204). I observed that the function metal_spi_transfer(spi, &config, 1, tx_buf, rx_buf); MOSI is showing some other arbitrary data other than 0x55 which it suppose to transfer as per the code and MISO is displaying arbitrary large numbers of datum even though as per metal_spi_transfer is suppose to transfer only 1 byte!!! and I am also not able to print data being read or written into the serial terminal.

Hence, now I am finding in difficult to understand how this function metal_spi_transfer() is working.

Contrary to that below is an example of SPI using BCM2835 in raspberry Pi.
.
#include <bcm2835.h>
#include <stdio.h>

int main(int argc, char **argv)
{
// If you call this, it will not actually access the GPIO
// Use for testing
// bcm2835_set_debug(1);

if (!bcm2835_init())
{
  printf("bcm2835_init failed. Are you running as root??\n");
  return 1;
}

if (!bcm2835_spi_begin())
{
  printf("bcm2835_spi_begin failed. Are you running as root??\n");
  return 1;
}
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);      // The default
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);                   // The default
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536); // The default
bcm2835_spi_chipSelect(BCM2835_SPI_CS0);                      // The default
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);      // the default

// Send a byte to the slave and simultaneously read a byte back from the slave
// If you tie MISO to MOSI, you should read back what was sent
uint8_t send_data = 0x23;
uint8_t read_data = bcm2835_spi_transfer(send_data);
printf("Sent to SPI: 0x%02X. Read back from SPI: 0x%02X.\n", send_data, read_data);
if (send_data != read_data)
  printf("Do you have the loopback from MOSI to MISO connected?\n");
bcm2835_spi_end();
bcm2835_close();
return 0;

}

and it works fine, and I am very clear that Raspberry Pi is CPU whereas HiFive1 Rev b is MCU.

But its easier to understand how we can play with SPI in Raspberry Pi using BCM2835 than working with SPI examples used in Freedom Metal library and it’s not yielding the desired result at all.

Hope some one from Sifive goes through the complete post and either re-looks into the SPI code and improves it or in case if I am wrong - then advises me accordingly in above matter with the tested example.