Skip to content
Snippets Groups Projects
Select Git revision
  • 9ff1ffa1a0ba33251123e9b7b7f8c233d9e2cbaa
  • main default protected
  • renovate/lock-file-maintenance
  • demo protected
  • person-select-custom
  • dbp-translation-component
  • icon-set-mapping
  • port-i18next-parser
  • remove-sentry
  • favorites-and-recent-files
  • revert-6c632dc6
  • lit2
  • advertisement
  • wc-part
  • automagic
  • publish
  • wip-cleanup
  • demo-file-handling
18 results

i18next.js

Blame
  • spi.c 8.05 KiB
    /*
     * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
     *
     * SPDX-License-Identifier: BSD-3-Clause
     */
    
    #include "hardware/resets.h"
    #include "hardware/clocks.h"
    #include "hardware/spi.h"
    
    static inline void spi_reset(spi_inst_t *spi) {
        invalid_params_if(SPI, spi != spi0 && spi != spi1);
        reset_block(spi == spi0 ? RESETS_RESET_SPI0_BITS : RESETS_RESET_SPI1_BITS);
    }
    
    static inline void spi_unreset(spi_inst_t *spi) {
        invalid_params_if(SPI, spi != spi0 && spi != spi1);
        unreset_block_wait(spi == spi0 ? RESETS_RESET_SPI0_BITS : RESETS_RESET_SPI1_BITS);
    }
    
    uint spi_init(spi_inst_t *spi, uint baudrate) {
        spi_reset(spi);
        spi_unreset(spi);
    
        uint baud = spi_set_baudrate(spi, baudrate);
        spi_set_format(spi, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
        // Always enable DREQ signals -- harmless if DMA is not listening
        hw_set_bits(&spi_get_hw(spi)->dmacr, SPI_SSPDMACR_TXDMAE_BITS | SPI_SSPDMACR_RXDMAE_BITS);
    
        // Finally enable the SPI
        hw_set_bits(&spi_get_hw(spi)->cr1, SPI_SSPCR1_SSE_BITS);
    
        return baud;
    }
    
    void spi_deinit(spi_inst_t *spi) {
        hw_clear_bits(&spi_get_hw(spi)->cr1, SPI_SSPCR1_SSE_BITS);
        hw_clear_bits(&spi_get_hw(spi)->dmacr, SPI_SSPDMACR_TXDMAE_BITS | SPI_SSPDMACR_RXDMAE_BITS);
        spi_reset(spi);
    }
    
    uint spi_set_baudrate(spi_inst_t *spi, uint baudrate) {
        uint freq_in = clock_get_hz(clk_peri);
        uint prescale, postdiv;
        invalid_params_if(SPI, baudrate > freq_in);
    
        // Disable the SPI
        uint32_t enable_mask = spi_get_hw(spi)->cr1 & SPI_SSPCR1_SSE_BITS;
        hw_clear_bits(&spi_get_hw(spi)->cr1, SPI_SSPCR1_SSE_BITS);
    
        // Find smallest prescale value which puts output frequency in range of
        // post-divide. Prescale is an even number from 2 to 254 inclusive.
        for (prescale = 2; prescale <= 254; prescale += 2) {
            if (freq_in < prescale * 256 * (uint64_t) baudrate)
                break;
        }
        invalid_params_if(SPI, prescale > 254); // Frequency too low
    
        // Find largest post-divide which makes output <= baudrate. Post-divide is
        // an integer in the range 1 to 256 inclusive.
        for (postdiv = 256; postdiv > 1; --postdiv) {
            if (freq_in / (prescale * (postdiv - 1)) > baudrate)
                break;
        }
    
        spi_get_hw(spi)->cpsr = prescale;
        hw_write_masked(&spi_get_hw(spi)->cr0, (postdiv - 1) << SPI_SSPCR0_SCR_LSB, SPI_SSPCR0_SCR_BITS);
    
        // Re-enable the SPI
        hw_set_bits(&spi_get_hw(spi)->cr1, enable_mask);