RetroBSD
http://retrobsd.org/

How to set SPICTL_SETSELPIN?
http://retrobsd.org/viewtopic.php?f=5&t=37246
Page 1 of 1

Author:  ole [ Mon Jul 13, 2015 6:36 pm ]
Post subject:  How to set SPICTL_SETSELPIN?

Hello everyone,

I try to write small c program to connect my 12 bits ADC via SPI interface.
But I don't understand how to set SPICTL_SETSELPIN.
Just like w5100.c that assigned pin to 0x0404 as D4 pin of chipKIT board.
I look up to datasheet of this board D4 pin is 10 of chipKIT pin and 81 of PIC32 pin.
How can I assign this HEX value? and function SPICTL_IO8 is read/write data to spi.
Can I return data value for feedback value of that address?

Thanks for your help,
Ole.

Author:  vak [ Mon Jul 13, 2015 7:31 pm ]
Post subject:  Re: How to set SPICTL_SETSELPIN?

Hi Ole,

The pin value for SPICTL_SETSELPIN is encoded as a binary value:
Code:
0000_0xxx_0000_yyyy
where xxx is a port index:
Code:
001 - port A
010 - port B
011 - port C
100 - port D
101 - port E
110 - port F
111 - port G
and yyyy specifies a pin index 0...15.

So for pin RA15 it will be 0x010f, and for RG9 - 0x0709. It's all about logical signal names, not physical pin numbers.

In case of SPICTL_IO8 call, the read value is returned in place, overwriting your transmit data. For example:
Code:
unsigned w5100_read_byte(unsigned addr)
{
    uint8_t data[4];

    data[0] = 0x0F;
    data[1] = addr >> 8;
    data[2] = addr;
    data[3] = 0xFF;
    ioctl(spi, SPICTL_IO8(4), data);

    return data[3];
}
Here you can see a 32-bit SPI transaction (four bytes) with received bits 24...31 (byte #3) returned as a resulting value.

Best wishes,
--Serge

Author:  ole [ Tue Jul 14, 2015 4:52 pm ]
Post subject:  Re: How to set SPICTL_SETSELPIN?

Hi vak,

Thank you very much for your information. So I try to connect my MCP3204 (ADC 12 bits) via spi1 (pin 0, 1, 18 , 19 of chipKIT board am I right?) and also use datasheet information to read 2 byte of 12 bits return to printf just like code below :

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/spi.h>

#define SPI_DEVNAME     "/dev/spi1"
#define SPI_KHZ              1000        // Clock speed 1 MHz
#define SPI_SELPIN          0x040E     // SS1A for RD14 pin 19 of chipKIT
#define SPI_MODE            0

static int spi;                       

void ADC_init()
{
   spi = open (SPI_DEVNAME, O_RDWR);
   if (spi < 0) {
      perror (SPI_DEVNAME);
      exit (-1);
   }
   ioctl (spi, SPICTL_SETRATE, SPI_MODE);
   ioctl (spi, SPICTL_SETRATE, SPI_KHZ);
   ioctl (spi, SPICTL_SETSELPIN, SPI_SELPIN);
}
unsigned ADC_read_byte()
{
   unsigned int data[3];
   data[0] = 0x06;  // first byte for set channel configure.
   data[1] = 0x00;  // read CH0 for 4 last bit
   data[2] = 0x00;  // read CH0 for 8 first bit
   ioctl (spi, SPICTL_IO8(3), data);
   return ((data[1] << 8) | data[2]) ;
}


int main(){
   ADC_init();
   printf("START...\r\n");
   printf(ADC_read_byte());
   printf("END...\r\n");
}


result of run is
# ./spitest
START...
(null)
END...

I also check my MCP3204 board with arduino it's still OK.
In the code use MSBFIRST for BitOrder. How can I set BitOrder?
Or am I do anything wrong why the return bytes is null?

Sorry for long question I'm new in RETROBSD with spi implement.

Thanks for your help,
Ole.

Author:  vak [ Tue Jul 14, 2015 8:30 pm ]
Post subject:  Re: How to set SPICTL_SETSELPIN?

Hi Ole,

On chipKIT Max32 board, pins 0, 1 and 18 are connected to port SPI3, not SPI1. So you should use "/dev/spi3" in your program. Pin 19 is D14, so the value 0x040E is correct.

Quote:
# ./spitest
START...
(null)
END...
Null output is caused by a missing format string in printf() call. Correct version would be:
Code:
   printf("%04x\n", ADC_read_byte());

Data transfer is always MSB first. This is compatible with MCP3204 chip, so no need to change it.

ole wrote:
Sorry for long question I'm new in RETROBSD with spi implement.
Thanks for your help,
Ole.
You are welcome!

Author:  ole [ Sun Jul 26, 2015 10:19 am ]
Post subject:  Re: How to set SPICTL_SETSELPIN?

Hi vak,

My MCP3204 still not work with RetroBSD. I was changed DEV_NAME to spi3 and then recompile again it's still not work. So I saw in usage diagram the CS of MCP3204 is implement of CS. I try to make new function just like SPICTL_IO24 (just the test name) the code below.
Code:
    case SPICTL_IO24(0):         /* transfer n*8 bits */
        spi_deselect(spi_fd[channel]);   // cs toggle to low fist before transmit
        nelem = (cmd >> 16) & IOCPARM_MASK;
        if (baduaddr (addr) || baduaddr (addr + nelem - 1))
            return EFAULT;
        spi_bulk_rw(spi_fd[channel], nelem, cval);
        spi_select(spi_fd[channel]);
        break;

other way I try to duplicate spi_bulk_rw for 3 times it's still not work.
the usage diagram of this IC
[img]
http://hobbyembedded.com/Untitled.png
[/img]
Make CS to high first then toggle CS to low and send 3 bytes of data to IC the result return to 2 last bytes.

Now I already order new ADC IC for test but I still need to know how can implements this?

Thanks for your help,
Ole.

Author:  vak [ Sat Aug 01, 2015 11:01 pm ]
Post subject:  Re: How to set SPICTL_SETSELPIN?

Hi Ole,

I would propose to use a scope to view the real signals. Obviously something is wrong here, but it's hard to tell without a full picture. Probably it's not a software issue.

BTW, it looks like a polarity of /CS signal is treated incorrectly in your code. Function spi_select() makes /CS active, i.e. sets it _low_. Function spi_deselect() sets /CS _high_, or inactive.

Regards,
--Serge

Page 1 of 1 All times are UTC
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/