From 65a034de675085680208f5d0db8b222cd62ef166 Mon Sep 17 00:00:00 2001 From: true Date: Sun, 28 Jul 2024 16:16:03 -0700 Subject: [PATCH] improve i2c; add gpio init functions; some minor fixups and cleanup i2c is totally fucking broken though and needs to be replaced before con. --- code/firmware/user/main.c | 47 +++++++++++++++++++++++++++++++ code/firmware/user/src/31fl3729.c | 5 ++++ code/firmware/user/src/31fl3729.h | 4 +++ code/firmware/user/src/adc.c | 10 ++++--- code/firmware/user/src/eeprom.c | 22 +++++++++++++++ code/firmware/user/src/eeprom.h | 6 ++++ code/firmware/user/src/i2c.c | 34 ++++++++++++++++++++-- code/firmware/user/src/i2c.h | 2 ++ 8 files changed, 123 insertions(+), 7 deletions(-) diff --git a/code/firmware/user/main.c b/code/firmware/user/main.c index 2f98fc9..c91788a 100644 --- a/code/firmware/user/main.c +++ b/code/firmware/user/main.c @@ -38,6 +38,50 @@ void systick_init(void) NVIC_EnableIRQ(SysTicK_IRQn); // enable interrupt } +void gpio_init() +{ + GPIO_InitTypeDef gpio = {0}; + + gpio.GPIO_Speed = GPIO_Speed_2MHz; + + // Soft I2C, USART TX/RX; currently unused + gpio.GPIO_Mode = GPIO_Mode_IPD; + gpio.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6; + GPIO_Init(GPIOD, &gpio); + + gpio.GPIO_Pin = GPIO_Pin_1; + GPIO_Init(GPIOA, &gpio); + + // lightsense LED anode + gpio.GPIO_Mode = GPIO_Mode_Out_OD; + gpio.GPIO_Pin = GPIO_Pin_0; + GPIO_Init(GPIOD, &gpio); + + // unused pins + gpio.GPIO_Mode = GPIO_Mode_IPD; + gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_7; + GPIO_Init(GPIOC, &gpio); + + gpio.GPIO_Pin = GPIO_Pin_2; + GPIO_Init(GPIOD, &gpio); + + // I2C will be handled by the driver + + // IS_SDB IS31FL3729 shutdown pin (active low) + GPIOC->BCR = GPIO_Pin_3; + gpio.GPIO_Mode = GPIO_Mode_Out_OD; + gpio.GPIO_Pin = GPIO_Pin_3; + GPIO_Init(GPIOC, &gpio); + + // BTN1, BTN2 will be handled by button handler + + // WP for EEPROM + GPIOC->BSHR = GPIO_Pin_6; + gpio.GPIO_Mode = GPIO_Mode_Out_OD; + gpio.GPIO_Pin = GPIO_Pin_6; + GPIO_Init(GPIOC, &gpio); +} + /********************************************************************* * @fn main * @@ -57,6 +101,9 @@ int main(void) RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_ADC1 | RCC_APB2Periph_TIM1, ENABLE); + // configure gpio pins + gpio_init(); + // get saved settings i2c_init(); userconf_load(); diff --git a/code/firmware/user/src/31fl3729.c b/code/firmware/user/src/31fl3729.c index 33f00cf..33a0966 100644 --- a/code/firmware/user/src/31fl3729.c +++ b/code/firmware/user/src/31fl3729.c @@ -18,6 +18,11 @@ void is31fl3729_init(uint8_t i2c_addr, uint8_t config, uint8_t global_current) { uint8_t buf; + // enable device +#ifdef FL3729_SDB_PORT + FL3729_SDB_PORT->BSHR = FL3729_SDB_PIN; +#endif + // reset config registers buf = FL3729_RESET_VALUE; i2c_write_addr1b(i2c_addr, FL3729_REG_RESET, &buf, 1); diff --git a/code/firmware/user/src/31fl3729.h b/code/firmware/user/src/31fl3729.h index 22ccd21..a243bbf 100644 --- a/code/firmware/user/src/31fl3729.h +++ b/code/firmware/user/src/31fl3729.h @@ -7,10 +7,14 @@ +#include #include +#define FL3729_SDB_PORT GPIOC +#define FL3729_SDB_PIN GPIO_Pin_3 + #define FL3729_BASE_ADDR 0x68 #define FL3729_ADPIN_GND 0 diff --git a/code/firmware/user/src/adc.c b/code/firmware/user/src/adc.c index 8247ede..1032455 100644 --- a/code/firmware/user/src/adc.c +++ b/code/firmware/user/src/adc.c @@ -13,13 +13,15 @@ +// deadzone fudge factors for potentionmeter. test on actual badge +// and see if necessary, or if pot hardware + adc periph is good enough #define POT_LO 40 #define POT_HI (1024-POT_LO) -uint16_t adc_idx; uint16_t adc_val[16]; +uint16_t adc_val_idx; uint16_t adc_avg; uint16_t lsens_val; @@ -80,9 +82,9 @@ void adc_convert() void adc_read() { while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); - adc_val[adc_idx++] = ADC_GetConversionValue(ADC1); - adc_idx &= 0x0f; - if (!adc_idx) adc_calc_avg(); + adc_val[adc_val_idx++] = ADC_GetConversionValue(ADC1); + adc_val_idx &= 0x0f; + if (!adc_val_idx) adc_calc_avg(); if (ADC1->CTLR1 & ADC_JAUTO) { while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_JEOC)); diff --git a/code/firmware/user/src/eeprom.c b/code/firmware/user/src/eeprom.c index 0ab9e85..b802777 100644 --- a/code/firmware/user/src/eeprom.c +++ b/code/firmware/user/src/eeprom.c @@ -14,6 +14,7 @@ #include #include +#include "eeprom.h" #include "i2c.h" @@ -52,5 +53,26 @@ void eeprom_write_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len) page |= EEPROM_BASE_ADDR; // add address to page page <<= 1; // make i2c address from page + // disable systick interrupt + NVIC_DisableIRQ(SysTicK_IRQn); + + // write the data +#ifdef EEPROM_WP_PORT + EEPROM_WP_PORT->BCR = EEPROM_WP_PIN; +#endif + + while (i2c_ack_poll(page)); i2c_write_addr1b(page, addr, data, len); + while (i2c_ack_poll(page)); + +#ifdef EEPROM_WP_PORT + EEPROM_WP_PORT->BSHR = EEPROM_WP_PIN; +#endif + + // clear systick timer + SysTick->CNT = 0; + SysTick->SR = 0; + + // re-enable systick interrupt + NVIC_EnableIRQ(SysTicK_IRQn); } diff --git a/code/firmware/user/src/eeprom.h b/code/firmware/user/src/eeprom.h index 5a553d1..d498341 100644 --- a/code/firmware/user/src/eeprom.h +++ b/code/firmware/user/src/eeprom.h @@ -9,10 +9,16 @@ #define USER_SRC_EEPROM_H_ +#include #include +#define EEPROM_WP_PORT GPIOC +#define EEPROM_WP_PIN GPIO_Pin_7 + + + void eeprom_read_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len); void eeprom_write_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len); diff --git a/code/firmware/user/src/i2c.c b/code/firmware/user/src/i2c.c index f45ddd3..3620857 100644 --- a/code/firmware/user/src/i2c.c +++ b/code/firmware/user/src/i2c.c @@ -1,13 +1,23 @@ /* * i2c.c * - * Created on: Jul 27, 2024 - * Author: true + * routines more or less copied from WCH example code, then fucked around with to work. + * + * these routines have serious issues. + * - any i2c issue will lock up the machine, and there's no timeout handlers + * - there's no error handling of any kind + * - the library code makes some serious assumptions re: flags + * + * this MUST be fixed before con. */ #include + +#define I2C_TIMEOUT 0xffff; + + void i2c_init() { GPIO_InitTypeDef gpio = {0}; @@ -87,5 +97,23 @@ void i2c_write_addr1b(uint8_t devaddr, uint8_t addr, uint8_t *data, uint8_t len) } } - I2C_GenerateSTOP( I2C1, ENABLE ); + I2C_GenerateSTOP(I2C1, ENABLE); +} + +int8_t i2c_ack_poll(uint8_t devaddr) +{ + int8_t addr_match = 0; + + while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET); + I2C_GenerateSTART(I2C1, ENABLE); + + while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); + I2C_Send7bitAddress(I2C1, devaddr, I2C_Direction_Receiver); + + if (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) + addr_match = -1; + + I2C_GenerateSTOP(I2C1, ENABLE); + + return addr_match; } diff --git a/code/firmware/user/src/i2c.h b/code/firmware/user/src/i2c.h index 2905c19..c4a532f 100644 --- a/code/firmware/user/src/i2c.h +++ b/code/firmware/user/src/i2c.h @@ -19,6 +19,8 @@ void i2c_init(); void i2c_read_addr1b(uint8_t devaddr, uint8_t addr, uint8_t *data, uint8_t len); void i2c_write_addr1b(uint8_t devaddr, uint8_t addr, uint8_t *data, uint8_t len); +int8_t i2c_ack_poll(uint8_t devaddr); + #endif /* USER_SRC_I2C_H_ */