dac, adc switch and documentation

This commit is contained in:
Peter McGoron 2023-04-04 15:10:32 -04:00
parent b7ca97695a
commit e19a626945
4 changed files with 78 additions and 10 deletions

2
creole

@ -1 +1 @@
Subproject commit c7fc965fcfa72f26456f5221a6480de52f7d776a
Subproject commit 0ead095044c93825c7db8cec0a6b92769bac7a7d

View File

@ -2,9 +2,22 @@ m4_changequote(`⟨', `⟩')
m4_changecom(⟨/*⟩, ⟨*/⟩)
m4_define(generate_macro, ⟨m4_define(M4_$1, $2)⟩)
m4_include(../control_loop/control_loop_cmds.m4)
/* Since yosys only allows for standard Verilog (no system verilog),
* arrays (which would make everything much cleaner) cannot be used.
* A preprocessor is used instead, and M4 is used because it is much
* cleaner than the Verilog preprocessor (which is bad).
*/
/*********************************************************/
/********************** M4 macros ************************/
/*********************************************************/
/* This macro is used in the module declaration.
* The first argument is the number of wires the select switch must
* support (2 for most DACs, 3 for the control loop DAC).
* The second argument is the DAC number.
*/
m4_define(m4_dac_wires, ⟨
input [$1-1:0] dac_sel_$2,
output dac_finished_$2,
@ -27,12 +40,20 @@ m4_define(m4_dac_wires, ⟨
input wf_ram_valid_$2
⟩)
/* Same thing but for ADCs */
m4_define(m4_adc_wires, ⟨
output adc_finished_$2,
input adc_arm_$2,
output [$1-1:0] from_adc_$2
⟩)
/* This is used in the body of the module. It declares the interconnect
* for each DAC. The first argument is the amount of switch ports the
* DAC requires (2 for most DACs, 3 for the control loop DAC). The
* second argument is the DAC number.
*/
m4_define(m4_dac_switch, ⟨
wire [$1-1:0] mosi_port_$2;
wire [$1-1:0] miso_port_$2;
@ -111,6 +132,8 @@ m4_define(m4_dac_switch, ⟨
)
⟩)
/* Same thing but for ADCs */
m4_define(m4_adc_switch, ⟨
spi_master_ss_no_write #(
.WID($1),

View File

@ -18,6 +18,10 @@
LOG_MODULE_REGISTER(access);
/* The values from converters are not aligned to an 8-bit byte.
* These values are still in twos compliment and have to be
* manually sign-extended.
*/
static inline uint32_t
sign_extend(uint32_t in, unsigned len)
{
@ -74,6 +78,7 @@ dac_read_write(int dac, creole_word send, k_timeout_t timeout,
int e = dac_take(dac, timeout);
if (e != 0)
return e;
dac_switch(dac, DAC_SPI_PORT, K_NO_WAIT);
*to_dac[dac] = send;
*dac_arm[dac] = 1;
@ -94,6 +99,19 @@ dac_read_write(int dac, creole_word send, k_timeout_t timeout,
return 0;
}
int
dac_switch(int dac, int setting, k_timeout_t timeout)
{
int e = dac_take(dac, timeout);
if (e != 0)
return e;
*dac_sel[dac] = setting;
dac_release(dac);
return 0;
}
/**********************
* adc read
*********************/
@ -132,6 +150,25 @@ adc_release(int adc)
return e;
}
int
adc_switch(int adc, int setting, k_timeout_t timeout)
{
/* As of now, only one ADC (the CLOOP adc) is used
* by two modules at the same time.
*/
if (adc != 0)
return -ENOENT;
int e = adc_take(adc, timeout);
if (e != 0)
return e;
*adc_sel_0 = setting;
adc_release(adc);
return 0;
}
int
adc_read(int adc, k_timeout_t timeout, creole_word *wrd)
{
@ -139,6 +176,7 @@ adc_read(int adc, k_timeout_t timeout, creole_word *wrd)
if ((e = adc_take(adc, timeout)) != 0)
return e;
adc_switch(adc, ADC_SPI_PORT, K_NO_WAIT);
*adc_arm[adc] = 1;
/* Recursive locks should busy wait. */
@ -173,15 +211,10 @@ cloop_take(k_timeout_t timeout)
int
cloop_release(void)
{
/* If being unlocked for the last time. */
if (cloop_locked == 1) {
*cl_cmd = CONTROL_LOOP_WRITE_BIT | CONTROL_LOOP_STATUS;
cl_word_out[0] = 0;
cl_word_out[1] = 0;
*cl_start_cmd = 1;
while (!*cl_finish_cmd);
*cl_start_cmd = 0;
}
/* Do not attempt to reset the CLOOP interface.
* Other scripts will fight to modify the CLOOP constants
* while the loop is still running.
*/
int e = k_mutex_unlock(&cloop_mutex);
if (e == 0) {
cloop_locked--;
@ -320,6 +353,8 @@ waveform_arm(int slot, bool halt_on_finish, uint32_t wait, k_timeout_t timeout)
return 0;
}
dac_switch(slot, DAC_WF_PORT, K_NO_WAIT);
*wf_halt_on_finish[slot] = halt_on_finish;
*wf_time_to_wait[slot] = wait;
*wf_arm[slot] = 1;

View File

@ -7,10 +7,20 @@ int dac_release(int dac);
int dac_read_write(int dac, creole_word send, k_timeout_t timeout,
creole_word *recv);
/* These ports are defined in firmware/rtl/base/base.v.m4 */
#define DAC_SPI_PORT 0
#define DAC_WF_PORT 1
#define DAC_CLOOP_PORT 2
int dac_switch(int dac, int setting, k_timeout_t timeout);
int adc_take(int adc, k_timeout_t timeout);
int adc_release(int adc);
int adc_read(int adc, k_timeout_t timeout, creole_word *wrd);
#define ADC_SPI_PORT 0
#define ADC_CLOOP_PORT 1
int adc_switch(int adc, int setting, k_timeout_t timeout);
int cloop_take(k_timeout_t timeout);
int cloop_read(int code, uint32_t *high_reg, uint32_t *low_reg,
k_timeout_t timeout);