Jonas Thörnblad 5c50a2b5de
Add incoming and outgoing CTS (Clear To Send) signals for the CH552
- Add CTS signals let the FPGA and CH552 signal each other that
    it is OK send UART data.
  - Update the CH552 rx and frame handling logic.
  - Fix minor spelling errors and indentation
2025-02-03 13:39:38 +01:00

261 lines
8.6 KiB
C

#ifndef __DEBUG_H__
#define __DEBUG_H__
/* Debug */
/* Provide printf subroutine and delay function */
#pragma once
#include <stdint.h>
#include "ch554.h"
// UART1 baud rates
// Setting Actual % error
//Std 9600 9615.38 0.16%
// 14400 14492.75 0.64%
//Std 19200 19230.77 0.16%
//Std 38400 38461.54 0.16%
//Std 57600 58823.53 2.12%
// 100000 100000 0.00%
//Std 115200 111111.1 -3.55%
// 128000 142857.14 11.61%
//Std 230400 250000 8.51%
// 250000 250000 0%
// 256000 333333.33 30.21%
//Std 460800 500000 8.51%
//Std 500000 500000 0%
//Std 576000
//Std 921600
//Std 1000000 1000000 0.00%
#ifndef UART0_BAUD
//#define UART0_BAUD 115200
#define UART0_BAUD 1000000
#endif
#ifndef UART1_BAUD
#define UART1_BAUD 500000
//#define UART1_BAUD 1000000
#endif
void CfgFsys(void); // CH554 clock selection and configuration
void mDelayuS(uint16_t n); // Delay in units of uS
void mDelaymS(uint16_t n); // Delay in mS
// Set pin p1.4 and p1.5 to GPIO output mode.
void gpio_init(void);
void gpio_set(uint8_t pin);
void gpio_unset(uint8_t pin);
uint8_t gpio_get(uint8_t pin);
void gpio_init_p1_4_in(void);
void gpio_init_p1_5_out(void);
uint8_t gpio_p1_4_get(void);
void gpio_p1_5_set(void);
void gpio_p1_5_unset(void);
/*******************************************************************************
* Function Name : CH554UART0Alter()
* Description : Set the alternate pin mappings for UART0 (RX on P1.2, TX on P1.3)
*******************************************************************************/
inline void CH554UART0Alter()
{
PIN_FUNC |= bUART0_PIN_X; // RX on P1.2, TX on P1.3
}
/*******************************************************************************
* Function Name : mInitSTDIO()
* Description : CH554 UART0 is initialized
* T1 is used as the baud rate generator of UART0 by default
* T2 can also be used as baud rate generator
* RX on P3.0, TX on P3.1
*******************************************************************************/
inline void mInitSTDIO( )
{
uint32_t x;
uint8_t x2;
SM0 = 0; // 8-bit data asynchronous communication
SM1 = 1; // Variable baud rate, which is generated by timer T1 or T2
// With SM0=0 and SM1=1 we are now in UART0 Mode 1
SM2 = 0; // In Mode 1, SM2=0 gives that the Receive interrupt flag bit is set when receiving data and the reception is valid
// Use Timer1 as a baud rate generator
RCLK = 0; // UART0 receive clock
TCLK = 0; // UART0 transmit clock
PCON |= SMOD; // Set Fast mode for UART0 baud rate communication
x = 10 * FREQ_SYS / UART0_BAUD / 16; // If you change the main frequency, be careful not to overflow the value of x
x2 = x % 10;
x /= 10;
if (x2 >= 5) {
x++; // Rounding
}
TMOD = (TMOD & ~bT1_GATE & ~bT1_CT & ~MASK_T1_MOD) | bT1_M1; // Timer1 as 8-bit auto-reload timer
T2MOD = T2MOD | bTMR_CLK | bT1_CLK; // Timer1 clock selection
TH1 = 0-x; // 12MHz crystal oscillator, baud / 12 is the actual need to set the baud rate
TR1 = 1; // Start timer 1
TI = 1; // Enable transmit interrupt
REN = 1; // UART0 receive enable
ES = 1; // UART0 interrupt enable
}
/*******************************************************************************
* Function Name : CH554UART0RcvByte()
* Description : CH554UART0 receives a byte
* Return : SBUF
*******************************************************************************/
inline uint8_t CH554UART0RcvByte()
{
while (RI == 0)
; // Wait for uart rx interrupt flag
RI = 0;
return SBUF;
}
/*******************************************************************************
* Function Name : CH554UART0SendByte(uint8_t SendDat)
* Description : CH554UART0 sends a byte
* Input : uint8_t SendDat; the data to be sent
*******************************************************************************/
inline void CH554UART0SendByte(uint8_t SendDat)
{
SBUF = SendDat;
while (TI == 0)
; // Wait for transmit to finish (TI == 1)
TI = 0;
}
/*******************************************************************************
* Function Name : CH554UART1Alter()
* Description : Set the alternate pin mappings for UART1 (RX on P3.4, TX on P3.2)
*******************************************************************************/
inline void CH554UART1Alter()
{
PIN_FUNC |= bUART1_PIN_X; // RX on P3.4, TX on P3.2
}
/*******************************************************************************
* Function Name : UART1Setup()
* Description : CH554 serial port 1 initialization
* RX on P1.6, TX on P1.7
*
*******************************************************************************/
inline void UART1Setup()
{
U1SM0 = 0; // UART1 selects 8-bit data bit
U1SMOD = 1; // Fast mode
U1REN = 1; // Enable receiving
// Should correct for rounding in SBAUD1 calculation
SBAUD1 = 256 - FREQ_SYS/16/UART1_BAUD; // Calculation for Fast mode
IE_UART1 = 1; // Enable UART1 interrupt
}
/*******************************************************************************
* Function Name : UART1Clean()
* Description : Read out spurious data
*******************************************************************************/
inline void UART1Clean()
{
uint8_t tmp;
while (U1RI) {
tmp = SBUF1;
U1RI = 0;
}
}
/*******************************************************************************
* Function Name : CH554UART1RcvByte()
* Description : CH554UART1 receives a byte
* Return : SBUF
*******************************************************************************/
inline uint8_t CH554UART1RcvByte( )
{
while (U1RI == 0) // Query reception, interrupt mode is not required
;
U1RI = 0;
return SBUF1;
}
/*******************************************************************************
* Function Name : CH554UART1SendByte(uint8_t SendDat)
* Description : CH554UART1 sends a byte
* Input : uint8_t SendDat; data to be sent
*******************************************************************************/
inline void CH554UART1SendByte(uint8_t SendDat)
{
SBUF1 = SendDat; // Query sending, the interrupt mode does not need the following two statements, but TI=0 is required before sending
while (U1TI == 0)
;
U1TI = 0;
}
/*******************************************************************************
* Function Name : CH554UART1SendBuffer(uint8_t SendDat)
* Description : CH554UART1 sends a complete buffer
* Input : uint8_t *Buf; Data to be sent
* Input : uint32_t Len; Length of data
*******************************************************************************/
inline void CH554UART1SendBuffer(uint8_t *Buf, uint32_t Len)
{
uint32_t Count = 0;
while (Count < Len) {
if (gpio_p1_4_get()) {
SBUF1 = Buf[Count++];
while (U1TI == 0)
;
U1TI = 0;
}
}
}
#if SDCC < 370
void putchar(char c);
char getchar(void);
#else
int putchar(int c);
int getchar(void);
#endif
/*******************************************************************************
* Function Name : CH554WDTModeSelect(uint8_t mode)
* Description : CH554 watchdog mode selection
* Input : uint8_t mode
0 timer
1 watchDog
* Output : None
* Return : None
*******************************************************************************/
inline void CH554WDTModeSelect(uint8_t mode)
{
SAFE_MOD = 0x55;
SAFE_MOD = 0xaa; // Enter Safe Mode
if (mode) {
GLOBAL_CFG |= bWDOG_EN; // Start watchdog reset
} else {
GLOBAL_CFG &= ~bWDOG_EN; //Start watchdog only as a timer
}
SAFE_MOD = 0x00; // Exit safe Mode
WDOG_COUNT = 0; // Watchdog assignment initial value
}
/*******************************************************************************
* Function Name : CH554WDTFeed(uint8_t tim)
* Description : CH554 watchdog timer time setting
* Input : uint8_t tim watchdog reset time setting
00H(6MHz)=2.8s
80H(6MHz)=1.4s
* Output : None
* Return : None
*******************************************************************************/
inline void CH554WDTFeed(uint8_t tim)
{
WDOG_COUNT = tim; // Watchdog counter assignment
}
#endif