make it work!
This commit is contained in:
@@ -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 */
|
||||
|
||||
+2
-2
@@ -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 */
|
||||
|
||||
+10
-1
@@ -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 */
|
||||
|
||||
@@ -6361,7 +6361,8 @@ static void I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c)
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
|
||||
+3
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user