Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TCAN4550 development #46

Open
wants to merge 16 commits into
base: master
Choose a base branch
from

Conversation

maksimdrachov
Copy link

@maksimdrachov maksimdrachov commented Jun 26, 2024

Hi, Maksim. I have implemented the following things:

  • CAN Initialisation, incl. settings for MRAM layout, bit timing parameters etc
  • SID and XID filter setting
  • CAN message sending

I am currently testing and debugging upon necessity. I am using ESP32 as an MCU for tests. My API needs custom implementation of functions to read and write a 32-bit register for every used MCU. As long as I use ESP32, I am implementing those read/write funcs with ESP-IDF and I am currently experiencing some abnormal behaviour. May I please ask for a quick advice on the write function? If this function is debugged, the rest will be much easier to verify.

Thanks in advance!

This is the repo for ESP32 project (I test the driver there):
https://github.com/bragin-d/driver-tests

And this is the main repo (fork of your platform-specific-components). This one is not needed for you now, but still:

https://github.com/bragin-d/platform_specific_components

The problem is in components/lib/src/ti_can.c. This is the source code of the driver. spiRegisterWrite function is implemented there. spiRegisterRead works as expected. When I was debugging the write function, I decided to hardcode the tx_buffer. Now whenever you build and run the project, some simple code is executed from initCAN() function. The weird thing is that the first function that gets executed in initCAN() is the read function, meaning that the register hasn't yet been written. But if you run the code and change hardcoded values to smth else, they will already be in the register on the first read. If spiRegisterWrite works, then there is a high chance that driver from my fork of platform-specific-components can send CAN messages

I used esp32 wroom-32 for tests

@bragin-d
Copy link

bragin-d commented Jun 26, 2024

In the provided driver, SPI write and read functions are exclusive for a specific MCU. Currently it is being tested with ESP32 WROOM-32. When implementing the write functions, an anomaly appeared. The values in the TX buffer of the write function have been hardcoded for testing purposes. Surprisingly, whenever the spiRegisterRead() function is called (fully tested and functional) before the values have been written by spiRegisterWrite(), values seem to be already in the register (register for read/write tests: 0x0808 of TCAN4550).

Below is the read/write and init functions:

`
void spi_init() {
esp_err_t ret;

// Configure the SPI bus
spi_bus_config_t buscfg = {
    .miso_io_num = PIN_NUM_MISO,
    .mosi_io_num = PIN_NUM_MOSI,
    .sclk_io_num = PIN_NUM_CLK,
    .quadwp_io_num = -1,
    .quadhd_io_num = -1,
    .max_transfer_sz = 4096,
};

// Initialize the SPI bus
ret = spi_bus_initialize(VSPI_HOST, &buscfg, 1);
assert(ret == ESP_OK);

// Configure the SPI device
spi_device_interface_config_t devcfg = {
    .clock_speed_hz = 26 * 1000 * 1000,    // Clock out at 10 MHz
    .mode = 0,                             // SPI mode 0
    
    .spics_io_num = PIN_NUM_CS,            // CS pin
    .queue_size = 7,                     
    .pre_cb = NULL,
    .post_cb = NULL,
    .command_bits = 8,                     // Important! 
    .address_bits = 16                     // Important!
};

// Attach the SPI device to the SPI bus
ret = spi_bus_add_device(VSPI_HOST, &devcfg, &spi);
assert(ret == ESP_OK);

}

uint8_t spiRegisterWrite(uint16_t reg_addr, uint32_t reg_value, uint32_t * pointer) {

uint8_t tx_buffer[5];
uint8_t rx_buffer[5];

tx_buffer[1] = 0xFF;
tx_buffer[2] = 0xFF;
tx_buffer[3] = 0xAA;
tx_buffer[4] = 0xAA;

spi_transaction_t t;

memset(&t, 0, sizeof(spi_transaction_t));

t.cmd = SPI_WRITE_OPCODE;
t.addr = reg_addr;
t.length = 5 * 8; // length byte
t.rxlength = 5 * 8;
t.rx_buffer = NULL;
t.tx_buffer = tx_buffer;

spi_device_transmit(spi, &t);


return 0;

}

uint32_t spiRegisterRead(uint16_t reg_addr) {

// TODO: Process global status byte
// TODO: Consider switching to working with pointers

uint8_t rx_buffer[5];

spi_transaction_t t;

memset(&t, 0, sizeof(spi_transaction_t)); 

t.cmd = SPI_READ_OPCODE;
t.addr = reg_addr;
t.length = 5 * 8; // length byte
t.rxlength = 5 * 8;
t.rx_buffer = rx_buffer;
t.tx_buffer = NULL;

// Transmit the dummy bytes to read the actual data
spi_device_transmit(spi, &t);

// Combine the received bytes into a 32-bit value
uint32_t reg_value = ((uint64_t)rx_buffer[1] << 24) |
            ((uint64_t)rx_buffer[2] << 16) | ((uint64_t)rx_buffer[3] << 8) | (rx_buffer[4]);

return reg_value;

}

`

This is the way functions were called:

`
uint32_t value = 0;

spi_init();

printf("Initialized SPI\n");

// TODO: Cover edge cases for values in structs + error reporting

value = spiRegisterRead(0x0808);

printf("Test reg value: %lX\n", value);

value = spiRegisterRead(0x0808);

printf("Test reg value: %lX\n", value);

spiRegisterWrite(0x0808, 0xBB, NULL);

value = spiRegisterRead(0x0808);

printf("Test reg value: %lX\n", value);

`

@bragin-d
Copy link

Issue seems to have been resolved. Steps taken:

  • Length of dummy data section has been explicitly set
  • The byte indicating the length of data is now added to the TX buffer as the first element

Updated code:

`
uint8_t spiRegisterWrite(uint16_t reg_addr, uint32_t reg_value, uint32_t * pointer) {

uint8_t tx_buffer[] =
{
    0x04,
    (uint8_t)(reg_value >> 24),
    (uint8_t)(reg_value >> 16), 
    (uint8_t)(reg_value >> 8),  
    (uint8_t)(reg_value) 
};

spi_transaction_t t;

memset(&t, 0, sizeof(spi_transaction_t)); 

t.cmd = SPI_WRITE_OPCODE;
t.addr = reg_addr;
t.length = 5 * 8; // length byte
t.rxlength = 5 * 8;
t.rx_buffer = NULL;
t.tx_buffer = tx_buffer;

// Transmit the dummy bytes to read the actual data
spi_device_transmit(spi, &t);

return 0;

}
`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants