Compare commits
8 commits
master
...
circuitpyt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49c0c1613d | ||
|
|
218b3826a9 | ||
|
|
7a6660134a | ||
|
|
7142b366a6 | ||
|
|
f998690e65 | ||
|
|
b7e38276a7 | ||
|
|
9323b67fce | ||
|
|
12538a7c45 |
4 changed files with 30 additions and 5 deletions
|
|
@ -123,9 +123,7 @@ static void __no_inline_not_in_flash_func(flash_cs_force)(bool high) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// May want to expose this at some point but this is unlikely to be the right
|
void __no_inline_not_in_flash_func(flash_do_cmd)(const uint8_t *txbuf, uint8_t *rxbuf, size_t count) {
|
||||||
// interface to do so. Keep it static
|
|
||||||
static void __no_inline_not_in_flash_func(flash_do_cmd)(const uint8_t *txbuf, uint8_t *rxbuf, size_t count) {
|
|
||||||
void (*connect_internal_flash)(void) = (void(*)(void))rom_func_lookup(rom_table_code('I', 'F'));
|
void (*connect_internal_flash)(void) = (void(*)(void))rom_func_lookup(rom_table_code('I', 'F'));
|
||||||
void (*flash_exit_xip)(void) = (void(*)(void))rom_func_lookup(rom_table_code('E', 'X'));
|
void (*flash_exit_xip)(void) = (void(*)(void))rom_func_lookup(rom_table_code('E', 'X'));
|
||||||
void (*flash_flush_cache)(void) = (void(*)(void))rom_func_lookup(rom_table_code('F', 'C'));
|
void (*flash_flush_cache)(void) = (void(*)(void))rom_func_lookup(rom_table_code('F', 'C'));
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,22 @@ void flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count)
|
||||||
*/
|
*/
|
||||||
void flash_get_unique_id(uint8_t *id_out);
|
void flash_get_unique_id(uint8_t *id_out);
|
||||||
|
|
||||||
|
/*! \brief Execute bidirectional flash command
|
||||||
|
* \ingroup hardware_flash
|
||||||
|
*
|
||||||
|
* Execute a bidirectional command to the flash. Bytes are simultaneously
|
||||||
|
* transmitted and received. Therefore, both buffers must be the same length,
|
||||||
|
* count, which is the length of the overall transaction. This is useful for
|
||||||
|
* reading metadata from the flash chip. Do *NOT* use it to mutate the data
|
||||||
|
* stored on the flash because it will not flush the cache.
|
||||||
|
*
|
||||||
|
* \param txbuf Pointer to a byte buffer which will be transmitted to the flash
|
||||||
|
* \param rxbuf Pointer to a byte buffer where data received from the flash will be written
|
||||||
|
* \param count Length in bytes of txbuf and of rxbuf
|
||||||
|
*/
|
||||||
|
void flash_do_cmd(const uint8_t *txbuf, uint8_t *rxbuf, size_t count);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,14 @@ uint i2c_set_baudrate(i2c_inst_t *i2c, uint baudrate) {
|
||||||
i2c->hw->fs_scl_lcnt = lcnt;
|
i2c->hw->fs_scl_lcnt = lcnt;
|
||||||
i2c->hw->fs_spklen = lcnt < 16 ? 1 : lcnt / 16;
|
i2c->hw->fs_spklen = lcnt < 16 ? 1 : lcnt / 16;
|
||||||
|
|
||||||
|
// The SDA hold time should be at least 300 ns, per the I2C standard.
|
||||||
|
// sda_hold_count [cycles] = freq_in [cycles/s]) * 300ns * (1s / 1e9ns)
|
||||||
|
// Reduce 300/1e9 to 3/1e7 to avoid really big numbers.
|
||||||
|
// Add 1 to avoid division truncation.
|
||||||
|
uint sda_hold_count = ((freq_in * 3) / 10000000) + 1;
|
||||||
|
i2c->hw->sda_hold =
|
||||||
|
I2C_IC_SDA_HOLD_IC_SDA_RX_HOLD_RESET << I2C_IC_SDA_HOLD_IC_SDA_RX_HOLD_LSB |
|
||||||
|
sda_hold_count << I2C_IC_SDA_HOLD_IC_SDA_TX_HOLD_LSB;
|
||||||
i2c->hw->enable = 1;
|
i2c->hw->enable = 1;
|
||||||
return freq_in / period;
|
return freq_in / period;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@
|
||||||
#include "hardware/regs/xosc.h"
|
#include "hardware/regs/xosc.h"
|
||||||
#include "hardware/structs/xosc.h"
|
#include "hardware/structs/xosc.h"
|
||||||
|
|
||||||
|
#define XOSC_STARTUP_DELAY_MULTIPLIER (64)
|
||||||
|
|
||||||
void xosc_init(void) {
|
void xosc_init(void) {
|
||||||
// Assumes 1-15 MHz input
|
// Assumes 1-15 MHz input
|
||||||
assert(XOSC_MHZ <= 15);
|
assert(XOSC_MHZ <= 15);
|
||||||
|
|
@ -20,7 +22,8 @@ void xosc_init(void) {
|
||||||
|
|
||||||
// Set xosc startup delay
|
// Set xosc startup delay
|
||||||
uint32_t startup_delay = (((12 * MHZ) / 1000) + 128) / 256;
|
uint32_t startup_delay = (((12 * MHZ) / 1000) + 128) / 256;
|
||||||
xosc_hw->startup = startup_delay;
|
// Lengthen startup delay to accomodate slow-starting oscillators
|
||||||
|
xosc_hw->startup = startup_delay * XOSC_STARTUP_DELAY_MULTIPLIER;
|
||||||
|
|
||||||
// Set the enable bit now that we have set freq range and startup delay
|
// Set the enable bit now that we have set freq range and startup delay
|
||||||
hw_set_bits(&xosc_hw->ctrl, XOSC_CTRL_ENABLE_VALUE_ENABLE << XOSC_CTRL_ENABLE_LSB);
|
hw_set_bits(&xosc_hw->ctrl, XOSC_CTRL_ENABLE_VALUE_ENABLE << XOSC_CTRL_ENABLE_LSB);
|
||||||
|
|
@ -43,4 +46,4 @@ void xosc_dormant(void) {
|
||||||
xosc_hw->dormant = XOSC_DORMANT_VALUE_DORMANT;
|
xosc_hw->dormant = XOSC_DORMANT_VALUE_DORMANT;
|
||||||
// Wait for it to become stable once woken up
|
// Wait for it to become stable once woken up
|
||||||
while(!(xosc_hw->status & XOSC_STATUS_STABLE_BITS));
|
while(!(xosc_hw->status & XOSC_STATUS_STABLE_BITS));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue