1
0
mirror of https://github.com/elua/elua.git synced 2025-01-08 20:56:17 +08:00

XMC47: DAC module: Functions for pattern generation

This commit is contained in:
Raman 2019-01-19 16:36:15 +05:30
parent 3ebd57255d
commit 5536736595
5 changed files with 281 additions and 10 deletions

View File

@ -25,6 +25,7 @@ return {
linenoise = { shell_lines = 10, lua_lines = 50 }, linenoise = { shell_lines = 10, lua_lines = 50 },
xmodem = false, xmodem = false,
niffs = false, niffs = false,
xmc47_dac = true,
}, },
config = { config = {
egc = { mode = "alloc" }, egc = { mode = "alloc" },

View File

@ -26,6 +26,9 @@ function add_platform_components( t, board, cpu )
t.xmc45_rtc = { macro = 'ENABLE_RTC' } t.xmc45_rtc = { macro = 'ENABLE_RTC' }
t.xmc45_disp = { macro = 'ENABLE_OLED_DISPLAY' } t.xmc45_disp = { macro = 'ENABLE_OLED_DISPLAY' }
end end
if board == 'XMC4700-RELAX' then
t.xmc47_dac = { macro = 'ENABLE_DAC' }
end
end end
-- Add specific configuration to the 'configs' table -- Add specific configuration to the 'configs' table
@ -43,5 +46,8 @@ function get_platform_modules( board, cpu )
m.rtc = { guards = { 'ENABLE_RTC' }, lib = '"rtc"', open = false } m.rtc = { guards = { 'ENABLE_RTC' }, lib = '"rtc"', open = false }
m.disp = { guards = { 'ENABLE_OLED_DISPLAY' }, lib = '"disp"', open = false } m.disp = { guards = { 'ENABLE_OLED_DISPLAY' }, lib = '"disp"', open = false }
end end
if board == 'XMC4700-RELAX' then
m.dac = { guards = { 'ENABLE_DAC' }, lib = '"dac"', open = false }
end
return m return m
end end

View File

@ -1,7 +1,7 @@
-- eLua configuration file for the XMC4000 series of microcontrollers -- eLua configuration file for the XMC4000 series of microcontrollers
specific_files = "platform.c xmclib/src/xmc4_eru.c xmclib/src/xmc4_flash.c xmclib/src/xmc4_gpio.c xmclib/src/xmc4_rtc.c xmclib/src/xmc4_scu.c xmclib/src/xmc_can.c xmclib/src/xmc_ccu4.c xmclib/src/xmc_ccu8.c xmclib/src/xmc_common.c xmclib/src/xmc_dac.c xmclib/src/xmc_dma.c xmclib/src/xmc_dsd.c xmclib/src/xmc_ebu.c xmclib/src/xmc_ecat.c xmclib/src/xmc_eru.c xmclib/src/xmc_eth_mac.c xmclib/src/xmc_fce.c xmclib/src/xmc_gpio.c xmclib/src/xmc_hrpwm.c xmclib/src/xmc_i2c.c xmclib/src/xmc_i2s.c xmclib/src/xmc_ledts.c xmclib/src/xmc_posif.c xmclib/src/xmc_rtc.c xmclib/src/xmc_sdmmc.c xmclib/src/xmc_spi.c xmclib/src/xmc_uart.c xmclib/src/xmc_usbd.c xmclib/src/xmc_usic.c xmclib/src/xmc_vadc.c xmclib/src/xmc_wdt.c xmclib/gen/CLOCK_XMC4/clock_xmc4.c xmclib/gen/CLOCK_XMC4/clock_xmc4_conf.c xmclib/gen/UART/uart.c xmclib/gen/UART/uart_conf.c xmclib/gen/CPU_CTRL_XMC4/cpu_ctrl_xmc4.c xmclib/gen/CPU_CTRL_XMC4/cpu_ctrl_xmc4_conf.c xmclib/gen/FATFS/fatfs.c xmclib/gen/FATFS/fatfs_conf.c xmclib/gen/FATFS/sltha.c xmclib/gen/RTC/rtc.c xmclib/gen/RTC/rtc_conf.c xmclib/gen/SDMMC_BLOCK/sdmmc_block_private_sd.c xmclib/gen/SDMMC_BLOCK/sdmmc_block.c xmclib/gen/SDMMC_BLOCK/sdmmc_block_conf.c xmclib/gen/SYSTIMER/systimer.c xmclib/gen/SYSTIMER/systimer_conf.c xmclib/gen/DAVE.c pot.c dts.c rtc.c disp.c xmclib/gen/SPI_MASTER/spi_master.c xmclib/gen/SPI_MASTER/spi_master_conf.c xmclib/gen/GUI_SEGGERLIBRARY/gui_seggerlibrary.c xmclib/gen/GUI_SEGGERLIBRARY/gui_seggerlibrary_conf.c xmclib/gen/GUI_SEGGERLIBRARY/LCDConf.c xmclib/gen/GUI_SEGGERLIBRARY/Config/GUIConf.c xmclib/gen/GUI_SEGGERLIBRARY/Config/GUI_X.c ebu.c xmclib/gen/GLOBAL_DMA/global_dma.c xmclib/gen/GLOBAL_DMA/global_dma_conf.c" specific_files = "platform.c xmclib/src/xmc4_eru.c xmclib/src/xmc4_flash.c xmclib/src/xmc4_gpio.c xmclib/src/xmc4_rtc.c xmclib/src/xmc4_scu.c xmclib/src/xmc_can.c xmclib/src/xmc_ccu4.c xmclib/src/xmc_ccu8.c xmclib/src/xmc_common.c xmclib/src/xmc_dac.c xmclib/src/xmc_dma.c xmclib/src/xmc_dsd.c xmclib/src/xmc_ebu.c xmclib/src/xmc_ecat.c xmclib/src/xmc_eru.c xmclib/src/xmc_eth_mac.c xmclib/src/xmc_fce.c xmclib/src/xmc_gpio.c xmclib/src/xmc_hrpwm.c xmclib/src/xmc_i2c.c xmclib/src/xmc_i2s.c xmclib/src/xmc_ledts.c xmclib/src/xmc_posif.c xmclib/src/xmc_rtc.c xmclib/src/xmc_sdmmc.c xmclib/src/xmc_spi.c xmclib/src/xmc_uart.c xmclib/src/xmc_usbd.c xmclib/src/xmc_usic.c xmclib/src/xmc_vadc.c xmclib/src/xmc_wdt.c xmclib/gen/CLOCK_XMC4/clock_xmc4.c xmclib/gen/CLOCK_XMC4/clock_xmc4_conf.c xmclib/gen/UART/uart.c xmclib/gen/UART/uart_conf.c xmclib/gen/CPU_CTRL_XMC4/cpu_ctrl_xmc4.c xmclib/gen/CPU_CTRL_XMC4/cpu_ctrl_xmc4_conf.c xmclib/gen/FATFS/fatfs.c xmclib/gen/FATFS/fatfs_conf.c xmclib/gen/FATFS/sltha.c xmclib/gen/RTC/rtc.c xmclib/gen/RTC/rtc_conf.c xmclib/gen/SDMMC_BLOCK/sdmmc_block_private_sd.c xmclib/gen/SDMMC_BLOCK/sdmmc_block.c xmclib/gen/SDMMC_BLOCK/sdmmc_block_conf.c xmclib/gen/SYSTIMER/systimer.c xmclib/gen/SYSTIMER/systimer_conf.c xmclib/gen/DAVE.c pot.c dts.c rtc.c disp.c xmclib/gen/SPI_MASTER/spi_master.c xmclib/gen/SPI_MASTER/spi_master_conf.c xmclib/gen/GUI_SEGGERLIBRARY/gui_seggerlibrary.c xmclib/gen/GUI_SEGGERLIBRARY/gui_seggerlibrary_conf.c xmclib/gen/GUI_SEGGERLIBRARY/LCDConf.c xmclib/gen/GUI_SEGGERLIBRARY/Config/GUIConf.c xmclib/gen/GUI_SEGGERLIBRARY/Config/GUI_X.c ebu.c xmclib/gen/GLOBAL_DMA/global_dma.c xmclib/gen/GLOBAL_DMA/global_dma_conf.c dac.c"
local ldscript = "" local ldscript = ""
local target_files = "" local target_files = ""

241
src/platform/xmc4000/dac.c Normal file
View File

@ -0,0 +1,241 @@
// eLua Module for talking to the XMC's DAC peripheral
//
// Raman: I would really like to have this as a generic eLua module in
// src/modules/dac.c. More thoughts on stack. For now, we'll hack a
// simple function generator.
#include "lualib.h"
#include "lauxlib.h"
#include "platform.h"
#include "auxmods.h"
#include "lrotable.h"
#include "platform_conf.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "xmc_dac.h"
/* Local reference for a global DAC */
#define ELUA_XMC_DAC ( ( XMC_DAC_t * )( void * )DAC )
#define DAC_PATTERN_FIELDS 9
/* The DAC's amplitude in milli volts */
typedef enum DAC_AMP_MILLI_VOLTS_t {
DAC_AMP_MILLI_VOLTS_1 = 0,
DAC_AMP_MILLI_VOLTS_2,
DAC_AMP_MILLI_VOLTS_4,
DAC_AMP_MILLI_VOLTS_9,
DAC_AMP_MILLI_VOLTS_17,
DAC_AMP_MILLI_VOLTS_34,
DAC_AMP_MILLI_VOLTS_69,
DAC_AMP_MILLI_VOLTS_138,
DAC_AMP_MILLI_VOLTS_275,
DAC_AMP_MILLI_VOLTS_550,
DAC_AMP_MILLI_VOLTS_1100,
DAC_AMP_MILLI_VOLTS_2200,
} DAC_AMP_MILLI_VOLTS_t;
// ****************************************************************************
// DAC pattern mode
// Lua: dac.pattern.start( id )
static int dac_pattern_start( lua_State *L )
{
unsigned id;
id = luaL_checkinteger( L, 1 );
if( !( id < NUM_DAC ) )
return luaL_error( L, "dac %d does not exist", ( unsigned )id );
XMC_DAC_CH_EnableOutput( ELUA_XMC_DAC, id );
return 0;
}
// Lua: dac.pattern.stop( id )
static int dac_pattern_stop( lua_State *L )
{
unsigned id;
id = luaL_checkinteger( L, 1 );
if( !( id < NUM_DAC ) )
return luaL_error( L, "dac %d does not exist", ( unsigned )id );
XMC_DAC_CH_DisableOutput( ELUA_XMC_DAC, id );
return 0;
}
// Lua: dac.pattern.setup( id, pattern, amplitude, freq )
// Raman: How about the DAC offsets? You can generate some really
// strange signals with it!
static int dac_pattern_setup( lua_State *L )
{
XMC_DAC_CH_CONFIG_t dac_config;
uint32_t output_scale = 0;
int field; // Which field are we handling ( 0 - 8 )
uint8_t pat[ DAC_PATTERN_FIELDS ];
DAC_AMP_MILLI_VOLTS_t amp;
uint32_t freq;
unsigned id;
uint8_t patval;
id = luaL_checkinteger( L, 1 );
if( !( id < NUM_DAC ) )
return luaL_error( L, "dac %d does not exist", ( unsigned )id );
luaL_checktype( L, 2, LUA_TTABLE );
if( lua_objlen( L, 2) != DAC_PATTERN_FIELDS )
return luaL_error( L, "Pattern length must be 9 (PAT0, .. PAT8)" );
for( field = 0; field < DAC_PATTERN_FIELDS; field++ )
{
lua_pushinteger( L, field + 1 );
lua_gettable( L, 2 );
if( lua_isnumber( L, -1 ) )
{
patval = ( uint8_t )lua_tonumber( L, -1 );
if( patval < 0 || patval > 31 )
return luaL_error( L, "DAC's 5-bit pattern values must be between 0 - 31" );
pat[ field ] = patval;
}
else
{
return luaL_error( L, "DAC pattern: Expected number ( 0 - 31 )" );
}
lua_pop( L, 1 );
}
amp = luaL_checkinteger( L, 3 );
if( amp < DAC_AMP_MILLI_VOLTS_1 || amp > DAC_AMP_MILLI_VOLTS_2200 )
return luaL_error( L, "Invalid DAC amplitude setting" );
freq = luaL_checkinteger( L, 4 );
if( freq <= 0 )
return luaL_error( L, "DAC frequency must be > 0" );
dac_config.data_type = XMC_DAC_CH_DATA_TYPE_SIGNED;
dac_config.output_negation = XMC_DAC_CH_OUTPUT_NEGATION_DISABLED;
dac_config.output_offset = 0U;
switch( amp )
{
case DAC_AMP_MILLI_VOLTS_1:
output_scale = XMC_DAC_CH_OUTPUT_SCALE_DIV_32;
break;
case DAC_AMP_MILLI_VOLTS_2:
output_scale = XMC_DAC_CH_OUTPUT_SCALE_DIV_16;
break;
case DAC_AMP_MILLI_VOLTS_4:
output_scale = XMC_DAC_CH_OUTPUT_SCALE_DIV_8;
break;
case DAC_AMP_MILLI_VOLTS_9:
output_scale = XMC_DAC_CH_OUTPUT_SCALE_DIV_4;
break;
case DAC_AMP_MILLI_VOLTS_17:
output_scale = XMC_DAC_CH_OUTPUT_SCALE_DIV_2;
break;
case DAC_AMP_MILLI_VOLTS_34:
output_scale = XMC_DAC_CH_OUTPUT_SCALE_NONE;
break;
case DAC_AMP_MILLI_VOLTS_69:
output_scale = XMC_DAC_CH_OUTPUT_SCALE_MUL_2;
break;
case DAC_AMP_MILLI_VOLTS_138:
output_scale = XMC_DAC_CH_OUTPUT_SCALE_MUL_4;
break;
case DAC_AMP_MILLI_VOLTS_275:
output_scale = XMC_DAC_CH_OUTPUT_SCALE_MUL_8;
break;
case DAC_AMP_MILLI_VOLTS_550:
output_scale = XMC_DAC_CH_OUTPUT_SCALE_MUL_16;
break;
case DAC_AMP_MILLI_VOLTS_1100:
output_scale = XMC_DAC_CH_OUTPUT_SCALE_MUL_32;
break;
case DAC_AMP_MILLI_VOLTS_2200:
output_scale = XMC_DAC_CH_OUTPUT_SCALE_MUL_64;
break;
}
dac_config.output_scale = output_scale;
XMC_DAC_CH_Init( ELUA_XMC_DAC, id, &dac_config );
XMC_DAC_CH_StartPatternMode( ELUA_XMC_DAC, id, pat, XMC_DAC_CH_PATTERN_SIGN_OUTPUT_DISABLED, XMC_DAC_CH_TRIGGER_INTERNAL, freq );
//XMC_DAC_CH_SetMode( ELUA_XMC_DAC, id, XMC_DAC_CH_MODE_IDLE );
return 0;
}
// *****************************************************************************
// DAC function map
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
static const LUA_REG_TYPE dac_pattern_map[] =
{
{ LSTRKEY( "start" ), LFUNCVAL ( dac_pattern_start ) },
{ LSTRKEY( "setup" ), LFUNCVAL( dac_pattern_setup ) },
{ LSTRKEY( "stop" ), LFUNCVAL( dac_pattern_stop ) },
{ LNILKEY, LNILVAL }
};
const LUA_REG_TYPE dac_map[] =
{
#if LUA_OPTIMIZE_MEMORY > 0
/* { LSTRKEY( "noise" ), LROVAL( dac_noise_map ) }, */
{ LSTRKEY( "pattern" ), LROVAL( dac_pattern_map ) },
{ LSTRKEY( "MILLI_VOLTS_1" ), LNUMVAL( DAC_AMP_MILLI_VOLTS_1 ) },
{ LSTRKEY( "MILLI_VOLTS_2" ), LNUMVAL( DAC_AMP_MILLI_VOLTS_2 ) },
{ LSTRKEY( "MILLI_VOLTS_4" ), LNUMVAL( DAC_AMP_MILLI_VOLTS_4 ) },
{ LSTRKEY( "MILLI_VOLTS_9" ), LNUMVAL( DAC_AMP_MILLI_VOLTS_9 ) },
{ LSTRKEY( "MILLI_VOLTS_17" ), LNUMVAL( DAC_AMP_MILLI_VOLTS_17 ) },
{ LSTRKEY( "MILLI_VOLTS_34" ), LNUMVAL( DAC_AMP_MILLI_VOLTS_34 ) },
{ LSTRKEY( "MILLI_VOLTS_69" ), LNUMVAL( DAC_AMP_MILLI_VOLTS_69 ) },
{ LSTRKEY( "MILLI_VOLTS_138" ), LNUMVAL( DAC_AMP_MILLI_VOLTS_138 ) },
{ LSTRKEY( "MILLI_VOLTS_275" ), LNUMVAL( DAC_AMP_MILLI_VOLTS_275 ) },
{ LSTRKEY( "MILLI_VOLTS_550" ), LNUMVAL( DAC_AMP_MILLI_VOLTS_550 ) },
{ LSTRKEY( "MILLI_VOLTS_1100" ), LNUMVAL( DAC_AMP_MILLI_VOLTS_1100 ) },
{ LSTRKEY( "MILLI_VOLTS_2200" ), LNUMVAL( DAC_AMP_MILLI_VOLTS_2200 ) },
{ LSTRKEY( "__metatable" ), LROVAL( dac_map ) },
#endif
{ LNILKEY, LNILVAL }
};
LUALIB_API int luaopen_dac( lua_State *L )
{
#if LUA_OPTIMIZE_MEMORY > 0
return 0;
#else // #if LUA_OPTIMIZE_MEMORY > 0
luaL_register( L, AUXLIB_DAC, dac_map );
// Set it as its own metatable
lua_pushvalue( L, -1 );
lua_setmetatable( L, -2 );
// Set constants for direction/pullups
MOD_REG_NUMBER( L, "MILLI_VOLTS_1", DAC_AMP_MILLI_VOLTS_1 );
MOD_REG_NUMBER( L, "MILLI_VOLTS_2", DAC_AMP_MILLI_VOLTS_2 );
MOD_REG_NUMBER( L, "MILLI_VOLTS_4", DAC_AMP_MILLI_VOLTS_4 );
MOD_REG_NUMBER( L, "MILLI_VOLTS_9", DAC_AMP_MILLI_VOLTS_9 );
MOD_REG_NUMBER( L, "MILLI_VOLTS_17", DAC_AMP_MILLI_VOLTS_17 );
MOD_REG_NUMBER( L, "MILLI_VOLTS_34", DAC_AMP_MILLI_VOLTS_34 );
MOD_REG_NUMBER( L, "MILLI_VOLTS_69", DAC_AMP_MILLI_VOLTS_69 );
MOD_REG_NUMBER( L, "MILLI_VOLTS_138", DAC_AMP_MILLI_VOLTS_138 );
MOD_REG_NUMBER( L, "MILLI_VOLTS_275", DAC_AMP_MILLI_VOLTS_275 );
MOD_REG_NUMBER( L, "MILLI_VOLTS_550", DAC_AMP_MILLI_VOLTS_550 );
MOD_REG_NUMBER( L, "MILLI_VOLTS_1100", DAC_AMP_MILLI_VOLTS_1100 );
MOD_REG_NUMBER( L, "MILLI_VOLTS_2200", DAC_AMP_MILLI_VOLTS_2200);
// Setup the new tables (pattern, others) inside dac
lua_newtable( L );
luaL_register( L, NULL, dac_pattern_map );
lua_setfield( L, -2, "pattern" );
// lua_newtable( L );
// luaL_register( L, NULL, dac_noise_map );
// lua_setfield( L, -2, "noise" );
return 1;
#endif // #if LUA_OPTIMIZE_MEMORY > 0
}

View File

@ -16,11 +16,30 @@
// Platform includes // Platform includes
#include "DAVE.h" #include "DAVE.h"
#include "xmc_dac.h"
#if defined ( XMC4500_F144k1024 )
# include "XMC4500.h"
#endif
#if defined ( XMC4700_F144x2048 ) #if defined ( XMC4700_F144x2048 )
# include "XMC4700.h" # include "XMC4700.h"
#endif #endif
// Handles uart receive
uint8_t recv_byte;
// ****************************************************************************
// Function references
extern void ebu_main( void );
// Cleanup later: This should in theory be in inc/platform.h
void dacs_init( void );
// ****************************************************************************
// Platform initialization
/* /*
* Don't know why - the compiler complains that _init doesn't exist. I define the * Don't know why - the compiler complains that _init doesn't exist. I define the
* symbol now so he stops nagging me. * symbol now so he stops nagging me.
@ -29,14 +48,7 @@ void _init (void)
{ {
} }
// Handles uart receive /* Main platform initialization */
uint8_t recv_byte;
// ****************************************************************************
// Platform initialization
extern void ebu_main (void);
int platform_init() int platform_init()
{ {
DAVE_Init(); DAVE_Init();
@ -48,10 +60,12 @@ int platform_init()
ebu_main(); ebu_main();
#endif #endif
/* DAC */
dacs_init();
return PLATFORM_OK; return PLATFORM_OK;
} }
// **************************************************************************** // ****************************************************************************
// PIO // PIO
@ -213,3 +227,12 @@ u32 platform_uart_setup( unsigned id, u32 baud, int databits, int parity, int st
return 0; return 0;
} }
// ****************************************************************************
// DAC
void dacs_init( void )
{
/* SCU: Enable the DAC peripheral */
XMC_DAC_Enable( (XMC_DAC_t *)(void *)DAC );
}