element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Raspberry Pi
  • Products
  • More
Raspberry Pi
Raspberry Pi Forum BCM2835 and SPI Transfers
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Raspberry Pi to participate - click to join for free!
Featured Articles
Announcing Pi
Technical Specifications
Raspberry Pi FAQs
Win a Pi
Raspberry Pi Wishlist
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Suggested Answer
  • Replies 10 replies
  • Answers 5 answers
  • Subscribers 665 subscribers
  • Views 2882 views
  • Users 0 members are here
  • raspberry_pi
Related

BCM2835 and SPI Transfers

ceeej
ceeej over 5 years ago

I'm using a Pi3 to control a PLL (ADF4351) which requires an initial load of 6 32 bit config words to be sent via SPI, MSB first.

 

I've succesfully used BCM2835 to handle SPI before with a MCP23S17 so I know the library works and is installed correctly.

 

But, the 32 bit word thing, perhaps I'm missing something (likely) but I can't work out how to transfer more than 16 bits in one go, I can of course 'twiddle' the data to  make it work with bcm2835_spi_write but that feels unnecessarily awkward and not a little inelegant so, is it possible to do a 32 bit transfer using BCM2835 elegantly or do I need to start bit shifting and masking?

 

 

Any advice (except use another language) welcome and thanks in advance,

 

Clint

  • Sign in to reply
  • Cancel
  • rew
    0 rew over 5 years ago

    You hint at that you're using a library called BCM2835 in "a language". BCM2835 is hte name of a chip, the CPU on the raspberry pi one.

     

    Now, IF BCM2835 is the name of a library for SPI on BCM2835 and similar chips, then I expect that you can transmit a number of bytes (any number) by passing an array of bytes. For 32 bits, you'd need an array with 4 bytes.

     

    In theory, sending 4 bytes that you have as a 32 bit integer rewquires no conversion: The hardware doesn't know the difference between 4 bytes and a 32bit integer. On the other hand "your language" may.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • michaelkellett
    0 michaelkellett over 5 years ago

    You need to provide more information:

    SPI0 is different from SPI1 and 2 - which are you using ?

     

    Which language and which library are you using ?

     

    Have you read the Broadcom peripheral data sheet for the BCM2835?

     

    SPI0 supports  LOSSI which is not very common.

     

    SPI1 and 2 support 32 bit transfers in hardware.

     

    (Just saw Roger's post - sorry about duplication.)

     

    MK

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • balearicdynamics
    0 balearicdynamics over 5 years ago in reply to michaelkellett

    Repetita juvant, it seems

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • ceeej
    0 ceeej over 5 years ago in reply to rew

    Apologies, yes BCM2835 is an eponymously named library to control the low level peripherals of the chip.

     

    I think I've seen it mentioned here and assumed (I really should know better) which is why I wasn't more explicit.

     

    It's from https://www.airspayce.com/mikem/bcm2835/index.html

     

    You can pass it an array of bytes to send, there's an example of exactly that on the website which works but only 8 bits at a time before it deasserts CE, another of its functions allows 16 bit shorts to be sent but it still (correctly) deasserts CE after 16 bits.

     

    The ADF4351 needs to see all 32 bits of data before CE is deasserted as it latches them into the relevant registers on deassertion so sending it a short and deasserting CE produces 'odd' results.

     

    Using one of the other functions in the library allows me to send 16 bits at a time before CE deasserts so my code, at the moment, is shifting and masking 32 bit values from a 6 member 'int' array into a 12 member 'short' array, sending those 12 shorts and controlling CE instead of letting the library control it.

     

    I'm sure there's a more elegant way to do the bit manipulation but for now my main concern is that there may be a simpler, more obvious way to get 32bits out of the Pi without having to do the bit shuffling and 'manual' control of CE .

     

    To answer Michael, SPI0 but the functions appear to be the same for 'AUX' SPI (which I assume is SPI1, see above about knowing better)

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • rew
    0 rew over 5 years ago in reply to ceeej

    The SPI protocol allows for sending a number of bits before de-asserting CE. Commonly that number is a multiple of 8, but it doesn't have to be that way.

     

    For example, SD cards (in the simplest form) use an SPI protocol where you need to transfer 512 bytes at a time. That is 4096 bits. (There is probably a command prefixed to that, so there will be a few more than that.)

     

    Anyway, If your library de-asserts CE after each byte, then that is an unwanted restriction of the library you are using. That might be "correctly" because it is documetned that way, but it is not "correct" in that it allows you to talk to "normal" SPI devices. You have the following options:

     

    * Read the manual of your library to figure out how you can prevent this unusual and often unwanted behaviour.

    * Dive into the library and fix it to prevent this unusual behaviour.

    * Use a different library.

    * Wire your device to a different CS pin than the one that the library uses. Now program that pin low to enable your chip, send four bytes (which causes another output on the chip to go up and down 4 times.... So what?) and then program the pin high again.

     

    As far as I can see you need tow be able to write 24 bits without deasserting the CS line to make an MCP23S17 work. So I you might want to investigate how that's done.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • michaelkellett
    0 michaelkellett over 5 years ago in reply to ceeej

    OK,

     

    First thing - the library is not very good (tempted to say junk but that might be a bit hasty). The hardware is way better than that.

    (Actually library does seem to offer necessary functions but it has one hell of an attitude as expressed in the link you provided. I'm almost temped to contact the author directly just to wind him up  - who does he think he is  (Duchess of Sussex ?)image)

    De-asserting CS after each word is niether standard or even normal practice - are you sure there isn't a way of sending a group of words (8 or 16 bit) in a single cs defined frame ?

     

    bcm2835_spi_transfern and

    bcm2835_spi_transfernb

     

    look like likely candidates.

     

     

     

    MK

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • michaelkellett
    0 michaelkellett over 5 years ago in reply to michaelkellett

    That's the second time Roger has responded  while I'm still typing !image

     

    MK

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • ceeej
    0 ceeej over 5 years ago in reply to rew

    Never mind, I'll work it out for myself as we now seem to be bickering about how to control some other chip.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • rew
    0 rew over 5 years ago in reply to ceeej

    As far as I know you write three bytes to set a register in the 23S17 to a value, the opcode/addres, the register address and the data. If you deassert the CS each time, how would a non-addressed 23S17 be able to see the difference between the data for the other 23X17 and its address? (Assuming the data you  want in that register happens to be the address of another 23S17?)

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • adominator
    0 adominator over 5 years ago

    Well, I wish I could've gotten here earlier, but I stumbled upon this post while searching the web trying to find an answer for basically the same issue but this was while I was rewriting aspects of the BCM2835 to serve other purposes. What I found, but haven't implemented yet, is that you can modify the DLEN Register to the number of bytes you wish to send, and this can be done using Direct Memory Access(DMA) setup by the bcm2835 library through this function call: bcm2835_peri_write(bcm2835_spi0 + BCM2835_SPI0_DLEN/4, numOfBytes);

     

    BCM2835_SPI0_DLEN is divided by 4 since the addresses used are for 4 byte words so the address of the register needs to be divided by 4 in order to correct for DMA.

     

    If you want to look into this more, look at page 156 of the BCM2835 ARM Peripherals.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube