removing junk files accidentally commit last time.
This commit is contained in:
parent
f4bbad3d4a
commit
0e0e307f64
|
|
@ -1,418 +0,0 @@
|
|||
#include "swim.h"
|
||||
|
||||
//=================================================================================================
|
||||
//
|
||||
// SWIM operations
|
||||
// This file includes all the swim functions possible to be called from the swim dictionary.
|
||||
//
|
||||
// See description of the commands contained here in shared/shared_dictionaries.h
|
||||
//
|
||||
//=================================================================================================
|
||||
|
||||
/* Desc:Function takes an opcode which was transmitted via USB
|
||||
* then decodes it to call designated function.
|
||||
* shared_dict_swim.h is used in both host and fw to ensure opcodes/names align
|
||||
* Pre: Macros must be defined in firmware pinport.h
|
||||
* opcode must be defined in shared_dict_swim.h
|
||||
* Post:function call complete.
|
||||
* Rtn: SUCCESS if opcode found, error if opcode not present or other problem.
|
||||
*/
|
||||
uint8_t swim_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_t *rdata )
|
||||
{
|
||||
#define RD_LEN 0
|
||||
#define RD0 1
|
||||
#define RD1 2
|
||||
|
||||
#define BYTE_LEN 1
|
||||
#define HWORD_LEN 2
|
||||
switch (opcode) {
|
||||
case SWIM_ACTIVATE: swim_activate(); break;
|
||||
case SWIM_RESET: swim_reset(); break;
|
||||
// case SWIM_SRST: swim_srst(); break;
|
||||
case WOTF:
|
||||
rdata[RD_LEN] = BYTE_LEN;
|
||||
rdata[RD0] = swim_woft(operand); break;
|
||||
// case ROTF:
|
||||
// rdata[RD_LEN] = BYTE_LEN;
|
||||
// rdata[RD0] = swim_roft(); break;
|
||||
default:
|
||||
//opcode doesn't exist
|
||||
return ERR_UNKN_SWIM_OPCODE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
uint8_t swim_pin;
|
||||
uint16_t swim_mask;
|
||||
GPIO_TypeDef *swim_base;
|
||||
|
||||
void delay( uint16_t delay )
|
||||
{
|
||||
uint16_t i = 0;
|
||||
|
||||
for( i=0; i<delay; i++) {
|
||||
NOP();
|
||||
NOP();
|
||||
} //16->11.8 on stmad
|
||||
|
||||
}
|
||||
|
||||
/* Desc:Initiate SWIM activate sequence
|
||||
* Pre: swim_pin must be set and initialized via io.h
|
||||
* Post:STM8 mcu SWIM active
|
||||
* Rtn: SUCCESS if able to enter sucessfully.
|
||||
*/
|
||||
void swim_activate()
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
// pinport_call( CTL_OP_, 0, swim_pin, 0);
|
||||
|
||||
//toggles in this manner take 4.55-4.6usec on AVR
|
||||
//toggles in this manner take 4.9-4.95usec on STM adapter
|
||||
|
||||
//pulse low for 16usec spec says 16usec
|
||||
//but looking at working programmers they do twice the delays below
|
||||
pinport_call( CTL_SET_LO_, 0, swim_pin, 0);
|
||||
delay(16);
|
||||
pinport_call( CTL_SET_HI_, 0, swim_pin, 0);
|
||||
|
||||
//toggle high->low T=1msec 4x
|
||||
for( i = 0; i < 4; i++) {
|
||||
//STM adapter 720 = 500.9usec
|
||||
//TODO move this timed code into a timer to make timing more stable
|
||||
//between boards, pinport.c code, etc....
|
||||
#ifdef STM_INL6
|
||||
delay(719);
|
||||
#endif
|
||||
#ifdef STM_ADAPTER
|
||||
delay(720);
|
||||
#endif
|
||||
pinport_call( CTL_SET_LO_, 0, swim_pin, 0);
|
||||
delay(718);
|
||||
pinport_call( CTL_SET_HI_, 0, swim_pin, 0);
|
||||
}
|
||||
|
||||
//toggle high->low T=0.5msec 4x
|
||||
for( i = 0; i < 4; i++) {
|
||||
//STM adapter 358 = 256usec
|
||||
delay(356);
|
||||
pinport_call( CTL_SET_LO_, 0, swim_pin, 0);
|
||||
delay(355);
|
||||
pinport_call( CTL_SET_HI_, 0, swim_pin, 0);
|
||||
}
|
||||
|
||||
//pinport_call( CTL_IP_PU_, 0, swim_pin, 0);
|
||||
|
||||
|
||||
//wait for device to take swim_pin low for ~16usec
|
||||
//it's low for 128 SWIM clock sync pulse
|
||||
//Best way to do this would be to wait for an interrupt
|
||||
//on the swim pin going low, then have the isr count
|
||||
//low time. If anything takes too long timeout.
|
||||
|
||||
//TODO
|
||||
//return SUCCESS/FAIL depending on wether that ~16usec pulse was obtained
|
||||
// return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/* Desc:Hold swim pin low for >128 SWIM clocks (16usec)
|
||||
* Pre: swim must be activated by
|
||||
* Post:STM8 mcu SWIM comms are reset
|
||||
* Rtn: SUCCESS if device responds with sync window.
|
||||
*/
|
||||
void swim_reset()
|
||||
{
|
||||
//pinport_call( CTL_OP_, 0, swim_pin, 0);
|
||||
|
||||
//pulse low for 16usec spec says 16usec
|
||||
//but looking at working programmers they do twice the delays below
|
||||
pinport_call( CTL_SET_LO_, 0, swim_pin, 0);
|
||||
delay(16);
|
||||
pinport_call( CTL_SET_HI_, 0, swim_pin, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define mov_swim_mask_r0() __asm ("mov r0, %[val]" : : [val] "r" (swim_mask) : "r0" )
|
||||
#define mov_pushpull_r6() __asm ("mov r6, %[val]" : : [val] "r" (pushpull) : "r6" )
|
||||
#define mov_opendrain_r7() __asm ("mov r7, %[val]" : : [val] "r" (opendrain) : "r7" )
|
||||
|
||||
//BSRR 0x18
|
||||
#define str_r0_bset() __asm volatile ("strh r0, [%[mmio], #0x18]" : : [mmio] "r" (swim_base))
|
||||
//BRR 0x28
|
||||
#define str_r0_bres() __asm volatile ("strh r0, [%[mmio], #0x28]" : : [mmio] "r" (swim_base))
|
||||
//OTYPER 0x04
|
||||
#define pp_swim() __asm volatile ("strh r6, [%[mmio], #0x04]" : : [mmio] "r" (swim_base))
|
||||
#define od_swim() __asm volatile ("strh r7, [%[mmio], #0x04]" : : [mmio] "r" (swim_base))
|
||||
|
||||
/* Desc:Transfer SWIM bit stream
|
||||
* Always outputs '0' as first bit for header "from host"
|
||||
* Will output len number of bits plus one for header
|
||||
* Pre: swim_pin must be set and initialized via io.h
|
||||
* stream has first data bit stored in bit15 - bit[15-len+2]
|
||||
* pairity bit must be last bit in stream sequence bit[15-len+1]
|
||||
* ie bit7 contains pairity bit for 8bit data stream
|
||||
* Post:STM8 mcu SWIM active
|
||||
* Rtn: 0xFF if no response, 0-NAK, non-zero non-0xFF if ACK.
|
||||
*/
|
||||
uint16_t swim_out(uint16_t stream, uint8_t len)//, GPIO_TypeDef *base)
|
||||
{
|
||||
__asm("swim_out:\n\t");
|
||||
|
||||
uint16_t return_val;
|
||||
|
||||
uint16_t pushpull = swim_base->OTYPER & ~swim_mask;
|
||||
uint16_t opendrain = swim_base->OTYPER | swim_mask;
|
||||
|
||||
mov_swim_mask_r0(); //will store r0 to BSRR or BRR to set/clear
|
||||
mov_pushpull_r6(); //will store r7 to OTYPER to drive high
|
||||
mov_opendrain_r7(); //will store r6 to OTYPER to allow device to drive low
|
||||
|
||||
//store len in r5
|
||||
__asm volatile ("mov r5, %[val]" : : [val] "r" (len) : "r5" );
|
||||
|
||||
//set flags so first bit is header '0' "from host"
|
||||
//the stream comes in as 16bit value with stream bit 7 in bit position 15
|
||||
//shift the stream left so the current transfer bit is in bit position 31
|
||||
//15 -> 30 is 15bit shifts, this leaves header zero in bit position 31
|
||||
//store stream in r4
|
||||
__asm volatile ("lsl r4, %[val], #15" : : [val] "r" (stream) : "r4", "cc" );
|
||||
|
||||
//NOTE! cortex M0 only supports 'S' versions of lsl, sub, and, etc type
|
||||
//opcodes. I get compiler error for including the 's' at end of instruction
|
||||
//but lsl is same as lsls on M0, so just use lsl to avoid compiler error...
|
||||
|
||||
// bit start:
|
||||
__asm("bit_start:\n\t");
|
||||
|
||||
//always start going low
|
||||
str_r0_bres();
|
||||
|
||||
//current bit is stored in bit31 and Negative flag is set if
|
||||
//current bit is '1'
|
||||
__asm volatile ("bpl cur_bit_zero\n\t");
|
||||
//go high since current bit is '1'
|
||||
pp_swim();
|
||||
str_r0_bset();
|
||||
od_swim();
|
||||
__asm volatile ("b det_next_bit\n\t");
|
||||
|
||||
__asm("cur_bit_zero:\n\t");
|
||||
//must delay same amount of time as instructions above since branch
|
||||
//add delay here until '1' and '0' are same length
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
NOP();
|
||||
|
||||
__asm("det_next_bit:\n\t");
|
||||
|
||||
//determine if this is the last bit
|
||||
__asm volatile ("sub r5, #0x01" : : : "r5", "cc" );
|
||||
|
||||
//if last bit, go to stream end to prepare for ACK/NAK latch
|
||||
__asm volatile ("bmi stream_end\n\t");
|
||||
|
||||
//determine next bit value
|
||||
__asm volatile ("lsl r4, #1" : : : "r4", "cc" );
|
||||
//Negative flag is now set for '1', and clear for '0'
|
||||
|
||||
//delay until 'go high' time for '0'
|
||||
//add delay here to make all bit transfers longer
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
NOP(); NOP(); NOP(); NOP();
|
||||
|
||||
//always go high for '0' (no effect if already high for '1')
|
||||
pp_swim();
|
||||
str_r0_bset();
|
||||
od_swim();
|
||||
|
||||
//go to bit start
|
||||
__asm volatile ("b bit_start\n\t");
|
||||
|
||||
//stream end:
|
||||
__asm("stream_end:\n\t");
|
||||
|
||||
//delay until 'go high' time for '0'
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
NOP(); NOP(); NOP();
|
||||
|
||||
//always go high for '0' (no effect if already high for '1')
|
||||
pp_swim();
|
||||
str_r0_bset();
|
||||
od_swim();
|
||||
|
||||
//delay until time to latch ACK/NAK from device
|
||||
NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
|
||||
//first need to ensure device is actually responding
|
||||
//sample when output should be low for a 1 or 0
|
||||
//str_r0_bres(); //debug set low to denote when swim pin is being sampled with logic anaylzer
|
||||
//sampling ~100nsec into bit transfer (low for 125nsec min)
|
||||
|
||||
//latch SWIM pin value from IDR 0x10
|
||||
__asm volatile ("ldrh r3, [%[mmio], #0x10]" : : [mmio] "r" (swim_base) : "r3");
|
||||
__asm volatile ("and r3, r0" : : : "r3" );
|
||||
|
||||
//if it wasn't low, then the device didn't respond, so return error designating that
|
||||
__asm volatile ("bne no_response\n\t");
|
||||
|
||||
//if (return_val != 0) {
|
||||
// goto no_response;
|
||||
// }
|
||||
|
||||
//now delay until ~half way through bit transfer to sense 1-ACK or 0-NAK
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
|
||||
//debug set low to denote when swim pin is being sampled with logic anaylzer
|
||||
//str_r0_bres();
|
||||
//sampling 1.35usec into bit transfer (~half way)
|
||||
|
||||
//latch SWIM pin value from IDR 0x10
|
||||
__asm volatile ("ldrh r3, [%[mmio], #0x10]" : : [mmio] "r" (swim_base) : "r3");
|
||||
|
||||
//move r3 to return val reg
|
||||
__asm ("mov %[rv], r3" : [rv] "=r" (return_val) );
|
||||
//mask out swim pin so return value is 0 or non-zero based on device output
|
||||
return_val &= swim_mask;
|
||||
|
||||
if (return_val != 0xFF) {
|
||||
//dummy check that keeps labels below available
|
||||
//because inline assembly is pissing me off
|
||||
goto return_response;
|
||||
}
|
||||
|
||||
__asm("no_response:\n\t");
|
||||
//return "fail to respond"
|
||||
return_val = 0xFF;
|
||||
|
||||
return_response:
|
||||
//return ACK/NAK from device
|
||||
return return_val;
|
||||
|
||||
// __asm("bkpt");
|
||||
//BSRR 0x18
|
||||
//BRR 0x28
|
||||
//OTYPER 0x04
|
||||
// __asm ("mov r0, %[mask]" : : [mask] "r" (swim_mask) : "r0" );
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x28]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x18]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x28]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x18]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x28]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x18]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x28]" : : [mmio] "r" (swim_base));
|
||||
// //__asm volatile ("nop");
|
||||
// //__asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x04]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x18]" : : [mmio] "r" (swim_base));
|
||||
|
||||
// __asm volatile ("strh %[val], [%[mmio], #0x28]" : [val] "=l" (swim_mask) : [mmio] "l" (swim_base));
|
||||
//// __asm volatile ("nop");
|
||||
// __asm volatile ("strh %[val], [%[mmio], #0x18]" : [val] "=l" (swim_mask) : [mmio] "l" (swim_base));
|
||||
//// __asm volatile ("nop");
|
||||
// __asm volatile ("strh %[val], [%[mmio], #0x28]" : [val] "=l" (swim_mask) : [mmio] "l" (swim_base));
|
||||
//// __asm volatile ("nop");
|
||||
// __asm volatile ("strh %[val], [%[mmio], #0x18]" : [val] "=l" (swim_mask) : [mmio] "l" (swim_base));
|
||||
//
|
||||
// //for some reason this last store writes a different value to the mmio register! WTF!!!!
|
||||
// //8000800: 851a strh r2, [r3, #40] ; 0x28^M
|
||||
// //8000802: 831a strh r2, [r3, #24]^M
|
||||
// //8000804: 851a strh r2, [r3, #40] ; 0x28^M
|
||||
// //8000806: 831a strh r2, [r3, #24]^M
|
||||
// //8000808: 851a strh r2, [r3, #40] ; 0x28^M
|
||||
// //800080a: 831a strh r2, [r3, #24]^M
|
||||
// //800080c: 851a strh r2, [r3, #40] ; 0x28^M
|
||||
// //800080e: 831a strh r2, [r3, #24]^M
|
||||
// //8000810: 8319 strh r1, [r3, #24]^M
|
||||
// __asm volatile ("strh %[val], [%[mmio], #0x18]" : [val] "=l" (swim_mask) : [mmio] "l" (swim_base));
|
||||
|
||||
// __asm volatile ("nop");
|
||||
// __asm("bkpt");
|
||||
|
||||
|
||||
// NOP();
|
||||
// NOP();
|
||||
// //delay(1);
|
||||
// EXP0_HI();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// delay(10);
|
||||
// EXP0_LO();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// EXP0_HI();
|
||||
|
||||
|
||||
|
||||
// asm (
|
||||
// "TST LR, #0x40\n\t"
|
||||
// "BEQ from_nonsecure\n\t"
|
||||
// "from_secure:\n\t"
|
||||
// "TST LR, #0x04\n\t"
|
||||
// "ITE EQ\n\t"
|
||||
// "MRSEQ R0, MSP\n\t"
|
||||
// "MRSNE R0, PSP\n\t"
|
||||
// "B hard_fault_handler_c\n\t"
|
||||
// "from_nonsecure:\n\t"
|
||||
// "MRS R0, CONTROL_NS\n\t"
|
||||
// "TST R0, #2\n\t"
|
||||
// "ITE EQ\n\t"
|
||||
// "MRSEQ R0, MSP_NS\n\t"
|
||||
// "MRSNE R0, PSP_NS\n\t"
|
||||
// "B hard_fault_handler_c\n\t"
|
||||
// );
|
||||
|
||||
|
||||
//output bit stream from bit15 to bit15-len
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Desc:write byte to SWIM
|
||||
* Pre: swim must be activated
|
||||
* Post:
|
||||
* Rtn: 0-NAK, 1-ACK beware, no response looks like ACK!
|
||||
*/
|
||||
uint8_t swim_woft(uint8_t data)
|
||||
{
|
||||
//bit sequence:
|
||||
//1bit header "0" Host comm
|
||||
//3bit command b2-1-0 "010" WOTF
|
||||
//1bit pairity xor of cmd "1"
|
||||
//1bit ACK "1" or NAK "0" from device
|
||||
// 0b0_0101
|
||||
return swim_out( 0x5000, 4);
|
||||
|
||||
//1bit header "0" from host
|
||||
//8bits data7:0
|
||||
//1bit parity of data
|
||||
//1bit ACK "1" or NAK "0" from device
|
||||
// 0b0-data-pb
|
||||
//swim_out( data<<8, 9);//, EXP0bank, EXP0 );
|
||||
|
||||
}
|
||||
|
|
@ -1,428 +0,0 @@
|
|||
#include "swim.h"
|
||||
|
||||
//=================================================================================================
|
||||
//
|
||||
// SWIM operations
|
||||
// This file includes all the swim functions possible to be called from the swim dictionary.
|
||||
//
|
||||
// See description of the commands contained here in shared/shared_dictionaries.h
|
||||
//
|
||||
//=================================================================================================
|
||||
|
||||
/* Desc:Function takes an opcode which was transmitted via USB
|
||||
* then decodes it to call designated function.
|
||||
* shared_dict_swim.h is used in both host and fw to ensure opcodes/names align
|
||||
* Pre: Macros must be defined in firmware pinport.h
|
||||
* opcode must be defined in shared_dict_swim.h
|
||||
* Post:function call complete.
|
||||
* Rtn: SUCCESS if opcode found, error if opcode not present or other problem.
|
||||
*/
|
||||
uint8_t swim_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_t *rdata )
|
||||
{
|
||||
#define RD_LEN 0
|
||||
#define RD0 1
|
||||
#define RD1 2
|
||||
|
||||
#define BYTE_LEN 1
|
||||
#define HWORD_LEN 2
|
||||
switch (opcode) {
|
||||
case SWIM_ACTIVATE: swim_activate(); break;
|
||||
case SWIM_RESET: swim_reset(); break;
|
||||
// case SWIM_SRST: swim_srst(); break;
|
||||
case WOTF:
|
||||
rdata[RD_LEN] = BYTE_LEN;
|
||||
rdata[RD0] = swim_woft(operand); break;
|
||||
// case ROTF:
|
||||
// rdata[RD_LEN] = BYTE_LEN;
|
||||
// rdata[RD0] = swim_roft(); break;
|
||||
default:
|
||||
//opcode doesn't exist
|
||||
return ERR_UNKN_SWIM_OPCODE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
uint8_t swim_pin;
|
||||
uint16_t swim_mask;
|
||||
GPIO_TypeDef *swim_base;
|
||||
|
||||
void delay( uint16_t delay )
|
||||
{
|
||||
uint16_t i = 0;
|
||||
|
||||
for( i=0; i<delay; i++) {
|
||||
NOP();
|
||||
NOP();
|
||||
} //16->11.8 on stmad
|
||||
|
||||
}
|
||||
|
||||
/* Desc:Initiate SWIM activate sequence
|
||||
* Pre: swim_pin must be set and initialized via io.h
|
||||
* Post:STM8 mcu SWIM active
|
||||
* Rtn: SUCCESS if able to enter sucessfully.
|
||||
*/
|
||||
void swim_activate()
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
// pinport_call( CTL_OP_, 0, swim_pin, 0);
|
||||
|
||||
//toggles in this manner take 4.55-4.6usec on AVR
|
||||
//toggles in this manner take 4.9-4.95usec on STM adapter
|
||||
|
||||
//pulse low for 16usec spec says 16usec
|
||||
//but looking at working programmers they do twice the delays below
|
||||
pinport_call( CTL_SET_LO_, 0, swim_pin, 0);
|
||||
delay(16);
|
||||
pinport_call( CTL_SET_HI_, 0, swim_pin, 0);
|
||||
|
||||
//toggle high->low T=1msec 4x
|
||||
for( i = 0; i < 4; i++) {
|
||||
//STM adapter 720 = 500.9usec
|
||||
//TODO move this timed code into a timer to make timing more stable
|
||||
//between boards, pinport.c code, etc....
|
||||
#ifdef STM_INL6
|
||||
delay(719);
|
||||
#endif
|
||||
#ifdef STM_ADAPTER
|
||||
delay(720);
|
||||
#endif
|
||||
pinport_call( CTL_SET_LO_, 0, swim_pin, 0);
|
||||
delay(718);
|
||||
pinport_call( CTL_SET_HI_, 0, swim_pin, 0);
|
||||
}
|
||||
|
||||
//toggle high->low T=0.5msec 4x
|
||||
for( i = 0; i < 4; i++) {
|
||||
//STM adapter 358 = 256usec
|
||||
delay(356);
|
||||
pinport_call( CTL_SET_LO_, 0, swim_pin, 0);
|
||||
delay(355);
|
||||
pinport_call( CTL_SET_HI_, 0, swim_pin, 0);
|
||||
}
|
||||
|
||||
//pinport_call( CTL_IP_PU_, 0, swim_pin, 0);
|
||||
|
||||
|
||||
//wait for device to take swim_pin low for ~16usec
|
||||
//it's low for 128 SWIM clock sync pulse
|
||||
//Best way to do this would be to wait for an interrupt
|
||||
//on the swim pin going low, then have the isr count
|
||||
//low time. If anything takes too long timeout.
|
||||
|
||||
//TODO
|
||||
//return SUCCESS/FAIL depending on wether that ~16usec pulse was obtained
|
||||
// return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/* Desc:Hold swim pin low for >128 SWIM clocks (16usec)
|
||||
* Pre: swim must be activated by
|
||||
* Post:STM8 mcu SWIM comms are reset
|
||||
* Rtn: SUCCESS if device responds with sync window.
|
||||
*/
|
||||
void swim_reset()
|
||||
{
|
||||
//pinport_call( CTL_OP_, 0, swim_pin, 0);
|
||||
|
||||
//pulse low for 16usec spec says 16usec
|
||||
//but looking at working programmers they do twice the delays below
|
||||
pinport_call( CTL_SET_LO_, 0, swim_pin, 0);
|
||||
delay(16);
|
||||
pinport_call( CTL_SET_HI_, 0, swim_pin, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define mov_swim_mask_r0() __asm ("mov r0, %[val]" : : [val] "r" (swim_mask) : "r0" )
|
||||
#define mov_pushpull_r6() __asm ("mov r6, %[val]" : : [val] "r" (pushpull) : "r6" )
|
||||
#define mov_opendrain_r7() __asm ("mov r7, %[val]" : : [val] "r" (opendrain) : "r7" )
|
||||
|
||||
//BSRR 0x18
|
||||
#define str_r0_bset() __asm volatile ("strh r0, [%[mmio], #0x18]" : : [mmio] "r" (swim_base))
|
||||
//BRR 0x28
|
||||
#define str_r0_bres() __asm volatile ("strh r0, [%[mmio], #0x28]" : : [mmio] "r" (swim_base))
|
||||
//OTYPER 0x04
|
||||
#define pp_swim() __asm volatile ("strh r6, [%[mmio], #0x04]" : : [mmio] "r" (swim_base))
|
||||
#define od_swim() __asm volatile ("strh r7, [%[mmio], #0x04]" : : [mmio] "r" (swim_base))
|
||||
|
||||
/* Desc:Transfer SWIM bit stream
|
||||
* Always outputs '0' as first bit for header "from host"
|
||||
* Will output len number of bits plus one for header
|
||||
* Pre: swim_pin must be set and initialized via io.h
|
||||
* stream has first data bit stored in bit15 - bit[15-len+2]
|
||||
* pairity bit must be last bit in stream sequence bit[15-len+1]
|
||||
* ie bit7 contains pairity bit for 8bit data stream
|
||||
* Post:STM8 mcu SWIM active
|
||||
* Rtn: 0xFF if no response, 0-NAK, non-zero non-0xFF if ACK.
|
||||
*/
|
||||
uint8_t swim_out(uint16_t stream, uint8_t len)//, GPIO_TypeDef *base)
|
||||
{
|
||||
__asm("swim_out:\n\t");
|
||||
|
||||
uint8_t return_val;
|
||||
|
||||
uint16_t pushpull = swim_base->OTYPER & ~swim_mask;
|
||||
uint16_t opendrain = swim_base->OTYPER | swim_mask;
|
||||
|
||||
mov_swim_mask_r0(); //will store r0 to BSRR or BRR to set/clear
|
||||
mov_pushpull_r6(); //will store r7 to OTYPER to drive high
|
||||
mov_opendrain_r7(); //will store r6 to OTYPER to allow device to drive low
|
||||
|
||||
//store len in r5
|
||||
__asm volatile ("mov r5, %[val]" : : [val] "r" (len) : "r5" );
|
||||
|
||||
//set flags so first bit is header '0' "from host"
|
||||
//the stream comes in as 16bit value with stream bit 7 in bit position 15
|
||||
//shift the stream left so the current transfer bit is in bit position 31
|
||||
//15 -> 30 is 15bit shifts, this leaves header zero in bit position 31
|
||||
//store stream in r4
|
||||
__asm volatile ("lsl r4, %[val], #15" : : [val] "r" (stream) : "r4", "cc" );
|
||||
|
||||
//NOTE! cortex M0 only supports 'S' versions of lsl, sub, and, etc type
|
||||
//opcodes. I get compiler error for including the 's' at end of instruction
|
||||
//but lsl is same as lsls on M0, so just use lsl to avoid compiler error...
|
||||
|
||||
// bit start:
|
||||
__asm("bit_start:\n\t");
|
||||
|
||||
//always start going low
|
||||
str_r0_bres();
|
||||
|
||||
//current bit is stored in bit31 and Negative flag is set if
|
||||
//current bit is '1'
|
||||
__asm volatile ("bpl cur_bit_zero\n\t");
|
||||
//go high since current bit is '1'
|
||||
pp_swim();
|
||||
str_r0_bset();
|
||||
od_swim();
|
||||
__asm volatile ("b det_next_bit\n\t");
|
||||
|
||||
__asm("cur_bit_zero:\n\t");
|
||||
//must delay same amount of time as instructions above since branch
|
||||
//add delay here until '1' and '0' are same length
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
NOP();
|
||||
|
||||
__asm("det_next_bit:\n\t");
|
||||
|
||||
//determine if this is the last bit
|
||||
__asm volatile ("sub r5, #0x01" : : : "r5", "cc" );
|
||||
|
||||
//if last bit, go to stream end to prepare for ACK/NAK latch
|
||||
__asm volatile ("bmi stream_end\n\t");
|
||||
|
||||
//determine next bit value
|
||||
__asm volatile ("lsl r4, #1" : : : "r4", "cc" );
|
||||
//Negative flag is now set for '1', and clear for '0'
|
||||
|
||||
//delay until 'go high' time for '0'
|
||||
//add delay here to make all bit transfers longer
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
NOP(); NOP(); NOP(); NOP();
|
||||
|
||||
//always go high for '0' (no effect if already high for '1')
|
||||
pp_swim();
|
||||
str_r0_bset();
|
||||
od_swim();
|
||||
|
||||
//go to bit start
|
||||
__asm volatile ("b bit_start\n\t");
|
||||
|
||||
//stream end:
|
||||
__asm("stream_end:\n\t");
|
||||
|
||||
//delay until 'go high' time for '0'
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
NOP(); NOP(); NOP();
|
||||
|
||||
//always go high for '0' (no effect if already high for '1')
|
||||
pp_swim();
|
||||
str_r0_bset();
|
||||
od_swim();
|
||||
|
||||
//delay until time to latch ACK/NAK from device
|
||||
NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
|
||||
//first need to ensure device is actually responding
|
||||
//sample when output should be low for a 1 or 0
|
||||
//str_r0_bres(); //debug set low to denote when swim pin is being sampled with logic anaylzer
|
||||
//sampling ~100nsec into bit transfer (low for 125nsec min)
|
||||
|
||||
//latch SWIM pin value from IDR 0x10
|
||||
__asm volatile ("ldrh %[rv], [%[mmio], #0x10]" : [rv] "=r" (return_val) : [mmio] "r" (swim_base));
|
||||
__asm volatile ("and %[rv], r0" : [rv] "=r" (return_val) : : );
|
||||
|
||||
//if it wasn't low, then the device didn't respond, so return error designating that
|
||||
__asm volatile ("bne no_response\n\t");
|
||||
|
||||
//if (return_val != 0) {
|
||||
// goto no_response;
|
||||
// }
|
||||
|
||||
//now delay until ~half way through bit transfer to sense 1-ACK or 0-NAK
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
|
||||
//debug set low to denote when swim pin is being sampled with logic anaylzer
|
||||
//str_r0_bres();
|
||||
//sampling 1.35usec into bit transfer (~half way)
|
||||
|
||||
//latch SWIM pin value from IDR 0x10
|
||||
__asm volatile ("ldrh %[rv], [%[mmio], #0x10]" : [rv] "=r" (return_val) : [mmio] "r" (swim_base));
|
||||
|
||||
//mask out swim pin so return value is 0 or non-zero based on device output
|
||||
return_val &= swim_mask;
|
||||
|
||||
if (return_val != 0xFF) {
|
||||
//dummy check that keeps labels below available
|
||||
//because inline assembly is pissing me off
|
||||
goto return_response;
|
||||
}
|
||||
|
||||
__asm("no_response:\n\t");
|
||||
//return "fail to respond"
|
||||
return_val = 0xFF;
|
||||
|
||||
return_response:
|
||||
//return ACK/NAK from device
|
||||
return return_val;
|
||||
|
||||
// __asm("bkpt");
|
||||
//BSRR 0x18
|
||||
//BRR 0x28
|
||||
//OTYPER 0x04
|
||||
// __asm ("mov r0, %[mask]" : : [mask] "r" (swim_mask) : "r0" );
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x28]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x18]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x28]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x18]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x28]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x18]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x28]" : : [mmio] "r" (swim_base));
|
||||
// //__asm volatile ("nop");
|
||||
// //__asm volatile ("nop");
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x04]" : : [mmio] "r" (swim_base));
|
||||
// __asm volatile ("strh r0, [%[mmio], #0x18]" : : [mmio] "r" (swim_base));
|
||||
|
||||
// __asm volatile ("strh %[val], [%[mmio], #0x28]" : [val] "=l" (swim_mask) : [mmio] "l" (swim_base));
|
||||
//// __asm volatile ("nop");
|
||||
// __asm volatile ("strh %[val], [%[mmio], #0x18]" : [val] "=l" (swim_mask) : [mmio] "l" (swim_base));
|
||||
//// __asm volatile ("nop");
|
||||
// __asm volatile ("strh %[val], [%[mmio], #0x28]" : [val] "=l" (swim_mask) : [mmio] "l" (swim_base));
|
||||
//// __asm volatile ("nop");
|
||||
// __asm volatile ("strh %[val], [%[mmio], #0x18]" : [val] "=l" (swim_mask) : [mmio] "l" (swim_base));
|
||||
//
|
||||
// //for some reason this last store writes a different value to the mmio register! WTF!!!!
|
||||
// //8000800: 851a strh r2, [r3, #40] ; 0x28^M
|
||||
// //8000802: 831a strh r2, [r3, #24]^M
|
||||
// //8000804: 851a strh r2, [r3, #40] ; 0x28^M
|
||||
// //8000806: 831a strh r2, [r3, #24]^M
|
||||
// //8000808: 851a strh r2, [r3, #40] ; 0x28^M
|
||||
// //800080a: 831a strh r2, [r3, #24]^M
|
||||
// //800080c: 851a strh r2, [r3, #40] ; 0x28^M
|
||||
// //800080e: 831a strh r2, [r3, #24]^M
|
||||
// //8000810: 8319 strh r1, [r3, #24]^M
|
||||
// __asm volatile ("strh %[val], [%[mmio], #0x18]" : [val] "=l" (swim_mask) : [mmio] "l" (swim_base));
|
||||
|
||||
// __asm volatile ("nop");
|
||||
// __asm("bkpt");
|
||||
|
||||
|
||||
// NOP();
|
||||
// NOP();
|
||||
// //delay(1);
|
||||
// EXP0_HI();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// delay(10);
|
||||
// EXP0_LO();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// NOP();
|
||||
// EXP0_HI();
|
||||
|
||||
|
||||
|
||||
// asm (
|
||||
// "TST LR, #0x40\n\t"
|
||||
// "BEQ from_nonsecure\n\t"
|
||||
// "from_secure:\n\t"
|
||||
// "TST LR, #0x04\n\t"
|
||||
// "ITE EQ\n\t"
|
||||
// "MRSEQ R0, MSP\n\t"
|
||||
// "MRSNE R0, PSP\n\t"
|
||||
// "B hard_fault_handler_c\n\t"
|
||||
// "from_nonsecure:\n\t"
|
||||
// "MRS R0, CONTROL_NS\n\t"
|
||||
// "TST R0, #2\n\t"
|
||||
// "ITE EQ\n\t"
|
||||
// "MRSEQ R0, MSP_NS\n\t"
|
||||
// "MRSNE R0, PSP_NS\n\t"
|
||||
// "B hard_fault_handler_c\n\t"
|
||||
// );
|
||||
|
||||
|
||||
//output bit stream from bit15 to bit15-len
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Desc:write byte to SWIM
|
||||
* Pre: swim must be activated
|
||||
* Post:
|
||||
* Rtn: 0-NAK, 1-ACK beware, no response looks like ACK!
|
||||
*/
|
||||
uint8_t swim_woft(uint8_t data)
|
||||
{
|
||||
//bit sequence:
|
||||
//1bit header "0" Host comm
|
||||
//3bit command b2-1-0 "010" WOTF
|
||||
//1bit pairity xor of cmd "1"
|
||||
//1bit ACK "1" or NAK "0" from device
|
||||
// 0b0_0101
|
||||
uint16_t i;
|
||||
i = swim_out( 0x5000, 4);
|
||||
|
||||
//trim return value to single byte
|
||||
if (i == 0xFF) {
|
||||
return 0xFF;
|
||||
} else if ( i == 0) {
|
||||
//NAK
|
||||
return 0;
|
||||
} else {
|
||||
//ACK, continue to next byte
|
||||
return 1;
|
||||
}
|
||||
|
||||
//1bit header "0" from host
|
||||
//8bits data7:0
|
||||
//1bit parity of data
|
||||
//1bit ACK "1" or NAK "0" from device
|
||||
// 0b0-data-pb
|
||||
//swim_out( data<<8, 9);//, EXP0bank, EXP0 );
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue