ATMEGA808/3208 SPI issues with MCP41100 digipot

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi everyone,

 

I'm trying to control a MCP41100 digipot with an ATMEGA3208. I based my code on Atmel example, with the same pinout but the wiper position doesn't move at whatever value I send to it (0 to 255). Here is my simplified code for reference:

 

#define F_CPU 16000000
#define DIPOT_WRITE	0b00010011

#include <avr/io.h>

static void SPI0_init(void);
static uint8_t SPI0_exchangeData(uint8_t data);

static void SPI0_init(void)
{
    PORTA.DIR |= PIN4_bm; /* Set MOSI pin direction to output */
    PORTA.DIR |= PIN6_bm; /* Set SCK pin direction to output */
    PORTA.DIR |= PIN7_bm; /* Set SS pin direction to output */

    SPI0.CTRLA = SPI_ENABLE_bm          /* Enable module */
               | SPI_MASTER_bm          /* SPI module in Master mode */
               | SPI_PRESC_DIV16_gc;    /* System Clock divided by 16 */
}

static uint8_t SPI0_exchangeData(uint8_t data)
{
    
    SPI0.DATA = data;

    while (!(SPI0.INTFLAGS & SPI_IF_bm))  /* waits until data is exchanged*/
    {
        ;
    }

    return SPI0.DATA;
}

int main(void)
{
    CCP = CCP_IOREG_gc; // No clock division (full 16Mhz)
    CLKCTRL.MCLKCTRLB = 0; // No clock division (full 16Mhz)

    SPI0_init();
    
    while (1)
    {
        PORTA.OUT &= ~PIN7_bm; // Set SS pin value to LOW
        SPI0_exchangeData(DIPOT_WRITE); // Write command for the MCP41100
        SPI0_exchangeData(10); // Random value from 0 to 255
        PORTA.OUT |= PIN7_bm; // Set SS pin value to HIGH
        
    }
}

Any pointers would be much appreciated!

 

Thank you,

 

Octave

This topic has a solution.
Last Edited: Sun. Apr 10, 2022 - 09:40 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Set the SSD bit of CTRLB.
Set the ENABLE bit of CTRLA after completing all settings.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Couple things to go check (not saying they are wrong):

Check that 

PIN4_bm

,etc are defined properly for the particular chip you are using.  Any mixup will cause complete chaos!

 

SPI has 4 modes...double check that you are using the mode that corresponds to your chip (you prob want to explicitly config CTRLB in your code), so you can state there what mode you are using.

 

If SS is configured as input and is driven low when the SPI is in Master mode, this will also set this flag. IF is cleared by hardware when executing the corresponding interrupt vector. Alternatively, the IF flag can be cleared by first reading the SPIn.INTFLAGS register when IF is set, and then accessing the SPIn.DATA register.

Maybe you are getting a false IF setting, messing up your monitoring

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@kabasan @avrcandies thanks so much for your quick replies. Now don't laugh but I found the problem, I was using an SSOP-28 socket breakout, and sure enough my pin PA4 (MOSI) was not making contact... I switched to a soldered breakout board and sure enough now it's working totally fine, with my original code. I tried with and without setting the SSD bit, works in both cases.

 

Thanks again, we live we learn!