Перенести настройки таймингов из13e5bfe373и относящуюся к индикации часть04a9d989fb. Сохранить текущую последовательность DATA/CLOCK ветки 167, удерживать TESTLAMP при кратких провалах входа и исключить повторный вход Timer1. Адаптировать тесты TESTLAMP к типу накопителя и кодировкам проекта 166. Сохранить изменённые исходники и русские комментарии в UTF-8. Проверка: поведенческие и мутационные тесты TESTLAMP, полная сборка 27 модулей TI C2000 21.12.0.STS и линковка, образ SCI8 30174 байта, компиляция канала индикации с общей оптимизацией -O3.
210 lines
6.1 KiB
C
210 lines
6.1 KiB
C
/* Программный канал индикации. digits/readr задают символы и выбор
|
||
* элементов, DCLK/DOUT и kanal_Send формируют последовательность GPIO.
|
||
* Это другой интерфейс, чем dCLK/dCS в DAC.c. Похожие имена не
|
||
* означают общий ЦАП или общий выход запуска нагрузки.
|
||
*/
|
||
#include "DSP2833x_Device.h" // DSP281x Headerfile Include File
|
||
#include "DSP2833x_SWPrioritizedIsrLevels.h"
|
||
#include "filter_bat2.h"
|
||
#include "measure.h"
|
||
|
||
#include "RS485.h"
|
||
#include "message.h"
|
||
#include "kanal.h"
|
||
#include "pulto.h"
|
||
#include "package.h"
|
||
#include "tools.h"
|
||
|
||
#include "peripher.h"
|
||
|
||
int digits[16] = {63,6,91,79,102,109,125,7,127,111,64,0,0,0,121,0};
|
||
int readr[5] = {0x08,0x0C,0x10,0x00,0x04};
|
||
|
||
/* Ограничивает настройки таймингов компилятором TI C2000; модель на ПК не использует эти директивы. */
|
||
#if defined(__TI_COMPILER_VERSION__)
|
||
/* Сохраняет отдельный вызов переключения CLOCK: встраивание при -O3 сокращало удержание DATA после фронта. */
|
||
#pragma FUNC_CANNOT_INLINE(DCLK)
|
||
/* Возвращает генерацию DCLK как в образе от 06.10.2026: уровень 1 и приоритет скорости 3 сохраняют прежнюю последовательность инструкций GPIO. */
|
||
#pragma FUNCTION_OPTIONS(DCLK, "--opt_level=1 --opt_for_speed=3")
|
||
/* Сохраняет отдельный вызов переключения DATA, чтобы длительность импульсов не зависела от встраивания в передатчик. */
|
||
#pragma FUNC_CANNOT_INLINE(DOUT)
|
||
/* Возвращает генерацию DOUT с прежними параметрами -O1 и --opt_for_speed=3; значения взяты из старой конфигурации CCS. */
|
||
#pragma FUNCTION_OPTIONS(DOUT, "--opt_level=1 --opt_for_speed=3")
|
||
/* Не позволяет встроить разделитель пакетов в цикл передачи и изменить интервалы между переключениями линий. */
|
||
#pragma FUNC_CANNOT_INLINE(RESET)
|
||
/* Сохраняет прежнюю последовательность вызовов GPIO и задержек разделителя, используя настройки старого образа. */
|
||
#pragma FUNCTION_OPTIONS(RESET, "--opt_level=1 --opt_for_speed=3")
|
||
/* Сохраняет отдельный вызов передачи бита; протокол использует порядок и интервалы фронтов CLOCK и DATA. */
|
||
#pragma FUNC_CANNOT_INLINE(SENDBIT)
|
||
/* Закрепляет для передачи бита настройки из 167: -O1 и --opt_for_speed=3 сохраняют интервалы GPIO независимо от общего уровня оптимизации проекта. */
|
||
#pragma FUNCTION_OPTIONS(SENDBIT, "--opt_level=1 --opt_for_speed=3")
|
||
/* Завершает блок настроек TI, не изменяя формат пакетов и существующие счётчики задержек. */
|
||
#endif
|
||
|
||
void DCLK(int x)
|
||
{
|
||
if(x) GpioDataRegs.GPASET.bit.GPIO6=1;
|
||
else GpioDataRegs.GPACLEAR.bit.GPIO6=1;
|
||
}
|
||
|
||
void DOUT(int x)
|
||
{
|
||
if(x) GpioDataRegs.GPASET.bit.GPIO8=1;
|
||
else GpioDataRegs.GPACLEAR.bit.GPIO8=1;
|
||
}
|
||
|
||
#if CLKMULT==1
|
||
#define POWS0 0L
|
||
#define POWS1 10L
|
||
#endif
|
||
#if CLKMULT==2
|
||
#define POWS0 0L
|
||
#define POWS1 30L
|
||
#endif
|
||
#if CLKMULT==3
|
||
#define POWS0 1L
|
||
#define POWS1 50L
|
||
#endif
|
||
#if CLKMULT==4
|
||
#define POWS0 2L
|
||
#define POWS1 60L
|
||
#endif
|
||
#if CLKMULT==5
|
||
#define POWS0 4L
|
||
#define POWS1 80L
|
||
#endif
|
||
|
||
void RESET()
|
||
{
|
||
DCLK(0);
|
||
#if POWS1>0
|
||
DSP28x_usDelay(POWS1);
|
||
#endif
|
||
DOUT(1);
|
||
#if POWS1>0
|
||
DSP28x_usDelay(POWS1);
|
||
#endif
|
||
DOUT(0);
|
||
#if POWS1>0
|
||
DSP28x_usDelay(POWS1);
|
||
#endif
|
||
}
|
||
|
||
void SENDBIT(int x)
|
||
{
|
||
DOUT(x); DCLK(1);
|
||
#if POWS0>0
|
||
DSP28x_usDelay(POWS0);
|
||
#endif
|
||
DOUT(0);
|
||
DSP28x_usDelay(POWS0+1);
|
||
DCLK(0);
|
||
#if POWS1>0
|
||
DSP28x_usDelay(POWS1);
|
||
#endif
|
||
}
|
||
|
||
void kanal_Send(int adr, long dat, int dot)
|
||
{
|
||
long Word,data,aliq_part,dg[4];
|
||
int i,j,bit,byt,addr,sgn=0,punkt=0,aliq_len=0,full_len, isdot=0;
|
||
|
||
if(adr>1) // Адреса каналов выше 1 передают готовую битовую маску ламп; каналы 0 и 1 требуют преобразования числа в сегменты.
|
||
{
|
||
Word =dat;
|
||
}
|
||
|
||
else
|
||
|
||
{
|
||
if(dat<0) sgn=1;
|
||
data = labs(dat);
|
||
|
||
if(dot>=0 && dot<4) isdot = 1;
|
||
else dot=0;
|
||
|
||
aliq_part = data;
|
||
for(i=0;i<dot;i++) aliq_part/=10;
|
||
|
||
dat = aliq_part;
|
||
while(dat>0)
|
||
{
|
||
aliq_len++; dat/=10;
|
||
}
|
||
|
||
dat = data;
|
||
|
||
full_len = aliq_len+sgn;
|
||
if(full_len==0) full_len=1;
|
||
full_len += dot;
|
||
|
||
for(i=0; i<(full_len-4);i++)
|
||
{
|
||
dot--; dat/=10;
|
||
}
|
||
if(dot<0) dot=0;
|
||
punkt = 1<<dot;
|
||
if(punkt==1) punkt=0;
|
||
|
||
dg[3] = (dat)/1000;
|
||
dg[2] = (dat%1000)/100;
|
||
dg[1] = (dat%100)/10;
|
||
dg[0] = (dat%10);
|
||
|
||
if(dg[0]+dg[1]+dg[2]+dg[3]==0)
|
||
{
|
||
punkt=0; dot=0; sgn=0;
|
||
}
|
||
|
||
if(isdot)
|
||
for(i=3;i>0;i--)
|
||
{
|
||
if((dg[i]==0)&&(i!=dot))
|
||
dg[i]=0xF; // Индекс 0xF таблицы digits задаёт пустой символ, скрывая ведущий ноль вне позиции десятичной точки.
|
||
else break;
|
||
}
|
||
|
||
if(sgn)
|
||
for(i=1;i<4;i++)
|
||
{
|
||
if( (dg[i]==0xF)||(i==3))
|
||
{
|
||
dg[i]=0xA; // Индекс 0xA таблицы digits задаёт знак минуса в свободном разряде отрицательного числа.
|
||
break;
|
||
} }
|
||
|
||
for(i=0;i<4;i++)
|
||
{
|
||
dg[i] = digits[dg[i]];
|
||
if((punkt>>i)&1) dg[i]+= 128;
|
||
|
||
}
|
||
|
||
Word = ((dg[0] ) & 0x000000FF) | ((dg[1]<<8 ) & 0x0000FF00) |
|
||
((dg[2]<<16) & 0x00FF0000) | ((dg[3]<<24) & 0xFF000000);
|
||
}
|
||
|
||
addr = readr[adr];
|
||
|
||
for (i=0;i<4;i++)
|
||
{
|
||
if(addr>0x10) break;
|
||
|
||
for (j=0;j<8;j++)
|
||
{
|
||
bit = Word & 1; Word >>= 1;
|
||
SENDBIT(bit);
|
||
}
|
||
|
||
byt = addr;
|
||
for (j=0;j<6;j++)
|
||
{
|
||
bit = byt & 1; byt >>= 1;
|
||
SENDBIT(bit);
|
||
}
|
||
addr++;
|
||
|
||
RESET();
|
||
}
|
||
}
|