make it work!

master
Ondřej Hruška 2 years ago
parent fdcac81021
commit 01a18ef9cb
  1. 9
      Core/Inc/i2c_gateway.h
  2. 2
      Core/Inc/stm32f1xx_it.h
  3. 4
      Core/Src/freertos.c
  4. 11
      Core/Src/i2c.c
  5. 181
      Core/Src/i2c_gateway.c
  6. 29
      Core/Src/stm32f1xx_it.c
  7. 7
      Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
  8. 3
      Makefile
  9. 6
      USB_DEVICE/App/usbd_cdc_if.c
  10. 1
      USB_DEVICE/App/usbd_cdc_if.h
  11. 4
      bluepill-i2c-gw.ioc

@ -0,0 +1,9 @@
#ifndef I2C_GATEWAY_H
#define I2C_GATEWAY_H
#include <stdint.h>
#include <stddef.h>
void i2c_command(uint8_t *packet, size_t len);
#endif //I2C_GATEWAY_H

@ -55,6 +55,8 @@ void DebugMon_Handler(void);
void USB_HP_CAN1_TX_IRQHandler(void);
void USB_LP_CAN1_RX0_IRQHandler(void);
void TIM1_UP_IRQHandler(void);
void I2C1_EV_IRQHandler(void);
void I2C1_ER_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */

@ -150,14 +150,14 @@ void StartDefaultTask(void *argument)
//HAL_HalfDuplex_EnableTransmitter(&huart1);
/* Infinite loop */
int cnt = 0;
//int cnt = 0;
for (;;) {
vTaskDelay(pdMS_TO_TICKS(500));
HAL_IWDG_Refresh(&hiwdg);
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
printf("Hello, count is %d\r\n", cnt++);
//printf("Hello, count is %d\r\n", cnt++);
}
/* USER CODE END StartDefaultTask */

@ -45,7 +45,7 @@ void MX_I2C1_Init(void)
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
@ -78,6 +78,12 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
/* I2C1 clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* I2C1 interrupt Init */
HAL_NVIC_SetPriority(I2C1_EV_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
HAL_NVIC_SetPriority(I2C1_ER_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
@ -103,6 +109,9 @@ void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7);
/* I2C1 interrupt Deinit */
HAL_NVIC_DisableIRQ(I2C1_EV_IRQn);
HAL_NVIC_DisableIRQ(I2C1_ER_IRQn);
/* USER CODE BEGIN I2C1_MspDeInit 1 */
/* USER CODE END I2C1_MspDeInit 1 */

@ -0,0 +1,181 @@
#include <stdint.h>
#include <stdio.h>
#include "main.h"
#include "usbd_cdc_if.h"
#define I2C_DEBUG 0
#define I2C_MTU 512
#define HAL_CHECK(x) do { \
int rv = (x); \
if (rv != HAL_OK) { \
printf("HAL ERR %d at %s:%d\r\n", rv, __FILE__, __LINE__); \
}\
} while (0)
/**
* Packet format:
*
* Transmit packets
* LEN_MSB LEN_LSB ADDR Bytes...
*
* LEN does not include the length field itself!
*
* Command packets are sent as ADDR=255
* 0xFF CMD ARGs...
* - Set address: 0x01 ADDR
* - Set speed: 0x02 Speed TODO!!
* - Speed 1 ... 100kHz
* - Speed 4 ... 400kHz
*/
#define COMMAND_ADDRESS 0xFF
#define CMD_SET_ADDR 1 // the next param is the address, without shifting (i.e. 1-127)
#define CMD_SET_SPEED 2 // speed is 1 or 4 (100khz, 400khz)
enum FrameState {
FRAME_LEN_MSB,
FRAME_LEN_LSB,
FRAME_PAYLOAD,
};
static uint16_t framelen = 0;
static uint8_t i2c_recbuf[I2C_MTU + 3] = {};
static size_t recbuf_wp = 0;
static size_t framestate = FRAME_LEN_MSB;
static uint32_t last_rx_tick;
#define CMD_TIMEOUT_TICKS 500
static void handle_pkt(uint8_t *packet, size_t len);
static void handle_control_pkt(uint8_t *packet, size_t len);
void i2c_command(uint8_t *packet, size_t len)
{
uint32_t now = HAL_GetTick();
if (framestate != FRAME_LEN_MSB && (now - last_rx_tick) > CMD_TIMEOUT_TICKS) {
framestate = FRAME_LEN_MSB;
}
last_rx_tick = now;
for (int i=0; i<len;i++) {
uint8_t b = packet[i];
switch (framestate) {
case FRAME_LEN_MSB:
framelen = ((uint16_t)b) << 8;
framestate = FRAME_LEN_LSB;
break;
case FRAME_LEN_LSB:
framelen |= (uint16_t)b;
if (framelen == 0) {
framestate = FRAME_LEN_MSB;
} else {
framestate = FRAME_PAYLOAD;
recbuf_wp = 0;
}
break;
case FRAME_PAYLOAD:
i2c_recbuf[recbuf_wp++] = b;
if (recbuf_wp >= framelen) {
handle_pkt(i2c_recbuf, framelen);
framestate = FRAME_LEN_MSB;
}
break;
}
}
}
static void handle_pkt(uint8_t *packet, size_t len)
{
#if I2C_DEBUG
printf("Handle packet (%d bytes): ", len);
for(int i=0; i<len;i++) {
printf("%02x ", packet[i]);
}
printf("\r\n");
#endif
if (packet[0] == COMMAND_ADDRESS) {
printf("ctl: ");
// This is an in-band control packet
handle_control_pkt(packet, len);
} else {
uint8_t dest = packet[0];
#if I2C_DEBUG
printf("Tx(%d)->%d\r\n", len - 1, dest);
#endif
// Blocking transfer
HAL_CHECK(HAL_I2C_DisableListen_IT(&hi2c1));
HAL_CHECK(HAL_I2C_Master_Transmit(&hi2c1, (dest & 0x7F) << 1, &packet[1], len - 1, 100));
HAL_CHECK(HAL_I2C_EnableListen_IT(&hi2c1));
}
}
static void handle_control_pkt(uint8_t *packet, size_t len)
{
uint8_t cmd = packet[1];
uint8_t arg;
switch (cmd) {
case CMD_SET_ADDR:
if (len < 3) return;
arg = packet[2];
printf("Addr=0x%02x\r\n", arg);
MODIFY_REG(hi2c1.Instance->OAR1,
(I2C_OAR1_ADDMODE | I2C_OAR1_ADD8_9 | I2C_OAR1_ADD1_7 | I2C_OAR1_ADD0),
(I2C_ADDRESSINGMODE_7BIT | ((arg & 0x7F) << 1) ));
HAL_CHECK(HAL_I2C_EnableListen_IT(&hi2c1));
break;
default:
printf("bad cmd!\r\n");
}
}
/**
* @brief Slave Address Match callback.
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2C.
* @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XferDirection_definition
* @param AddrMatchCode Address Match Code
* @retval None
*/
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
HAL_CHECK(HAL_I2C_Slave_Seq_Receive_IT(hi2c, i2c_recbuf, I2C_MTU, I2C_FIRST_AND_LAST_FRAME));
}
/**
* @brief Slave Rx Transfer completed callback.
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2C.
* @retval None
*/
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
int numBytes = I2C_MTU - hi2c->XferCount;
#if I2C_DEBUG
printf("rxd %d\r\n", numBytes);
#endif
UserTxBufferFS[0] = (numBytes >> 8) & 0xFF;
UserTxBufferFS[1] = numBytes & 0xFF;
memcpy(&UserTxBufferFS[2], i2c_recbuf, numBytes);
CDC_Transmit_FS(UserTxBufferFS, numBytes + 2);
}
/**
* @brief Listen Complete callback.
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2C.
* @retval None
*/
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
{
// Start again
HAL_CHECK(HAL_I2C_EnableListen_IT(hi2c));
}

@ -56,6 +56,7 @@
/* External variables --------------------------------------------------------*/
extern PCD_HandleTypeDef hpcd_USB_FS;
extern I2C_HandleTypeDef hi2c1;
extern TIM_HandleTypeDef htim1;
/* USER CODE BEGIN EV */
@ -202,6 +203,34 @@ void TIM1_UP_IRQHandler(void)
/* USER CODE END TIM1_UP_IRQn 1 */
}
/**
* @brief This function handles I2C1 event interrupt.
*/
void I2C1_EV_IRQHandler(void)
{
/* USER CODE BEGIN I2C1_EV_IRQn 0 */
/* USER CODE END I2C1_EV_IRQn 0 */
HAL_I2C_EV_IRQHandler(&hi2c1);
/* USER CODE BEGIN I2C1_EV_IRQn 1 */
/* USER CODE END I2C1_EV_IRQn 1 */
}
/**
* @brief This function handles I2C1 error interrupt.
*/
void I2C1_ER_IRQHandler(void)
{
/* USER CODE BEGIN I2C1_ER_IRQn 0 */
/* USER CODE END I2C1_ER_IRQn 0 */
HAL_I2C_ER_IRQHandler(&hi2c1);
/* USER CODE BEGIN I2C1_ER_IRQn 1 */
/* USER CODE END I2C1_ER_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

@ -6356,12 +6356,13 @@ static void I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c)
if (hi2c->XferCount != 0U)
{
/* Set ErrorCode corresponding to a Non-Acknowledge */
hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
/* Set ErrorCode corresponding to a Non-Acknowledge */
hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
}
}
if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
// HACK - ignore HAL_I2C_ERROR_AF
if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE && hi2c->ErrorCode != HAL_I2C_ERROR_AF)
{
/* Call the corresponding callback to inform upper layer of End of Transfer */
I2C_ITError(hi2c);

@ -1,5 +1,5 @@
##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [3.16.0] date: [Fri Apr 01 20:27:44 CEST 2022]
# File automatically-generated by tool: [projectgenerator] version: [3.16.0] date: [Fri Apr 01 20:41:48 CEST 2022]
##########################################################################################################################
.PHONY: flash
@ -40,6 +40,7 @@ BUILD_DIR = build
C_SOURCES = \
Core/Src/main.c \
Core/Src/logging.c \
Core/Src/i2c_gateway.c \
Core/Src/freertos.c \
Core/Src/stm32f1xx_it.c \
Core/Src/stm32f1xx_hal_msp.c \

@ -22,6 +22,7 @@
#include "usbd_cdc_if.h"
/* USER CODE BEGIN INCLUDE */
#include "i2c_gateway.h"
/* USER CODE END INCLUDE */
@ -259,11 +260,12 @@ static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length)
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
printf("Rx %d b\r\n", (int) *Len);
printf("Bytes: %.*s\r\n", (int) *Len, Buf);
i2c_command(Buf, *Len);
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
}

@ -51,6 +51,7 @@
#define APP_RX_DATA_SIZE 1000
#define APP_TX_DATA_SIZE 1000
/* USER CODE BEGIN EXPORTED_DEFINES */
extern uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
/* USER CODE END EXPORTED_DEFINES */

@ -52,6 +52,8 @@ NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
NVIC.I2C1_ER_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.I2C1_EV_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:true
@ -148,7 +150,7 @@ USB_DEVICE.IPParameters=VirtualMode,VirtualModeFS,CLASS_NAME_FS,USBD_DEBUG_LEVEL
USB_DEVICE.MANUFACTURER_STRING=VZLU
USB_DEVICE.PID_CDC_FS=7717
USB_DEVICE.PRODUCT_STRING_CDC_FS=VZLU I2C GW
USB_DEVICE.USBD_DEBUG_LEVEL=2
USB_DEVICE.USBD_DEBUG_LEVEL=0
USB_DEVICE.VirtualMode=Cdc
USB_DEVICE.VirtualModeFS=Cdc_FS
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2

Loading…
Cancel
Save