Skip to content

Commit 644c0ef

Browse files
author
Andrey Filimonov
committed
Initial ESP8266 HW SPI implementation
ILI9341 lib as a client for SPI lib
1 parent 3278e1a commit 644c0ef

File tree

24 files changed

+2225
-74
lines changed

24 files changed

+2225
-74
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#include "include\HSPI.h"
2+
#include "include\spi_register.h"
3+
4+
#define __min(a,b) ((a > b) ? (b):(a))
5+
6+
void HSPI::begin()
7+
{
8+
spi_fifo = (uint32_t*)SPI_FLASH_C0(hspi_port);
9+
//bit9 of PERIPHS_IO_MUX should be cleared when HSPI clock doesn't equal CPU clock
10+
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105);
11+
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_HSPIQ_MISO); // gpio12
12+
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_HSPID_MOSI); // gpio13
13+
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_HSPI_CLK); // gpio14
14+
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_HSPI_CS0); // gpio15
15+
16+
uint32_t regvalue = SPI_FLASH_DOUT;
17+
regvalue |= SPI_DOUTDIN | SPI_CK_I_EDGE;
18+
regvalue &= ~(BIT2 | SPI_FLASH_USR_ADDR | SPI_FLASH_USR_DUMMY | SPI_FLASH_USR_DIN | SPI_USR_COMMAND);
19+
20+
SET_PERI_REG_MASK(SPI_FLASH_USER(hspi_port), regvalue);
21+
22+
// SPI clock=CPU clock/8
23+
WRITE_PERI_REG(SPI_FLASH_CLOCK(hspi_port),
24+
((1&SPI_CLKDIV_PRE)<<SPI_CLKDIV_PRE_S)|
25+
((3&SPI_CLKCNT_N)<<SPI_CLKCNT_N_S)|
26+
((1&SPI_CLKCNT_H)<<SPI_CLKCNT_H_S)|
27+
((3&SPI_CLKCNT_L)<<SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
28+
29+
}
30+
31+
void HSPI::end()
32+
{
33+
}
34+
35+
void HSPI::setDataMode(uint8_t dataMode)
36+
{
37+
}
38+
39+
void HSPI::setBitOrder(uint8_t bitOrder)
40+
{
41+
if (!bitOrder)
42+
{
43+
WRITE_PERI_REG(SPI_FLASH_CTRL(hspi_port),
44+
READ_PERI_REG(SPI_FLASH_CTRL(hspi_port)) & (~(SPI_WR_BIT_ODER | SPI_RD_BIT_ODER)));
45+
}
46+
else
47+
{
48+
WRITE_PERI_REG(SPI_FLASH_CTRL(hspi_port),
49+
READ_PERI_REG(SPI_FLASH_CTRL(hspi_port)) | (SPI_WR_BIT_ODER | SPI_RD_BIT_ODER));
50+
}
51+
}
52+
53+
void HSPI::setClockDivider(uint8_t clockDiv)
54+
{
55+
uint32_t clock_reg_val = (((clockDiv - 1) & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) |
56+
((1 & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) |
57+
((0 & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) |
58+
((1 & SPI_CLKCNT_L) << SPI_CLKCNT_L_S);
59+
WRITE_PERI_REG(SPI_FLASH_CLOCK(hspi_port), clock_reg_val);
60+
}
61+
62+
uint8_t HSPI::transfer(uint8_t data)
63+
{
64+
hspi_wait_ready();
65+
hspi_prepare_txrx(1);
66+
*spi_fifo = data;
67+
hspi_start_tx();
68+
hspi_wait_ready();
69+
return *spi_fifo & 0xFF;
70+
}
71+
72+
uint16_t HSPI::transfer16(uint16_t data)
73+
{
74+
hspi_wait_ready();
75+
hspi_prepare_txrx(2);
76+
*spi_fifo = data;
77+
hspi_start_tx();
78+
hspi_wait_ready();
79+
return *spi_fifo & 0xFFFF;
80+
}
81+
82+
void HSPI::transfer(void *buf, size_t count)
83+
{
84+
uint32_t *_data = (uint32_t*)buf;
85+
uint8_t i;
86+
87+
uint8_t words_to_send = __min((count + 3) / 4, hspi_fifo_size);
88+
hspi_prepare_tx(count);
89+
for(i = 0; i < words_to_send;i++)
90+
spi_fifo[i] = _data[i];
91+
hspi_start_tx();
92+
}
93+
94+
95+

hardware/esp8266com/esp8266/libraries/SPI/SPI.cpp

+18-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212

1313
#include "SPI.h"
14-
#include "HSPI.h"
14+
#include "include\HSPI.h"
1515

1616
SPIClass SPI;
1717

@@ -38,13 +38,29 @@ void SPIClass::end()
3838
_impl = 0;
3939
}
4040

41+
void SPIClass::beginTransaction(SPISettings settings)
42+
{
43+
if (!_impl)
44+
return;
45+
_impl->setBitOrder(settings._bitOrder);
46+
_impl->setDataMode(settings._dataMode);
47+
_impl->setClockDivider(settings._clock);
48+
}
49+
4150
uint8_t SPIClass::transfer(uint8_t data)
4251
{
4352
if (!_impl)
44-
return;
53+
return 0;
4554
return _impl->transfer(data);
4655
}
4756

57+
uint16_t SPIClass::transfer16(uint16_t data)
58+
{
59+
if (!_impl)
60+
return 0;
61+
return _impl->transfer16(data);
62+
}
63+
4864
void SPIClass::transfer(void *buf, size_t count)
4965
{
5066
if (!_impl)

hardware/esp8266com/esp8266/libraries/SPI/SPI.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define _SPI_H_INCLUDED
1515

1616
#include <Arduino.h>
17+
#include <stdlib.h>
1718
#include "include/SPIdef.h"
1819

1920

@@ -42,11 +43,11 @@ class SPIClass
4243
void begin();
4344

4445
// void usingInterrupt(uint8_t interruptNumber);
45-
// void beginTransaction(SPISettings settings);
46+
void beginTransaction(SPISettings settings);
4647
uint8_t transfer(uint8_t data);
47-
// uint16_t transfer16(uint16_t data);
48+
uint16_t transfer16(uint16_t data);
4849
void transfer(void *buf, size_t count);
49-
// void endTransaction(void);
50+
void endTransaction(void);
5051

5152
void end();
5253

hardware/esp8266com/esp8266/libraries/SPI/include/HSPI.h

+23-66
Original file line numberDiff line numberDiff line change
@@ -14,78 +14,35 @@ extern "C" {
1414
class HSPI : public SPIImpl
1515
{
1616
public:
17-
virtual void begin()
18-
{
19-
//bit9 of PERIPHS_IO_MUX should be cleared when HSPI clock doesn't equal CPU clock
20-
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105);
21-
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_HSPIQ_MISO); // gpio12
22-
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_HSPID_MOSI); // gpio13
23-
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_HSPI_CLK); // gpio14
24-
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_HSPI_CS0); // gpio15
25-
26-
27-
SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CS_SETUP|SPI_CS_HOLD|SPI_USR_COMMAND);
28-
CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_FLASH_MODE);
29-
30-
// SPI clock=CPU clock/8
31-
WRITE_PERI_REG(SPI_CLOCK(HSPI),
32-
((1&SPI_CLKDIV_PRE)<<SPI_CLKDIV_PRE_S)|
33-
((3&SPI_CLKCNT_N)<<SPI_CLKCNT_N_S)|
34-
((1&SPI_CLKCNT_H)<<SPI_CLKCNT_H_S)|
35-
((3&SPI_CLKCNT_L)<<SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
36-
37-
38-
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_USR_COMMAND|SPI_USR_MOSI);
39-
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE);
40-
41-
//clear Daul or Quad lines transmission mode
42-
CLEAR_PERI_REG_MASK(SPI_CTRL(spi_no), SPI_QIO_MODE|SPI_DIO_MODE|SPI_DOUT_MODE|SPI_QOUT_MODE);
43-
44-
WRITE_PERI_REG(SPI_CLOCK(spi_no),
45-
((3&SPI_CLKCNT_N)<<SPI_CLKCNT_N_S)|
46-
((1&SPI_CLKCNT_H)<<SPI_CLKCNT_H_S)|
47-
((3&SPI_CLKCNT_L)<<SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
48-
49-
//set 8bit output buffer length, the buffer is the low 8bit of register"SPI_FLASH_C0"
50-
WRITE_PERI_REG(SPI_USER1(spi_no),
51-
((7&SPI_USR_MOSI_BITLEN)<<SPI_USR_MOSI_BITLEN_S)|
52-
((7&SPI_USR_MISO_BITLEN)<<SPI_USR_MISO_BITLEN_S));
53-
54-
}
55-
56-
virtual void end()
57-
{
58-
59-
}
60-
61-
virtual void setBitOrder(uint8_t bitOrder)
62-
{
63-
64-
}
65-
66-
virtual void setDataMode(uint8_t dataMode)
67-
{
68-
69-
}
17+
virtual void begin();
18+
virtual void end();
19+
virtual void setBitOrder(uint8_t bitOrder);
20+
virtual void setDataMode(uint8_t dataMode);
21+
virtual void setClockDivider(uint8_t clockDiv);
22+
virtual uint8_t transfer(uint8_t data);
23+
virtual uint16_t transfer16(uint16_t data);
24+
virtual void transfer(void *buf, size_t count);
7025

71-
virtual void setClockDivider(uint8_t clockDiv)
72-
{
73-
74-
}
26+
private:
27+
uint32_t _clkDiv;
28+
uint32_t *spi_fifo;
29+
const uint32_t hspi_port = 1;
30+
const uint32_t hspi_fifo_size = 32;
7531

76-
virtual uint8_t transfer(uint8_t data)
32+
private:
33+
inline void hspi_wait_ready(void){while (READ_PERI_REG(SPI_FLASH_CMD(hspi_port))&SPI_FLASH_USR);}
34+
inline void hspi_start_tx(){SET_PERI_REG_MASK(SPI_FLASH_CMD(hspi_port), SPI_FLASH_USR);}
35+
inline void hspi_prepare_tx(uint32_t bytecount)
7736
{
78-
37+
uint32_t bitcount = bytecount * 8 - 1;
38+
WRITE_PERI_REG(SPI_FLASH_USER1(hspi_port), (bitcount & SPI_USR_OUT_BITLEN) << SPI_USR_OUT_BITLEN_S);
7939
}
80-
81-
virtual void transfer(void *buf, size_t count)
40+
inline void hspi_prepare_txrx(uint32_t bytecount)
8241
{
83-
42+
uint32_t bitcount = bytecount * 8 - 1;
43+
WRITE_PERI_REG(SPI_FLASH_USER1(hspi_port), ((bitcount & SPI_USR_OUT_BITLEN) << SPI_USR_OUT_BITLEN_S) |
44+
((bitcount & SPI_USR_DIN_BITLEN) << SPI_USR_DIN_BITLEN_S));
8445
}
85-
86-
private:
87-
uint32_t _clkDiv;
88-
8946

9047
};
9148

hardware/esp8266com/esp8266/libraries/SPI/include/SPIImpl.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
#ifndef SPIIMPL_H
22
#define SPIIMPL_H
33

4-
#include <stdint.h>
5-
4+
#include <cstdlib>
5+
#include <Arduino.h>
66
class SPIImpl
77
{
88
public:
99
virtual void begin() = 0;
1010
virtual uint8_t transfer(uint8_t data) = 0;
11+
virtual uint16_t transfer16(uint16_t data) = 0;
1112
virtual void transfer(void *buf, size_t count) = 0;
1213
virtual void end() = 0;
1314

1415
virtual void setBitOrder(uint8_t bitOrder) = 0;
1516
virtual void setDataMode(uint8_t dataMode) = 0;
1617
virtual void setClockDivider(uint8_t clockDiv) = 0;
17-
1818
};
1919

2020

0 commit comments

Comments
 (0)