From 1b9642ce30d12e492bd859b6a52b80411c51be04 Mon Sep 17 00:00:00 2001 From: CNLohr <lohr85@gmail.com> Date: Sun, 28 May 2023 05:34:06 -0400 Subject: [PATCH] Revert "Add I2C slave library & example" --- examples/i2c_slave/Makefile | 9 -- examples/i2c_slave/README.md | 9 -- examples/i2c_slave/i2c_slave.h | 150 ------------------------- examples/i2c_slave/i2c_slave_example.c | 30 ----- 4 files changed, 198 deletions(-) delete mode 100644 examples/i2c_slave/Makefile delete mode 100644 examples/i2c_slave/README.md delete mode 100644 examples/i2c_slave/i2c_slave.h delete mode 100644 examples/i2c_slave/i2c_slave_example.c diff --git a/examples/i2c_slave/Makefile b/examples/i2c_slave/Makefile deleted file mode 100644 index a87f07c..0000000 --- a/examples/i2c_slave/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -all : flash - -TARGET:=i2c_slave_example - -include ../../ch32v003fun/ch32v003fun.mk - -flash : cv_flash -clean : cv_clean - diff --git a/examples/i2c_slave/README.md b/examples/i2c_slave/README.md deleted file mode 100644 index cfdbd1b..0000000 --- a/examples/i2c_slave/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# I2C peripheral in slave mode - -This library and example show how to use the I2C peripheral in slave mode. - -The library uses a one-byte address, allowing for up to 256 registers to be defined. - -The first byte written to the device within a transaction determines the offset for following reads and writes, emulating a simple EEPROM. - -The example will turn on a LED connected to PD0 when the LSB of register 0 is set to 1 and off when it's set to 0. diff --git a/examples/i2c_slave/i2c_slave.h b/examples/i2c_slave/i2c_slave.h deleted file mode 100644 index a488eaf..0000000 --- a/examples/i2c_slave/i2c_slave.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Single-File-Header for using the I2C peripheral in slave mode - * - * MIT License - * - * Copyright (c) 2023 Renze Nicolai - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef __I2C_SLAVE_H -#define __I2C_SLAVE_H - -#include <stdint.h> - -#define APB_CLOCK SYSTEM_CORE_CLOCK - -struct _i2c_slave_state { - uint8_t first_write; - uint8_t offset; - uint8_t position; - volatile uint8_t* volatile registers; - uint8_t size; -} i2c_slave_state; - -void SetupI2CSlave(uint8_t address, volatile uint8_t* registers, uint8_t size) { - i2c_slave_state.first_write = 1; - i2c_slave_state.offset = 0; - i2c_slave_state.position = 0; - i2c_slave_state.registers = registers; - i2c_slave_state.size = size; - - // Enable GPIOC and I2C - RCC->APB2PCENR |= RCC_APB2Periph_GPIOC; - RCC->APB1PCENR |= RCC_APB1Periph_I2C1; - - // PC1 is SDA, 10MHz Output, alt func, open-drain - GPIOC->CFGLR &= ~(0xf<<(4*1)); - GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_OD_AF)<<(4*1); - - // PC2 is SCL, 10MHz Output, alt func, open-drain - GPIOC->CFGLR &= ~(0xf<<(4*2)); - GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_OD_AF)<<(4*2); - - // Reset I2C1 to init all regs - RCC->APB1PRSTR |= RCC_APB1Periph_I2C1; - RCC->APB1PRSTR &= ~RCC_APB1Periph_I2C1; - - I2C1->CTLR1 |= I2C_CTLR1_SWRST; - I2C1->CTLR1 &= ~I2C_CTLR1_SWRST; - - // Set module clock frequency - uint32_t prerate = 2000000; // I2C Logic clock rate, must be higher than the bus clock rate - I2C1->CTLR2 |= (APB_CLOCK/prerate) & I2C_CTLR2_FREQ; - - // Enable interrupts - I2C1->CTLR2 |= I2C_CTLR2_ITBUFEN; - I2C1->CTLR2 |= I2C_CTLR2_ITEVTEN; // Event interrupt - I2C1->CTLR2 |= I2C_CTLR2_ITERREN; // Error interrupt - - NVIC_EnableIRQ(I2C1_EV_IRQn); // Event interrupt - NVIC_SetPriority(I2C1_EV_IRQn, 2 << 4); - NVIC_EnableIRQ(I2C1_ER_IRQn); // Error interrupt - - // Set clock configuration - uint32_t clockrate = 1000000; // I2C Bus clock rate, must be lower than the logic clock rate - I2C1->CKCFGR = ((APB_CLOCK/(3*clockrate))&I2C_CKCFGR_CCR) | I2C_CKCFGR_FS; // Fast mode 33% duty cycle - //I2C1->CKCFGR = ((APB_CLOCK/(25*clockrate))&I2C_CKCFGR_CCR) | I2C_CKCFGR_DUTY | I2C_CKCFGR_FS; // Fast mode 36% duty cycle - //I2C1->CKCFGR = (APB_CLOCK/(2*clockrate))&I2C_CKCFGR_CCR; // Standard mode good to 100kHz - - // Set I2C address - I2C1->OADDR1 = address << 1; - - // Enable I2C - I2C1->CTLR1 |= I2C_CTLR1_PE; - - // Acknowledge the first address match event when it happens - I2C1->CTLR1 |= I2C_CTLR1_ACK; -} - -void I2C1_EV_IRQHandler(void) __attribute__((interrupt)); -void I2C1_EV_IRQHandler(void) { - uint16_t STAR1, STAR2 __attribute__((unused)); - STAR1 = I2C1->STAR1; - STAR2 = I2C1->STAR2; - - I2C1->CTLR1 |= I2C_CTLR1_ACK; - - if (STAR1 & I2C_STAR1_ADDR) { // Start event - i2c_slave_state.first_write = 1; // Next write will be the offset - i2c_slave_state.position = i2c_slave_state.offset; // Reset position - } - - if (STAR1 & I2C_STAR1_RXNE) { // Write event - if (i2c_slave_state.first_write) { // First byte written, set the offset - i2c_slave_state.offset = I2C1->DATAR; - i2c_slave_state.position = i2c_slave_state.offset; - i2c_slave_state.first_write = 0; - } else { // Normal register write - if (i2c_slave_state.position < i2c_slave_state.size) { - i2c_slave_state.registers[i2c_slave_state.position] = I2C1->DATAR; - i2c_slave_state.position++; - } - } - } - - if (STAR1 & I2C_STAR1_TXE) { // Read event - if (i2c_slave_state.position < i2c_slave_state.size) { - I2C1->DATAR = i2c_slave_state.registers[i2c_slave_state.position]; - i2c_slave_state.position++; - } else { - I2C1->DATAR = 0x00; - } - } -} - -void I2C1_ER_IRQHandler(void) __attribute__((interrupt)); -void I2C1_ER_IRQHandler(void) { - uint16_t STAR1 = I2C1->STAR1; - - if (STAR1 & I2C_STAR1_BERR) { // Bus error - I2C1->STAR1 &= ~(I2C_STAR1_BERR); // Clear error - } - - if (STAR1 & I2C_STAR1_ARLO) { // Arbitration lost error - I2C1->STAR1 &= ~(I2C_STAR1_ARLO); // Clear error - } - - if (STAR1 & I2C_STAR1_AF) { // Acknowledge failure - I2C1->STAR1 &= ~(I2C_STAR1_AF); // Clear error - } -} - -#endif diff --git a/examples/i2c_slave/i2c_slave_example.c b/examples/i2c_slave/i2c_slave_example.c deleted file mode 100644 index dbfaf80..0000000 --- a/examples/i2c_slave/i2c_slave_example.c +++ /dev/null @@ -1,30 +0,0 @@ -#define SYSTEM_CORE_CLOCK 48000000 - -#include "ch32v003fun.h" -#include "i2c_slave.h" -#include <stdio.h> - -// The I2C slave library uses a one byte address so you can extend the size of this array up to 256 registers -// note that the register set is modified by interrupts, to prevent the compiler from accidently optimizing stuff -// away make sure to declare the register array volatile - -volatile uint8_t i2c_registers[32] = {0x00}; - -int main() { - SystemInit48HSI(); - SetupDebugPrintf(); - SetupI2CSlave(0x9, i2c_registers, sizeof(i2c_registers)); - - // Enable GPIOD and set pin 0 to output - RCC->APB2PCENR |= RCC_APB2Periph_GPIOD; - GPIOD->CFGLR &= ~(0xf<<(4*0)); - GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0); - - while (1) { - if (i2c_registers[0] & 1) { // Turn on LED (PD0) if bit 1 of register 0 is set - GPIOD-> BSHR |= 1 << 16; - } else { - GPIOD-> BSHR |= 1; - } - } -} -- GitLab