LoadProhibited Exception in driver/i2s.c

BuddyCasino
Posts: 263
Joined: Sun Jun 19, 2016 12:00 am

LoadProhibited Exception in driver/i2s.c

Postby BuddyCasino » Sun Jan 15, 2017 2:29 pm

I'm trying to get I2S to work, and I've hit a problem.
I call i2s_push_sample() like so, just for test purposes and to avoid other error sources with a zero sample:

Code: Select all

const uint32_t zero_sample[2] = { 0 };
void render_sample_block(short *short_sample_buff, int no_samples) {
    i2s_push_sample(I2S_NUM_0,  (const char*) zero_sample, portMAX_DELAY);
}
This is the I2S driver function thats being called, which is the current esp-idf SDK driver. The line that fails is "*data_ptr++ = *sample++;", xtensa-esp32-elf-addr2line output says "esp-idf/components/driver/i2s.c:767 (discriminator 3)".

Code: Select all

int i2s_push_sample(i2s_port_t i2s_num, const char *sample, TickType_t ticks_to_wait)
{
    int i, bytes_to_push = 0;
    char *data_ptr;
    I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_FAIL);
    if (p_i2s_obj[i2s_num]->tx->rw_pos == p_i2s_obj[i2s_num]->tx->buf_size || p_i2s_obj[i2s_num]->tx->curr_ptr == NULL) {
        if (xQueueReceive(p_i2s_obj[i2s_num]->tx->queue, &p_i2s_obj[i2s_num]->tx->curr_ptr, ticks_to_wait) == pdFALSE) {
            return 0;
        }
        ESP_LOGD(I2S_TAG, "rw_pos: %d, buf_size: %d, curr_ptr: %d", p_i2s_obj[i2s_num]->tx->rw_pos, p_i2s_obj[i2s_num]->tx->buf_size, (int)p_i2s_obj[i2s_num]->tx->curr_ptr);
        p_i2s_obj[i2s_num]->tx->rw_pos = 0;
    }
    data_ptr = (char*)p_i2s_obj[i2s_num]->tx->curr_ptr;
    data_ptr += p_i2s_obj[i2s_num]->tx->rw_pos;
    for (i = 0; i < p_i2s_obj[i2s_num]->bytes_per_sample; i++) {
        *data_ptr++ = *sample++;
        bytes_to_push ++;
    }
    
[...removed...]

}

This is the error message from the UART:

Code: Select all

Guru Meditation Error of type LoadProhibited occurred on core  0. Exception was unhandled.
Register dump:
PC      : 0x401087f4
PS      : 0x00060830
A0      : 0x801065a6
A1      : 0x3ffd0d60
A2      : 0x00000000
A3      : 0x00000000
A4      : 0x00000000
A5      : 0x00000000
A6      : 0x000003c0
A7      : 0x3ffb6fc0
A8      : 0x3ffbc474
A9      : 0x3ffd4290
A10     : 0x00000002
A11     : 0x00000000
A12     : 0x3ffbc87c
A13     : 0x00000000
A14     : 0x3ffbc8b0
A15     : 0x46640406
SAR     : 0x00000004
EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000
LBEG    : 0x4000c2e0
LEND    : 0x4000c2f6
LCOUNT  : 0xffffffff

Backtrace: 0x401087f4:0x3ffd0d60 0x401065a6:0x3ffd0d90 0x40106686:0x3ffd0db0
I attached a JTAG debugger and set a breakpoint at the offending line, this is the memory of the variables, maybe this is helpful?

Code: Select all

const char *data_ptr : 0x3FFD335D <Hex>
  Address   0 - 3     4 - 7     8 - B     C - F               
  3FFD32F0  00000000  00000000  00000000  00000000          
  3FFD3300  00000000  00000000  00000000  00000000          
  3FFD3310  00000000  00000000  40000080  5C33FD3F          
  3FFD3320  6437FD3F  6C3BFD3F  743FFD3F  7C43FD3F          
  3FFD3330  8447FD3F  8C4BFD3F  944FFD3F  9C53FD3F          
  3FFD3340  A457FD3F  AC5BFD3F  B45FFD3F  BC63FD3F          
  3FFD3350  C467FD3F  00000000  08040080  00000000          
  3FFD3360  00000000  00000000  00000000  00000000          
  3FFD3370  00000000  00000000  00000000  00000000          
  3FFD3380  00000000  00000000  00000000  00000000          
  3FFD3390  00000000  00000000  00000000  00000000          
  3FFD33A0  00000000  00000000  00000000  00000000          
  3FFD33B0  00000000  00000000  00000000  00000000          

