Thanks @ESP_Sprite for your reply
I have changed mode to HALF-DUPLEX and I've added CS delay (.cs_ena_pretrans), as you suggested. Basic communication started working but sending anything messes up in communication:
Code: Select all
static void ds1390_spi_init() {
spi_bus_config_t buscfg = {
.miso_io_num=PIN_NUM_SPI_MISO, .mosi_io_num=PIN_NUM_SPI_MOSI, .sclk_io_num=PIN_NUM_SPI_CLK,
.quadwp_io_num=-1, .quadhd_io_num=-1,
.max_transfer_sz=256 // ************
};
spi_device_interface_config_t devcfg = {
.spics_io_num=PIN_NUM_SPI_RTC_CS,
.clock_speed_hz=4000000, // 4MHz max
.mode=1, // SPI MODE 1
.command_bits=8, // 8-bit command length
.queue_size=1,
.input_delay_ns = 80, // SCLK to Data Valid tCDD 80ns max
.cs_ena_pretrans = 2, // CS to SCLK Setup tCC 400ns min; 2*1/4MHz=500ns
.flags = SPI_DEVICE_HALFDUPLEX
};
spi_bus_initialize(VSPI_HOST, &buscfg, 1 /*dma_chan - 0 no DMA*/);
ESP_ERROR_CHECK(spi_bus_add_device(VSPI_HOST, &devcfg, &ds1390_spi));
}
static void ds1390_trickle_charger_init() {
ESP_LOGI(TAG, "ds1390_trickle_charger_init");
spi_transaction_t transaction;
memset(&transaction, 0, sizeof(transaction));
transaction.cmd = DS1390_REG_TRICKLE | DS1390_REG_WRITE_MASK;
transaction.length = 8;
transaction.flags = SPI_TRANS_USE_TXDATA;
transaction.tx_data[0] = DS1390_TRICKLE_CHARGER_ENABLE | DS1390_TRICKLE_CHARGER_NO_DIODE | DS1390_TRICKLE_CHARGER_2K_OHM;
assert(spi_device_polling_transmit(ds1390_spi, &transaction) == ESP_OK);
}
void ds1390_set_time() {
ESP_LOGI(TAG, "ds1390_set_time");
uint8_t data[8] = {
ds1390_dec2bcd(0) /* Hundredths of Seconds */,
ds1390_dec2bcd(23) /* Seconds */,
ds1390_dec2bcd(24) /* Minutes */,
ds1390_dec2bcd(16) /* Hours */,
ds1390_dec2bcd(3) /* Day */,
ds1390_dec2bcd(3) /* Date */,
ds1390_dec2bcd(12) /* Month / Century */,
ds1390_dec2bcd(19) /* Year */
};
spi_transaction_t transaction;
memset(&transaction, 0, sizeof(transaction));
transaction.cmd = DS1390_REG_100THS | DS1390_REG_WRITE_MASK;
transaction.length = 8 * 8;
transaction.tx_buffer = data;
assert(spi_device_polling_transmit(ds1390_spi, &transaction) == ESP_OK);
}
void ds1390_get_time() {
ESP_LOGI(TAG, "ds1390_get_time");
char * buffer = heap_caps_malloc(8, MALLOC_CAP_DMA);
spi_transaction_t transaction;
memset(&transaction, 0, sizeof(transaction));
transaction.cmd = DS1390_REG_SECONDS;
transaction.rx_buffer = buffer;
transaction.rxlength = 7 * 8;
transaction.length = transaction.rxlength;
assert(spi_device_polling_transmit(ds1390_spi, &transaction) == ESP_OK);
ESP_LOGI(TAG, "DS1390 Time: %02x %02x %02x %02x %02x %02x %02x %02x", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]);
free(buffer);
}
When whole executed code looks like:
Code: Select all
ds1390_initialise();
while (1) {
ds1390_get_time();
vTaskDelay(200 / portTICK_PERIOD_MS);
}
Log is
OK, eg:
DS1390 Time: 14 26 16 03 03 12 19 00
when code looks like:
Code: Select all
ds1390_initialise();
ds1390_trickle_charger_init();
while (1) {
ds1390_get_time();
vTaskDelay(200 / portTICK_PERIOD_MS);
}
Log is
INVALID - last byte is missing:
DS1390 Time: 14 26 16 03 03 12 00 00
when code looks like:
Code: Select all
ds1390_initialise();
ds1390_set_time();
while (1) {
ds1390_get_time();
vTaskDelay(200 / portTICK_PERIOD_MS);
}
Log is
INVALID - first byte is ok, all the rest looks random:
DS1390 Time: 25 00 00 00 cc 6c fb 3f
Adding delay (vTaskDelay or ets_delay_us) before while loop changes nothing.
All bytes are valid, doesnt mater if I add ds1390_trickle_charger_init / ds1390_set_time or not. Logic analyzer screen: