Commit ac50f9c6 authored by devsaurus's avatar devsaurus
Browse files

add divider for arbitrary HSPI clock frequencies

parent 5a29bab4
...@@ -64,7 +64,7 @@ void spi_lcd_9bit_write(uint8 spi_no,uint8 high_bit,uint8 low_8bit) ...@@ -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 * Description : SPI master initial function for common byte units transmission
* 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
*******************************************************************************/ *******************************************************************************/
void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock) void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock_div)
{ {
uint32 regvalue; uint32 regvalue;
...@@ -109,12 +109,18 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, unsigned databi ...@@ -109,12 +109,18 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, unsigned databi
//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);
// SPI clock=CPU clock/8 // SPI clock = CPU clock / clock_div
// the divider needs to be a multiple of 2 to get a proper waveform shape
if ((clock_div & 0x01) != 0) {
// bump the divider to the nextN*2
clock_div += 0x02;
}
clock_div >>= 1;
WRITE_PERI_REG(SPI_CLOCK(spi_no), WRITE_PERI_REG(SPI_CLOCK(spi_no),
((1&SPI_CLKDIV_PRE)<<SPI_CLKDIV_PRE_S)| ((clock_div&SPI_CLKDIV_PRE)<<SPI_CLKDIV_PRE_S)|
((3&SPI_CLKCNT_N)<<SPI_CLKCNT_N_S)| ((1&SPI_CLKCNT_N)<<SPI_CLKCNT_N_S)|
((1&SPI_CLKCNT_H)<<SPI_CLKCNT_H_S)| ((0&SPI_CLKCNT_H)<<SPI_CLKCNT_H_S)|
((3&SPI_CLKCNT_L)<<SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div ((1&SPI_CLKCNT_L)<<SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
//set 8bit output buffer length, the buffer is the low 8bit of register"SPI_FLASH_C0" //set 8bit output buffer length, the buffer is the low 8bit of register"SPI_FLASH_C0"
WRITE_PERI_REG(SPI_USER1(spi_no), WRITE_PERI_REG(SPI_USER1(spi_no),
......
...@@ -18,7 +18,7 @@ void spi_lcd_mode_init(uint8 spi_no); ...@@ -18,7 +18,7 @@ void spi_lcd_mode_init(uint8 spi_no);
void spi_lcd_9bit_write(uint8 spi_no,uint8 high_bit,uint8 low_8bit); void spi_lcd_9bit_write(uint8 spi_no,uint8 high_bit,uint8 low_8bit);
//spi master init funtion //spi master init funtion
void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock); void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock_div);
//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);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include "auxmods.h" #include "auxmods.h"
#include "lrotable.h" #include "lrotable.h"
// Lua: = spi.setup( id, mode, cpol, cpha, databits, clock ) // Lua: = spi.setup( id, mode, cpol, cpha, databits, clock_div )
static int spi_setup( lua_State *L ) static int spi_setup( lua_State *L )
{ {
unsigned id = luaL_checkinteger( L, 1 ); unsigned id = luaL_checkinteger( L, 1 );
...@@ -15,7 +15,7 @@ static int spi_setup( lua_State *L ) ...@@ -15,7 +15,7 @@ static int spi_setup( lua_State *L )
unsigned cpol = luaL_checkinteger( L, 3 ); unsigned cpol = luaL_checkinteger( L, 3 );
unsigned cpha = luaL_checkinteger( L, 4 ); unsigned cpha = luaL_checkinteger( L, 4 );
unsigned databits = luaL_checkinteger( L, 5 ); unsigned databits = luaL_checkinteger( L, 5 );
uint32_t clock = luaL_checkinteger( L, 6 ); uint32_t clock_div = luaL_checkinteger( L, 6 );
MOD_CHECK_ID( spi, id ); MOD_CHECK_ID( spi, id );
...@@ -35,7 +35,11 @@ static int spi_setup( lua_State *L ) ...@@ -35,7 +35,11 @@ static int spi_setup( lua_State *L )
return luaL_error( L, "wrong arg type" ); return luaL_error( L, "wrong arg type" );
} }
u32 res = platform_spi_setup(id, mode, cpol, cpha, databits, clock); if (clock_div < 4) {
return luaL_error( L, "invalid clock divider" );
}
u32 res = platform_spi_setup(id, mode, cpol, cpha, databits, clock_div);
lua_pushinteger( L, res ); lua_pushinteger( L, res );
return 1; return 1;
} }
......
...@@ -445,9 +445,9 @@ int platform_i2c_recv_byte( unsigned id, int ack ){ ...@@ -445,9 +445,9 @@ int platform_i2c_recv_byte( unsigned id, int ack ){
// ***************************************************************************** // *****************************************************************************
// SPI platform interface // SPI platform interface
uint32_t platform_spi_setup( unsigned id, int mode, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock) uint32_t platform_spi_setup( unsigned id, int mode, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock_div)
{ {
spi_master_init(id, cpol, cpha, databits, clock); spi_master_init(id, cpol, cpha, databits, clock_div);
return 1; return 1;
} }
......
...@@ -100,7 +100,7 @@ typedef uint32_t spi_data_type; ...@@ -100,7 +100,7 @@ typedef uint32_t spi_data_type;
// The platform SPI functions // The platform SPI functions
int platform_spi_exists( unsigned id ); int platform_spi_exists( unsigned id );
uint32_t platform_spi_setup( unsigned id, int mode, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock); uint32_t platform_spi_setup( unsigned id, int mode, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock_div);
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 );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment