added 1-wire support

This commit is contained in:
eddyem 2015-07-28 15:49:10 +03:00
parent 26e13666e1
commit 32d8c310fc
18 changed files with 608 additions and 607 deletions

View File

@ -20,6 +20,7 @@
*/
#include "main.h"
#include "AD7794.h"
#include "spi.h"
#include "cdcacm.h"

View File

@ -5,7 +5,8 @@ BOOTSPEED ?= 115200
# for example, if you have STM32F103VBT6, you should write:
LDSCRIPT = ld/stm32f103xB.ld
LIBNAME = opencm3_stm32f1
DEFS = -DSTM32F1 -DEBUG
DEFS = -DSTM32F1
# -DEBUG
OBJDIR = mk
INDEPENDENT_HEADERS=

View File

@ -1,4 +1,4 @@
The work begins
The work started
First PCB have been prodused, so I need "only" to solder elements & finish the code
Pinout of MCU is in file schematics/STM32_PINS

View File

@ -22,6 +22,7 @@
#include "user_proto.h"
#include "main.h"
#include "uart.h"
#include "sync.h"
// Buffer for USB Tx
static uint8_t USB_Tx_Buffer[USB_TX_DATA_SIZE];

View File

@ -37,7 +37,18 @@ const flash_data Flash_Data __attribute__ ((aligned(FLASH_BLOCK_SIZE))) = {
._ADC_divisors = {1,1,1,1,1,1,1,1, // TRD
25, // shutter
7 // power
}
},
._OW_id_array = { // ID of 1-wire sensors
{0x10, 0xad, 0xbc, 0x8f, 0x02, 0x08, 0x00, 0xf9},
{0x10, 0x78, 0xe4, 0x8f, 0x02, 0x08, 0x00, 0x7d},
{0x10, 0x46, 0x0a, 0x90, 0x02, 0x08, 0x00, 0x59},
{0x10, 0x68, 0xd6, 0x8f, 0x02, 0x08, 0x00, 0x21},
{0x10, 0x7c, 0xee, 0x8f, 0x02, 0x08, 0x00, 0x1c},
{0x10, 0xf7, 0x02, 0x90, 0x02, 0x08, 0x00, 0x57},
{0x10, 0x92, 0xf1, 0x8f, 0x02, 0x08, 0x00, 0x35},
{0x10, 0x5f, 0x02, 0x90, 0x02, 0x08, 0x00, 0xaa}
},
._OW_dev_amount = 8
}
};
@ -104,14 +115,27 @@ void dump_flash_data(sendfun s){
// P("magick: ", s);
// print_int(Stored_Data.magick, s);
P("\nADC multipliers: ", s);
for(i = 0; i < ADC_CHANNELS_NUMBER; i++){
for(i = 0; i < ADC_CHANNELS_NUMBER; ++i){
if(i) P(", ", s);
print_int(Flash_Data.all_stored._ADC_multipliers[i], s);
}
P("\nADC divisors: ", s);
for(i = 0; i < ADC_CHANNELS_NUMBER; i++){
for(i = 0; i < ADC_CHANNELS_NUMBER; ++i){
if(i) P(", ", s);
print_int(Flash_Data.all_stored._ADC_divisors[i], s);
}
P("\n1-wire IDs:\n", s);
for(i = 0; i < OW_dev_amount; ++i){
int j;
uint8_t *ROM = OW_id_array[i];
s('\t');
print_int(i, s);
P(") ", s);
for(j = 0; j < 8; ++j){
if(j) P(", ", s);
print_hex(&ROM[j], 1, s);
}
s('\n');
}
}

View File

@ -25,6 +25,7 @@
#include "main.h"
#include "user_proto.h"
#include "onewire.h"
/*
* this is a default values of stored data
@ -41,6 +42,8 @@ typedef struct{
// A-D value[x] = ADU * ADC_multipliers[x] / ADC_divisors[x]
uint32_t _ADC_multipliers[ADC_CHANNELS_NUMBER];
uint32_t _ADC_divisors[ADC_CHANNELS_NUMBER];
uint8_t _OW_id_array[8][OW_MAX_NUM];
uint8_t _OW_dev_amount;
// char last_addr[0]; // we need this pointer to calculate real size of structure
}stored_data;
@ -53,6 +56,8 @@ extern stored_data Stored_Data;
#define ADC_multipliers Stored_Data._ADC_multipliers
#define ADC_divisors Stored_Data._ADC_divisors
#define OW_id_array Stored_Data._OW_id_array
#define OW_dev_amount Stored_Data._OW_dev_amount
void dump_flash_data(sendfun s);
uint8_t save_flashdata();

View File

@ -137,10 +137,12 @@ void GPIO_init(){
GPIO_CNF_OUTPUT_OPENDRAIN, LED_STATUS_PIN);
LED_STATUS_BAD(); // turn LED off
// Shutter control: input pull up
gpio_set_mode(SHUTTER_EXT_PORT, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_PULL_UPDOWN, SHUTTER_CAM_PIN | SHUTTER_MAN_PIN | SHUTTER_FBSW_PIN);
//gpio_set(SHUTTER_EXT_PORT, SHUTTER_CAM_PIN | SHUTTER_MAN_PIN | SHUTTER_FBSW_PIN); // turn on pull up
GPIO_ODR(SHUTTER_EXT_PORT) |= SHUTTER_CAM_PIN | SHUTTER_MAN_PIN | SHUTTER_FBSW_PIN;
gpio_set(SHUTTER_CAM_PORT, SHUTTER_CAM_PIN);
gpio_set(SHUTTER_MAN_PORT, SHUTTER_MAN_PIN);
gpio_set(SHUTTER_FBSW_PORT, SHUTTER_FBSW_PIN);
gpio_set_mode(SHUTTER_CAM_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, SHUTTER_CAM_PIN);
gpio_set_mode(SHUTTER_MAN_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, SHUTTER_MAN_PIN);
gpio_set_mode(SHUTTER_FBSW_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, SHUTTER_FBSW_PIN);
// shutter status LED: opendrain
gpio_set_mode(LED_SHUTTER_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_OPENDRAIN, LED_SHUTTER_PIN);
@ -286,254 +288,3 @@ int TRD_value(uint8_t num){
return (int) r;
}
uint16_t tim2_buff[TIM2_DMABUFF_SIZE];
uint16_t tim2_inbuff[TIM2_DMABUFF_SIZE];
int tum2buff_ctr = 0;
uint8_t ow_done = 1;
/**
* this function sends bits of ow_byte (LSB first) to 1-wire line
* @param ow_byte - byte to convert
* @param Nbits - number of bits to send
* @param ini - 1 to zero counter
*/
uint8_t OW_add_byte(_U_ uint8_t ow_byte, _U_ uint8_t Nbits, _U_ uint8_t ini){
uint8_t i, byte;
if(ini) tum2buff_ctr = 0;
if(Nbits == 0) return 0;
if(Nbits > 8) Nbits = 8;
for(i = 0; i < Nbits; i++){
if(ow_byte & 0x01){
byte = OW_1;
}else{
byte = OW_0;
}
tim2_buff[tum2buff_ctr++] = byte;
if(tum2buff_ctr == TIM2_DMABUFF_SIZE) return 0; // avoid buffer overflow
ow_byte = ow_byte >> 1;
}
// print_int(tum2buff_ctr, lastsendfun);
// MSG(" bytes in send buffer\n");
return 1;
}
/**
* Adds Nbytes bytes 0xff for reading sequence
*/
uint8_t OW_add_read_seq(uint8_t Nbytes){
uint8_t i;
if(Nbytes == 0) return 0;
Nbytes *= 8; // 8 bits for each byte
for(i = 0; i < Nbytes; i++){
tim2_buff[tum2buff_ctr++] = 1;
if(tum2buff_ctr == TIM2_DMABUFF_SIZE) return 0;
}
#ifdef EBUG
if(mode == BYTE_MODE){
print_int(tum2buff_ctr, lastsendfun);
P(" bytes in send buffer\n", lastsendfun);
}
#endif
return 1;
}
/**
* Fill output buffer with data from 1-wire
* @param start_idx - index from which to start (bit number)
* @param N - data length (in **bytes**)
* @outbuf - where to place data
*/
void read_from_OWbuf(_U_ uint8_t start_idx, _U_ uint8_t N, _U_ uint8_t *outbuf){
uint8_t i, j, last = start_idx + N * 8, byte;
if(last >= TIM2_DMABUFF_SIZE) last = TIM2_DMABUFF_SIZE;
for(i = start_idx; i < last;){
byte = 0;
for(j = 0; j < 8; j++){
byte >>= 1;
#ifdef EBUG
if(mode == BYTE_MODE){
print_int(tim2_inbuff[i], lastsendfun);
lastsendfun(' ');
}
#endif
if(tim2_inbuff[i++] < OW_READ1)
byte |= 0x80;
}
*outbuf++ = byte;
DBG("readed \n");
}
}
// there's a mistake in opencm3, so redefine this if needed (TIM_CCMR2_CC3S_IN_TI1 -> TIM_CCMR2_CC3S_IN_TI4)
#ifndef TIM_CCMR2_CC3S_IN_TI4
#define TIM_CCMR2_CC3S_IN_TI4 (2)
#endif
void init_ow_dmatimer(){ // tim2_ch4 - PA3, no remap
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO3);
rcc_periph_clock_enable(RCC_TIM2);
rcc_periph_clock_enable(RCC_DMA1);
timer_reset(TIM2);
// timers have frequency of 1MHz -- 1us for one step
// 36MHz of APB1
timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
// 72MHz div 72 = 1MHz
// TODO: WHY 71 if freq = 36MHz?
TIM2_PSC = 71; // prescaler is (div - 1)
TIM2_CR1 &= ~(TIM_CR1_OPM | TIM_CR1_UDIS); // continuous mode & enable update events
TIM2_CR1 |= TIM_CR1_ARPE; // changing period immediately
TIM2_ARR = OW_BIT; // default period of timer
// PWM_OUT: TIM2_CH4; capture: TIM2_CH3
// PWM edge-aligned mode & enable preload for CCR4, CC3 takes input from TI4
TIM2_CCMR2 = TIM_CCMR2_OC4M_PWM1 | TIM_CCMR2_OC4PE | TIM_CCMR2_CC3S_IN_TI4;
TIM2_CCR4 = 0; // set output value to 1 by clearing CCR4
TIM2_EGR = TIM_EGR_UG; // update values of ARR & CCR4
// set low polarity for CC4, high for CC4 & enable CC4 out and CC3 in
TIM2_CCER = TIM_CCER_CC4P | TIM_CCER_CC4E | TIM_CCER_CC3E;
// TIM2_CH4 - DMA1, channel 7
dma_channel_reset(DMA1, DMA_CHANNEL7);
DMA1_CCR7 = DMA_CCR_DIR | DMA_CCR_MINC | DMA_CCR_PSIZE_16BIT | DMA_CCR_MSIZE_16BIT
| DMA_CCR_TEIE | DMA_CCR_TCIE | DMA_CCR_PL_HIGH;
/*
DMA1_CCR7 |= DMA_CCR_DIR; // dma_set_read_from_memory(DMA1, DMA_CHANNEL7);
DMA1_CCR7 |= DMA_CCR_MINC; // dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
//dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
DMA1_CCR7 |= DMA_CCR_PSIZE_16BIT; // dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_16BIT);
DMA1_CCR7 |= DMA_CCR_MSIZE_16BIT; // dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_16BIT);
DMA1_CCR7 |= DMA_CCR_TEIE; // dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL7);
DMA1_CCR7 |= DMA_CCR_TCIE; // dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL7);
*/
nvic_enable_irq(NVIC_DMA1_CHANNEL7_IRQ); // enable dma1_channel7_isr
}
void run_dmatimer(){
ow_done = 0;
adc_disable_dma(ADC1); // turn off DMA & ADC
adc_off(ADC1);
DMA1_IFCR = DMA_ISR_TEIF7|DMA_ISR_HTIF7|DMA_ISR_TCIF7|DMA_ISR_GIF7 |
DMA_ISR_TEIF1|DMA_ISR_HTIF1|DMA_ISR_TCIF1|DMA_ISR_GIF1; // clear flags
//init_ow_dmatimer();
/*
// TIM2_CH4 - DMA1, channel 7
dma_channel_reset(DMA1, DMA_CHANNEL7);
dma_set_read_from_memory(DMA1, DMA_CHANNEL7);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_16BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_16BIT);
dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL7);
dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL7);
*/
DMA1_CCR7 &= ~DMA_CCR_EN; // disable (what if it's enabled?) to set address
DMA1_CPAR7 = (uint32_t) &(TIM_CCR4(TIM2)); // dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t) &(TIM_CCR4(TIM2)));
DMA1_CMAR7 = (uint32_t) tim2_buff; // dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t)tim2_buff);
DMA1_CNDTR7 = tum2buff_ctr;//dma_set_number_of_data(DMA1, DMA_CHANNEL7, tum2buff_ctr);
// TIM2_CH4 - DMA1, channel 7
dma_channel_reset(DMA1, DMA_CHANNEL1);
DMA1_CCR1 = DMA_CCR_MINC | DMA_CCR_PSIZE_16BIT | DMA_CCR_MSIZE_16BIT
| DMA_CCR_TEIE | DMA_CCR_TCIE | DMA_CCR_PL_HIGH;
/*
dma_set_read_from_peripheral(DMA1, DMA_CHANNEL1);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL1);
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL1);
dma_set_peripheral_size(DMA1, DMA_CHANNEL1, DMA_CCR_PSIZE_16BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_16BIT);
dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL1);
dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL1);
*/
DMA1_CPAR1 = (uint32_t) &(TIM_CCR3(TIM2)); //dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t) &(TIM_CCR3(TIM2)));
DMA1_CMAR1 = (uint32_t) tim2_inbuff; //dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t) tim2_inbuff);
DMA1_CNDTR1 = tum2buff_ctr; //dma_set_number_of_data(DMA1, DMA_CHANNEL1, tum2buff_ctr);
nvic_enable_irq(NVIC_DMA1_CHANNEL1_IRQ);
DMA1_CCR7 |= DMA_CCR_EN; //dma_enable_channel(DMA1, DMA_CHANNEL7);
DMA1_CCR1 |= DMA_CCR_EN; //dma_enable_channel(DMA1, DMA_CHANNEL1);
TIM2_SR = 0; // clear all flags
TIM2_CR1 &= ~TIM_CR1_OPM; // continuous mode
TIM2_ARR = OW_BIT; // bit length
TIM2_EGR = TIM_EGR_UG; // update value of ARR
TIM2_CR2 &= ~TIM_CR2_CCDS; // timer_set_dma_on_compare_event(TIM2);
TIM2_CCER |= TIM_CCER_CC3E; // enable input capture
TIM2_DIER = TIM_DIER_CC4DE | TIM_DIER_CC3DE; // enable DMA events
// set low polarity, enable cc out & enable input capture
TIM2_CCER |= TIM_CCER_CC4P | TIM_CCER_CC4E | TIM_CCER_CC3E;
TIM2_CR1 |= TIM_CR1_CEN; // run timer
}
uint16_t rstat = 0, lastcc3;
void ow_reset(){
ow_done = 0;
rstat = 0;
TIM2_SR = 0; // clear all flags
TIM2_DIER = 0; // disable timer interrupts
TIM2_ARR = OW_RESET_TIME; // set period to 1ms
TIM2_CCR4 = OW_RESET; // zero pulse length
TIM2_EGR = TIM_EGR_UG; // update values of ARR & CCR4
TIM2_CR1 |= TIM_CR1_OPM | TIM_CR1_CEN; // we need only single pulse & run timer
TIM2_SR = 0; // clear update flag generated after timer's running
TIM2_DIER = TIM_DIER_UIE | TIM_DIER_CC3IE; // generate interrupts on update event & cc
nvic_enable_irq(NVIC_TIM2_IRQ);
}
void tim2_isr(){
if(TIM2_SR & TIM_SR_UIF){ // update interrupt
TIM2_SR &= ~TIM_SR_UIF; // clear flag
TIM2_DIER = 0; // disable all timer interrupts
TIM2_CCR4 = 0; // set output value to 1
TIM2_EGR |= TIM_EGR_UG; // generate update event to change value in CCR4
TIM2_CR1 &= ~TIM_CR1_CEN; // timer_disable_counter(TIM2);
nvic_disable_irq(NVIC_TIM2_IRQ);
ow_done = 1;
rstat = lastcc3;
/* print_int(rstat, lastsendfun);
MSG("\n");*/
}
if(TIM2_SR & TIM_SR_CC3IF){ // we need this interrupt to store CCR3 value
TIM2_SR = 0; // clear flag (we've manage TIM_SR_UIF before, so can simply do =0)
lastcc3 = TIM2_CCR3;
//TIM2_DIER &= ~TIM_DIER_CC3IE; // disable CCR3 interrupts
}
}
void dma1_channel7_isr(){
if(DMA1_ISR & DMA_ISR_TCIF7){
DMA1_IFCR = DMA_IFCR_CTCIF7; // clear flag
DMA1_CCR7 &= ~DMA_CCR_EN; // disable DMA1 channel 7
//TIM2_DIER &= ~TIM_DIER_CC4DE;
}else if(DMA1_ISR & DMA_ISR_TEIF7){
DMA1_IFCR = DMA_IFCR_CTEIF7;
DBG("DMA out transfer error\n");
}
}
void dma1_channel1_isr(){
//int i;
if(DMA1_ISR & DMA_ISR_TCIF1) {
DMA1_IFCR = DMA_IFCR_CTCIF1;
TIM2_CR1 &= ~TIM_CR1_CEN; // timer_disable_counter(TIM2);
//TIM2_DIER &= ~TIM_DIER_CC3DE;
DMA1_CCR1 &= ~DMA_CCR_EN; // disable DMA1 channel 1
nvic_disable_irq(NVIC_DMA1_CHANNEL1_IRQ);
ow_done = 1;
/* for(i = 0; i < tum2buff_ctr; i++){
print_int(tim2_inbuff[i], lastsendfun);
MSG(" ");
}
MSG("\n");*/
}else if(DMA1_ISR & DMA_ISR_TEIF1){
DMA1_IFCR = DMA_IFCR_CTEIF1;
DBG("DMA in transfer error\n");
}
}
uint8_t OW_get_reset_status(){
/* print_int(rstat, lastsendfun);
MSG("\n");*/
if(rstat < OW_PRESENT) return 0; // no devices
return 1;
}

View File

@ -34,16 +34,6 @@
*/
#define TIM2_DMABUFF_SIZE 128
// 1-wire zero-state lengths (in us minus 1)
#define OW_1 (9)
#define OW_0 (69)
#define OW_READ1 (14)
#define OW_BIT (79)
#define OW_RESET (499)
#define OW_RESET_TIME (999)
#define OW_PRESENT (549)
extern volatile uint16_t ADC_value[]; // ADC DMA value
#define TRD_NO (8) // number of TRD devices
@ -60,6 +50,8 @@ void SysTick_init();
void ADC_init();
void ADC_calibrate_and_start();
void adc_dma_on();
/*
* USB interface
*/
@ -104,22 +96,27 @@ void ADC_calibrate_and_start();
/*
* One Wire interface
*/
*
// In case of using other USART for 1-wire port, make corresponding change
// and redefine pins in OW_Init
#define OW_USART_X USART2
#define OW_RX_PORT GPIO_BANK_USART2_RX
#define OW_RX_PIN GPIO_USART2_RX
*/
/*
* Shutter defines
*/
// external signals for shutter opening: PB3 (SPI1_SCK) - from camera electronics, PB4 (SPI1_MISO) - from manual switch
// both are pull-up inputs
#define SHUTTER_EXT_PORT (GPIOB)
#define SHUTTER_CAM_PIN (GPIO3)
//#define SHUTTER_CAM_PORT (GPIOB)
//#define SHUTTER_CAM_PIN (GPIO3)
// As PB3 was burned, redefine CAM to EXT0 - PD10
#define SHUTTER_CAM_PORT (GPIOD)
#define SHUTTER_CAM_PIN (GPIO10)
#define SHUTTER_MAN_PORT (GPIOB)
#define SHUTTER_MAN_PIN (GPIO4)
// shutter feedback ==0 when opened, PB5 (SPI1_MOSI)
#define SHUTTER_FBSW_PORT (GPIOB)
#define SHUTTER_FBSW_PIN (GPIO5)
// LED status open-drain output: PB8 (CAN RX)
#define LED_STATUS_PORT (GPIOB)
@ -153,15 +150,4 @@ int shutter_voltage();
int power_voltage();
int TRD_value(uint8_t num);
void init_ow_dmatimer();
void run_dmatimer();
extern uint8_t ow_done;
#define OW_READY() (ow_done)
void ow_dma_on();
void adc_dma_on();
uint8_t OW_add_byte(uint8_t ow_byte, uint8_t Nbits, uint8_t ini);
uint8_t OW_add_read_seq(uint8_t Nbytes);
void read_from_OWbuf(uint8_t start_idx, uint8_t N, uint8_t *outbuf);
void ow_reset();
uint8_t OW_get_reset_status();
#endif // __HARDWARE_INI_H__

Binary file not shown.

View File

@ -24,11 +24,19 @@
#include "cdcacm.h"
#include "uart.h"
#include "spi.h"
//#include "stepper_motors.h"
#include "sync.h"
#include "flash.h"
#include "AD7794.h"
#include "onewire.h"
#include "stepper_motors.h"
#include "powerhw.h"
volatile uint32_t Timer = 0, tOVRFL = 0; // global timer (milliseconds), overflow counter
usbd_device *usbd_dev;
uint8_t OW_scan = 1;
uint8_t ADC_monitoring = 0; // ==1 to make continuous monitoring
uint32_t ad7794_on = 0;
@ -135,9 +143,30 @@ void AD7794_init(){
}
}
void scan_onewire(){
if(!OW_get_reset_status()){ // try to send read sequence if there wasn't any 1-wire devices
int i;
for(i = 0; i < OW_dev_amount; ++i)
OW_temperature[i] = ERR_TEMP_VAL;
OW_send_read_seq();
return;
}
if(OW_MEASUREMENTS_DONE()){
OW_CLEAR_DONE_FLAG();
OW_read_next_temp();
}
if(OW_DATA_READY()){
OW_CLEAR_READY_FLAG();
if(OW_current_num() == OW_dev_amount - 1)
OW_send_read_seq();
else
OW_read_next_temp();
}
}
int main(){
//int i;
uint32_t Shtr_blink_timer = 0, Old_timer = 0, lastTRDread = 0, lastTmon = 0;
uint32_t Shtr_blink_timer = 0, Old_timer = 0, lastTRDread = 0, lastTmon = 0, OW_timer = 0;
int oldusbdatalen = 0;
//SPI_read_status SPI_stat;
@ -149,7 +178,6 @@ int main(){
// GPIO
GPIO_init();
usb_disconnect(); // turn off USB while initializing all
// init USART3 (master) & USART1 (slave)
@ -166,7 +194,6 @@ int main(){
// SPI2 used for working with external ADC
switch_SPI(SPI2); // init SPI2
SPI_init();
init_ow_dmatimer();
// wait a little and then turn on USB pullup
// for (i = 0; i < 0x800000; i++)
@ -183,6 +210,9 @@ int main(){
read_stored_data(); // copy stored data into RAM
init_ow_dmatimer();
//OW_send_read_seq();
LED_STATUS_OK(); // All initialized - light up LED
while(1){
usbd_poll(usbd_dev);
@ -199,11 +229,10 @@ int main(){
}
}
OW_process(); // process 1-wire commands
if(OW_DATA_READY()){
OW_CLEAR_READY_FLAG();
#ifdef EBUG
OW_printID(0, lastsendfun);
#endif
// scan 1-wire each 1 second
if(OW_scan && (Timer - OW_timer > 999 || Timer < OW_timer)){
OW_timer = Timer;
scan_onewire();
}
process_stepper_motors(); // check flags of motors' timers
process_shutter(); // shutter state machine
@ -221,12 +250,6 @@ int main(){
if(Shutter_State == SHUTTER_NOTREADY){
shutter_init();
}
//OW_fill_ID(0);
//gpio_toggle(GPIOC, GPIO12); // toggle LED
//gpio_toggle(GPIO_BANK_SPI2_MOSI, GPIO_SPI2_MOSI);
//gpio_toggle(GPIO_BANK_SPI2_SCK, GPIO_SPI2_SCK);
// if(!ad7794_on) AD7794_init(); // try to init ADC if it doesn't work
//print_int(Timer/1000, usb_send);
}else if(Timer < Old_timer){ // Timer overflow
Old_timer = 0;
tOVRFL++; // this is an overflow counter - for workinkg in long-long time interval

View File

@ -36,17 +36,12 @@
#include <libopencm3/stm32/adc.h>
#include <libopencm3/stm32/dma.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/timer.h>
#include "user_proto.h"
#define ADC_CHANNELS_NUMBER (10)
#include "sync.h" // mutexes
#include "flash.h"
#include "user_proto.h"
#include "AD7794.h"
#include "onewire.h"
#include "stepper_motors.h"
#include "powerhw.h"
#define _U_ __attribute__((__unused__))
#define U8(x) ((uint8_t) x)
#define U16(x) ((uint16_t) x)
@ -56,6 +51,7 @@ extern uint32_t ad7794_values[]; // array with ADC data
extern uint8_t doubleconv; // single/double ADC conversion
extern uint32_t ad7794_on; // ==1 after AD7794 initialisation
extern uint8_t ADC_monitoring; // ==1 to make continuous monitoring
extern uint8_t OW_scan;
void AD7794_init();
extern volatile uint32_t Timer; // global timer (milliseconds)

View File

@ -18,9 +18,10 @@
*/
#include "onewire.h"
#include "user_proto.h"
#include "hardware_ini.h"
#include "flash.h"
OW_ID id_array[OW_MAX_NUM]; // 1-wire devices ID buffer (not more than eight)
uint8_t dev_amount = 0; // amount of 1-wire devices
//OW_ID id_array[OW_MAX_NUM]; // 1-wire devices ID buffer (not more than eight)
// states of 1-wire processing queue
typedef enum{
@ -29,34 +30,224 @@ typedef enum{
OW_SEND_STATE, // send data
OW_READ_STATE, // wait for reading
} OW_States;
static volatile OW_States OW_State = OW_OFF_STATE; // 1-wire state, 0-not runned
void (*ow_process_resdata)() = NULL;
void wait_reading();
static uint16_t tim2_buff[TIM2_DMABUFF_SIZE];
static uint16_t tim2_inbuff[TIM2_DMABUFF_SIZE];
int tum2buff_ctr = 0;
uint8_t ow_done = 1;
uint8_t ow_measurements_done = 0;
/**
* this function sends bits of ow_byte (LSB first) to 1-wire line
* @param ow_byte - byte to convert
* @param Nbits - number of bits to send
* @param ini - 1 to zero counter
*/
uint8_t OW_add_byte(uint8_t ow_byte){
uint8_t i, byte;
for(i = 0; i < 8; i++){
if(ow_byte & 0x01){
byte = BIT_ONE_P;
}else{
byte = BIT_ZERO_P;
}
if(tum2buff_ctr == TIM2_DMABUFF_SIZE){
ERR("Tim2 buffer overflow");
return 0; // avoid buffer overflow
}
tim2_buff[tum2buff_ctr++] = byte;
ow_byte >>= 1;
}
return 1;
}
/**
* Adds Nbytes bytes 0xff for reading sequence
*/
uint8_t OW_add_read_seq(uint8_t Nbytes){
uint8_t i;
if(Nbytes == 0) return 0;
Nbytes *= 8; // 8 bits for each byte
for(i = 0; i < Nbytes; i++){
if(tum2buff_ctr == TIM2_DMABUFF_SIZE){
ERR("Tim2 buffer overflow");
return 0;
}
tim2_buff[tum2buff_ctr++] = BIT_READ_P;
}
return 1;
}
/**
* Fill output buffer with data from 1-wire
* @param start_idx - index from which to start (byte number)
* @param N - data length (in **bytes**)
* @outbuf - where to place data
*/
void read_from_OWbuf(uint8_t start_idx, uint8_t N, uint8_t *outbuf){
start_idx *= 8;
uint8_t i, j, last = start_idx + N * 8, byte;
if(last >= TIM2_DMABUFF_SIZE) last = TIM2_DMABUFF_SIZE;
for(i = start_idx; i < last;){
byte = 0;
for(j = 0; j < 8; j++){
byte >>= 1;
if(tim2_inbuff[i++] < ONE_ZERO_BARRIER)
byte |= 0x80;
}
*outbuf++ = byte;
}
}
// there's a mistake in opencm3, so redefine this if needed (TIM_CCMR2_CC3S_IN_TI1 -> TIM_CCMR2_CC3S_IN_TI4)
#ifndef TIM_CCMR2_CC3S_IN_TI4
#define TIM_CCMR2_CC3S_IN_TI4 (2)
#endif
void init_ow_dmatimer(){ // tim2_ch4 - PA3, no remap
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO3);
rcc_periph_clock_enable(RCC_TIM2);
rcc_periph_clock_enable(RCC_DMA1);
timer_reset(TIM2);
// timers have frequency of 1MHz -- 1us for one step
// 36MHz of APB1
timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
// 72MHz div 72 = 1MHz
TIM2_PSC = 71; // prescaler is (div - 1)
TIM2_CR1 = TIM_CR1_ARPE; // bufferize ARR/CCR
TIM2_ARR = RESET_LEN;
// PWM_OUT: TIM2_CH4; capture: TIM2_CH3
// PWM edge-aligned mode & enable preload for CCR4, CC3 takes input from TI4
TIM2_CCMR2 = TIM_CCMR2_OC4M_PWM1 | TIM_CCMR2_OC4PE | TIM_CCMR2_CC3S_IN_TI4;
TIM2_CCR4 = 0; // set output value to 1 by clearing CCR4
TIM2_EGR = TIM_EGR_UG; // update values of ARR & CCR4
// set low polarity for CC4, high for CC3 & enable CC4 out and CC3 in
TIM2_CCER = TIM_CCER_CC4P | TIM_CCER_CC4E | TIM_CCER_CC3E;
// TIM2_CH4 - DMA1, channel 7
dma_channel_reset(DMA1, DMA_CHANNEL7);
DMA1_CCR7 = DMA_CCR_DIR | DMA_CCR_MINC | DMA_CCR_PSIZE_16BIT | DMA_CCR_MSIZE_16BIT
| DMA_CCR_TEIE | DMA_CCR_TCIE | DMA_CCR_PL_HIGH;
nvic_enable_irq(NVIC_DMA1_CHANNEL7_IRQ); // enable dma1_channel7_isr
tum2buff_ctr = 0;
DBG("OW INITED\n");
}
void run_dmatimer(){
ow_done = 0;
TIM2_CR1 = 0;
adc_disable_dma(ADC1); // turn off DMA & ADC
adc_off(ADC1);
// TIM2_CH4 - DMA1, channel 7
DMA1_IFCR = DMA_ISR_TEIF7|DMA_ISR_HTIF7|DMA_ISR_TCIF7|DMA_ISR_GIF7 |
DMA_ISR_TEIF1|DMA_ISR_HTIF1|DMA_ISR_TCIF1|DMA_ISR_GIF1; // clear flags
DMA1_CCR7 &= ~DMA_CCR_EN; // disable (what if it's enabled?) to set address
DMA1_CPAR7 = (uint32_t) &(TIM_CCR4(TIM2)); // dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t) &(TIM_CCR4(TIM2)));
DMA1_CMAR7 = (uint32_t) &tim2_buff[1]; // dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t)tim2_buff);
DMA1_CNDTR7 = tum2buff_ctr-1;//dma_set_number_of_data(DMA1, DMA_CHANNEL7, tum2buff_ctr);
// TIM2_CH3 - DMA1, channel 1
dma_channel_reset(DMA1, DMA_CHANNEL1);
DMA1_CCR1 = DMA_CCR_MINC | DMA_CCR_PSIZE_16BIT | DMA_CCR_MSIZE_16BIT
| DMA_CCR_TEIE | DMA_CCR_TCIE | DMA_CCR_PL_HIGH;
DMA1_CPAR1 = (uint32_t) &(TIM_CCR3(TIM2)); //dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t) &(TIM_CCR3(TIM2)));
DMA1_CMAR1 = (uint32_t) tim2_inbuff; //dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t) tim2_inbuff);
DMA1_CNDTR1 = tum2buff_ctr; //dma_set_number_of_data(DMA1, DMA_CHANNEL1, tum2buff_ctr);
nvic_enable_irq(NVIC_DMA1_CHANNEL1_IRQ);
DMA1_CCR7 |= DMA_CCR_EN; //dma_enable_channel(DMA1, DMA_CHANNEL7);
DMA1_CCR1 |= DMA_CCR_EN; //dma_enable_channel(DMA1, DMA_CHANNEL1);
TIM2_SR = 0; // clear all flags
TIM2_ARR = BIT_LEN; // bit length
TIM2_CCR4 = tim2_buff[0]; // we should manually set first bit to avoid zero in tim2_inbuff[0]
TIM2_EGR = TIM_EGR_UG; // update value of ARR
TIM2_CR1 = TIM_CR1_ARPE; // bufferize ARR/CCR
TIM2_CR2 &= ~TIM_CR2_CCDS; // timer_set_dma_on_compare_event(TIM2);
TIM2_DIER = TIM_DIER_CC4DE | TIM_DIER_CC3DE; // enable DMA events
// set low polarity, enable cc out & enable input capture
TIM2_CR1 |= TIM_CR1_CEN; // run timer
}
uint16_t rstat = 0, lastcc3 = 3;
void ow_reset(){
ow_done = 0;
rstat = 0;
TIM2_SR = 0; // clear all flags
TIM2_CR1 = 0;
TIM2_DIER = 0; // disable timer interrupts
TIM2_ARR = RESET_LEN; // set period to 1ms
TIM2_CCR4 = RESET_P; // zero pulse length
TIM2_EGR = TIM_EGR_UG; // update values of ARR & CCR4
TIM2_DIER = TIM_DIER_CC3IE;
TIM2_CR1 = TIM_CR1_OPM | TIM_CR1_CEN | TIM_CR1_UDIS; // we need only single pulse & run timer; disable UEV
TIM2_SR = 0; // clear update flag generated after timer's running
nvic_enable_irq(NVIC_TIM2_IRQ);
}
void tim2_isr(){
if(TIM2_SR & TIM_SR_UIF){ // update interrupt
TIM2_DIER = 0; // disable all timer interrupts
TIM2_CCR4 = 0; // set output value to 1
TIM2_EGR = TIM_EGR_UG; // update values of ARR & CCR4
nvic_disable_irq(NVIC_TIM2_IRQ);
TIM2_SR = 0; // clear flag
ow_done = 1;
rstat = lastcc3;
}
if(TIM2_SR & TIM_SR_CC3IF){ // we need this interrupt to store CCR3 value
lastcc3 = TIM2_CCR3;
TIM2_CR1 &= ~TIM_CR1_UDIS; // enable UEV
TIM2_SR = 0; // clear flag (we've manage TIM_SR_UIF before, so can simply do =0)
TIM2_DIER |= TIM_DIER_UIE; // Now allow also Update interrupts to turn off everything
}
}
/**
* DMA interrupt in 1-wire mode
*/
void dma1_channel1_isr(){
if(DMA1_ISR & DMA_ISR_TCIF1){
DMA1_IFCR = DMA_IFCR_CTCIF1;
TIM2_CR1 &= ~TIM_CR1_CEN; // timer_disable_counter(TIM2);
DMA1_CCR1 &= ~DMA_CCR_EN; // disable DMA1 channel 1
nvic_disable_irq(NVIC_DMA1_CHANNEL1_IRQ);
ow_done = 1;
}else if(DMA1_ISR & DMA_ISR_TEIF1){
DMA1_IFCR = DMA_IFCR_CTEIF1;
DBG("DMA in transfer error\n");
}
}
void dma1_channel7_isr(){
if(DMA1_ISR & DMA_ISR_TCIF7){
DMA1_IFCR = DMA_IFCR_CTCIF7; // clear flag
DMA1_CCR7 &= ~DMA_CCR_EN; // disable DMA1 channel 7
}else if(DMA1_ISR & DMA_ISR_TEIF7){
DMA1_IFCR = DMA_IFCR_CTEIF7;
DBG("DMA out transfer error\n");
}
}
uint8_t OW_get_reset_status(){
if(rstat < RESET_BARRIER) return 0; // no devices
return 1;
}
OW_States OW_State = OW_OFF_STATE; // 1-wire state, 0-not runned
uint8_t OW_wait_bytes = 0; // amount of bytes needed to read
uint8_t OW_start_idx = 0; // starting index to read from 1-wire buffer
uint8_t *read_buf = NULL; // buffer to read
uint8_t ow_data_ready = 0; // flag of reading OK
void OW_printID(uint8_t N, sendfun s){
void putc(uint8_t c){
if(c < 10)
s(c + '0');
else
s(c + 'a' - 10);
}
int i;
uint8_t *b = id_array[N].bytes;
s('0'); s('x'); // prefix 0x
for(i = 0; i < 8; i++){
putc(b[i] >> 4);
putc(b[i] & 0x0f);
}
s('\n');
}
uint8_t ow_was_reseting = 0;
/**
* Process 1-wire commands depending on its state
*/
void OW_process(){
static uint8_t ow_was_reseting = 0;
switch(OW_State){
case OW_OFF_STATE:
return;
@ -65,61 +256,82 @@ void OW_process(){
OW_State = OW_SEND_STATE;
ow_was_reseting = 1;
ow_reset();
//MSG("reset\n");
break;
case OW_SEND_STATE:
if(!OW_READY()) return; // reset in work
if(!ow_done) return; // reset in work
if(ow_was_reseting){
if(!OW_get_reset_status()){
BYTE_MSG("error: no 1-wire devices found\n");
if(rstat < RESET_BARRIER){
ERR("Error: no 1-wire devices found\n");
ow_was_reseting = 0;
// OW_State = OW_OFF_STATE;
// return;
OW_State = OW_OFF_STATE;
return;
}
}
ow_was_reseting = 0;
OW_State = OW_READ_STATE;
run_dmatimer(); // turn on data transfer
//MSG("send\n");
break;
case OW_READ_STATE:
if(!OW_READY()) return; // data isn't ready
if(!ow_done) return; // data isn't ready
OW_State = OW_OFF_STATE;
adc_dma_on(); // return DMA1_1 to ADC at end of data transmitting
if(read_buf){
read_from_OWbuf(OW_start_idx, OW_wait_bytes, read_buf);
}
adc_start_conversion_regular(ADC1);
adc_start_conversion_direct(ADC1);
if(ow_process_resdata)
ow_process_resdata();
ow_data_ready = 1;
//MSG("read\n");
break;
}
}
static uint8_t *read_buf = NULL; // buffer for storing readed data
/**
* fill ID buffer with readed data
*/
void fill_buff_with_data(){
ow_process_resdata = NULL;
if(!read_buf) return;
read_from_OWbuf(1, 8, read_buf);
int i, j;
LP("Readed ID: ");
for(i = 0; i < 8; ++i){
print_hex(&read_buf[i], 1, lastsendfun);
lastsendfun(' ');
}
lastsendfun('\n');
// now check stored ROMs
for(i = 0; i < OW_dev_amount; ++i){
uint8_t *ROM = OW_id_array[i];
for(j = 0; j < 8; j++)
if(ROM[j] != read_buf[j]) break;
if(j == 8){ // we found this cell
ERR("Such ID exists\n");
goto ret;
}
}
++OW_dev_amount;
ret:
read_buf = NULL;
}
/**
* fill Nth array with identificators
*/
//uint8_t comtosend = 0;
void OW_fill_ID(uint8_t N){
if(N >= OW_MAX_NUM){
BYTE_MSG("number too big\n");
void OW_fill_next_ID(){
if(OW_dev_amount >= OW_MAX_NUM){
ERR("No memory left for new device\n");
return;
}
//OW_Send(1, (uint8_t*)"\xcc\x33", 2);
OW_Send(1, (uint8_t*)"\x19", 1);
// OW_Send(1, &comtosend, 1);
// comtosend++;
//OW_Send(1, (uint8_t*)"\xcc\xbe", 2);
OW_add_read_seq(9); // wait for 9 bytes
//OW_Send(0, (uint8_t*)"\xcc\x33\x10\x45\x94\x67\x7e\x8a", 8);
read_buf = id_array[N].bytes;
OW_wait_bytes = 8;
OW_start_idx = 0;
/*
OW_Send(0, (uint8_t*)"\x99\xee", 2);
OW_wait_bytes = 2;
OW_start_idx = 0;
read_buf = id_array[N].bytes;
*/
ow_data_ready = 0;
OW_State = OW_RESET_STATE;
OW_reset_buffer();
OW_add_byte(OW_READ_ROM);
OW_add_read_seq(8); // wait for 8 bytes
read_buf = OW_id_array[OW_dev_amount];
ow_process_resdata = fill_buff_with_data;
DBG("wait for ID\n");
}
/**
@ -131,112 +343,132 @@ void OW_fill_ID(uint8_t N){
* @return 1 if succeed, 0 if failure
*/
uint8_t OW_Send(uint8_t sendReset, uint8_t *command, uint8_t cLen){
uint8_t f = 1;
ow_data_ready = 0;
// if reset needed - send RESET and check bus
if(sendReset)
OW_State = OW_RESET_STATE;
else
OW_State = OW_SEND_STATE;
OW_reset_buffer();
while(cLen-- > 0){
if(!OW_add_byte(*command, 8, f)) return 0;
command++;
f = 0;
if(!OW_add_byte(*command++)) return 0;
}
return 1;
}
#if 0
void OW_ClearBuff(){
UART_buff *curbuff = get_uart_buffer(OW_USART_X);
curbuff->end = 0;
}
/*
* Inverce conversion - read data (not more than 8 bits)
*/
uint8_t OW_ConvertByte(uint8_t *bits, uint8_t L){
uint8_t ow_byte = 0, i, *st = bits;
if(L > 8) L = 8; // forget all other data
for(i = 0; i < L; i++, st++){
ow_byte = ow_byte >> 1; // prepare for next bit filling
if(*st == OW_1){
ow_byte |= 0x80; // MSB = 1
}
}
ow_byte >>= (8 - L);
print_hex(bits, L, lastsendfun);
lastsendfun(' ');
print_hex(&ow_byte, 1, lastsendfun);
newline(lastsendfun);
return ow_byte; // shift to the end: L could be != 8 ???
}
/*
* 1-wire reset
* Reset procedure: USART settings are 9600,8,n,1,
* send 0xf0 then check what we get
* if not 0xf0 line is busy.
* Other operations work with next USART settings: 115200,8,n,1
*
* return 1 in case of 1-wire devices present; otherwise return 0
*/
uint8_t OW_Reset(){
uint8_t ow_presence;
UART_buff *curbuff;
// change speed to 9600
usart_set_baudrate(OW_USART_X, 9600);
//USART_ClearFlag(OW_USART_X, USART_FLAG_TC);
fill_uart_buff(OW_USART_X, OW_RST); // send 1 byte data
// wait for end of transmission
while(!(USART_SR(OW_USART_X) & USART_SR_TC));
curbuff = get_uart_buffer(OW_USART_X);
if(!curbuff || !(curbuff->end)) return 0; // error reading
curbuff->end = 0; // zero counter
ow_presence = curbuff->buf[0];
// change speed back
usart_set_baudrate(OW_USART_X, 115200);
// if there is any device on bus, it will pull it, so we'll get not 0xf0
if(ow_presence != OW_RST){
return 1;
}
// we get 0xf0 -> there's nothing on the bus
return 0;
}
/**
* Check USART IN buffer for ready & fill user buffer with data on success
* @param buflen - expected buffer length
* @param data - pointer for reading buffer (if reading needed must be at least buflen-readStart bytes)
* @param readStart - first byte to read (starts from 0) or OW_NO_READ (not read)
* @return 0 if buffer not ready; 1 if OK
* convert temperature from scratchpad
* in case of error return 200000 (ERR_TEMP_VAL)
* return value in 10th degrees centigrade
*
* 0 - themperature LSB
* 1 - themperature MSB (all higher bits are sign)
* 2 - T_H
* 3 - T_L
* 4 - B20: Configuration register (only bits 6/5 valid: 9..12 bits resolution); 0xff for S20
* 5 - 0xff (reserved)
* 6 - (reserved for B20); S20: COUNT_REMAIN (0x0c)
* 7 - COUNT PER DEGR (0x10)
* 8 - CRC
*/
uint8_t OW_Get(uint8_t buflen, uint8_t *data, uint8_t readStart){
UART_buff *curbuff = get_uart_buffer(OW_USART_X);
uint8_t *buff = curbuff->buf;
if(curbuff->end < buflen/8) return 0;
while(buflen-- > 0){
if(readStart == 0){
*data++ = OW_ConvertByte(buff, 8);
}else{
if(readStart != OW_NO_READ){
readStart--;
int32_t gettemp(uint8_t *scratchpad){
// detect DS18S20
int32_t t = 0;
uint8_t l,m;
int8_t v;
if(scratchpad[7] == 0xff) // 0xff can be only if there's no such device or some other error
return ERR_TEMP_VAL;
m = scratchpad[1];
l = scratchpad[0];
if(scratchpad[4] == 0xff){ // DS18S20
v = l >> 1 | (m & 0x80); // take signum from MSB
t = ((int32_t)v) * 10L;
if(l&1) t += 5L; // decimal 0.5
}else{ // DS18B20
v = l>>4 | ((m & 7)<<4) | (m & 0x80);
t = ((int32_t)v) * 10L;
m = l & 0x0f; // add decimal
t += (int32_t)m; // t = v*10 + l*1.25 -> convert
if(m > 1) ++t; // 1->1, 2->3, 3->4, 4->5, 5->6
else if(m > 5) t += 2L; // 6->8, 7->9
}
}
buff += 8;
}
curbuff->end = 0; // zero counter
return 1;
return t;
}
int32_t OW_temperature[OW_MAX_NUM];
int8_t Ncur = -1;
/**
* get temperature from buffer
*/
void convert_next_temp(){
uint8_t scratchpad[9], idx = Ncur;
ow_process_resdata = NULL;
if(OW_dev_amount < 2){
idx = 0;
read_from_OWbuf(2, 9, scratchpad);
}else{
read_from_OWbuf(10, 9, scratchpad);
}
OW_temperature[idx] = gettemp(scratchpad);
#ifdef EBUG
if(mode == BYTE_MODE){
LP("T[");
print_int(idx, lastsendfun);
LP("] = ");
print_int(OW_temperature[idx], lastsendfun);
LP("/10 degrC\n");
}
#endif
}
/**
* read next stored thermometer
*/
void OW_read_next_temp(){
ow_data_ready = 0;
OW_State = OW_RESET_STATE;
OW_reset_buffer();
int i;
if(OW_dev_amount < 2){
Ncur = -1;
OW_add_byte(OW_SKIP_ROM);
}else{
if(++Ncur >= OW_dev_amount) Ncur = 0;
OW_add_byte(OW_MATCH_ROM);
uint8_t *ROM = OW_id_array[Ncur];
for(i = 0; i < 8; ++i)
OW_add_byte(ROM[i]);
}
OW_add_byte(OW_READ_SCRATCHPAD);
OW_add_read_seq(9); // wait for 9 bytes - ROM
ow_process_resdata = convert_next_temp;
}
void wait_reading(){
uint8_t bt;
read_from_OWbuf(0, 1, &bt);
if(bt == 0xff){ // the conversion is done!
ow_measurements_done = 1;
ow_process_resdata = NULL;
DBG("Measurements done!\n");
}else{
OW_State = OW_SEND_STATE;
OW_reset_buffer();
ow_data_ready = 0;
OW_add_read_seq(1); // send read seq waiting for end of conversion
}
}
void OW_send_read_seq(){
ow_data_ready = 0;
ow_measurements_done = 0;
OW_State = OW_RESET_STATE;
OW_reset_buffer();
OW_add_byte(OW_SKIP_ROM);
OW_add_byte(OW_CONVERT_T);
OW_add_read_seq(1); // send read seq waiting for end of conversion
ow_process_resdata = wait_reading;
}
/*
* scan 1-wire bus
* WARNING! The procedure works in real-time, so it is VERY LONG
@ -285,47 +517,3 @@ uint8_t OW_Scan(uint8_t *buf, uint8_t num){
return cnt_num;
}*/
uint8_t OW_Scan(uint8_t *buf, uint8_t num){
uint8_t flg, b[11], i;
flg = OW_Send(1, (uint8_t*)"\xcc\x33\xff\xff\xff\xff\xff\xff\xff\xff\xff", 11);
if(!flg) return 0;
OW_Wait_TX();
if(!OW_Get(11, b, 0)) return 0;
num += 2;
for(i = 2; i < num; i++) *buf++ = b[i];
return 1;
}
//OW_USART_X
/*
void OW_getTemp(){
uint8_t buf[9], i;
void printTBuf(){
uint8_t j;
OW_Send(0, (uint8_t*)"\xbe\xff\xff\xff\xff\xff\xff\xff\xff\xff", 10, buf, 9, 1);
for(j = 0; j != 9; j++)
printInt(&buf[j], 1);
newline();
}
// send broadcast message to start measurement
if(!OW_Send(1, (uint8_t*)"\xcc\x44", 2)) return;
Delay(1000);
// read values
if(dev_amount == 1){
if(OW_WriteCmd(OW_SKIP_ROM)) printTBuf();
}else{
for(i = 0; i < dev_amount; i++){
MSG("Device ", "ow");
USB_Send_Data(i + '0');
MSG(": ", 0);
if(OW_WriteCmd(OW_MATCH_ROM)){
OW_SendOnly(0, &ID_buf[i*8], 8);
printTBuf();
}
}
}
}
*/
#endif

View File

@ -24,51 +24,95 @@
#include "main.h"
#include "hardware_ini.h"
// 1-wire status
#define OW_OK (1)
#define OW_ERROR (2)
#define OW_NO_DEVICE (3)
// 20 bytes x 8bits
#define TIM2_DMABUFF_SIZE 160
#define OW_NO_READ (0xff)
#define OW_READ_SLOT (uint8_t*)"0xff"
// freq = 1MHz
// ARR values: 1000 for reset, 100 for data in/out
// CCR4 values: 500 for reset, 60 for sending 0 or reading, <15 for sending 1
// CCR3 values: >550 if there's devices on line (on reset), >12 (typ.15) - read 0, < 12 (typ.1) - read 1
#define RESET_LEN ((uint16_t)1000)
#define BIT_LEN ((uint16_t)100)
#define RESET_P ((uint16_t)500)
#define BIT_ONE_P ((uint16_t)10)
#define BIT_ZERO_P ((uint16_t)60)
#define BIT_READ_P ((uint16_t)5)
#define RESET_BARRIER ((uint16_t)550)
#define ONE_ZERO_BARRIER ((uint16_t)10)
#define ERR_TEMP_VAL ((int32_t)200000)
/*
typedef struct{
uint8_t bytes[8];
} OW_ID;
*/
#define OW_MAX_NUM 8
//extern OW_ID id_array[];
void init_ow_dmatimer();
void run_dmatimer();
extern uint8_t ow_done;
#define OW_READY() (ow_done)
void ow_dma_on();
uint8_t OW_add_byte(uint8_t ow_byte);
uint8_t OW_add_read_seq(uint8_t Nbytes);
void read_from_OWbuf(uint8_t start_idx, uint8_t N, uint8_t *outbuf);
void ow_reset();
uint8_t OW_get_reset_status();
extern int tum2buff_ctr;
#define OW_reset_buffer() do{tum2buff_ctr = 0;}while(0)
extern uint8_t ow_data_ready;
extern uint8_t ow_measurements_done;
#define OW_DATA_READY() (ow_data_ready)
#define OW_CLEAR_READY_FLAG() do{ow_data_ready = 0;}while(0)
#define OW_MEASUREMENTS_DONE() (ow_measurements_done)
#define OW_CLEAR_DONE_FLAG() do{ow_measurements_done = 0;}while(0)
void OW_process();
void OW_fill_ID(uint8_t N);
void OW_fill_next_ID();
void OW_send_read_seq();
uint8_t OW_Send(uint8_t sendReset, uint8_t *command, uint8_t cLen);
void OW_printID(uint8_t N, sendfun s);
extern int32_t OW_temperature[];
extern int8_t Ncur;
void OW_read_next_temp();
#define OW_current_num() (Ncur)
/*
* thermometer commands
* send them with bus reset!
*/
// find devices
#define OW_SEARCH_ROM (0xf0)
// read device (when it is alone on the bus)
#define OW_READ_ROM (0x33)
// send device ID (after this command - 8 bytes of ID)
#define OW_MATCH_ROM (0x55)
// broadcast command
#define OW_SKIP_ROM (0xcc)
// find devices with critical conditions
#define OW_ALARM_SEARCH (0xec)
/*
* thermometer functions
* send them without bus reset!
*/
// start themperature reading
#define OW_CONVERT_T (0x44)
// write critical temperature to device's RAM
#define OW_SCRATCHPAD (0x4e)
// read whole device flash
#define OW_READ_SCRATCHPAD (0xbe)
// copy critical themperature from device's RAM to its EEPROM
#define OW_COPY_SCRATCHPAD (0x48)
// copy critical themperature from EEPROM to RAM (when power on this operation runs automatically)
#define OW_RECALL_E2 (0xb8)
// check whether there is devices wich power up from bus
#define OW_READ_POWER_SUPPLY (0xb4)
#if 0
uint8_t OW_Get(uint8_t buflen, uint8_t *data, uint8_t readStart);
uint8_t OW_Scan(uint8_t *buf, uint8_t num);
// shortcuts for functions
// only send message b wich length is c with RESET flag a
#define OW_SendOnly(a,b,c) OW_Send(a, b, c)
// send 1 command (with bus reset)
#define OW_WriteCmd(cmd) OW_Send(1, cmd, 1)
// send 1 function (without bus reset)
#define OW_WriteFn(cmd) OW_Send(0, cmd, 1)
#define OW_Wait_TX() while(!(USART_SR(OW_USART_X) & USART_SR_TC))
void OW_getTemp();
#endif
/*
* thermometer identificator is: 8bits CRC, 48bits serial, 8bits device code (10h)
@ -78,48 +122,6 @@ void OW_getTemp();
* format T_H and T_L: 1bit sigh + 7bits of data
*/
/*
* thermometer commands (DS18S20)\
* send them with bus reset!
*/
// find devices
#define T_SEARCH_ROM (0xf0)
#define OW_SEARCH_ROM (uint8_t*)"\xf0"
// read device (when it is alone on the bus)
#define T_READ_ROM (0x33)
#define OW_READ_ROM (uint8_t*)"\x33"
// send device ID (after this command - 8 bytes of ID)
#define T_MATCH_ROM (0x55)
#define OW_MATCH_ROM (uint8_t*)"\x55"
// broadcast command
#define T_SKIP_ROM (0xcc)
#define OW_SKIP_ROM (uint8_t*)"\xcc"
// find devices with critical conditions
#define T_ALARM_SEARCH (0xec)
#define OW_ALARM_SEARCH (uint8_t*)"\xec"
/*
* thermometer functions
* send them without bus reset!
*/
// start themperature reading
#define T_CONVERT_T (0x44)
#define OW_CONVERT_T (uint8_t*)"\x44"
// write critical temperature to device's RAM
#define T_SCRATCHPAD (0x4e)
#define OW_SCRATCHPAD (uint8_t*)"\x4e"
// read whole device flash
#define T_READ_SCRATCHPAD (0xbe)
#define OW_READ_SCRATCHPAD (uint8_t*)"\xbe"
// copy critical themperature from device's RAM to its EEPROM
#define T_COPY_SCRATCHPAD (0x48)
#define OW_COPY_SCRATCHPAD (uint8_t*)"\x48"
// copy critical themperature from EEPROM to RAM (when power on this operation runs automatically)
#define T_RECALL_E2 (0xb8)
#define OW_RECALL_E2 (uint8_t*)"\xb8"
// check whether there is devices wich power up from bus
#define T_READ_POWER_SUPPLY (0xb4)
#define OW_READ_POWER_SUPPLY (uint8_t*)"\xb4"
/*
* RAM register:

View File

@ -20,6 +20,8 @@
*/
#include "main.h"
#include "powerhw.h"
// state of shutter - global variable to omit interface functions
shutter_state Shutter_State = SHUTTER_NOTREADY;
int8_t manual_pin_old_state = -1;
@ -148,7 +150,7 @@ void shutter_test(){
void shutter_ready(){
uint8_t test_err = 0;
//DBG("shtr ready\n");
uint32_t shtr_status = gpio_get(SHUTTER_EXT_PORT, SHUTTER_FBSW_PIN); // 0 when opened
uint32_t shtr_status = gpio_get(SHUTTER_FBSW_PORT, SHUTTER_FBSW_PIN); // 0 when opened
switch (Shutter_State){
case SHUTTER_CLOSED: // repeated pulse to check errors
if(shtr_status)
@ -235,14 +237,9 @@ shutter_state shutter_init(){
// feedback: floating input
gpio_set_mode(SHUTTER_PORT, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, SHUTTER_FB_PIN);
// Shutter control: input pull up
// gpio_set_mode(SHUTTER_EXT_PORT, GPIO_MODE_INPUT,
// GPIO_CNF_INPUT_FLOAT, SHUTTER_CAM_PIN | SHUTTER_MAN_PIN | SHUTTER_FBSW_PIN);
// gpio_set(SHUTTER_EXT_PORT, SHUTTER_CAM_PIN | SHUTTER_MAN_PIN | SHUTTER_FBSW_PIN); // turn on pull up
//DBG("shutter fb ready\n");
shutter_off();
camera_pin_old_state = (gpio_get(SHUTTER_EXT_PORT, SHUTTER_CAM_PIN)) ? 1 : 0;
manual_pin_old_state = (gpio_get(SHUTTER_EXT_PORT, SHUTTER_MAN_PIN)) ? 1 : 0;
camera_pin_old_state = (gpio_get(SHUTTER_CAM_PORT, SHUTTER_CAM_PIN)) ? 1 : 0;
manual_pin_old_state = (gpio_get(SHUTTER_MAN_PORT, SHUTTER_MAN_PIN)) ? 1 : 0;
//shutter_timer_fn = NULL;
shutter_wait_block(SHUTTER_OP_DELAY, shutter_test);
return SHUTTER_INITIALIZED; // we return this state in spite of the shutter isn't really initialized yet
@ -260,7 +257,7 @@ void process_shutter(){
if(Shutter_State == SHUTTER_NOTREADY) return;
// test state of external control pins
cam_pin_state = (gpio_get(SHUTTER_EXT_PORT, SHUTTER_CAM_PIN)) ? 1 : 0;
cam_pin_state = (gpio_get(SHUTTER_CAM_PORT, SHUTTER_CAM_PIN)) ? 1 : 0;
if(camera_pin_old_state != cam_pin_state){ // camera signal changed or initialisation
camera_pin_old_state = cam_pin_state;
if(cam_pin_state){ // close
@ -269,7 +266,7 @@ void process_shutter(){
ext_open = 1;
}
}
man_pin_state = (gpio_get(SHUTTER_EXT_PORT, SHUTTER_MAN_PIN)) ? 1 : 0;
man_pin_state = (gpio_get(SHUTTER_MAN_PORT, SHUTTER_MAN_PIN)) ? 1 : 0;
// to avoid opening shutter if user forget to set manual switch to "closed" position
// all operations with manual switch processed only in changing state of the switch
if(manual_pin_old_state != man_pin_state){ // user changed switch state -> open/close
@ -377,7 +374,7 @@ void print_shutter_state(sendfun s){
P("not initialised or broken", s);
}
P(" (reed ", s);
if(gpio_get(SHUTTER_EXT_PORT, SHUTTER_FBSW_PIN)){ // closed
if(gpio_get(SHUTTER_FBSW_PORT, SHUTTER_FBSW_PIN)){ // closed
P("closed", s);
}else{//opened
P("opened", s);
@ -387,9 +384,9 @@ void print_shutter_state(sendfun s){
#ifdef EBUG
if(mode == BYTE_MODE){
P("MAN: ",s);
if(gpio_get(SHUTTER_EXT_PORT, SHUTTER_MAN_PIN)) P("not ",s);
if(gpio_get(SHUTTER_MAN_PORT, SHUTTER_MAN_PIN)) P("not ",s);
P("pressed, EXT: ",s);
if(gpio_get(SHUTTER_EXT_PORT, SHUTTER_CAM_PIN)) P("not ",s);
if(gpio_get(SHUTTER_CAM_PORT, SHUTTER_CAM_PIN)) P("not ",s);
P("pressed\n", s);
}
#endif

View File

@ -20,6 +20,7 @@
*/
#include "main.h"
#include "stepper_motors.h"
#include "hardware_ini.h"
// TODO: function "move motor to given position"

View File

@ -22,6 +22,7 @@
#include "main.h"
#include "uart.h"
#include "cdcacm.h"
#include "hardware_ini.h"
// Buffers for Tx
static UART_buff TX_buffer[3]; // Tx buffers for all three ports
@ -74,7 +75,7 @@ void UART_setspeed(uint32_t UART, struct usb_cdc_line_coding *lc){
void UART_init(uint32_t UART){
uint32_t irq, rcc, rccgpio, gpioport, gpiopin;
switch(UART){
case USART2: // 1-wire
/* case USART2: // 1-wire
irq = NVIC_USART2_IRQ; // interrupt for given USART
rcc = RCC_USART2; // RCC timing of USART
rccgpio = RCC_GPIOA; // RCC timing of GPIO pin (for output)
@ -85,7 +86,7 @@ void UART_init(uint32_t UART){
// output pin setup
gpioport = GPIO_BANK_USART2_TX;
gpiopin = GPIO_USART2_TX;
break;
break;*/
case USART3: // without remapping
irq = NVIC_USART3_IRQ;
rcc = RCC_USART3;
@ -114,17 +115,17 @@ void UART_init(uint32_t UART){
rcc_periph_clock_enable(rcc); // USART
rcc_periph_clock_enable(rccgpio); // GPIO pins
// enable output pin
if(UART == OW_USART_X){ // one wire
/* if(UART == OW_USART_X){ // one wire
// TX: open-drain output
gpio_set_mode(gpioport, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, gpiopin);
// RX: floating input
gpio_set_mode(OW_RX_PORT, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, OW_RX_PIN);
}else{
}else{*/
gpio_set_mode(gpioport, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, gpiopin);
}
//}
// enable IRQ
nvic_enable_irq(irq);
UART_setspeed(UART, NULL);
@ -181,10 +182,10 @@ void UART_isr(uint32_t UART){
// particular interrupt handlers
void usart1_isr(){
UART_isr(USART1);
}
}/*
void usart2_isr(){
UART_isr(USART2);
}
}*/
void usart3_isr(){
UART_isr(USART3);
}

View File

@ -24,6 +24,9 @@
#include "uart.h"
#include "hardware_ini.h"
#include "flash.h"
#include "stepper_motors.h"
#include "powerhw.h"
#include "AD7794.h"
// mode:
curmode_t mode = BYTE_MODE; // text protocol, activated on 1st meeteng of '['
@ -57,7 +60,7 @@ static intfun I = NULL; // function to process entered integer
void print_ad_vals(sendfun s){
int j;
if(ad7794_on){
for(j = 0; j < TRD_NO; j++){
for(j = 0; j < TRD_NO; ++j){
if(mode == LINE_MODE){
P("[ " STR_EXTADC_VALUES " ", s);
print_int(j, s);
@ -92,6 +95,22 @@ void print_int_ad_vals(sendfun s){
else if(mode == LINE_MODE)
P(" ]\n", s);
}
if(OW_scan){ // print 1-wire temperatures
for(j = 0; j < OW_dev_amount; ++j){
if(OW_temperature[j] != ERR_TEMP_VAL){
if(mode == LINE_MODE)
P("[ " STR_INTADC_VALUES " ", s);
else
s('N');
print_int(j + TRD_NO, s);
s(' ');
print_int(OW_temperature[j], s);
if(mode == LINE_MODE)
P(" ]\n", s);
else s(' ');
}
}
}
}
/*
@ -225,10 +244,10 @@ void help(sendfun s){
pr("L\tmove filters (2) wheel to Nth position");
pr("M\tswitch on/off ADC monitoring");
//pr("N");
//pr("O");
pr("P\ttest (ow_fill_id)");
//pr("Q");
//pr("R");
pr("O\tturn on 1-wire scan");
pr("P\tadd 1-wire sensor");
pr("Q\tturn off 1-wire scan");
pr("R\terase 1-wire IDs from memory");
pr("S\tturn AD7794 to single conversion mode");
pr(STR_PRINT_TIME "\tprint current value of time counters");
//pr("U\t(reserved)");
@ -242,7 +261,7 @@ void help(sendfun s){
pr("c\tclose shutter");
pr("d\tchange value of ADC divisor No N");
//pr("e");
pr("f\tsave current values of ADC mult/div to flash");
pr("f\tupdate flash settings");
pr("g\tchange AD7794 gain");
pr(STR_SHTR_VOLTAGE "\tshow shutter voltage");
pr(STR_EXTADC_INIT "\tinit AD7794");
@ -431,6 +450,12 @@ int parce_incoming_buf(char *buf, int len, sendfun s){
case 'o': // open shutter
do_echo = try_to_open_shutter();
break;
case 'O': // 1-wire scan ON
if(!OW_scan){
OW_scan = 1;
OW_send_read_seq();
}
break;
case CMD_MOTORS_VOLTAGE: // [p] show motors voltage * 100
if(mode == LINE_MODE) P("[ " STR_MOTORS_VOLTAGE " ", s);
print_int(power_voltage(), s);
@ -438,10 +463,16 @@ int parce_incoming_buf(char *buf, int len, sendfun s){
newline(s);
do_echo = 0;
break;
case 'P': // (only for byte mode)
case 'P': // (only for byte mode) - add 1-wire device
if(mode != BYTE_MODE) return 0;
OW_fill_ID(0);
//run_dmatimer();
OW_fill_next_ID();
break;
case 'Q': // 1-wire scan OFF
OW_scan = 0;
break;
case 'R': // (only for byte mode) - reset 1-wire IDs in RAM
if(mode != BYTE_MODE) return 0;
OW_dev_amount = 0;
break;
case 'r': // reinit shutter
shutter_init();
@ -477,14 +508,6 @@ int parce_incoming_buf(char *buf, int len, sendfun s){
/* case 'U': // test: init USART1
UART_init(USART1);
break; */
/* case 'W': // scan for one 1-wire device
if(1 == OW_Scan(onewire_addr, 1)){
P("found 1-wire: ", s);
print_hex(onewire_addr, 8, s);
}else
P("1-wire error",s );
P("\n", s);
break;*/
case 'x': // set period of TIM1 (motors 1..3)
active_motor = 1;
I = set_timr;

View File

@ -28,9 +28,10 @@
// shorthand for prnt
#define P(arg, s) prnt((uint8_t*)arg, s)
#define LP(arg) prnt((uint8_t*)arg, lastsendfun)
// debug message - over USB
#ifdef EBUG
#define DBG(a) do{if(mode == BYTE_MODE) prnt((uint8_t*)a, usb_send);}while(0)
#define DBG(a) do{if(mode == BYTE_MODE) prnt((uint8_t*)a, lastsendfun);}while(0)
#else
#define DBG(a)
#endif