Add string support for spi.set_mosi() and spi.get_miso() (#1753)

clean-up endianess handling in spi driver
This commit is contained in:
Arnim Läuger 2017-02-06 13:55:26 +01:00 committed by Marcel Stör
parent 2c8961d153
commit 416d53eb39
6 changed files with 137 additions and 130 deletions

View File

@ -19,13 +19,13 @@ void spi_lcd_mode_init(uint8 spi_no)
if(spi_no>1) return; //handle invalid input number if(spi_no>1) return; //handle invalid input number
//bit9 of PERIPHS_IO_MUX should be cleared when HSPI clock doesn't equal CPU clock //bit9 of PERIPHS_IO_MUX should be cleared when HSPI clock doesn't equal CPU clock
//bit8 of PERIPHS_IO_MUX should be cleared when SPI clock doesn't equal CPU clock //bit8 of PERIPHS_IO_MUX should be cleared when SPI clock doesn't equal CPU clock
if(spi_no==SPI){ if(spi_no==SPI_SPI){
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005); //clear bit9,and bit8 WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005); //clear bit9,and bit8
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode
}else if(spi_no==HSPI){ }else if(spi_no==SPI_HSPI){
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); //clear bit9 WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); //clear bit9
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode
@ -93,10 +93,10 @@ uint32_t spi_set_clkdiv(uint8 spi_no, uint32_t clock_div)
WRITE_PERI_REG(SPI_CLOCK(spi_no), SPI_CLK_EQU_SYSCLK); // 80Mhz speed WRITE_PERI_REG(SPI_CLOCK(spi_no), SPI_CLK_EQU_SYSCLK); // 80Mhz speed
} }
if(spi_no==SPI){ if(spi_no==SPI_SPI){
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005 | (clock_div <= 1 ? 0x100 : 0)); WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005 | (clock_div <= 1 ? 0x100 : 0));
} }
else if(spi_no==HSPI){ else if(spi_no==SPI_HSPI){
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div <= 1 ? 0x200 : 0)); WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div <= 1 ? 0x200 : 0));
} }
@ -144,13 +144,13 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_
spi_set_clkdiv(spi_no, clock_div); spi_set_clkdiv(spi_no, clock_div);
if(spi_no==SPI){ if(spi_no==SPI_SPI){
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode
} }
else if(spi_no==HSPI){ else if(spi_no==SPI_HSPI){
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode
@ -179,8 +179,16 @@ void spi_mast_byte_order(uint8 spi_no, uint8 order)
*******************************************************************************/ *******************************************************************************/
void spi_mast_blkset(uint8 spi_no, size_t bitlen, const uint8 *data) void spi_mast_blkset(uint8 spi_no, size_t bitlen, const uint8 *data)
{ {
size_t aligned_len = bitlen >> 3;
while(READ_PERI_REG(SPI_CMD(spi_no)) & SPI_USR); while(READ_PERI_REG(SPI_CMD(spi_no)) & SPI_USR);
os_memcpy((void *)SPI_W0(spi_no), (const void *)data, bitlen >> 3);
if (aligned_len % 4) {
// length for memcpy needs to be aligned to uint32 bounday
// otherwise single byte writes are issued to the register and corrupt data
aligned_len += 4 - (aligned_len % 4);
}
os_memcpy((void *)SPI_W0(spi_no), (const void *)data, aligned_len);
} }
/****************************************************************************** /******************************************************************************
@ -188,12 +196,29 @@ void spi_mast_blkset(uint8 spi_no, size_t bitlen, const uint8 *data)
* Description : Copy a block of data from the MISO FIFO * Description : Copy a block of data from the MISO FIFO
* Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
* size_t bitlen - number of bits to copy, multiple of 8 * size_t bitlen - number of bits to copy, multiple of 8
* uint8 *data - pointer to data buffer * uint8 *data - pointer to data buffer, the buffer must be able to
* accept a multiple of 4*8 bits
*******************************************************************************/ *******************************************************************************/
void spi_mast_blkget(uint8 spi_no, size_t bitlen, uint8 *data) void spi_mast_blkget(uint8 spi_no, size_t bitlen, uint8 *data)
{ {
size_t aligned_len = bitlen >> 3;
while(READ_PERI_REG(SPI_CMD(spi_no)) & SPI_USR); while(READ_PERI_REG(SPI_CMD(spi_no)) & SPI_USR);
os_memcpy((void *)data, (void *)SPI_W0(spi_no), bitlen >> 3);
if (aligned_len % 4) {
// length for memcpy needs to be aligned to uint32 bounday
// otherwise single byte reads are issued to the register and corrupt data
aligned_len += 4 - (aligned_len % 4);
}
os_memcpy((void *)data, (void *)SPI_W0(spi_no), aligned_len);
}
static uint32 swap_endianess(uint32 n)
{
return ((n & 0xff) << 24) |
((n & 0xff00) << 8) |
((n & 0xff0000UL) >> 8) |
((n & 0xff000000UL) >> 24);
} }
/****************************************************************************** /******************************************************************************
@ -208,8 +233,8 @@ void spi_mast_blkget(uint8 spi_no, size_t bitlen, uint8 *data)
*******************************************************************************/ *******************************************************************************/
void spi_mast_set_mosi(uint8 spi_no, uint16 offset, uint8 bitlen, uint32 data) void spi_mast_set_mosi(uint8 spi_no, uint16 offset, uint8 bitlen, uint32 data)
{ {
uint8 wn, shift;
spi_buf_t spi_buf; spi_buf_t spi_buf;
uint8 wn, shift;
if (spi_no > 1) if (spi_no > 1)
return; // handle invalid input number return; // handle invalid input number
@ -226,8 +251,10 @@ void spi_mast_set_mosi(uint8 spi_no, uint16 offset, uint8 bitlen, uint32 data)
// transfer Wn to buf // transfer Wn to buf
spi_buf.word[1] = READ_PERI_REG(SPI_W0(spi_no) + wn*4); spi_buf.word[1] = READ_PERI_REG(SPI_W0(spi_no) + wn*4);
spi_buf.word[1] = swap_endianess(spi_buf.word[1]);
if (wn < 15) { if (wn < 15) {
spi_buf.word[0] = READ_PERI_REG(SPI_W0(spi_no) + (wn+1)*4); spi_buf.word[0] = READ_PERI_REG(SPI_W0(spi_no) + (wn+1)*4);
spi_buf.word[0] = swap_endianess(spi_buf.word[0]);
} }
shift = 64 - (offset & 0x1f) - bitlen; shift = 64 - (offset & 0x1f) - bitlen;
@ -235,9 +262,9 @@ void spi_mast_set_mosi(uint8 spi_no, uint16 offset, uint8 bitlen, uint32 data)
spi_buf.dword |= (uint64)data << shift; spi_buf.dword |= (uint64)data << shift;
if (wn < 15) { if (wn < 15) {
WRITE_PERI_REG(SPI_W0(spi_no) + (wn+1)*4, spi_buf.word[0]); WRITE_PERI_REG(SPI_W0(spi_no) + (wn+1)*4, swap_endianess(spi_buf.word[0]));
} }
WRITE_PERI_REG(SPI_W0(spi_no) + wn*4, spi_buf.word[1]); WRITE_PERI_REG(SPI_W0(spi_no) + wn*4, swap_endianess(spi_buf.word[1]));
return; return;
} }
@ -269,8 +296,10 @@ uint32 spi_mast_get_miso(uint8 spi_no, uint16 offset, uint8 bitlen)
// transfer Wn to buf // transfer Wn to buf
spi_buf.word[1] = READ_PERI_REG(SPI_W0(spi_no) + wn*4); spi_buf.word[1] = READ_PERI_REG(SPI_W0(spi_no) + wn*4);
spi_buf.word[1] = swap_endianess(spi_buf.word[1]);
if (wn < 15) { if (wn < 15) {
spi_buf.word[0] = READ_PERI_REG(SPI_W0(spi_no) + (wn+1)*4); spi_buf.word[0] = READ_PERI_REG(SPI_W0(spi_no) + (wn+1)*4);
spi_buf.word[0] = swap_endianess(spi_buf.word[0]);
} }
result = (uint32)(spi_buf.dword >> (64 - ((offset & 0x1f) + bitlen))); result = (uint32)(spi_buf.dword >> (64 - ((offset & 0x1f) + bitlen)));
@ -419,12 +448,12 @@ void spi_slave_init(uint8 spi_no)
//bit9 should be cleared when HSPI clock doesn't equal CPU clock //bit9 should be cleared when HSPI clock doesn't equal CPU clock
//bit8 should be cleared when SPI clock doesn't equal CPU clock //bit8 should be cleared when SPI clock doesn't equal CPU clock
////WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); //clear bit9//TEST ////WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); //clear bit9//TEST
if(spi_no==SPI){ if(spi_no==SPI_SPI){
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode
}else if(spi_no==HSPI){ }else if(spi_no==SPI_HSPI){
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode
@ -511,10 +540,10 @@ void hspi_master_readwrite_repeat(void)
uint8 temp; uint8 temp;
os_timer_disarm(&timer2); os_timer_disarm(&timer2);
spi_byte_read_espslave(HSPI,&temp); spi_byte_read_espslave(SPI_HSPI,&temp);
temp++; temp++;
spi_byte_write_espslave(HSPI,temp); spi_byte_write_espslave(SPI_HSPI,temp);
os_timer_setfn(&timer2, (os_timer_func_t *)hspi_master_readwrite_repeat, NULL); os_timer_setfn(&timer2, (os_timer_func_t *)hspi_master_readwrite_repeat, NULL);
os_timer_arm(&timer2, 500, 0); os_timer_arm(&timer2, 500, 0);
} }
@ -570,23 +599,23 @@ void spi_slave_isr_handler(void *para)
if(READ_PERI_REG(0x3ff00020)&BIT4){ if(READ_PERI_REG(0x3ff00020)&BIT4){
//following 3 lines is to clear isr signal //following 3 lines is to clear isr signal
CLEAR_PERI_REG_MASK(SPI_SLAVE(SPI), 0x3ff); CLEAR_PERI_REG_MASK(SPI_SLAVE(SPI_SPI), 0x3ff);
}else if(READ_PERI_REG(0x3ff00020)&BIT7){ //bit7 is for hspi isr, }else if(READ_PERI_REG(0x3ff00020)&BIT7){ //bit7 is for hspi isr,
regvalue=READ_PERI_REG(SPI_SLAVE(HSPI)); regvalue=READ_PERI_REG(SPI_SLAVE(SPI_HSPI));
CLEAR_PERI_REG_MASK(SPI_SLAVE(HSPI), CLEAR_PERI_REG_MASK(SPI_SLAVE(SPI_HSPI),
SPI_TRANS_DONE_EN| SPI_TRANS_DONE_EN|
SPI_SLV_WR_STA_DONE_EN| SPI_SLV_WR_STA_DONE_EN|
SPI_SLV_RD_STA_DONE_EN| SPI_SLV_RD_STA_DONE_EN|
SPI_SLV_WR_BUF_DONE_EN| SPI_SLV_WR_BUF_DONE_EN|
SPI_SLV_RD_BUF_DONE_EN); SPI_SLV_RD_BUF_DONE_EN);
SET_PERI_REG_MASK(SPI_SLAVE(HSPI), SPI_SYNC_RESET); SET_PERI_REG_MASK(SPI_SLAVE(SPI_HSPI), SPI_SYNC_RESET);
CLEAR_PERI_REG_MASK(SPI_SLAVE(HSPI), CLEAR_PERI_REG_MASK(SPI_SLAVE(SPI_HSPI),
SPI_TRANS_DONE| SPI_TRANS_DONE|
SPI_SLV_WR_STA_DONE| SPI_SLV_WR_STA_DONE|
SPI_SLV_RD_STA_DONE| SPI_SLV_RD_STA_DONE|
SPI_SLV_WR_BUF_DONE| SPI_SLV_WR_BUF_DONE|
SPI_SLV_RD_BUF_DONE); SPI_SLV_RD_BUF_DONE);
SET_PERI_REG_MASK(SPI_SLAVE(HSPI), SET_PERI_REG_MASK(SPI_SLAVE(SPI_HSPI),
SPI_TRANS_DONE_EN| SPI_TRANS_DONE_EN|
SPI_SLV_WR_STA_DONE_EN| SPI_SLV_WR_STA_DONE_EN|
SPI_SLV_RD_STA_DONE_EN| SPI_SLV_RD_STA_DONE_EN|
@ -597,7 +626,7 @@ void spi_slave_isr_handler(void *para)
GPIO_OUTPUT_SET(0, 0); GPIO_OUTPUT_SET(0, 0);
idx=0; idx=0;
while(idx<8){ while(idx<8){
recv_data=READ_PERI_REG(SPI_W0(HSPI)+(idx<<2)); recv_data=READ_PERI_REG(SPI_W0(SPI_HSPI)+(idx<<2));
spi_data[idx<<2] = recv_data&0xff; spi_data[idx<<2] = recv_data&0xff;
spi_data[(idx<<2)+1] = (recv_data>>8)&0xff; spi_data[(idx<<2)+1] = (recv_data>>8)&0xff;
spi_data[(idx<<2)+2] = (recv_data>>16)&0xff; spi_data[(idx<<2)+2] = (recv_data>>16)&0xff;
@ -627,15 +656,15 @@ void ICACHE_FLASH_ATTR
set_miso_data() set_miso_data()
{ {
if(GPIO_INPUT_GET(2)==0){ if(GPIO_INPUT_GET(2)==0){
WRITE_PERI_REG(SPI_W8(HSPI),0x05040302); WRITE_PERI_REG(SPI_W8(SPI_HSPI),0x05040302);
WRITE_PERI_REG(SPI_W9(HSPI),0x09080706); WRITE_PERI_REG(SPI_W9(SPI_HSPI),0x09080706);
WRITE_PERI_REG(SPI_W10(HSPI),0x0d0c0b0a); WRITE_PERI_REG(SPI_W10(SPI_HSPI),0x0d0c0b0a);
WRITE_PERI_REG(SPI_W11(HSPI),0x11100f0e); WRITE_PERI_REG(SPI_W11(SPI_HSPI),0x11100f0e);
WRITE_PERI_REG(SPI_W12(HSPI),0x15141312); WRITE_PERI_REG(SPI_W12(SPI_HSPI),0x15141312);
WRITE_PERI_REG(SPI_W13(HSPI),0x19181716); WRITE_PERI_REG(SPI_W13(SPI_HSPI),0x19181716);
WRITE_PERI_REG(SPI_W14(HSPI),0x1d1c1b1a); WRITE_PERI_REG(SPI_W14(SPI_HSPI),0x1d1c1b1a);
WRITE_PERI_REG(SPI_W15(HSPI),0x21201f1e); WRITE_PERI_REG(SPI_W15(SPI_HSPI),0x21201f1e);
GPIO_OUTPUT_SET(2, 1); GPIO_OUTPUT_SET(2, 1);
} }
} }
@ -697,7 +726,7 @@ void ICACHE_FLASH_ATTR
spi_test_init() spi_test_init()
{ {
os_printf("spi init\n\r"); os_printf("spi init\n\r");
spi_slave_init(HSPI); spi_slave_init(SPI_HSPI);
os_printf("gpio init\n\r"); os_printf("gpio init\n\r");
gpio_init(); gpio_init();
os_printf("spi task init \n\r"); os_printf("spi task init \n\r");

View File

@ -8,8 +8,8 @@
#include "os_type.h" #include "os_type.h"
/*SPI number define*/ /*SPI number define*/
#define SPI 0 #define SPI_SPI 0
#define HSPI 1 #define SPI_HSPI 1
#define SPI_ORDER_LSB 0 #define SPI_ORDER_LSB 0
#define SPI_ORDER_MSB 1 #define SPI_ORDER_MSB 1

View File

@ -4,6 +4,8 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "platform.h" #include "platform.h"
#include "driver/spi.h"
#define SPI_HALFDUPLEX 0 #define SPI_HALFDUPLEX 0
#define SPI_FULLDUPLEX 1 #define SPI_FULLDUPLEX 1
@ -196,37 +198,35 @@ static int spi_recv( lua_State *L )
} }
// Lua: spi.set_mosi( id, offset, bitlen, data1, [data2], ..., [datan] ) // Lua: spi.set_mosi( id, offset, bitlen, data1, [data2], ..., [datan] )
// Lua: spi.set_mosi( id, string )
static int spi_set_mosi( lua_State *L ) static int spi_set_mosi( lua_State *L )
{ {
int id = luaL_checkinteger( L, 1 ); int id = luaL_checkinteger( L, 1 );
int offset = luaL_checkinteger( L, 2 );
int bitlen = luaL_checkinteger( L, 3 );
int argn;
MOD_CHECK_ID( spi, id ); MOD_CHECK_ID( spi, id );
if (offset < 0 || offset > 511) { if (lua_type( L, 2 ) == LUA_TSTRING) {
return luaL_error( L, "offset out of range" ); size_t len;
} const char *data = luaL_checklstring( L, 2, &len );
luaL_argcheck( L, 2, len <= 64, "out of range" );
if (bitlen < 1 || bitlen > 32) { spi_mast_blkset( id, len * 8, data );
return luaL_error( L, "bitlen out of range" );
}
if (lua_gettop( L ) < 4) { } else {
return luaL_error( L, "too few args" ); int offset = luaL_checkinteger( L, 2 );
} int bitlen = luaL_checkinteger( L, 3 );
for (argn = 4; argn <= lua_gettop( L ); argn++, offset += bitlen ) luaL_argcheck( L, 2, offset >= 0 && offset <= 511, "out of range" );
{ luaL_argcheck( L, 3, bitlen >= 1 && bitlen <= 32, "out of range" );
u32 data = ( u32 )luaL_checkinteger(L, argn );
if (offset + bitlen > 512) { for (int argn = 4; argn <= lua_gettop( L ); argn++, offset += bitlen ) {
return luaL_error( L, "data range exceeded > 512 bits" ); u32 data = ( u32 )luaL_checkinteger(L, argn );
}
if (PLATFORM_OK != platform_spi_set_mosi( id, offset, bitlen, data )) { if (offset + bitlen > 512) {
return luaL_error( L, "failed" ); return luaL_error( L, "data range exceeded > 512 bits" );
}
spi_mast_set_mosi( id, offset, bitlen, data );
} }
} }
@ -234,72 +234,69 @@ static int spi_set_mosi( lua_State *L )
} }
// Lua: data = spi.get_miso( id, offset, bitlen, num ) // Lua: data = spi.get_miso( id, offset, bitlen, num )
// Lua: string = spi.get_miso( id, len )
static int spi_get_miso( lua_State *L ) static int spi_get_miso( lua_State *L )
{ {
int id = luaL_checkinteger( L, 1 ); int id = luaL_checkinteger( L, 1 );
int offset = luaL_checkinteger( L, 2 );
int bitlen = luaL_checkinteger( L, 3 );
int num = luaL_checkinteger( L, 4 ), i;
MOD_CHECK_ID( spi, id ); MOD_CHECK_ID( spi, id );
if (offset < 0 || offset > 511) { if (lua_gettop( L ) == 2) {
return luaL_error( L, "out of range" ); uint8_t data[64];
} int len = luaL_checkinteger( L, 2 );
if (bitlen < 1 || bitlen > 32) { luaL_argcheck( L, 2, len >= 1 && len <= 64, "out of range" );
return luaL_error( L, "bitlen out of range" );
}
if (offset + bitlen * num > 512) { spi_mast_blkget( id, len * 8, data );
return luaL_error( L, "out of range" );
}
for (i = 0; i < num; i++) lua_pushlstring( L, data, len );
{ return 1;
lua_pushinteger( L, platform_spi_get_miso( id, offset + (bitlen * i), bitlen ) );
} else {
int offset = luaL_checkinteger( L, 2 );
int bitlen = luaL_checkinteger( L, 3 );
int num = luaL_checkinteger( L, 4 ), i;
luaL_argcheck( L, 2, offset >= 0 && offset <= 511, "out of range" );
luaL_argcheck( L, 3, bitlen >= 1 && bitlen <= 32, "out of range" );
if (offset + bitlen * num > 512) {
return luaL_error( L, "out of range" );
}
for (i = 0; i < num; i++) {
lua_pushinteger( L, spi_mast_get_miso( id, offset + (bitlen * i), bitlen ) );
}
return num;
} }
return num;
} }
// Lua: spi.transaction( id, cmd_bitlen, cmd_data, addr_bitlen, addr_data, mosi_bitlen, dummy_bitlen, miso_bitlen ) // 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 ) static int spi_transaction( lua_State *L )
{ {
int id = luaL_checkinteger( L, 1 ); int id = luaL_checkinteger( L, 1 );
int cmd_bitlen = luaL_checkinteger( L, 2 );
u16 cmd_data = ( u16 )luaL_checkinteger( L, 3 );
int addr_bitlen = luaL_checkinteger( L, 4 );
u32 addr_data = ( u32 )luaL_checkinteger( L, 5 );
int mosi_bitlen = luaL_checkinteger( L, 6 );
int dummy_bitlen = luaL_checkinteger( L, 7 );
int miso_bitlen = luaL_checkinteger( L, 8 );
MOD_CHECK_ID( spi, id ); MOD_CHECK_ID( spi, id );
if (cmd_bitlen < 0 || cmd_bitlen > 16) { int cmd_bitlen = luaL_checkinteger( L, 2 );
return luaL_error( L, "cmd_bitlen out of range" ); u16 cmd_data = ( u16 )luaL_checkinteger( L, 3 );
} luaL_argcheck( L, 2, cmd_bitlen >= 0 && cmd_bitlen <= 16, "out of range" );
if (addr_bitlen < 0 || addr_bitlen > 32) { int addr_bitlen = luaL_checkinteger( L, 4 );
return luaL_error( L, "addr_bitlen out of range" ); u32 addr_data = ( u32 )luaL_checkinteger( L, 5 );
} luaL_argcheck( L, 4, addr_bitlen >= 0 && addr_bitlen <= 32, "out of range" );
if (mosi_bitlen < 0 || mosi_bitlen > 512) { int mosi_bitlen = luaL_checkinteger( L, 6 );
return luaL_error( L, "mosi_bitlen out of range" ); luaL_argcheck( L, 6, mosi_bitlen >= 0 && mosi_bitlen <= 512, "out of range" );
}
if (dummy_bitlen < 0 || dummy_bitlen > 256) { int dummy_bitlen = luaL_checkinteger( L, 7 );
return luaL_error( L, "dummy_bitlen out of range" ); luaL_argcheck( L, 7, dummy_bitlen >= 0 && dummy_bitlen <= 256, "out of range" );
}
if (miso_bitlen < -512 || miso_bitlen > 512) { int miso_bitlen = luaL_checkinteger( L, 8 );
return luaL_error( L, "miso_bitlen out of range" ); luaL_argcheck( L, 8, miso_bitlen >= -512 && miso_bitlen <= 512, "out of range" );
}
if (PLATFORM_OK != platform_spi_transaction( id, cmd_bitlen, cmd_data, addr_bitlen, addr_data, spi_mast_transaction( id, cmd_bitlen, cmd_data, addr_bitlen, addr_data,
mosi_bitlen, dummy_bitlen, miso_bitlen) ) { mosi_bitlen, dummy_bitlen, miso_bitlen );
return luaL_error( L, "failed" );
}
return 0; return 0;
} }

View File

@ -755,6 +755,8 @@ int platform_i2c_recv_byte( unsigned id, int ack ){
uint32_t platform_spi_setup( uint8_t id, int mode, unsigned cpol, unsigned cpha, uint32_t clock_div ) uint32_t platform_spi_setup( uint8_t id, int mode, unsigned cpol, unsigned cpha, uint32_t clock_div )
{ {
spi_master_init( id, cpol, cpha, clock_div ); spi_master_init( id, cpol, cpha, clock_div );
// all platform functions assume LSB order for MOSI & MISO buffer
spi_mast_byte_order( id, SPI_ORDER_LSB );
return 1; return 1;
} }
@ -779,8 +781,6 @@ spi_data_type platform_spi_send_recv( uint8_t id, uint8_t bitlen, spi_data_type
int platform_spi_blkwrite( uint8_t id, size_t len, const uint8_t *data ) int platform_spi_blkwrite( uint8_t id, size_t len, const uint8_t *data )
{ {
spi_mast_byte_order( id, SPI_ORDER_LSB );
while (len > 0) { while (len > 0) {
size_t chunk_len = len > 64 ? 64 : len; size_t chunk_len = len > 64 ? 64 : len;
@ -791,8 +791,6 @@ int platform_spi_blkwrite( uint8_t id, size_t len, const uint8_t *data )
len -= chunk_len; len -= chunk_len;
} }
spi_mast_byte_order( id, SPI_ORDER_MSB );
return PLATFORM_OK; return PLATFORM_OK;
} }
@ -802,8 +800,6 @@ int platform_spi_blkread( uint8_t id, size_t len, uint8_t *data )
os_memset( (void *)mosi_idle, 0xff, len > 64 ? 64 : len ); os_memset( (void *)mosi_idle, 0xff, len > 64 ? 64 : len );
spi_mast_byte_order( id, SPI_ORDER_LSB );
while (len > 0 ) { while (len > 0 ) {
size_t chunk_len = len > 64 ? 64 : len; size_t chunk_len = len > 64 ? 64 : len;
@ -815,29 +811,9 @@ int platform_spi_blkread( uint8_t id, size_t len, uint8_t *data )
len -= chunk_len; len -= chunk_len;
} }
spi_mast_byte_order( id, SPI_ORDER_MSB );
return PLATFORM_OK; return PLATFORM_OK;
} }
int platform_spi_set_mosi( uint8_t id, uint16_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;
}
spi_data_type platform_spi_get_miso( uint8_t id, uint16_t offset, uint8_t bitlen )
{
if (offset + bitlen > 512)
return 0;
return spi_mast_get_miso( id, offset, bitlen );
}
int platform_spi_transaction( uint8_t id, uint8_t cmd_bitlen, spi_data_type cmd_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 addr_bitlen, spi_data_type addr_data,
uint16_t mosi_bitlen, uint8_t dummy_bitlen, int16_t miso_bitlen ) uint16_t mosi_bitlen, uint8_t dummy_bitlen, int16_t miso_bitlen )

View File

@ -113,8 +113,6 @@ void platform_spi_select( unsigned id, int is_select );
int platform_spi_blkwrite( uint8_t id, size_t len, const uint8_t *data ); int platform_spi_blkwrite( uint8_t id, size_t len, const uint8_t *data );
int platform_spi_blkread( uint8_t id, size_t len, uint8_t *data ); int platform_spi_blkread( uint8_t id, size_t len, uint8_t *data );
int platform_spi_set_mosi( uint8_t id, uint16_t offset, uint8_t bitlen, spi_data_type data );
spi_data_type platform_spi_get_miso( uint8_t id, uint16_t offset, uint8_t bitlen );
int platform_spi_transaction( uint8_t id, uint8_t cmd_bitlen, spi_data_type cmd_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 addr_bitlen, spi_data_type addr_data,
uint16_t mosi_bitlen, uint8_t dummy_bitlen, int16_t miso_bitlen ); uint16_t mosi_bitlen, uint8_t dummy_bitlen, int16_t miso_bitlen );

View File

@ -119,7 +119,10 @@ transactions are initiated with full control over the hardware features.
Extract data items from MISO buffer after `spi.transaction()`. Extract data items from MISO buffer after `spi.transaction()`.
#### Syntax #### Syntax
`data1[, data2[, ..., datan]] = spi.get_miso(id, offset, bitlen, num)` ```lua
data1[, data2[, ..., datan]] = spi.get_miso(id, offset, bitlen, num)
string = spi.get_miso(id, num)
```
#### Parameters #### Parameters
- `id` SPI ID number: 0 for SPI, 1 for HSPI - `id` SPI ID number: 0 for SPI, 1 for HSPI
@ -128,7 +131,7 @@ Extract data items from MISO buffer after `spi.transaction()`.
- `num` number of data items to retrieve - `num` number of data items to retrieve
####Returns ####Returns
`num` data items `num` data items or `string`
#### See also #### See also
[spi.transaction()](#spitransaction) [spi.transaction()](#spitransaction)
@ -137,13 +140,17 @@ Extract data items from MISO buffer after `spi.transaction()`.
Insert data items into MOSI buffer for `spi.transaction()`. Insert data items into MOSI buffer for `spi.transaction()`.
#### Syntax #### Syntax
`spi.set_mosi(id, offset, bitlen, data1[, data2[, ..., datan]])` ```lua
spi.set_mosi(id, offset, bitlen, data1[, data2[, ..., datan]])
spi.set_mosi(id, string)
```
####Parameters ####Parameters
- `id` SPI ID number: 0 for SPI, 1 for HSPI - `id` SPI ID number: 0 for SPI, 1 for HSPI
- `offset` bit offset into MOSI buffer for inserting data1 and subsequent items - `offset` bit offset into MOSI buffer for inserting data1 and subsequent items
- `bitlen` bit length of data1, data2, ... - `bitlen` bit length of data1, data2, ...
- `data` data items where `bitlen` number of bits are considered for the transaction. - `data` data items where `bitlen` number of bits are considered for the transaction.
- `string` send data to be copied into MOSI buffer at offset 0, bit length 8
#### Returns #### Returns
`nil` `nil`