Code: Select all

const char	*sample : 0x1 <Hex>
  Address   0 - 3     4 - 7     8 - B     C - F               
  00000000  00000000  00000000  00000000  00000000          
  00000010  00000000  00000000  00000000  00000000          
  00000020  00000000  00000000  00000000  00000000          
  00000030  00000000  00000000  00000000  00000000          
  00000040  00000000  00000000  00000000  00000000          
  00000050  00000000  00000000  00000000  00000000          
  00000060  00000000  00000000  00000000  00000000          
  00000070  00000000  00000000  00000000  00000000          
  00000080  00000000  00000000  00000000  00000000          
  00000090  00000000  00000000  00000000  00000000   
I have a theory that the "const char *sample" variable is in a memory region that may not be read, address 00000000 sure looks suspicious to me. I don't know how to move into a different memory region though, I tried declaring the variable like like this:

Code: Select all

DRAM_ATTR const uint32_t zero_sample[2] = { 0 };
but that didn't help.

Any ideas?

BuddyCasino
Posts: 263
Joined: Sun Jun 19, 2016 12:00 am

Re: LoadProhibited Exception in driver/i2s.c

Postby BuddyCasino » Sun Jan 15, 2017 5:34 pm

Ok, I think I've found the issue. The I2S subsystem was called from another location which sent a zero address while attempting to fill the DMA buffer with silence.

Sorry!

User avatar
Jakobsen
Posts: 89
Joined: Mon Jan 16, 2017 8:12 am

Re: LoadProhibited Exception in driver/i2s.c

Postby Jakobsen » Mon Jan 16, 2017 8:41 am

Hi
I also is trying to get the i2s driver pump out data and has still not succeed.

Did a simple test using the exsample/22_i2s/ -
I crank up the data rate 44100, 32 bits pr sample, I2S_rigth_left mode and allocated some DMA buffers.
DMA allocation look ok, From the specified number of buffers and length to the allocated memory when the i2s_driver gets install.

Each time i call i2s_push_sample it return 8 as expected, 32 bits (4 byte) right audio data and 32 bits (4 byte) left audio data.

But when I capture data on i2s_data_out it looks like only 16 bits get pumped out 2 bytes right, 2 bytes left and every second sample set is corrupted. BCK and WS are as expected.

I am very happy to have found the I2s example and at least have some things working. Code quality of the driver look very good - sure we can get it working.

I will post scope plots and code example later to night when I get back from my day job @ #merus-audio :-)

/Jakobsen
Analog Digital IC designer / DevOps @ Merus Audio, Copenhagen, Denmark.
We do novel and best in class Audio amplifiers for consumer products.
Programmed assembler for C-64 back in 1980's, learned some electronics - hacking since then

BuddyCasino
Posts: 263
Joined: Sun Jun 19, 2016 12:00 am

Re: LoadProhibited Exception in driver/i2s.c

Postby BuddyCasino » Mon Jan 16, 2017 9:11 am

I'm only using 16 Bit / 44,1kHz and only got it to work since yesterday.
My Rigol DS1054Z has no I2S decoder afaik, how do you verify the data?

User avatar
Jakobsen
Posts: 89
Joined: Mon Jan 16, 2017 8:12 am

Re: LoadProhibited Exception in driver/i2s.c

Postby Jakobsen » Mon Jan 16, 2017 10:15 pm

I made my own chip - but I would not recommed that :-)

We support up till 24 bits but requires a full 64 bits frame on WC, if not at faster related MCLK is pressent.
Amplifier/Codec differ on flexiblity in the interface here.

BuddyCasino get a Amplifier/Codec - your ear is you best friend here. Where are you located?

If I get a working setup I will let you know here you can get my amplifier 2x40 or 2x70 watts, digital input and beats all other amplifiers on idle/low volume power consumption.
/Jakobsen
Analog Digital IC designer / DevOps @ Merus Audio, Copenhagen, Denmark.
We do novel and best in class Audio amplifiers for consumer products.
Programmed assembler for C-64 back in 1980's, learned some electronics - hacking since then

BuddyCasino
Posts: 263
Joined: Sun Jun 19, 2016 12:00 am

Re: LoadProhibited Exception in driver/i2s.c

Postby BuddyCasino » Tue Jan 17, 2017 8:30 am

I'm using this one:
https://www.adafruit.com/product/3006

Doesn't need MCLCK, works great. It would be nice though to see that the data is actually clean and I'm not loosing precision due to signal integrity issue, which definitely is an issue with the speeds I2S operates at (at least on a breadboard).

Who is online

Users browsing this forum: MicroController and 185 guests