How to configure SERCOM SPI master for multibyte transfers

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

Lars provided a skeleton program for single byte transfer using hardware control (CTRLB.MSSEN = 1), it works correctly

I'm still fighting a program which should control a MAX7219 8-digit 7-segment LED display driver

This needs 3 signals, slave select (SS), serial data out (MOSI), serial clock (SCK).

At the start SS = 1 and CTRLB.MSSEN = 0

 

The required operations are:

1. Set SS = 0 using program control

2. Transmit the first byte, these are shifted into the MAX7219 shift register

3. Transmit the second byte, these are then in the shift register

4. Set SS = 1, the MAX7219 loads the16 bits in the shift register 

 

It's not possible to use hardware control of the SS line because one has to transmit two bytes, then raise SS

 

The problem:

The SCK signal does not appear, although in Lars' program it does.

The SS signal and MOSI signals are as expected.

 

Can anyone tell me how to make the SCK clock signal visible?

Many thanks for suggestions

Best wishes, Jerry

 

 

 

This topic has a solution.
Last Edited: Fri. Jan 14, 2022 - 03:40 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is odd, I think you need to show the code.

/Lars

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

Hello Lars,

    Thanks for the reply. The code is part of a bigger program. I'll make a smaller program out of it and post it

Bist wishes, Jerry

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

Hello Lars,

    Sorry for the delay, I was away

The attached .zip file is of the complete larger program, it would have taken longer to remove the unneeded parts

Directions:

  1. Unpack the .zip file, a directory SAMD21BLDCtest containing all sources is created
  2. There's a file SAMD21BLDC.cproj in the directory, open it with Microchip Studio
  3. Connect a SAMD21 board to the debugger (I use a Sparkfun board and an Atmel-ICE debugger)
  4. Compile and load the program

The pins used here are:

  • Pin PA05 is the SCLK output,
  • pin PA07 is the SS output and
  • pin PA04 is MOSI

The SS and MOSI outputs are as expected

 

Except for the  device_startup all source files are in the directory src. 

The initialisation of the SERCOM SPI is done by the subroutine init_MAX7219_SERCOM() in file system_samd21.c

Every 10msec init_MAX7219_SERCOM() in file timer.c causes MAX7219hndlr(void *param_p) to start transmitting commands to the MAX7219 display driver. This is interrupt controlled, the SERCOM DRE handler clears the SS line before the first byte is transmitted and the SERCOM TXC sets the SS line so that the MAX7219 loads the two bytes. This is repeated until all commands have been transmitted. The MAX7219 subroutines are in file MAX7219.c, the interrupt handler is MAX7219hndlr() in file int_handlers.c 

The MOSI and SS signals are as expected, the SCLK remains stuck at logical 0

Thanks for any help in finding SCLK. Please ask if you need more information 

Best wishes, Jerry

 

PS A note on the rest of the program. It uses an extremely primitive scheduler in dispatch.c, short interrupt handlers and no wait loops except in main.c

Attachment(s): 

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

Well there is an obvious copy paste error here with the PINCFG setup for SCLK.

      PORT->Group[MAX7219_MOSI / 32].PINCFG[MAX7219_MOSI % 32].reg = port_pincfg.reg;
      set_pmux(MAX7219_MPX, MAX7219_MOSI);  /* Overrides DIR, see 23.6.1 */
/* Now for the SCLK pin */
      PORT->Group[MAX7219_SCLK / 32].PINCFG[MAX7219_MOSI % 32].reg = port_pincfg.reg;

/Lars

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

Hello Lars,

     Thanks very much Lars, that fixed the problem

All goes to show that a second set of eyes is very helpful

In German one says "I could have bitten myself in the behind" if one is angry with one self about a mistake that one has made oneself - in this case I wasted a lot of time on my bug

Best wishes, Jerry

Last Edited: Fri. Jan 14, 2022 - 04:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I checked the datasheet and ran some tests...

It seems like the SERCOM-SPI can only drive the SS line low for each byte or "frame" (8/9 bits) in hardware-mode (CTRLB.MSSEN = 1).

32-bit Extension mode resulted in 2 to 4 bytes, each separated by SS low->high->low

 

Only two options comes to mind:

  1. Drive the SS pin from software (high->low before writing 1st data to SPI, then low->high in SERCOM transmit complete interrupt handler, or by polling INTFLAG.TXC).
  2. Use a single-shot timer to generate the SS signal.