From 9444ae28df4a119e69d3d1066c122123f3c49cb1 Mon Sep 17 00:00:00 2001 From: devsaurus Date: Tue, 27 Oct 2015 23:30:33 +0100 Subject: [PATCH] simplify spi api duplex_mode configuration enables/disables receiving with spi.send() spi.send_recv removed --- app/driver/spi.c | 27 ++++++++++---------- app/include/driver/spi.h | 4 +-- app/modules/spi.c | 54 ++++++++++++++++++++-------------------- app/platform/platform.c | 12 +++------ app/platform/platform.h | 4 +-- 5 files changed, 48 insertions(+), 53 deletions(-) diff --git a/app/driver/spi.c b/app/driver/spi.c index ed0bd2ba..4581e457 100644 --- a/app/driver/spi.c +++ b/app/driver/spi.c @@ -64,7 +64,7 @@ void spi_lcd_9bit_write(uint8 spi_no,uint8 high_bit,uint8 low_8bit) * Description : SPI master initial function for common byte units transmission * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid *******************************************************************************/ -void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_div, uint8 full_duplex) +void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_div) { uint32 regvalue; @@ -85,7 +85,7 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_ 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_RD_BYTE_ORDER|SPI_WR_BYTE_ORDER); + SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_RD_BYTE_ORDER|SPI_WR_BYTE_ORDER|SPI_DOUTDIN); //set clock polarity // TODO: This doesn't work @@ -103,8 +103,7 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_ CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE|SPI_CK_I_EDGE); } - CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE|SPI_USR_MISO| - SPI_USR_ADDR|SPI_USR_COMMAND|SPI_USR_DUMMY|SPI_DOUTDIN); + CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE|SPI_USR_MISO|SPI_USR_ADDR|SPI_USR_COMMAND|SPI_USR_DUMMY); //clear Dual 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); @@ -124,11 +123,6 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_ ((1&SPI_CLKCNT_N)< 0) - { - SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_DOUTDIN); - } } /****************************************************************************** @@ -250,20 +244,21 @@ uint32 spi_mast_get_miso(uint8 spi_no, uint8 offset, uint8 bitlen) * 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. + * uint16 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. + * sint16 miso_bitlen - number of bits to be captured in MISO buffer. + * negative value activates full-duplex mode. *******************************************************************************/ 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) + uint16 mosi_bitlen, uint8 dummy_bitlen, sint16 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 disable COMMAND, ADDR, MOSI, DUMMY, MISO, and DOUTDIN (aka full-duplex) + CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_COMMAND|SPI_USR_ADDR|SPI_USR_MOSI|SPI_USR_DUMMY|SPI_USR_MISO|SPI_DOUTDIN); // default set bit lengths WRITE_PERI_REG(SPI_USER1(spi_no), ((addr_bitlen - 1) & SPI_USR_ADDR_BITLEN) << SPI_USR_ADDR_BITLEN_S | @@ -298,6 +293,10 @@ void spi_mast_transaction(uint8 spi_no, uint8 cmd_bitlen, uint16 cmd_data, uint8 { SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MISO); } + else if (miso_bitlen < 0) + { + SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_DOUTDIN); + } // start transaction SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR); diff --git a/app/include/driver/spi.h b/app/include/driver/spi.h index 22c9d400..bb8e0314 100644 --- a/app/include/driver/spi.h +++ b/app/include/driver/spi.h @@ -18,14 +18,14 @@ void spi_lcd_mode_init(uint8 spi_no); void spi_lcd_9bit_write(uint8 spi_no,uint8 high_bit,uint8 low_8bit); //spi master init funtion -void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_div, uint8 full_duplex); +void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_div); // fill MOSI buffer void spi_set_mosi(uint8 spi_no, uint8 offset, uint8 bitlen, uint32 data); // retrieve data from MISO buffer uint32 spi_get_miso(uint8 spi_no, uint8 offset, uint8 bitlen); // initiate SPI transaction 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); + uint16 mosi_bitlen, uint8 dummy_bitlen, sint16 miso_bitlen); //transmit data to esp8266 slave buffer,which needs 16bit transmission , //first byte is master command 0x04, second byte is master data diff --git a/app/modules/spi.c b/app/modules/spi.c index 10348a17..6074ec82 100644 --- a/app/modules/spi.c +++ b/app/modules/spi.c @@ -7,9 +7,13 @@ #include "auxmods.h" #include "lrotable.h" -static u8 spi_databits[NUM_SPI] = {0, 0}; +#define SPI_HALFDUPLEX 0 +#define SPI_FULLDUPLEX 1 -// Lua: = spi.setup( id, mode, cpol, cpha, databits, clock_div, [full_duplex] ) +static u8 spi_databits[NUM_SPI] = {0, 0}; +static u8 spi_duplex[NUM_SPI] = {SPI_HALFDUPLEX, SPI_HALFDUPLEX}; + +// Lua: = spi.setup( id, mode, cpol, cpha, databits, clock_div, [duplex_mode] ) static int spi_setup( lua_State *L ) { int id = luaL_checkinteger( L, 1 ); @@ -18,7 +22,7 @@ static int spi_setup( lua_State *L ) int cpha = luaL_checkinteger( L, 4 ); int databits = luaL_checkinteger( L, 5 ); u32 clock_div = luaL_checkinteger( L, 6 ); - int full_duplex = luaL_optinteger( L, 7, 1 ); + int duplex_mode = luaL_optinteger( L, 7, SPI_HALFDUPLEX ); MOD_CHECK_ID( spi, id ); @@ -43,18 +47,28 @@ static int spi_setup( lua_State *L ) clock_div = 8; } - if (full_duplex != 0 && full_duplex != 1) { + if (duplex_mode == SPI_HALFDUPLEX || duplex_mode == SPI_FULLDUPLEX) + { + spi_duplex[id] = duplex_mode; + } + else + { return luaL_error( L, "out of range" ); } spi_databits[id] = databits; - u32 res = platform_spi_setup(id, mode, cpol, cpha, clock_div, full_duplex); + u32 res = platform_spi_setup(id, mode, cpol, cpha, clock_div); lua_pushinteger( L, res ); return 1; } -static int spi_generic_send_recv( lua_State *L, u8 recv ) +// Half-duplex mode: +// Lua: wrote = spi.send( id, data1, [data2], ..., [datan] ) +// Full-duplex mode: +// Lua: wrote, [data1], ..., [datan] = spi.send_recv( id, data1, [data2], ..., [datan] ) +// data can be either a string, a table or an 8-bit number +static int spi_send_recv( lua_State *L ) { unsigned id = luaL_checkinteger( L, 1 ); const char *pdata; @@ -63,6 +77,7 @@ static int spi_generic_send_recv( lua_State *L, u8 recv ) u32 wrote = 0; int pushed = 1; unsigned argn, tos; + u8 recv = spi_duplex[id] == SPI_FULLDUPLEX ? 1 : 0; MOD_CHECK_ID( spi, id ); if( (tos = lua_gettop( L )) < 2 ) @@ -159,20 +174,6 @@ static int spi_generic_send_recv( lua_State *L, u8 recv ) return pushed; } -// Lua: wrote = spi.send( id, data1, [data2], ..., [datan] ) -// data can be either a string, a table or an 8-bit number -static int spi_send( lua_State *L ) -{ - return spi_generic_send_recv( L, 0 ); -} - -// Lua: wrote, [data1], ..., [datan] = spi.send_recv( id, data1, [data2], ..., [datan] ) -// data can be either a string, a table or an 8-bit number -static int spi_send_recv( lua_State *L ) -{ - return spi_generic_send_recv( L, 1 ); -} - // Lua: read = spi.recv( id, size, [default data] ) static int spi_recv( lua_State *L ) { @@ -294,7 +295,7 @@ static int spi_transaction( lua_State *L ) return luaL_error( L, "dummy_bitlen out of range" ); } - if (miso_bitlen < 0 || miso_bitlen > 511) { + if (miso_bitlen < -512 || miso_bitlen > 511) { return luaL_error( L, "miso_bitlen out of range" ); } @@ -313,8 +314,7 @@ static int spi_transaction( lua_State *L ) const LUA_REG_TYPE spi_map[] = { { LSTRKEY( "setup" ), LFUNCVAL( spi_setup ) }, - { LSTRKEY( "send" ), LFUNCVAL( spi_send ) }, - { LSTRKEY( "send_recv" ), LFUNCVAL( spi_send_recv ) }, + { LSTRKEY( "send" ), LFUNCVAL( spi_send_recv ) }, { LSTRKEY( "recv" ), LFUNCVAL( spi_recv ) }, { LSTRKEY( "set_mosi" ), LFUNCVAL( spi_set_mosi ) }, { LSTRKEY( "get_miso" ), LFUNCVAL( spi_get_miso ) }, @@ -327,8 +327,8 @@ const LUA_REG_TYPE spi_map[] = { LSTRKEY( "CPOL_LOW" ), LNUMVAL( PLATFORM_SPI_CPOL_LOW) }, { LSTRKEY( "CPOL_HIGH" ), LNUMVAL( PLATFORM_SPI_CPOL_HIGH) }, { LSTRKEY( "DATABITS_8" ), LNUMVAL( 8 ) }, - { LSTRKEY( "HALFDUPLEX" ), LNUMVAL( 0 ) }, - { LSTRKEY( "FULLDUPLEX" ), LNUMVAL( 1 ) }, + { LSTRKEY( "HALFDUPLEX" ), LNUMVAL( SPI_HALFDUPLEX ) }, + { LSTRKEY( "FULLDUPLEX" ), LNUMVAL( SPI_FULLDUPLEX ) }, #endif // #if LUA_OPTIMIZE_MEMORY > 0 { LNILKEY, LNILVAL } }; @@ -348,8 +348,8 @@ LUALIB_API int luaopen_spi( lua_State *L ) MOD_REG_NUMBER( L, "CPOL_LOW" , PLATFORM_SPI_CPOL_LOW); MOD_REG_NUMBER( L, "CPOL_HIGH", PLATFORM_SPI_CPOL_HIGH); MOD_REG_NUMBER( L, "DATABITS_8", 8 ); - MOD_REG_NUMBER( L, "HALFDUPLEX", 0 ); - MOD_REG_NUMBER( L, "FULLDUPLEX", 1 ); + MOD_REG_NUMBER( L, "HALFDUPLEX", SPI_HALFDUPLEX ); + MOD_REG_NUMBER( L, "FULLDUPLEX", SPI_FULLDUPLEX ); return 1; #endif // #if LUA_OPTIMIZE_MEMORY > 0 diff --git a/app/platform/platform.c b/app/platform/platform.c index 04963f48..7bbbaea1 100644 --- a/app/platform/platform.c +++ b/app/platform/platform.c @@ -435,15 +435,11 @@ int platform_i2c_recv_byte( unsigned id, int ack ){ return r; } -static uint8_t platform_spi_fdplx[NUM_SPI] = {0, 0}; - // ***************************************************************************** // SPI platform interface -uint32_t platform_spi_setup( uint8_t id, int mode, unsigned cpol, unsigned cpha, - uint32_t clock_div, uint8 full_duplex ) +uint32_t platform_spi_setup( uint8_t id, int mode, unsigned cpol, unsigned cpha, uint32_t clock_div) { - platform_spi_fdplx[id] = full_duplex; - spi_master_init( id, cpol, cpha, clock_div, full_duplex ); + spi_master_init( id, cpol, cpha, clock_div ); return 1; } @@ -462,7 +458,7 @@ spi_data_type platform_spi_send_recv( uint8_t id, uint8_t bitlen, spi_data_type return 0; spi_mast_set_mosi( id, 0, bitlen, data ); - spi_mast_transaction( id, 0, 0, 0, 0, bitlen, 0, platform_spi_fdplx[id] > 0 ? 0 : bitlen ); + spi_mast_transaction( id, 0, 0, 0, 0, bitlen, 0, -1 ); return spi_mast_get_miso( id, 0, bitlen ); } @@ -486,7 +482,7 @@ spi_data_type platform_spi_get_miso( uint8_t id, uint8_t offset, uint8_t bitlen 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 ) + uint16_t mosi_bitlen, uint8_t dummy_bitlen, int16_t miso_bitlen ) { if ((cmd_bitlen > 16) || (addr_bitlen > 32) || diff --git a/app/platform/platform.h b/app/platform/platform.h index 5fb607bc..b4d3a00a 100644 --- a/app/platform/platform.h +++ b/app/platform/platform.h @@ -96,7 +96,7 @@ typedef uint32_t spi_data_type; // The platform SPI functions int platform_spi_exists( unsigned id ); -uint32_t platform_spi_setup( uint8_t id, int mode, unsigned cpol, unsigned cpha, uint32_t clock_div, uint8_t full_duplex); +uint32_t platform_spi_setup( uint8_t id, int mode, unsigned cpol, unsigned cpha, uint32_t clock_div); int platform_spi_send( uint8_t id, uint8_t bitlen, spi_data_type data ); spi_data_type platform_spi_send_recv( uint8_t id, uint8_t bitlen, spi_data_type data ); void platform_spi_select( unsigned id, int is_select ); @@ -105,7 +105,7 @@ int platform_spi_set_mosi( uint8_t id, uint8_t offset, uint8_t bitlen, spi_data_ spi_data_type platform_spi_get_miso( uint8_t id, uint8_t offset, uint8_t bitlen ); 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 ); + uint16_t mosi_bitlen, uint8_t dummy_bitlen, int16_t miso_bitlen ); // *****************************************************************************