Thursday, June 4, 2015

June 4 - New code for MAX11205

The following link contains information about bit banging, and an example of it being used. It's similar to what we're trying to do.
http://electronics.stackexchange.com/questions/44670/what-is-bit-banging

The following link has new operators that we used in our C code:
http://www.tutorialspoint.com/cprogramming/c_operators.htm

Here is the code that we are using for the MAX11205 peripheral. It waits for the transition of the ready line from high to low, meaning the data sample is available and provides 25 clocks.

/* Include Files */
#include "xparameters.h"
#include "xgpio.h"
#include "xstatus.h"
#include "xil_printf.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/* Definitions */
#define GPIO_DEVICE_ID  XPAR_AXI_GPIO_0_DEVICE_ID /* GPIO device that LEDs are connected to */
#define LED 0xFC          /* Initial LED value - XX0000XX */
#define CLOCK_on 0x08    //high for the clock
#define DATAREADY_high 0x04   //high for data ready pin 3
#define PMOD 0         /*  */
#define LED_DELAY 100000000       /* Software delay length */
#define LED_CHANNEL 1        /* GPIO port for LEDs */
#define PMOD_CHANNEL 1        /* GPIO port for PMODs */
#define printf xil_printf       /* smaller, optimised printf */
#define PMOD_JA1_DEVICE_ID  XPAR_AXI_GPIO_1_DEVICE_ID


XGpio Gpio, GpioP;           /* GPIO Device driver instance */


int max_MAX11205_GPIO_SPI_read(
void)
/**
* \brief       Performs a SPI read using bit banging. Written specifically for the MAX11205 ADC.
*
* \par         Description
*              The MAX11205 sets the RDY# line high during sampling, then low when a sample is available.
*              The function waits for that transition, then provides the appropriate number of clocks
*              to the MAX11205 to complete the read.  Note that the 11205 is a 16 bit device, but requires
*              9 additional clocks (25 in total) to complete a read cycle
*              An optional self-calibration mode can be selected by setting uchUseCalibrationMode==TRUE
*              which will send a 26th clock to the MAX11205.
*
* \param[in]   *port                       - pointer to the GPIO port instance
* \param[in]   uchUseCalibrationMode       - TRUE = perform function in self-calibration mode.
*
* \retval      adcValue                    - 16-bit value from ADC conversion
*/
{
    int i=0;
    u8 uchPortWriteData=0;
    u8 uchPortReadData=0;
    int adcValue=0;
    int nClockCount=8;


    XGpio_SetDataDirection(&GpioP, 1, 0x04);  // Set pin 3 to be an input.  All the rest (including SCLK) are outputs

    sleep(10);
    // First, set the clock and data lines low, and the SS# line high
        // GPIO[3:0] = {SCK, CLR#, MOSI, SS#} // default 'off' is 4'b0101 = 0x05
    sleep(10);
    uchPortWriteData = 0;
    XGpio_DiscreteWrite(&GpioP, 1, uchPortWriteData);  // The (1) means write to the only port (#1) on the uBlaze GPIO port
    sleep(10);

    // Wait until RDY# goes high
    uchPortReadData = XGpio_DiscreteRead(&GpioP,1);
    while((uchPortReadData & DATAREADY_high)==0x00)  // keep looping while low
    {
        uchPortReadData = XGpio_DiscreteRead(&GpioP,1);
    }

    // Now, wait until RDY# goes low
    uchPortReadData = XGpio_DiscreteRead(&GpioP,1);
    while((uchPortReadData & DATAREADY_high)==DATAREADY_high)
    {
        uchPortReadData = XGpio_DiscreteRead(&GpioP,1);
    }

    // Now, send in clocks.
    for(i=15;i>=0;i--)
    {
        // Send clock high
        uchPortWriteData |= CLOCK_on;
        XGpio_DiscreteWrite(&GpioP, 1, uchPortWriteData);

        sleep(10);  // small delay, then read
        uchPortReadData = XGpio_DiscreteRead(&GpioP,1);

        // Shift the GPIO read data to the lowest bit, mask off all the other bits, then shift i (15:0)
        // number of bits to set the appropriate bit in the
        if(((uchPortReadData >> 2) & 0x01)==0x01) // the serial bit is a one, set the bit
        {
            if(i==15)
                adcValue = 0xFFFF8000;  // extend the sign of the 2s complement number to bits 31..16, and set bit 15 = 1
            else
                adcValue |= (int)(1 << i);  // bit shift
        }
        uchPortWriteData &= ~CLOCK_on;// Clock in data via negative edge
        XGpio_DiscreteWrite(&GpioP, 1, uchPortWriteData);
        sleep(10);
    }

    // The 11205 device requires 25 clocks total to complete a read.
    // We have already sent (16) clocks, so send 9 more clocks.
    // (If self-calibration mode set then we send 10 more clocks.)

        nClockCount=8;
    for(i=nClockCount;i>=0;i--)
    {
        // Send clock high
        uchPortWriteData |= CLOCK_on;
        XGpio_DiscreteWrite(&GpioP, 1, uchPortWriteData);

        sleep(10);  // small delay, then read
        uchPortWriteData &= ~CLOCK_on;// Clock in data via negative edge
        XGpio_DiscreteWrite(&GpioP, 1, uchPortWriteData);
        sleep(10);
    }
    return XST_SUCCESS; /* Should be unreachable */;
}




/* Main function. */
int main(void){


 int Status;


 /* Execute the LED output. */
// Status = LEDOutputExample();
 Status = max_MAX11205_GPIO_SPI_read();
 if (Status != XST_SUCCESS) {
  xil_printf("GPIO read of ADC failed!\r\n");
 }


 return 0;
}


 We can run the code with no error messages, but we are still in the process of trying to test it.

No comments:

Post a Comment