Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
Nodemcu Firmware
Commits
9cde0bbb
Commit
9cde0bbb
authored
Oct 08, 2015
by
devsaurus
Browse files
add SPI transaction support
parent
8c419b8a
Changes
5
Hide whitespace changes
Inline
Side-by-side
app/driver/spi.c
View file @
9cde0bbb
...
@@ -85,26 +85,27 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, unsigned databi
...
@@ -85,26 +85,27 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, unsigned databi
PIN_FUNC_SELECT
(
PERIPHS_IO_MUX_MTDO_U
,
2
);
//configure io to spi mode
PIN_FUNC_SELECT
(
PERIPHS_IO_MUX_MTDO_U
,
2
);
//configure io to spi mode
}
}
SET_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_CS_SETUP
|
SPI_CS_HOLD
|
SPI_DOUTDIN
|
SPI_USR_MOSI
);
SET_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_CS_SETUP
|
SPI_CS_HOLD
|
SPI_DOUTDIN
|
SPI_USR_MOSI
|
SPI_RD_BYTE_ORDER
|
SPI_WR_BYTE_ORDER
);
//set clock polarity
// TODO: This doesn't work
//set clock polarity
//if (cpol == 1) {
// TODO: This doesn't work
// SET_PERI_REG_MASK(SPI_CTRL2(spi_no), (SPI_CK_OUT_HIGH_MODE<<SPI_CK_OUT_HIGH_MODE_S));
//if (cpol == 1) {
//} else {
// SET_PERI_REG_MASK(SPI_CTRL2(spi_no), (SPI_CK_OUT_HIGH_MODE<<SPI_CK_OUT_HIGH_MODE_S));
// SET_PERI_REG_MASK(SPI_CTRL2(spi_no), (SPI_CK_OUT_LOW_MODE<<SPI_CK_OUT_LOW_MODE_S));
//} else {
//}
// SET_PERI_REG_MASK(SPI_CTRL2(spi_no), (SPI_CK_OUT_LOW_MODE<<SPI_CK_OUT_LOW_MODE_S));
//os_printf("SPI_CTRL2 is %08x\n",READ_PERI_REG(SPI_CTRL2(spi_no)));
//}
//os_printf("SPI_CTRL2 is %08x\n",READ_PERI_REG(SPI_CTRL2(spi_no)));
//set clock phase
if
(
cpha
==
1
)
{
//set clock phase
SET_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_CK_OUT_EDGE
|
SPI_CK_I_EDGE
);
if
(
cpha
==
1
)
{
}
else
{
SET_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_CK_OUT_EDGE
|
SPI_CK_I_EDGE
);
CLEAR_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_CK_OUT_EDGE
|
SPI_CK_I_EDGE
);
}
else
{
}
CLEAR_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_CK_OUT_EDGE
|
SPI_CK_I_EDGE
);
}
CLEAR_PERI_REG_MASK
(
SPI_USER
(
HSPI
),
SPI_FLASH_MODE
|
SPI_
WR_BYTE_ORDER
|
SPI_
USR_MISO
|
CLEAR_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_FLASH_MODE
|
SPI_USR_MISO
|
SPI_RD_BYTE_ORDER
|
SPI_USR_ADDR
|
SPI_USR_COMMAND
|
SPI_USR_DUMMY
);
SPI_USR_ADDR
|
SPI_USR_COMMAND
|
SPI_USR_DUMMY
);
//clear Daul or Quad lines transmission mode
//clear Daul or Quad lines transmission mode
CLEAR_PERI_REG_MASK
(
SPI_CTRL
(
spi_no
),
SPI_QIO_MODE
|
SPI_DIO_MODE
|
SPI_DOUT_MODE
|
SPI_QOUT_MODE
);
CLEAR_PERI_REG_MASK
(
SPI_CTRL
(
spi_no
),
SPI_QIO_MODE
|
SPI_DIO_MODE
|
SPI_DOUT_MODE
|
SPI_QOUT_MODE
);
...
@@ -151,6 +152,126 @@ void spi_mast_byte_write(uint8 spi_no, uint8 *data)
...
@@ -151,6 +152,126 @@ void spi_mast_byte_write(uint8 spi_no, uint8 *data)
*
data
=
(
uint8
)(
READ_PERI_REG
(
SPI_W0
(
spi_no
))
&
0xff
);
*
data
=
(
uint8
)(
READ_PERI_REG
(
SPI_W0
(
spi_no
))
&
0xff
);
}
}
/******************************************************************************
* FunctionName : spi_mast_set_mosi
* Description : Enter provided data into MOSI buffer.
* The data is regarded as a sequence of bits with length 'bitlen'.
* It will be written left-aligned starting from position 'offset'.
* Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
* uint8 offset - offset into MOSI buffer (number of bits)
* uint8 bitlen - valid number of bits in data
* uint32 data - data to be written into buffer
*******************************************************************************/
void
spi_mast_set_mosi
(
uint8
spi_no
,
uint8
offset
,
uint8
bitlen
,
uint32
data
)
{
uint8
wn
,
wn_offset
,
wn_bitlen
;
uint32
wn_data
;
if
(
spi_no
>
1
)
return
;
// handle invalid input number
if
(
bitlen
>
32
)
return
;
// handle invalid input number
while
(
READ_PERI_REG
(
SPI_CMD
(
spi_no
))
&
SPI_USR
);
// determine which SPI_Wn register is addressed
wn
=
offset
>>
5
;
if
(
wn
>
15
)
return
;
// out of range
wn_offset
=
offset
&
0x1f
;
if
(
32
-
wn_offset
<
bitlen
)
{
// splitting required
wn_bitlen
=
32
-
wn_offset
;
wn_data
=
data
>>
(
bitlen
-
wn_bitlen
);
}
else
{
wn_bitlen
=
bitlen
;
wn_data
=
data
;
}
do
{
// write payload data to SPI_Wn
SET_PERI_REG_BITS
(
REG_SPI_BASE
(
spi_no
)
+
0x40
+
wn
*
4
,
BIT
(
wn_bitlen
)
-
1
,
wn_data
,
32
-
(
wn_offset
+
wn_bitlen
));
// prepare writing of dangling data part
wn
+=
1
;
wn_offset
=
0
;
if
(
wn
<=
15
)
bitlen
-=
wn_bitlen
;
else
bitlen
=
0
;
// force abort
wn_bitlen
=
bitlen
;
wn_data
=
data
;
}
while
(
bitlen
>
0
);
}
/******************************************************************************
* FunctionName : spi_mast_transaction
* Description : Start a transaction and wait for completion.
* Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
* uint8 cmd_bitlen - Valid number of bits in cmd_data.
* uint16 cmd_data - Command data.
* uint8 addr_bitlen - Valid number of bits in addr_data.
* uint32 addr_data - Address data.
* uint8 mosi_bitlen - Valid number of bits in MOSI buffer.
* uint8 dummy_bitlen - Number of dummy cycles.
* uint8 miso_bitlen - number of bits to be captured in MISO buffer.
*******************************************************************************/
void
spi_mast_transaction
(
uint8
spi_no
,
uint8
cmd_bitlen
,
uint16
cmd_data
,
uint8
addr_bitlen
,
uint32
addr_data
,
uint8
mosi_bitlen
,
uint8
dummy_bitlen
,
uint8
miso_bitlen
)
{
if
(
spi_no
>
1
)
return
;
// handle invalid input number
while
(
READ_PERI_REG
(
SPI_CMD
(
spi_no
))
&
SPI_USR
);
// default disable COMMAND, ADDR, MOSI, DUMMY, MISO
CLEAR_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_USR_COMMAND
|
SPI_USR_ADDR
|
SPI_USR_MOSI
|
SPI_USR_DUMMY
|
SPI_USR_MISO
);
// default set bit lengths
WRITE_PERI_REG
(
SPI_USER1
(
spi_no
),
((
addr_bitlen
-
1
)
&
SPI_USR_ADDR_BITLEN
)
<<
SPI_USR_ADDR_BITLEN_S
|
((
mosi_bitlen
-
1
)
&
SPI_USR_MOSI_BITLEN
)
<<
SPI_USR_MOSI_BITLEN_S
|
((
dummy_bitlen
-
1
)
&
SPI_USR_DUMMY_CYCLELEN
)
<<
SPI_USR_DUMMY_CYCLELEN_S
|
((
miso_bitlen
-
1
)
&
SPI_USR_MISO_BITLEN
)
<<
SPI_USR_MISO_BITLEN_S
);
// handle the transaction components
if
(
cmd_bitlen
>
0
)
{
uint16
cmd
=
cmd_data
<<
(
16
-
cmd_bitlen
);
// align to MSB
cmd
=
(
cmd
>>
8
)
|
(
cmd
<<
8
);
// swap byte order
WRITE_PERI_REG
(
SPI_USER2
(
spi_no
),
((
cmd_bitlen
-
1
&
SPI_USR_COMMAND_BITLEN
)
<<
SPI_USR_COMMAND_BITLEN_S
)
|
(
cmd
&
SPI_USR_COMMAND_VALUE
));
SET_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_USR_COMMAND
);
}
if
(
addr_bitlen
>
0
)
{
WRITE_PERI_REG
(
SPI_ADDR
(
spi_no
),
addr_data
<<
(
32
-
addr_bitlen
));
SET_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_USR_ADDR
);
}
if
(
mosi_bitlen
>
0
)
{
SET_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_USR_MOSI
);
}
if
(
dummy_bitlen
>
0
)
{
SET_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_USR_DUMMY
);
}
if
(
miso_bitlen
>
0
)
{
SET_PERI_REG_MASK
(
SPI_USER
(
spi_no
),
SPI_USR_MISO
);
}
// start transaction
SET_PERI_REG_MASK
(
SPI_CMD
(
spi_no
),
SPI_USR
);
while
(
READ_PERI_REG
(
SPI_CMD
(
spi_no
))
&
SPI_USR
);
}
/******************************************************************************
/******************************************************************************
* FunctionName : spi_byte_write_espslave
* FunctionName : spi_byte_write_espslave
* Description : SPI master 1 byte transmission function for esp8266 slave,
* Description : SPI master 1 byte transmission function for esp8266 slave,
...
...
app/include/driver/spi.h
View file @
9cde0bbb
...
@@ -22,6 +22,10 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, unsigned databi
...
@@ -22,6 +22,10 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, unsigned databi
//use spi send 8bit data
//use spi send 8bit data
void
spi_mast_byte_write
(
uint8
spi_no
,
uint8
*
data
);
void
spi_mast_byte_write
(
uint8
spi_no
,
uint8
*
data
);
void
spi_set_mosi
(
uint8
spi_no
,
uint8
offset
,
uint8
bitlen
,
uint32
data
);
void
spi_mast_transaction
(
uint8
spi_no
,
uint8
cmd_bitlen
,
uint16
cmd_data
,
uint8
addr_bitlen
,
uint32
addr_data
,
uint8
mosi_bitlen
,
uint8
dummy_bitlen
,
uint8
miso_bitlen
);
//transmit data to esp8266 slave buffer,which needs 16bit transmission ,
//transmit data to esp8266 slave buffer,which needs 16bit transmission ,
//first byte is master command 0x04, second byte is master data
//first byte is master command 0x04, second byte is master data
void
spi_byte_write_espslave
(
uint8
spi_no
,
uint8
data
);
void
spi_byte_write_espslave
(
uint8
spi_no
,
uint8
data
);
...
...
app/modules/spi.c
View file @
9cde0bbb
...
@@ -57,7 +57,7 @@ static int spi_send( lua_State *L )
...
@@ -57,7 +57,7 @@ static int spi_send( lua_State *L )
MOD_CHECK_ID
(
spi
,
id
);
MOD_CHECK_ID
(
spi
,
id
);
if
(
lua_gettop
(
L
)
<
2
)
if
(
lua_gettop
(
L
)
<
2
)
return
luaL_error
(
L
,
"
wrong arg type
"
);
return
luaL_error
(
L
,
"
too few args
"
);
for
(
argn
=
2
;
argn
<=
lua_gettop
(
L
);
argn
++
)
for
(
argn
=
2
;
argn
<=
lua_gettop
(
L
);
argn
++
)
{
{
...
@@ -68,7 +68,7 @@ static int spi_send( lua_State *L )
...
@@ -68,7 +68,7 @@ static int spi_send( lua_State *L )
numdata
=
(
int
)
luaL_checkinteger
(
L
,
argn
);
numdata
=
(
int
)
luaL_checkinteger
(
L
,
argn
);
if
(
numdata
<
0
||
numdata
>
255
)
if
(
numdata
<
0
||
numdata
>
255
)
return
luaL_error
(
L
,
"wrong arg range"
);
return
luaL_error
(
L
,
"wrong arg range"
);
platform_spi_
send_recv
(
id
,
numdata
);
platform_spi_
transaction
(
id
,
8
,
numdata
,
0
,
0
,
0
,
0
,
0
);
wrote
++
;
wrote
++
;
}
}
else
if
(
lua_istable
(
L
,
argn
)
)
else
if
(
lua_istable
(
L
,
argn
)
)
...
@@ -81,7 +81,7 @@ static int spi_send( lua_State *L )
...
@@ -81,7 +81,7 @@ static int spi_send( lua_State *L )
lua_pop
(
L
,
1
);
lua_pop
(
L
,
1
);
if
(
numdata
<
0
||
numdata
>
255
)
if
(
numdata
<
0
||
numdata
>
255
)
return
luaL_error
(
L
,
"wrong arg range"
);
return
luaL_error
(
L
,
"wrong arg range"
);
platform_spi_
send_recv
(
id
,
numdata
);
platform_spi_
transaction
(
id
,
8
,
numdata
,
0
,
0
,
0
,
0
,
0
);
}
}
wrote
+=
i
;
wrote
+=
i
;
if
(
i
<
datalen
)
if
(
i
<
datalen
)
...
@@ -91,7 +91,7 @@ static int spi_send( lua_State *L )
...
@@ -91,7 +91,7 @@ static int spi_send( lua_State *L )
{
{
pdata
=
luaL_checklstring
(
L
,
argn
,
&
datalen
);
pdata
=
luaL_checklstring
(
L
,
argn
,
&
datalen
);
for
(
i
=
0
;
i
<
datalen
;
i
++
)
for
(
i
=
0
;
i
<
datalen
;
i
++
)
platform_spi_
send_recv
(
id
,
pdata
[
i
]
);
platform_spi_
transaction
(
id
,
8
,
pdata
[
i
]
,
0
,
0
,
0
,
0
,
0
);
wrote
+=
i
;
wrote
+=
i
;
if
(
i
<
datalen
)
if
(
i
<
datalen
)
break
;
break
;
...
@@ -126,14 +126,89 @@ static int spi_recv( lua_State *L )
...
@@ -126,14 +126,89 @@ static int spi_recv( lua_State *L )
return
1
;
return
1
;
}
}
// Lua: spi.set_mosi( id, offset, bitlen, data1, [data2], ..., [datan] )
static
int
spi_set_mosi
(
lua_State
*
L
)
{
unsigned
id
=
luaL_checkinteger
(
L
,
1
);
unsigned
offset
=
luaL_checkinteger
(
L
,
2
);
unsigned
bitlen
=
luaL_checkinteger
(
L
,
3
);
unsigned
argn
;
MOD_CHECK_ID
(
spi
,
id
);
if
(
offset
<
0
||
offset
>
511
)
{
return
luaL_error
(
L
,
"offset out of range"
);
}
if
(
bitlen
<
1
||
bitlen
>
32
)
{
return
luaL_error
(
L
,
"bitlen out of range"
);
}
if
(
lua_gettop
(
L
)
<
4
)
{
return
luaL_error
(
L
,
"too few args"
);
}
for
(
argn
=
4
;
argn
<=
lua_gettop
(
L
);
argn
++
,
offset
+=
bitlen
)
{
u32
data
=
luaL_checkinteger
(
L
,
argn
);
if
(
offset
+
bitlen
>
512
)
return
luaL_error
(
L
,
"data range exceeded > 512 bits"
);
if
(
platform_spi_set_mosi
(
id
,
offset
,
bitlen
,
data
)
!=
PLATFORM_OK
)
return
luaL_error
(
L
,
"failed"
);
}
return
0
;
}
// Lua: spi.transaction( id, cmd_bitlen, cmd_data, addr_bitlen, addr_data, mosi_bitlen, dummy_bitlen, miso_bitlen )
static
int
spi_transaction
(
lua_State
*
L
)
{
unsigned
id
=
luaL_checkinteger
(
L
,
1
);
unsigned
cmd_bitlen
=
luaL_checkinteger
(
L
,
2
);
u32
cmd_data
=
luaL_checkinteger
(
L
,
3
);
unsigned
addr_bitlen
=
luaL_checkinteger
(
L
,
4
);
u32
addr_data
=
luaL_checkinteger
(
L
,
5
);
unsigned
mosi_bitlen
=
luaL_checkinteger
(
L
,
6
);
unsigned
dummy_bitlen
=
luaL_checkinteger
(
L
,
7
);
unsigned
miso_bitlen
=
luaL_checkinteger
(
L
,
8
);
MOD_CHECK_ID
(
spi
,
id
);
if
(
cmd_bitlen
<
0
||
cmd_bitlen
>
16
)
{
return
luaL_error
(
L
,
"cmd_bitlen out of range"
);
}
if
(
addr_bitlen
<
0
||
addr_bitlen
>
32
)
{
return
luaL_error
(
L
,
"addr_bitlen out of range"
);
}
if
(
mosi_bitlen
<
0
||
mosi_bitlen
>
512
)
{
return
luaL_error
(
L
,
"mosi_bitlen out of range"
);
}
if
(
dummy_bitlen
<
0
||
dummy_bitlen
>
256
)
{
return
luaL_error
(
L
,
"dummy_bitlen out of range"
);
}
if
(
miso_bitlen
<
0
||
miso_bitlen
>
511
)
{
return
luaL_error
(
L
,
"miso_bitlen out of range"
);
}
if
(
platform_spi_transaction
(
id
,
cmd_bitlen
,
cmd_data
,
addr_bitlen
,
addr_data
,
mosi_bitlen
,
dummy_bitlen
,
miso_bitlen
)
!=
PLATFORM_OK
)
return
luaL_error
(
L
,
"failed"
);
return
0
;
}
// Module function map
// Module function map
#define MIN_OPT_LEVEL 2
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
#include "lrodefs.h"
const
LUA_REG_TYPE
spi_map
[]
=
const
LUA_REG_TYPE
spi_map
[]
=
{
{
{
LSTRKEY
(
"setup"
),
LFUNCVAL
(
spi_setup
)
},
{
LSTRKEY
(
"setup"
),
LFUNCVAL
(
spi_setup
)
},
{
LSTRKEY
(
"send"
),
LFUNCVAL
(
spi_send
)
},
{
LSTRKEY
(
"send"
),
LFUNCVAL
(
spi_send
)
},
{
LSTRKEY
(
"recv"
),
LFUNCVAL
(
spi_recv
)
},
{
LSTRKEY
(
"recv"
),
LFUNCVAL
(
spi_recv
)
},
{
LSTRKEY
(
"set_mosi"
),
LFUNCVAL
(
spi_set_mosi
)
},
{
LSTRKEY
(
"transaction"
),
LFUNCVAL
(
spi_transaction
)
},
#if LUA_OPTIMIZE_MEMORY > 0
#if LUA_OPTIMIZE_MEMORY > 0
{
LSTRKEY
(
"MASTER"
),
LNUMVAL
(
PLATFORM_SPI_MASTER
)
},
{
LSTRKEY
(
"MASTER"
),
LNUMVAL
(
PLATFORM_SPI_MASTER
)
},
{
LSTRKEY
(
"SLAVE"
),
LNUMVAL
(
PLATFORM_SPI_SLAVE
)
},
{
LSTRKEY
(
"SLAVE"
),
LNUMVAL
(
PLATFORM_SPI_SLAVE
)
},
...
...
app/platform/platform.c
View file @
9cde0bbb
...
@@ -449,6 +449,32 @@ spi_data_type platform_spi_send_recv( unsigned id, spi_data_type data )
...
@@ -449,6 +449,32 @@ spi_data_type platform_spi_send_recv( unsigned id, spi_data_type data )
return
data
;
return
data
;
}
}
int
platform_spi_set_mosi
(
uint8_t
id
,
uint8_t
offset
,
uint8_t
bitlen
,
spi_data_type
data
)
{
if
(
offset
+
bitlen
>
512
)
return
PLATFORM_ERR
;
spi_mast_set_mosi
(
id
,
offset
,
bitlen
,
data
);
return
PLATFORM_OK
;
}
int
platform_spi_transaction
(
uint8_t
id
,
uint8_t
cmd_bitlen
,
spi_data_type
cmd_data
,
uint8_t
addr_bitlen
,
spi_data_type
addr_data
,
uint8_t
mosi_bitlen
,
uint8_t
dummy_bitlen
,
uint8_t
miso_bitlen
)
{
if
((
cmd_bitlen
>
16
)
||
(
addr_bitlen
>
32
)
||
(
mosi_bitlen
>
512
)
||
(
dummy_bitlen
>
256
)
||
(
miso_bitlen
>
512
))
return
PLATFORM_ERR
;
spi_mast_transaction
(
id
,
cmd_bitlen
,
cmd_data
,
addr_bitlen
,
addr_data
,
mosi_bitlen
,
dummy_bitlen
,
miso_bitlen
);
return
PLATFORM_OK
;
}
// ****************************************************************************
// ****************************************************************************
// Flash access functions
// Flash access functions
...
...
app/platform/platform.h
View file @
9cde0bbb
...
@@ -103,6 +103,12 @@ uint32_t platform_spi_setup( unsigned id, int mode, unsigned cpol, unsigned cpha
...
@@ -103,6 +103,12 @@ uint32_t platform_spi_setup( unsigned id, int mode, unsigned cpol, unsigned cpha
spi_data_type
platform_spi_send_recv
(
unsigned
id
,
spi_data_type
data
);
spi_data_type
platform_spi_send_recv
(
unsigned
id
,
spi_data_type
data
);
void
platform_spi_select
(
unsigned
id
,
int
is_select
);
void
platform_spi_select
(
unsigned
id
,
int
is_select
);
int
platform_spi_set_mosi
(
uint8_t
id
,
uint8_t
offset
,
uint8_t
bitlen
,
spi_data_type
data
);
int
platform_spi_transaction
(
uint8_t
id
,
uint8_t
cmd_bitlen
,
spi_data_type
cmd_data
,
uint8_t
addr_bitlen
,
spi_data_type
addr_data
,
uint8_t
mosi_bitlen
,
uint8_t
dummy_bitlen
,
uint8_t
miso_bitlen
);
// *****************************************************************************
// *****************************************************************************
// UART subsection
// UART subsection
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment