summaryrefslogtreecommitdiffstatshomepage
path: root/esp8266/hspi.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2017-09-06 13:40:51 +1000
committerDamien George <damien.p.george@gmail.com>2017-09-06 13:40:51 +1000
commit01dd7804b87d60b2deab16712eccb3b97351a9b7 (patch)
tree1aa21f38a872b8e62a3d4e4f74f68033c6f827e4 /esp8266/hspi.c
parenta9862b30068fc9df1022f08019fb35aaa5085f64 (diff)
downloadmicropython-01dd7804b87d60b2deab16712eccb3b97351a9b7.tar.gz
micropython-01dd7804b87d60b2deab16712eccb3b97351a9b7.zip
ports: Make new ports/ sub-directory and move all ports there.
This is to keep the top-level directory clean, to make it clear what is core and what is a port, and to allow the repository to grow with new ports in a sustainable way.
Diffstat (limited to 'esp8266/hspi.c')
-rw-r--r--esp8266/hspi.c331
1 files changed, 0 insertions, 331 deletions
diff --git a/esp8266/hspi.c b/esp8266/hspi.c
deleted file mode 100644
index 554a50460f..0000000000
--- a/esp8266/hspi.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
-* The MIT License (MIT)
-*
-* Copyright (c) 2015 David Ogilvy (MetalPhreak)
-* Modified 2016 by Radomir Dopieralski
-*
-* Permission is hereby granted, free of charge, to any person obtaining a copy
-* of this software and associated documentation files (the "Software"), to deal
-* in the Software without restriction, including without limitation the rights
-* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-* copies of the Software, and to permit persons to whom the Software is
-* furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included in all
-* copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-* SOFTWARE.
-*/
-
-#include "hspi.h"
-
-/*
-Wrapper to setup HSPI/SPI GPIO pins and default SPI clock
- spi_no - SPI (0) or HSPI (1)
-Not used in MicroPython.
-*/
-void spi_init(uint8_t spi_no) {
- spi_init_gpio(spi_no, SPI_CLK_USE_DIV);
- spi_clock(spi_no, SPI_CLK_PREDIV, SPI_CLK_CNTDIV);
- spi_tx_byte_order(spi_no, SPI_BYTE_ORDER_HIGH_TO_LOW);
- spi_rx_byte_order(spi_no, SPI_BYTE_ORDER_HIGH_TO_LOW);
-
- SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD);
- CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE);
-}
-
-
-/*
-Configures SPI mode parameters for clock edge and clock polarity.
- spi_no - SPI (0) or HSPI (1)
- spi_cpha - (0) Data is valid on clock leading edge
- (1) Data is valid on clock trailing edge
- spi_cpol - (0) Clock is low when inactive
- (1) Clock is high when inactive
-For MicroPython this version is different from original.
-*/
-void spi_mode(uint8_t spi_no, uint8_t spi_cpha, uint8_t spi_cpol) {
- if (spi_cpol) {
- SET_PERI_REG_MASK(SPI_PIN(HSPI), SPI_IDLE_EDGE);
- } else {
- CLEAR_PERI_REG_MASK(SPI_PIN(HSPI), SPI_IDLE_EDGE);
- }
- if (spi_cpha == spi_cpol) {
- // Mode 3 - MOSI is set on falling edge of clock
- // Mode 0 - MOSI is set on falling edge of clock
- CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_OUT_EDGE);
- SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_I_EDGE);
- } else {
- // Mode 2 - MOSI is set on rising edge of clock
- // Mode 1 - MOSI is set on rising edge of clock
- SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_OUT_EDGE);
- CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_I_EDGE);
- }
-}
-
-
-/*
-Initialise the GPIO pins for use as SPI pins.
- spi_no - SPI (0) or HSPI (1)
- sysclk_as_spiclk -
- SPI_CLK_80MHZ_NODIV (1) if using 80MHz for SPI clock.
- SPI_CLK_USE_DIV (0) if using divider for lower speed.
-*/
-void spi_init_gpio(uint8_t spi_no, uint8_t sysclk_as_spiclk) {
- uint32_t clock_div_flag = 0;
- if (sysclk_as_spiclk) {
- clock_div_flag = 0x0001;
- }
- if (spi_no == SPI) {
- // Set bit 8 if 80MHz sysclock required
- WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005 | (clock_div_flag<<8));
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);
- } else if (spi_no == HSPI) {
- // Set bit 9 if 80MHz sysclock required
- WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div_flag<<9));
- // GPIO12 is HSPI MISO pin (Master Data In)
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);
- // GPIO13 is HSPI MOSI pin (Master Data Out)
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);
- // GPIO14 is HSPI CLK pin (Clock)
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);
- // GPIO15 is HSPI CS pin (Chip Select / Slave Select)
- // In MicroPython, we are handling CS ourself in drivers.
- // PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);
- }
-}
-
-
-/*
-Set up the control registers for the SPI clock
- spi_no - SPI (0) or HSPI (1)
- prediv - predivider value (actual division value)
- cntdiv - postdivider value (actual division value)
-Set either divider to 0 to disable all division (80MHz sysclock)
-*/
-void spi_clock(uint8_t spi_no, uint16_t prediv, uint8_t cntdiv) {
- if (prediv == 0 || cntdiv == 0) {
- WRITE_PERI_REG(SPI_CLOCK(spi_no), SPI_CLK_EQU_SYSCLK);
- } else {
- WRITE_PERI_REG(SPI_CLOCK(spi_no),
- (((prediv - 1) & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) |
- (((cntdiv - 1) & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) |
- (((cntdiv >> 1) & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) |
- ((0 & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)
- );
- }
-}
-
-
-/*
-Setup the byte order for shifting data out of buffer
- spi_no - SPI (0) or HSPI (1)
- byte_order -
- SPI_BYTE_ORDER_HIGH_TO_LOW (1)
- Data is sent out starting with Bit31 and down to Bit0
- SPI_BYTE_ORDER_LOW_TO_HIGH (0)
- Data is sent out starting with the lowest BYTE, from MSB to LSB,
- followed by the second lowest BYTE, from MSB to LSB, followed by
- the second highest BYTE, from MSB to LSB, followed by the highest
- BYTE, from MSB to LSB 0xABCDEFGH would be sent as 0xGHEFCDAB.
-*/
-void spi_tx_byte_order(uint8_t spi_no, uint8_t byte_order) {
- if (byte_order) {
- SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_WR_BYTE_ORDER);
- } else {
- CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_WR_BYTE_ORDER);
- }
-}
-
-
-/*
-Setup the byte order for shifting data into buffer
- spi_no - SPI (0) or HSPI (1)
- byte_order -
- SPI_BYTE_ORDER_HIGH_TO_LOW (1)
- Data is read in starting with Bit31 and down to Bit0
- SPI_BYTE_ORDER_LOW_TO_HIGH (0)
- Data is read in starting with the lowest BYTE, from MSB to LSB,
- followed by the second lowest BYTE, from MSB to LSB, followed by
- the second highest BYTE, from MSB to LSB, followed by the highest
- BYTE, from MSB to LSB 0xABCDEFGH would be read as 0xGHEFCDAB
-*/
-void spi_rx_byte_order(uint8_t spi_no, uint8_t byte_order) {
- if (byte_order) {
- SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_RD_BYTE_ORDER);
- } else {
- CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_RD_BYTE_ORDER);
- }
-}
-
-
-/*
-SPI transaction function
- spi_no - SPI (0) or HSPI (1)
- cmd_bits - actual number of bits to transmit
- cmd_data - command data
- addr_bits - actual number of bits to transmit
- addr_data - address data
- dout_bits - actual number of bits to transmit
- dout_data - output data
- din_bits - actual number of bits to receive
-Returns: read data - uint32_t containing read in data only if RX was set
- 0 - something went wrong (or actual read data was 0)
- 1 - data sent ok (or actual read data is 1)
-Note: all data is assumed to be stored in the lower bits of the data variables
-(for anything <32 bits).
-*/
-uint32_t spi_transaction(uint8_t spi_no, uint8_t cmd_bits, uint16_t cmd_data,
- uint32_t addr_bits, uint32_t addr_data,
- uint32_t dout_bits, uint32_t dout_data,
- uint32_t din_bits, uint32_t dummy_bits) {
- while (spi_busy(spi_no)) {}; // Wait for SPI to be ready
-
-// Enable SPI Functions
- // Disable MOSI, MISO, ADDR, COMMAND, DUMMY in case previously set.
- CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI | SPI_USR_MISO |
- SPI_USR_COMMAND | SPI_USR_ADDR | SPI_USR_DUMMY);
-
- // Enable functions based on number of bits. 0 bits = disabled.
- // This is rather inefficient but allows for a very generic function.
- // CMD ADDR and MOSI are set below to save on an extra if statement.
- if (din_bits) {
- if (dout_bits) {
- SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_DOUTDIN);
- } else {
- SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MISO);
- }
- }
- if (dummy_bits) {
- SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_DUMMY);
- }
-
-// Setup Bitlengths
- WRITE_PERI_REG(SPI_USER1(spi_no),
- // Number of bits in Address
- ((addr_bits - 1) & SPI_USR_ADDR_BITLEN) << SPI_USR_ADDR_BITLEN_S |
- // Number of bits to Send
- ((dout_bits - 1) & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S |
- // Number of bits to receive
- ((din_bits - 1) & SPI_USR_MISO_BITLEN) << SPI_USR_MISO_BITLEN_S |
- // Number of Dummy bits to insert
- ((dummy_bits - 1) & SPI_USR_DUMMY_CYCLELEN) << SPI_USR_DUMMY_CYCLELEN_S);
-
-// Setup Command Data
- if (cmd_bits) {
- // Enable COMMAND function in SPI module
- SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_COMMAND);
- // Align command data to high bits
- uint16_t command = cmd_data << (16-cmd_bits);
- // Swap byte order
- command = ((command>>8)&0xff) | ((command<<8)&0xff00);
- WRITE_PERI_REG(SPI_USER2(spi_no), (
- (((cmd_bits - 1) & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) |
- (command & SPI_USR_COMMAND_VALUE)
- ));
- }
-
-// Setup Address Data
- if (addr_bits) {
- // Enable ADDRess function in SPI module
- SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_ADDR);
- // Align address data to high bits
- WRITE_PERI_REG(SPI_ADDR(spi_no), addr_data << (32 - addr_bits));
- }
-
-// Setup DOUT data
- if (dout_bits) {
- // Enable MOSI function in SPI module
- SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI);
- // Copy data to W0
- if (READ_PERI_REG(SPI_USER(spi_no))&SPI_WR_BYTE_ORDER) {
- WRITE_PERI_REG(SPI_W0(spi_no), dout_data << (32 - dout_bits));
- } else {
- uint8_t dout_extra_bits = dout_bits%8;
-
- if (dout_extra_bits) {
- // If your data isn't a byte multiple (8/16/24/32 bits) and you
- // don't have SPI_WR_BYTE_ORDER set, you need this to move the
- // non-8bit remainder to the MSBs. Not sure if there's even a use
- // case for this, but it's here if you need it... For example,
- // 0xDA4 12 bits without SPI_WR_BYTE_ORDER would usually be output
- // as if it were 0x0DA4, of which 0xA4, and then 0x0 would be
- // shifted out (first 8 bits of low byte, then 4 MSB bits of high
- // byte - ie reverse byte order).
- // The code below shifts it out as 0xA4 followed by 0xD as you
- // might require.
- WRITE_PERI_REG(SPI_W0(spi_no), (
- (0xFFFFFFFF << (dout_bits - dout_extra_bits) & dout_data)
- << (8-dout_extra_bits) |
- ((0xFFFFFFFF >> (32 - (dout_bits - dout_extra_bits)))
- & dout_data)
- ));
- } else {
- WRITE_PERI_REG(SPI_W0(spi_no), dout_data);
- }
- }
-}
-
-// Begin SPI Transaction
- SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);
-
-// Return DIN data
- if (din_bits) {
- while (spi_busy(spi_no)) {}; // Wait for SPI transaction to complete
- if (READ_PERI_REG(SPI_USER(spi_no))&SPI_RD_BYTE_ORDER) {
- // Assuming data in is written to MSB. TBC
- return READ_PERI_REG(SPI_W0(spi_no)) >> (32 - din_bits);
- } else {
- // Read in the same way as DOUT is sent. Note existing contents of
- // SPI_W0 remain unless overwritten!
- return READ_PERI_REG(SPI_W0(spi_no));
- }
- return 0; // Something went wrong
- }
-
- // Transaction completed
- return 1; // Success
-}
-
-
-/*
-Just do minimal work needed to send 8 bits.
-*/
-inline void spi_tx8fast(uint8_t spi_no, uint8_t dout_data) {
- while (spi_busy(spi_no)) {}; // Wait for SPI to be ready
-
-// Enable SPI Functions
- // Disable MOSI, MISO, ADDR, COMMAND, DUMMY in case previously set.
- CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI | SPI_USR_MISO |
- SPI_USR_COMMAND | SPI_USR_ADDR | SPI_USR_DUMMY);
-
-// Setup Bitlengths
- WRITE_PERI_REG(SPI_USER1(spi_no),
- // Number of bits to Send
- ((8 - 1) & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S |
- // Number of bits to receive
- ((8 - 1) & SPI_USR_MISO_BITLEN) << SPI_USR_MISO_BITLEN_S);
-
-
-// Setup DOUT data
- // Enable MOSI function in SPI module
- SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI);
- // Copy data to W0
- if (READ_PERI_REG(SPI_USER(spi_no)) & SPI_WR_BYTE_ORDER) {
- WRITE_PERI_REG(SPI_W0(spi_no), dout_data << (32 - 8));
- } else {
- WRITE_PERI_REG(SPI_W0(spi_no), dout_data);
- }
-
-// Begin SPI Transaction
- SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);
-}