Hi,
i try to setup a SPI communication, but it has to run in 16 Bit (which should be possible).
Unfortunately i don't get how to switch the resolution. Can anyone help me please?
16 Bit HardwareSPI
(6 posts) (4 voices)-
Posted 3 years ago #
-
Hello Ron,
Welcome to the LeafLabs forums.
Please refer to the "Guidelines for Posting". It is a "sticky" topic at the beginning of the forum discussions.
For example, your title is short and descriptive (great!). However, it is also helpful to describe the board you are using, your OS, etc.
Just trying to help get an answer which helps both you and other people with similar questions.
Posted 3 years ago # -
Hi, thanks for the hint. I'm using a maple r5 on a OS X 10.7.4 System and i try to read an AS5048A magnetic rotary encoder (http://www.ams.com). I guess i found a way for the 16 Bit communication but still i get no valid data. The following code is based on the AS5048B-AB-v1-1.0_Operation-Manual_Rev.1.0.pdf.
HardwareSPI SPI(1); #define SPI_CMD_READ 0x4000 /*!< flag indicating read attempt when using SPI interface */ #define SPI_REG_AGC 0x3ffd /*!< agc register when using SPI */ #define SPI_REG_MAG 0x3ffe /*!< magnitude register when using SPI */ #define SPI_REG_DATA 0x3fff /*!< data register when using SPI */ #define SPI_REG_CLRERR 0x1 /*!< clear error register when using SPI */ uint16 dat=0, datIn=0; unsigned int angle, agcreg, magreg; byte agc; boolean alarmHi, alarmLo; void setup() { SPI.begin(SPI_4_5MHZ, MSBFIRST, 1); // Freq < 8MHz, MSBFIRST, CLK idle LOW, read falling edge -> MODE 1 } void loop() { spiReadData(); delay(50); } /*! ***************************************************************************** * Reads out chip data via SPI interface * * This function is used to read out cordic value from chips supporting SPI * interface. ***************************************************************************** */ void spiReadData(){ /* Send READ AGC command. Received data is thrown away: this data comes from the precedent command (unknown)*/ dat = SPI_CMD_READ | SPI_REG_AGC; dat |= spiCalcEvenParity(dat) << 15; SPI.write((uint8*)&dat, sizeof(uint16)); SPI.read((uint8*)&datIn, sizeof(uint16)); /* Send READ MAG command. Received data is the AGC value: this data comes from the precedent command (unknown)*/ dat = SPI_CMD_READ | SPI_REG_MAG; dat |= spiCalcEvenParity(dat) << 15; SPI.write((uint8*)&dat, sizeof(uint16)); SPI.read((uint8*)&datIn, sizeof(uint16)); magreg = datIn; /* Send READ ANGLE command. Received data is the MAG value, from the precedent command */ dat = SPI_CMD_READ | SPI_REG_DATA; dat |= spiCalcEvenParity(dat) << 15; SPI.write((uint8*)&dat, sizeof(uint16)); SPI.read((uint8*)&datIn, sizeof(uint16)); agcreg = datIn; /* Send NOP command. Received data is the ANGLE value, from the precedent command */ dat = 0x0000; // NOP command. SPI.write((uint8*)&dat, sizeof(uint16)); SPI.read((uint8*)&datIn, sizeof(uint16)); angle = datIn >> 2; if ((datIn & 0x4000) || (agcreg & 0x4000) || (magreg & 0x4000)) { /* error flag set - need to reset it */ dat = SPI_CMD_READ | SPI_REG_CLRERR; dat |= spiCalcEvenParity(dat)<<15; SPI.write((uint8*)&dat, sizeof(uint16)); SPI.read((uint8*)&datIn, sizeof(uint16)); SerialUSB.println("err"); } else { SerialUSB.println(magreg); } } /*! ***************************************************************************** * Calculate even parity of a 16 bit unsigned integer * * This function is used by the SPI interface to calculate the even parity * of the data which will be sent via SPI to the encoder. * * \param[in] datIn : 16 bit unsigned integer whose parity shall be calculated * * \return : Even parity * ***************************************************************************** */ uint8 spiCalcEvenParity(uint16 datIn){ uint8 cnt = 0; uint8 i; for (i = 0; i < 16; i++) { if (datIn & 0x1){ cnt++; } datIn >>= 1; } return cnt & 0x1; }
Posted 3 years ago # -
Posted 3 years ago #
-
Are you pulling SS low before you read/write? I think you need to do that manually. That is, I don't think HardwareSPI pulls the SS pin low for you, so you need to do a
digitalWrite(<insert_ss_pin_number>, LOW)
to get the slave device to listen to you, assuming the Maple is the master. At least, when I use SPI, I control it manually :).
- Andy
Posted 3 years ago # -
Thanks for the help Andy, i tried this in a previous sketch ... but it doesn't seem to make any difference. SS got pulled LOW at the beginning of spiReadData() and set to HIGH again at the end. Maybe i get the diagram for mode and timing wrong ... is it possible to post an image?
Posted 3 years ago #
Reply
You must log in to post.